fix(codex): isolate standalone search per Claude Agent - #132
Open
momomuchu wants to merge 1 commit into
Open
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Summary
Codex standalone WebSearch identified its upstream search session only by the Claude Code session ID. Claude Code Workflow children share that parent session while carrying distinct direct Agent IDs, so sibling searches contended on one upstream search session and returned
409 Search session is busyafter the proxy's internal wait.This applies the ownership contract already established for continuation in #95/#96 to the standalone-search path.
Fixes #131.
Ownership model
(session ID, direct Agent ID)pair, length-prefixed so no delimiter shift can alias two different tuples.search-<uuid>fallback.The raw session and Agent IDs are never sent in the derived owner, and the owner has fixed length regardless of input size.
Change
CodexProvider::handle_messages_inneralready receives the parsedConversationIdentity; the standalone-search branch now passes it tosearch::build_search_requestinstead ofctx.session_id.The same owner also had to reach the wire headers.
post_searchthreadsSearchRequest.idthroughattempt_post_searchintobuild_codex_search_headers, which overridessession_id,x-client-request-id, andx-codex-window-id(<id>:0) for search requests only. Without that, the body was agent-scoped while the headers still carried the shared parent session.Ordinary generation, continuation, compaction, count-tokens, model routing, and other providers are untouched.
Tests
request_identity: same agent stable; siblings distinct; same agent across sessions distinct; length-prefix boundary case (session-aa/gent-avssession-a/agent-a); bounded length; no raw ID disclosure; Main preserved.providers::codex::search: Main preserves the raw session ID; agent owners stable and isolated; absent identity yields fresh distinct IDs; the existing forced-vs-automatic negative control is unchanged.tests/smoke_cutover.rs::codex_standalone_search_uses_conversation_identity_owner: drives/v1/messagesend to end against a mock upstream and asserts all four identity carriers agree, siblings differ, differing parents do not change the owner, Main stays raw, and missing/malformed identity stays stateless.Validation
just check-cion the committed tree:format-check✓clippy(-D warnings) ✓build✓test✓ (866 lib + 5 bin + all integration suites, includingcodex_agent_continuation12/12)Measured effect
Local fleet, three authenticated Codex accounts, several concurrent research workflows.
Before, five-minute window: 644 completions, 478
409, 163200; 409 latency p50 15.1 s, p95 24.5 s.After, running this build: an eight-agent Workflow issued 24
WebSearchand 8WebFetchcalls across 8 distinct Agent IDs with 0 tool errors, and the proxy log after cutover shows 964 completions, 0 failures, 31 completed searches at p50 2.0 s, p95 3.0 s.No credentials, request bodies, or target data are included.