feat(codex): support async questions - #9512
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default 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 375ba22. Configure here.
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This change adds a new Codex async-question workflow across protocol handling, orchestration, persistence, streaming, retention, and web/mobile clients. It also adds a static-analysis diagnostic suppression in a test file, while the runtime changes to active turns and durable pending-question state merit focused human review. You can add or adjust custom eligibility rules. Learn more. |
375ba22 to
44eae6a
Compare

Codex's new
request_user_input_asynctool sends questions inagentMessagenotifications, notitem/tool/requestUserInputrequests. T3 dropped the question metadata and could not show an answer form.Preserve that metadata and use the existing web, desktop, and mobile question panels. Answers go through the normal user-message path while Codex keeps working, or resume the session after it finishes. Pending questions survive reconnects and long runs. Duplicate replies are rejected.
The Codex handler and installed 0.153.0 schema confirm the format. The older blocking request path is unchanged.
Verification
Screenshot
Created with GPT-6 Astra (preview) in Codex.
Note
Medium Risk
Touches orchestration command handling, turn-pause/streaming semantics, and activity retention; behavior is heavily tested but mistakes could break async replies or duplicate-answer guards.
Overview
Adds end-to-end support for Codex async user questions (
request_user_input_async): completedagentMessageitems withdelivery: "async"are mapped touser-input.requestedevents carryingresponseMode: "message", so web, desktop, and mobile can show the existing question UI without blocking the turn.Orchestration behavior changes for that mode: ingestion no longer pauses the turn on
user-input.requested, assistant streaming can continue, andthread.user-input.respondresolves the request by appendinguser-input.resolved, sending a formatted user message, and starting/resuming a turn (with validation for incomplete answers and duplicate replies). The engine loads the latest request/resolution via newgetUserInputActivitybefore deciding, so replies still work when command snapshots omit or cap activities; the projector retains unresolved message-mode requests past the usual 500-activity window.Clients now keep questions with no options when custom answers are allowed (including free-text-only async prompts). Contracts and Codex protocol schemas gain
responseModeand asyncquestions/deliveryfields onagentMessageitems.Reviewed by Cursor Bugbot for commit 44eae6a. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add async question support for Codex provider across adapter, orchestration, and schemas
CodexAdapter.mapToRuntimeEventsnow emitsuser-input.requestedevents (withresponseMode: "message") for completed async agent messages containing questions, instead of normal item lifecycle handlingProviderRuntimeIngestionskips the pause-and-flush path for message-modeuser-input.requestedevents so subsequent assistant text continues streaming in the same turndecideOrchestrationCommandin decider.ts validates message-mode answers (non-empty, not duplicate, not already resolved), appendsuser-input.resolved, and starts a new user turnProjectionSnapshotQuery.getUserInputActivityin ProjectionSnapshotQuery.ts queries SQLite for the latest requested/resolved user-input activity by thread and request ID, so orchestration can resolve requests even after they fall outside the capped in-memory read modelretainThreadActivitiesin projector.ts preserves unresolved message-mode questions beyond the 500-activity window; resolved requests are dropped from the pending setagentMessageschemas with optional nullabledeliveryandquestionsfieldsallowCustomAnsweris explicitlyfalseProjectionSnapshotQueryShapenow requiresgetUserInputActivity; all in-tree test doubles are updated but out-of-tree implementations of this interface must add the method.UserInputQuestionOption.descriptionin providerRuntime.ts now accepts empty strings.Macroscope summarized 44eae6a.