mirror of
https://github.com/openai/codex.git
synced 2026-05-02 20:32:04 +03:00
Handle orphan exec ends without clobbering active exploring cell (#12313)
Summary - distinguish exec end handling targets (active tracking, active orphan history, new cell) so unified exec responses don’t clobber unrelated exploring cells - ensure orphan ends flush existing exploring history when complete, insert standalone history entries, and keep active cells correct - add regression tests plus a snapshot covering the new behavior and expose the ExecCell completion result for verification Fix for https://github.com/openai/codex/issues/12278 --------- Co-authored-by: Josh McKinney <joshka@openai.com>
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
//! Data model for grouped exec-call history cells in the TUI transcript.
|
||||
//!
|
||||
//! An `ExecCell` can represent either a single command or an "exploring" group of related read/
|
||||
//! list/search commands. The chat widget relies on stable `call_id` matching to route progress and
|
||||
//! end events into the right cell, and it treats "call id not found" as a real signal (for
|
||||
//! example, an orphan end that should render as a separate history entry).
|
||||
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
@@ -67,17 +74,24 @@ impl ExecCell {
|
||||
}
|
||||
}
|
||||
|
||||
/// Marks the most recently matching call as finished and returns whether a call was found.
|
||||
///
|
||||
/// Callers should treat `false` as a routing mismatch rather than silently ignoring it. The
|
||||
/// chat widget uses that signal to avoid attaching an orphan `exec_end` event to an unrelated
|
||||
/// active exploring cell, which would incorrectly collapse two transcript entries together.
|
||||
pub(crate) fn complete_call(
|
||||
&mut self,
|
||||
call_id: &str,
|
||||
output: CommandOutput,
|
||||
duration: Duration,
|
||||
) {
|
||||
if let Some(call) = self.calls.iter_mut().rev().find(|c| c.call_id == call_id) {
|
||||
call.output = Some(output);
|
||||
call.duration = Some(duration);
|
||||
call.start_time = None;
|
||||
}
|
||||
) -> bool {
|
||||
let Some(call) = self.calls.iter_mut().rev().find(|c| c.call_id == call_id) else {
|
||||
return false;
|
||||
};
|
||||
call.output = Some(output);
|
||||
call.duration = Some(duration);
|
||||
call.start_time = None;
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn should_flush(&self) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user