You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Summary
- absorb repeated empty ACP `end_turn` responses after a cancelled turn
before admitting the next logical prompt
- add a deterministic mock ACP scenario plus ACP and TUI PTY regressions
for the cancel-tail ordering bug
- include the investigation report and evidence captured for the
cancellation-ordering behavior
## Test Plan
- [x] `cargo test -p mock-acp-agent`
- [x] `cargo test -p codex-acp`
- [x] `cargo build --bin nori && cargo test -p tui-pty-e2e`
Copy file name to clipboardExpand all lines: codex-rs/acp/docs.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -818,6 +818,8 @@ When `Op::Interrupt` fires, the ACP backend now only submits `InboundEvent::Canc
818
818
-`SessionPhaseChanged(Idle)` and `PromptCompleted { stop_reason, last_agent_message }` are emitted only when that prompt response is reduced
819
819
- queued follow-up prompts remain in the reducer-owned outbound queue until an eligible drain point (`stop_reason: end_turn`)
820
820
821
+
`SacpConnection::prompt()` also carries a small amount of session-local transport state so cancellation tails can be absorbed without widening the public phase model. If the previous prompt ended with `Cancelled`, the next prompt request may receive one or more immediate empty `end_turn` responses before the agent starts working on the user's real follow-up prompt. The connection layer now treats those empty terminal responses as stale cancel-tail cleanup and retries the same ACP prompt request until either streamed updates arrive or a non-stale stop reason is observed. That keeps the reducer contract unchanged: it still only sees the final logical completion for the user-facing prompt turn.
822
+
821
823
This removes the old synthetic interrupt-abort fast-path that treated cancel as immediate idle. The TUI now renders ACP interrupt state from reducer-owned phase/completion projections instead of inferring prompt ownership from interrupt timing.
0 commit comments