Repository navigation
fix(codex): restore output omitted from terminal snapshots - #551
Merged
Menci merged 5 commits intoSep 30, 2026
Merged
Conversation
… snapshot
When Codex CLI triggers remote compaction over WebSocket, Floway failed
during native compaction decryption with `OpenAI Responses compact decryption:
native compaction returned no compaction output item`.
The Codex upstream streams `response.created` (output []) →
`response.in_progress` (output []) → `response.output_item.added` (item
`{type: "compaction", ...}`, output_index 0) → two
`response.compaction.compacting` events → `response.output_item.done` (same
item) → `response.completed` with `response.output: []`.
`reassembleOpenAIResponsesEvents` returned the terminal event's response
verbatim and ignored `response.output_item.done`, so
`collectOpenAIResponsesProtocolEventsToResult` yielded an empty output array.
Upstream Menci#530 (7a7b2c6) widened the type guard to
`compaction | compaction_summary`, but its tests fed a pre-filled terminal
`output`, leaving this stream shape uncovered.
The reassembler now follows the rule the client-facing egress already
applies: the spec makes the item lifecycle the authority, so once any item
closes, the closed items in `output_index` order replace the terminal
`output`; a turn that closed nothing keeps the terminal snapshot. That also
covers a Codex terminal that omits an assistant message it just closed, so
`collectSummaryTurn` in `compact-shim.ts` drops its own copy of that
collection. `OpenAIResponsesCompactionItem` types the wire metadata fields,
and `response.compaction.compacting` is recognized as a stream event.
A Responses Lite fixture that listed a reasoning item only in the terminal
now streams its lifecycle like the other items, as Codex CLI itself reads
items only from `response.output_item.done`.
Codex can emit complete message and compaction items while returning an empty or partial terminal output snapshot. Restore omissions inside the Codex provider after Responses Lite restoration, using observed output indices and item identities; expose ambiguous positions rather than guessing their order. Keep the generic Responses collector and client egress snapshot-based. OpenResponses defines item finalization and response snapshots without prescribing precedence for inconsistent upstream representations. Validated with 153 focused tests and live production gpt-6-luna generation and native compaction decryption. Existing access credentials were reused without OAuth refresh or production writes.
Reference the official OpenAI SDK definition for the event fields and distinguish progress from the final encrypted output item.
yyyr-p
added a commit
to yyyr-p/Floway
that referenced
this pull request
Oct 4, 2026
Integrates upstream commits e286553..c7e4d78: - refactor(responses): lower agent_message in a request middleware (Menci#576) - fix(claude-code): update subscription request defaults (Menci#571) - fix(compaction): use the context compaction shim by default (Menci#572) - fix(codex): derive quota expiry from exhausted windows (Menci#570) - fix(tls): support IP-literal certificate identities (Menci#569) - fix(web-search): resolve the OpenAI search passthrough lazily (Menci#568) - fix(provider-codex): update stable client identity for newer models (Menci#567) - fix(provider-codex): preserve Responses Lite wire semantics (Menci#543) - feat(web): adopt the blue Floway logo (Menci#563) - feat(codex): show and redeem ChatGPT reset cards (Menci#528) - fix(responses): answer Codex WebSocket prewarms locally (Menci#552) - fix(responses): handle positional tool declarations in middleware (Menci#558) - fix(gateway): preserve first-token timing across tool continuations (Menci#561) - fix(responses): consume hosted-tool streams before billing metadata (Menci#560) - fix(codex): restore output omitted from terminal snapshots (Menci#551) - fix(codex): preserve model catalog context windows (Menci#559) - fix(web): disable inactive upstream disclosure (Menci#534) - fix(translate): isolate translated request payloads (Menci#557) - feat(models): support Claude Sonnet 5.5 (Menci#555) - feat(models): support GPT-6.1 Sol (Menci#553) - fix(web): allow imported credentials on upstream creation (Menci#556) - fix(gateway): preserve hosted tool selection across aliases and continuations (Menci#549) - fix(translate): restore Responses callable identities (Menci#547) - perf(translate): bound namespace tool name allocation work (Menci#548) - fix(translate): preserve namespace descriptions on child tools (Menci#545) - feat(requests): show each request's time to first token (Menci#550) - fix(translate): reject ambiguous flat callable kinds (Menci#542) - fix(gateway): preserve client tool identity in hosted dispatch (Menci#538) - fix(web): mask credential headers in request record exports (Menci#539) Conflict resolutions: - upstreams/access-control.tsx: keep the fork's parameterized title, description, and error props (title/description ?? defaults, plus defaultOpen/revealOn) alongside upstream Menci#534's disclosureDisabled={!override}. - upstreams/access-control_test.tsx: union the Control helper to accept both error and initialOverride, and keep both Menci#534's disabled-disclosure case and the fork's validation-error cases. - control-plane/routes.ts: union the schemas.ts named imports -- the fork's OAuth2 admin bodies plus upstream Menci#528's codexRateLimitResetCreditsBody and codexRateLimitResetConsumeBody; both sides' route blocks merged cleanly. - requests/ttft_test.tsx (Menci#550): pass the fork's required exchangeStreams={[]} to the RequestDetailPanel cases that construct it with no collected streams. Verified with pnpm run verify (typegen, lint, typecheck, 611 test files / 6644 tests, test:installers, check:agents-md, check:generated-assets, check:verify-parity, build:web).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Codex can close message and native compaction items in
response.output_item.donewhile returning an empty or partial terminaloutput. Reading that snapshot verbatim loses emitted output and makes native compaction decryption fail withnative compaction returned no compaction output item.Restore omitted output at the Codex provider boundary after Responses Lite identities and request echoes have been restored. Output order comes from observed
output_indexvalues, and terminal items are matched to those indices by ID. Preserve terminal item data and response metadata; report missing positions or conflicting identities when reconstruction cannot establish a reliable order. Complete snapshots pass through unchanged.Shared Responses collection and client egress use terminal snapshots, and the compaction shim reads the provider-restored result for native item extraction and summary collection. The protocol types include native compaction progress and the item metadata returned by the upstream. OpenResponses defines both item finalization and response snapshots without prescribing precedence for inconsistent upstream representations.
Test Plan
gpt-6-luna. Three upstream HTTP 200 responses had empty terminal output; recovered output was[message],[compaction], and[reasoning, message], and the replay recovered the requested calendar requirements.