feat: add active-turn message delivery controls - #5396
Conversation
|
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 Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
ApprovabilityVerdict: Needs human review This PR introduces a new 'Messages While Working' feature with steer/queue behavior, implementing a complete message queueing system (web) and turn-steering capability (server). The scope includes new user settings, UI changes, state management, and cross-cutting runtime behavior changes that warrant careful review. You can customize Macroscope's approvability policy. Learn more. |
|
@ClapFy this is a great start are you in a position to continue working on this until the AI reviews are clean? Some additional feedback:
|
56e5d17 to
508098f
Compare
There was a problem hiding this comment.
Effect service conventions review: one finding in apps/server/src/provider/Layers/CodexSessionRuntime.ts (tagged-failure recovery should use Effect.catchTags). Everything else in scope (new contracts schema, mobile preference atoms, web outbox store) looked consistent with the conventions.
Posted via Macroscope — Effect Service Conventions
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.
Reviewed by Cursor Bugbot for commit 57d23c5. Configure here.
| ...(input.effort ? { effort: input.effort } : {}), | ||
| ...(input.interactionMode ? { interactionMode: input.interactionMode } : {}), | ||
| }); | ||
| const rawResponse = yield* client.raw.request("turn/start", params); |
There was a problem hiding this comment.
Steer fallback starts second turn
High Severity
When turn/steer fails with CodexAppServerRequestError, sendTurn falls through to turn/start without re-reading whether the session is still running. A rejected steer while the active turn is alive can therefore open a second overlapping Codex turn.
Reviewed by Cursor Bugbot for commit 57d23c5. Configure here.
|
@chrisdeeming i fixed the issues but the ai checks are stick on the "Pending" status. |
The PR also contains a fix for a chat bug with Codex where you sometimes just can't stop the agent |


What Changed
Adds a Messages while working setting to web and mobile with two delivery behaviors:
The running web composer now keeps Stop generation visible beside the mode-specific send action. Mobile uses the same preference and snapshots it onto each outbox entry so existing queued work keeps its intended delivery behavior.
Codex sessions now use
turn/steerwhen a turn is active, matching the steering behavior already supported by the other provider adapters. A successful steer reaffirms the running turn to orchestration so no stale pending-turn projection is left behind.Why
While an agent was working, the composer only exposed Stop and did not let users choose whether a follow-up should affect the current turn or wait for the next one. That made rapid follow-ups awkward and left queue semantics inconsistent between web and mobile.
Delivery safeguards
Verification
vp test run packages/contracts/src/settings.test.ts apps/mobile/src/state/thread-outbox.test.ts apps/server/src/provider/Layers/CodexSessionRuntime.test.ts apps/server/src/provider/Layers/CodexAdapter.test.ts apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts apps/web/src/webThreadOutbox.test.ts apps/web/src/components/settings/settingsSearch.test.ts— 137 tests passedvp lintacross all 23 changed TypeScript files with--report-unused-disable-directivesvp fmtacross all 23 changed TypeScript filesgit diff --checkModel: GPT-5.6 Sol | Harness: Codex in T3 Code
Note
Add active-turn message delivery controls to steer or queue messages while a turn is running
ActiveTurnMessageBehavior('steer' or 'queue', default 'steer') toClientSettings, mobile preferences, and the server-sideQueuedThreadMessageschema, allowing users to configure what happens when they send a message while a session is active.ChatViewenqueues messages to a new per-threaduseWebThreadOutboxStore(cross-tab persistent via localStorage) when queuing is required;WebThreadOutboxDraindrains the queue in FIFO order, updating thread settings and pausing on definitive failures.useThreadComposerStateawaits persisted preferences before sending, clears the draft immediately, includesactiveTurnMessageBehaviorin the queued payload, and restores the draft on failure.sendTurnnow attempts aturn/steerwhen the session is running, falls back toturn/startif steering is rejected, and serializes concurrent calls with a semaphore.Macroscope summarized 57d23c5.
Note
High Risk
Changes message delivery, Codex session/orchestration reconciliation, and durable outbox state across web and mobile; mis-steering or queue drain bugs could duplicate turns or drop user messages.
Overview
Introduces
activeTurnMessageBehavior(steer|queue, default steer) in shared settings and on mobile preferences, with Messages while working controls in web and mobile settings.Steer injects follow-ups into the running turn; queue holds them per thread and delivers FIFO after the current turn. The running composer now shows Stop next to a mode-specific primary action (Steer / Queue / Send) and surfaces queued counts with retry when delivery pauses.
Web adds a durable
useWebThreadOutboxStore(localStorage, cross-tab) andWebThreadOutboxDrainto send queued heads when the thread is ready;ChatViewenqueues instead of blocking when queue mode (or an existing queue) applies, andrestoreComposerContentmerges failed sends without clobbering text typed after send.Mobile snapshots behavior on each outbox entry, awaits settled preferences before enqueue (avoiding a steer default while prefs load), and updates outbox drain so steer can send while a turn is running and steerable.
Server (Codex) routes active-turn sends through
turn/steer(semaphore-serialized, fallback toturn/starton rejection), synthesizesturn/startedwhen steer keeps the same turn, mapssession/error, and adds projection coverage so steers reconcile to a single running turn.Reviewed by Cursor Bugbot for commit 57d23c5. Bugbot is set up for automated code reviews on this repo. Configure here.