fix(tui/plan): defer PlanUpdate history while streaming to prevent interleaving between reasoning headings and content; queue and flush after stream finalization.

This commit is contained in:
James Peter
2025-09-01 21:45:35 +10:00
parent f1098ad1c2
commit 770d72c0ce
2 changed files with 15 additions and 2 deletions
+8 -2
View File
@@ -3149,8 +3149,14 @@ impl ChatWidget<'_> {
self.on_error(message);
}
EventMsg::PlanUpdate(update) => {
// Commit plan updates directly to history (no status-line preview).
self.add_to_history(history_cell::new_plan_update(update));
// Avoid interleaving plan updates inside streaming sections.
// If a stream is active, defer until the stream finalizes so
// the plan block doesn't split a heading and its content.
if self.is_write_cycle_active() {
self.interrupts.push_plan_update(update);
} else {
self.add_to_history(history_cell::new_plan_update(update));
}
}
EventMsg::ExecApprovalRequest(ev) => {
let id2 = id.clone();
@@ -7,6 +7,7 @@ use codex_core::protocol::ExecCommandEndEvent;
use codex_core::protocol::McpToolCallBeginEvent;
use codex_core::protocol::McpToolCallEndEvent;
use codex_core::protocol::PatchApplyEndEvent;
use codex_protocol::plan_tool::UpdatePlanArgs;
use super::ChatWidget;
@@ -19,6 +20,7 @@ pub(crate) enum QueuedInterrupt {
McpBegin(McpToolCallBeginEvent),
McpEnd(McpToolCallEndEvent),
PatchEnd(PatchApplyEndEvent),
PlanUpdate(UpdatePlanArgs),
}
#[derive(Default)]
@@ -67,6 +69,10 @@ impl InterruptManager {
self.queue.push_back(QueuedInterrupt::PatchEnd(ev));
}
pub(crate) fn push_plan_update(&mut self, ev: UpdatePlanArgs) {
self.queue.push_back(QueuedInterrupt::PlanUpdate(ev));
}
pub(crate) fn flush_all(&mut self, chat: &mut ChatWidget<'_>) {
while let Some(q) = self.queue.pop_front() {
match q {
@@ -79,6 +85,7 @@ impl InterruptManager {
QueuedInterrupt::McpBegin(ev) => chat.handle_mcp_begin_now(ev),
QueuedInterrupt::McpEnd(ev) => chat.handle_mcp_end_now(ev),
QueuedInterrupt::PatchEnd(ev) => chat.handle_patch_apply_end_now(ev),
QueuedInterrupt::PlanUpdate(ev) => chat.add_to_history(crate::history_cell::new_plan_update(ev)),
}
}
}