fix(chat): reprise robuste au retour d'un layout non conversationnel (composer verrouillé selon l'état réel, replay complet du scrollback, plus de fausse terminaison 'no reply') (#190)

This commit is contained in:
2026-08-11 19:50:35 +02:00
parent 5470d30371
commit ddecf9e0c5
4 changed files with 252 additions and 30 deletions

View File

@ -2415,6 +2415,7 @@ pub async fn agent_send(
let meta = state.structured_sessions.meta_for_session(&sid);
std::thread::spawn(move || {
let mut terminal_visible = false;
let mut streamed_text = String::new();
let mut settler = crate::chat::ProgressSettler::default();
for event in stream {
// Non-terminal, sans contenu chat : un signal de limite alimente le service
@ -2445,6 +2446,9 @@ pub async fn agent_send(
let Some(chunk) = crate::chat::chunk_from_event(event) else {
continue;
};
if let ReplyChunk::TextDelta { text } = &chunk {
streamed_text.push_str(text);
}
if matches!(chunk, ReplyChunk::Final { .. } | ReplyChunk::Error { .. }) {
terminal_visible = true;
}
@ -2455,13 +2459,16 @@ pub async fn agent_send(
let _ = bridge.send_output_settled(&sid, &mut settler, chunk);
}
if !terminal_visible {
let _ = bridge.send_output_settled(
&sid,
&mut settler,
let chunk = if streamed_text.trim().is_empty() {
ReplyChunk::Error {
message: "Le modèle n'a renvoyé aucune réponse.".to_owned(),
},
);
}
} else {
ReplyChunk::Final {
content: streamed_text,
}
};
let _ = bridge.send_output_settled(&sid, &mut settler, chunk);
}
bridge.detach_if(&sid, gen);
});