Conversation
|
Read through this since it overlaps the tool-call plumbing we've been poking at lately. Header precedence in buildBaseCodexHeaders looks right — attribution goes in first, the caller's additionalHeaders are applied last, so explicit overrides still win. I side-eyed x-client-request-id being threadId instead of a per-request id, but codex-rs does the same (core/src/client.rs sets it from responses_metadata.thread_id), so that's faithful to the official client. Also like that client_metadata is stripped from the WS input-delta comparison before caching a continuation, so the new attribution can't invalidate delta reuse, while response.create frames still merge turn_state into client_metadata. Nothing else jumped out — the attribution test coverage looks thorough. |
gaoanze888
left a comment
There was a problem hiding this comment.
Reviewed the full attribution lifecycle at exact head 08fcee626. The focused agent, proxy, Codex routing, compatible-provider, and coding-agent window tests pass: 108 tests across 7 files.
The identity boundaries are consistent: one foreground turn survives tool continuations, steering, provider/session retries, and overflow recovery; follow-ups/new prompts rotate the turn; compaction uses a separate request kind; committed compactions advance the branch-derived window while failed/cancelled attempts do not. Resume preserves the session/thread identity and a fork receives a new one.
Wire behavior is scoped correctly. Native Codex receives the canonical headers/client metadata; compatible OpenAI adapters require explicit codexAttribution: "official"; caller headers retain final override control. Routing state is isolated across account, endpoint, session, thread, and cleanup, and stale handshakes cannot repopulate cleared state. Metadata is opaque identifiers/timestamps rather than conversation content, and header JSON is ASCII escaped. No blocker found.
This comment is AI-generated by /wr
Pi does not send Codex's canonical session, thread, turn, window, and request-kind metadata. Requests within one user input group therefore cannot be reliably attributed across tool continuations, retries, steering, and compaction recovery.
Add a provider-neutral
requestIdentityto stream options, generated by the agent runtime and propagated through proxy serialization. Native Codex requests project that identity into the official headers andclient_metadatafor SSE, WebSocket handshakes, and each WebSocketresponse.createframe.OpenAI-compatible adapters can opt in explicitly:
Chat Completions sends the canonical headers. Responses sends the same headers plus
client_metadata. Unset preserves existing compatible-provider behavior, and explicit caller or extension headers retain final override control. Proxies must forward the supplied attribution to their backend.One logical turn ID is reused for the initial request, tool-result continuations, steering, provider retries, session retries, and overflow recovery. New prompts and queued follow-ups receive a new ID. Compaction requests are identified separately. Session and root thread identity remain stable across resume. Context-window numbers are derived from committed compactions on the active branch, without a separate persisted counter.
Attribution changes no longer invalidate otherwise valid WebSocket input deltas. Native Codex also retains the first server-provided
x-codex-turn-statefor each logical turn, replaying it in HTTP requests or WebSocket frames, not automatic WebSocket handshake headers. New turns receive fresh state. Account and endpoint changes discard old routing and cached connections; stale handshakes cannot restore them or trigger fallback for the new owner. Session cleanup releases the state.Fixes #9481.
Validation:
npm run checkand./test.shpass on the updated branch. All 82 focused AI tests pass, including stale handshake success/failure, account and endpoint changes, cleanup, concurrent connections, routing replay, and cached input. SDK regressions cover compaction success, failure, cancellation, overflow recovery, resume, tree navigation, and forks.A live native Codex check with
gpt-6-astraat medium reasoning verified a tool continuation after forced reconnect reused the turn's routing state and a subsequent new turn received fresh state. This checks observable routing behavior, not backend quota accounting. The final handshake-race correction was validated with deterministic tests; no additional live run or rebuild was performed for it.AI-assisted implementation and PR description.