fix(custom-cli): progression et messages d'outils restaurés au second tour — le projecteur ne retient plus les events de progress après le premier message, seuls Text/Error restent bufferisés — #252 (QA verte)
This commit is contained in:
@ -390,9 +390,12 @@ impl LiveTurnProjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.hold_until_new_message && self.seen_message_id {
|
if self.hold_until_new_message && self.seen_message_id {
|
||||||
|
if matches!(record.event, ParsedEvent::Text(_) | ParsedEvent::Error(_)) {
|
||||||
self.pending.push(record);
|
self.pending.push(record);
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
return self.emit_record(record);
|
||||||
|
}
|
||||||
|
|
||||||
self.emit_record(record)
|
self.emit_record(record)
|
||||||
}
|
}
|
||||||
@ -1226,6 +1229,84 @@ printf '%s\n' '{"type":"step_finish","sessionID":"seeded-engine","part":{"messag
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn send_with_tap_streams_progress_for_seeded_session_with_single_current_message_id() {
|
||||||
|
let tmp = TempDir::new("tap-seeded-single-message");
|
||||||
|
let script = tmp.path().join("opencode-fixture.sh");
|
||||||
|
write_executable_script(
|
||||||
|
&script,
|
||||||
|
r#"#!/bin/sh
|
||||||
|
printf '%s\n' '{"type":"step_start","sessionID":"seeded-engine","part":{"messageID":"current","type":"step-start"}}'
|
||||||
|
sleep 1
|
||||||
|
printf '%s\n' '{"type":"tool_use","sessionID":"seeded-engine","part":{"messageID":"current","type":"tool","tool":"idea_ask_agent"}}'
|
||||||
|
printf '%s\n' '{"type":"text","sessionID":"seeded-engine","part":{"messageID":"current","type":"text","text":"réponse courante"}}'
|
||||||
|
printf '%s\n' '{"type":"step_finish","sessionID":"seeded-engine","part":{"messageID":"current","type":"step-finish"}}'
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
let session = Arc::new(
|
||||||
|
OpenCodeSession::new(
|
||||||
|
SessionId::new_random(),
|
||||||
|
script.to_string_lossy(),
|
||||||
|
Vec::new(),
|
||||||
|
tmp.path().to_string_lossy(),
|
||||||
|
Some("seeded-engine".to_owned()),
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
|
let worker = {
|
||||||
|
let session = Arc::clone(&session);
|
||||||
|
tokio::spawn(async move {
|
||||||
|
session
|
||||||
|
.send_with_tap("prompt", tx)
|
||||||
|
.await
|
||||||
|
.map(|stream| stream.collect::<Vec<_>>())
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let (first_live, rx) = tokio::task::spawn_blocking(move || {
|
||||||
|
let first_live = rx
|
||||||
|
.recv_timeout(Duration::from_millis(500))
|
||||||
|
.expect("la session existante doit streamer le progress du tour courant");
|
||||||
|
(first_live, rx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
matches!(
|
||||||
|
first_live,
|
||||||
|
ReplyEvent::Progress { ref progress }
|
||||||
|
if progress.native_event.as_deref() == Some("step_start")
|
||||||
|
),
|
||||||
|
"le premier événement live doit être le step_start du message courant: {first_live:?}"
|
||||||
|
);
|
||||||
|
|
||||||
|
let returned = worker.await.unwrap().unwrap();
|
||||||
|
let live: Vec<_> = std::iter::once(first_live).chain(rx.into_iter()).collect();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
live.iter().any(|event| matches!(
|
||||||
|
event,
|
||||||
|
ReplyEvent::Progress { progress }
|
||||||
|
if progress.source == ReplyProgressSource::IdeaLocal
|
||||||
|
&& progress.kind == ReplyProgressKind::Mcp
|
||||||
|
&& progress.stage == ReplyProgressStage::Completed
|
||||||
|
&& progress.tool_name.as_deref() == Some("idea_ask_agent")
|
||||||
|
)),
|
||||||
|
"le tool_use du seul message courant doit atteindre le tap live: {live:?}"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
returned,
|
||||||
|
vec![ReplyEvent::Final {
|
||||||
|
content: "réponse courante".to_owned()
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_session_id_accepts_opencode_jsonl_session_id_variants() {
|
fn extract_session_id_accepts_opencode_jsonl_session_id_variants() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
Reference in New Issue
Block a user