Fix repeated steering and reliable stop#3903
Conversation
- Resolve the provider runtime’s authoritative active Codex turn - Treat projected steer messages as server dispatch acknowledgement - Avoid stale root turn IDs when interrupting for steering - Cover active-turn lookup and running-thread steer behavior
- Resolve active Codex turns from timed, observable thread reads - Match projected steer acknowledgements to the dispatched message - Add realistic regression coverage for interrupt and steer paths
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cf6b0c8. Configure here.
ApprovabilityVerdict: Needs human review This PR modifies core session runtime logic - turn interruption now makes an RPC call to the provider rather than using local state, and adds new steer acknowledgement tracking. Changes to session management behavior warrant human review. You can customize Macroscope's approvability policy. Learn more. |
- Fall back to provider response order when start times are absent - Cover both mixed timestamp ordering cases

Summary
Allow users to send consecutive steering prompts while a conversation is running and reliably stop the active Codex turn after any number of steers. Steering dispatches now clear as soon as the server projects the exact submitted user message, while interruption resolves the provider's live active turn instead of relying on potentially stale projected state.
What Changed
thread/readrequest with turns included, selecting the newest in-progress turn by timestamp and falling back to provider response order when timestamps are absent.Why
Running conversations could leave the composer busy after steering because acknowledgement depended on turn or session transitions that do not occur for an in-turn steer. After steering, stop could also target a stale cached turn rather than the provider's actual active turn. Together, these behaviors prevented repeated steering and made interruption unreliable precisely when users needed it most.
Validation
pnpm exec vp check(passes with existing lint warnings)pnpm exec vp run typecheckpnpm exec vp test apps/web/src/components/ChatView.logic.test.ts apps/server/src/provider/Layers/CodexSessionRuntime.test.ts(40 tests passed)pnpm exec vp test apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts(32 tests passed)Proof
Note
Medium Risk
Changes stop/interrupt targeting and composer in-flight semantics during active turns; behavior is constrained by timeouts, explicit fallbacks, and new regression tests.
Overview
Fixes in-turn steering leaving the composer stuck “busy” and stop targeting a stale Codex turn after multiple steers.
On the web side, each send records an expected user message id in the local dispatch snapshot.
hasServerAcknowledgedLocalDispatchnow treats a running session steer as acknowledged when that exact message appears on the thread, without waiting for turn or session field changes.ChatViewpasses the outgoing message id intobeginLocalDispatchand feedsgetLatestUserMessageIdinto the ack check.On the server, Codex
interruptTurnno longer defaults to the cachedsession.activeTurnIdalone.resolveCodexInterruptTurnIdissues a boundedthread/read(with turns), picks the active turn viafindActiveCodexTurnId, falls back to the cached id only when the read fails, and skips interrupt when the read succeeds but reports no in-progress turn.Reviewed by Cursor Bugbot for commit 3414977. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix repeated steering acknowledgment and reliable turn interrupt stop
expectedUserMessageIdfield inLocalDispatchSnapshot(ChatView.logic.ts).interruptTurnnow fetches the current thread state viathread/read(2-second timeout) to resolve the active turn, rather than relying on a potentially stale projectedactiveTurnId(CodexSessionRuntime.ts).hasServerAcknowledgedLocalDispatchnow requires alatestUserMessageIdargument at all call sites.Macroscope summarized 3414977.