Skip to content

feat(codex): support async questions - #9512

Merged
t3dotgg merged 2 commits into
mainfrom
t3code/support-codex-async-questions
Sep 4, 2026
Merged

feat(codex): support async questions#9512
t3dotgg merged 2 commits into
mainfrom
t3code/support-codex-async-questions

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Sep 3, 2026

Copy link
Copy Markdown
Member

Codex's new request_user_input_async tool sends questions in agentMessage notifications, not item/tool/requestUserInput requests. 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

  • 334 focused tests pass, including ongoing streaming, database reopen, duplicate replies, and retention after 500 later events.
  • Scoped server, protocol, web, and mobile typechecks pass.
  • Scoped lint passes with existing warnings in protocol schema tests.
  • Theo tested async questions in the shared local build and confirmed they work. The screenshot below shows a question while Codex continues working.

Screenshot

Async question shown while Codex continues working

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): completed agentMessage items with delivery: "async" are mapped to user-input.requested events carrying responseMode: "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, and thread.user-input.respond resolves the request by appending user-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 new getUserInputActivity before 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 responseMode and async questions/delivery fields on agentMessage items.

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.mapToRuntimeEvents now emits user-input.requested events (with responseMode: "message") for completed async agent messages containing questions, instead of normal item lifecycle handling
  • ProviderRuntimeIngestion skips the pause-and-flush path for message-mode user-input.requested events so subsequent assistant text continues streaming in the same turn
  • decideOrchestrationCommand in decider.ts validates message-mode answers (non-empty, not duplicate, not already resolved), appends user-input.resolved, and starts a new user turn
  • ProjectionSnapshotQuery.getUserInputActivity in 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 model
  • retainThreadActivities in projector.ts preserves unresolved message-mode questions beyond the 500-activity window; resolved requests are dropped from the pending set
  • Schema generation in generate.ts augments agentMessage schemas with optional nullable delivery and questions fields
  • Web and mobile parsers in session-logic.ts and threadActivity.ts now retain optionless questions unless allowCustomAnswer is explicitly false
  • Risk: ProjectionSnapshotQueryShape now requires getUserInputActivity; all in-tree test doubles are updated but out-of-tree implementations of this interface must add the method. UserInputQuestionOption.description in providerRuntime.ts now accepts empty strings.

Macroscope summarized 44eae6a.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Sep 3, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread apps/server/src/orchestration/decider.ts
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.7 KiB 13.7 KiB −2 B (−0.0%) 15.1 KiB
Codex Thread snapshot wire 7.0 KiB 7.0 KiB −9 B (−0.1%) 7.3 KiB
Codex Live turn WebSocket wire 6.7 KiB 6.7 KiB +7 B (+0.1%) 7.8 KiB
Codex Live turn WebSocket decoded 58.5 KiB 58.5 KiB 0 B (0.0%) 66.4 KiB
Codex Live turn messages 10 10 0 (0.0%) 21
Claude Total thread wire 13.4 KiB 13.6 KiB +153 B (+1.1%) 15.1 KiB
Claude Thread snapshot wire 7.0 KiB 7.0 KiB +3 B (+0.0%) 7.3 KiB
Claude Live turn WebSocket wire 6.4 KiB 6.6 KiB +150 B (+2.3%) 7.8 KiB
Claude Live turn WebSocket decoded 57.0 KiB 57.9 KiB +928 B (+1.6%) 66.4 KiB
Claude Live turn messages 8 10 +2 (+25.0%) 21

Baseline: e3723e0 · PR result: 44eae6a · Source CI: success

Scenario and decoded snapshot size

10 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.

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Comment thread apps/server/src/orchestration/decider.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

@t3dotgg
t3dotgg force-pushed the t3code/support-codex-async-questions branch from 375ba22 to 44eae6a Compare September 4, 2026 00:25
Comment thread apps/server/src/provider/Layers/CodexAdapter.ts
@t3dotgg
t3dotgg merged commit d76b24d into main Sep 4, 2026
26 checks passed
@t3dotgg
t3dotgg deleted the t3code/support-codex-async-questions branch September 4, 2026 00:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant