Skip to content

fix(server): render async Codex messages - #9227

Open
Gigioxx wants to merge 1 commit into
pingdotgg:mainfrom
Gigioxx:t3code/fix-issue-9222
Open

Gigioxx wants to merge 1 commit into
pingdotgg:mainfrom
Gigioxx:t3code/fix-issue-9222

Conversation

@Gigioxx

@Gigioxx Gigioxx commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Codex emits send_user_message_async as a separate completed agent message during an active turn. Provider ingestion always matched assistant completions to the active streamed segment, so it discarded the async message text whenever commentary was already buffered.

This matches completions to active segments by provider item ID. A different item now becomes its own assistant message while the original segment stays active. Focused coverage reproduces buffered commentary, an async message, and the original completion in one turn.

Fixes #9222.

Verification

  • vp test run apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts (51 passed)
  • server typecheck
  • targeted lint and formatting
  • diff whitespace check

Implemented with gpt-5.6-sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes assistant message completion and segment lifecycle in provider ingestion, which affects how all multi-item turns are projected; scope is narrow but message ordering/content is user-visible.

Overview
Fixes Codex async assistant messages (send_user_message_async) being dropped when a turn already had buffered/streaming commentary on another item.

Provider runtime ingestion now ties item.completed for assistant messages to the active segment only when the completion’s provider item id matches that segment’s baseKey. A completion for a different item finalizes as its own assistant message and no longer reuses or overwrites the in-flight segment. Segment state is cleared only when the completing event matches that active segment, so commentary can keep streaming after an interleaved async message completes.

Adds an integration test that streams commentary, completes a separate async assistant item, then completes the commentary item and asserts both texts appear in the thread projection.

Reviewed by Cursor Bugbot for commit f4be4d7. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix async assistant message preservation in ProviderRuntimeIngestion

Assistant completion events were updating the wrong active message when a turn contained separate async assistant messages. The completion handler now matches the active assistant segment by its segment base key, and derives the assistant message ID from that matching segment. Segment state is cleared only when a matching completing segment is found.

  • Adds an integration test in ProviderRuntimeIngestion.test.ts that emits commentary text, completes a separate async assistant message, then verifies both texts remain projected.

Macroscope summarized f4be4d7.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Sep 2, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at e0bb5bc

Macroscope's review found this PR approvable — This is a small, targeted server bug fix that associates assistant completions with the correct provider item and includes focused regression coverage for interleaved Codex messages. Existing matching behavior remains intact, with no schema, configuration, deployment, or sensitive-package changes.

You can add or adjust custom eligibility rules. Learn more.

@shivamhwp

Copy link
Copy Markdown
Collaborator

Note: GPT-6 on behalf of shivam (@shivamhwp).

Please rebase the item-ID match onto the current completion handler while preserving its direct projection queries. Current main uses getThreadMessageById and projectionThreadMessages.hasAssistantMessageForTurn; restoring the old whole-thread detail read would undo that change.

Use the existing emitAndDrain helper for the new regression instead of waitForThread polling. Include two async completions followed by another delta on the original item, so the regression covers both repeated updates and continued commentary.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Codex harness accepts send_user_message_async but the UI drops the messages

2 participants