You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Claude Code sends Anthropic Messages requests, while a Claude provider configured with api_format: "openai_responses" forwards them to an OpenAI Responses-compatible upstream. The existing bridge handles the common text and tool-call paths, but several protocol edges can still make otherwise compatible upstreams fail:
some Responses-compatible upstreams require stream: true, including when the downstream Anthropic request is non-streaming;
Anthropic hosted WebSearch tools, tool history, Responses web_search_call items, and URL citations need an explicit round-trip contract;
a Responses item may be assembled by multiple events, with terminal snapshots, citations, or titles arriving after earlier deltas;
failures may arrive as an HTTP non-2xx response, a JSON error document, or an SSE error/failed event;
a transient overload can be retried safely before any client-visible output, but replaying after output has been committed can duplicate text or tool calls.
I would like to contribute a staged fix and am opening this issue first to confirm the intended scope and PR split.
Relation to existing work
Intermittent Stream ended without receiving any events when translating OpenAI Responses to Anthropic SSE #390 and commit 9689abfe hardened the baseline Responses-to-Anthropic stream lifecycle for empty or terminal-only streams. This proposal builds on that fix; it does not reopen or replace it. The lifecycle work below is limited to the additional terminal validation and client-commit boundary needed by hosted WebSearch and safe retries.
feat(codex): add per-provider option to disable hosted web search #409 controls whether Codex advertises hosted web search to a native Responses provider. This proposal concerns the different path where Claude Code sends an Anthropic hosted-WebSearch request and cc-switch translates it to and from Responses.
I could not find an existing issue covering the Claude server_tool_use / web_search_tool_result round trip, URL citations, or retrying a transient Responses failure before any Anthropic output is committed.
User-visible failures
Depending on the upstream and request shape, these gaps can appear as:
an upstream 400 requiring stream to be enabled;
WebSearch completing without usable result blocks or citations;
malformed follow-up history after a search/open/find operation;
an HTTP error body being parsed as successful SSE;
a transient overload being returned immediately even though no output was exposed to Claude Code;
duplicated output if a retry happens after the client has already received content.
This proposal is provider-agnostic. It does not depend on a particular relay, model name, base URL, or credential format.
Proposed invariants
Responses request and terminal handling
Claude requests routed through openai_responses always use the upstream request shape required by the Responses streaming path.
Non-WebSearch requests keep the current fast streaming path and existing behavior.
HTTP status, content type, JSON error documents, SSE error events, and terminal Responses events are classified before a successful Anthropic response is committed.
A terminal event must agree with the embedded response status. Conflicting identities, indexes, event types, or terminal states fail closed.
Output items are owned and ordered by output_index; partial events may enrich an item but must not silently replace a conflicting completed item.
Stream validation is bounded by both time and bytes and must not retain an unbounded post-terminal tail.
Hosted WebSearch
Enable the special path only when the incoming Anthropic request contains a supported hosted WebSearch tool.
Map supported request fields explicitly. Reject unsupported tool versions or incompatible fields instead of guessing.
Fold valid prior server_tool_use and web_search_tool_result history back into Responses input items so follow-up turns remain valid.
Treat completed Responses items as the authoritative source for search/open/find actions, result sources, and message annotations.
Emit stable adjacent Anthropic server_tool_use and web_search_tool_result blocks in output_index order.
Preserve URL citations on the owning text block and calculate offsets without corrupting non-ASCII text.
Enforce the caller's WebSearch usage limit locally when the upstream format cannot represent it safely.
Buffer only the hosted-WebSearch response path when late metadata makes early emission unsafe. Ordinary requests remain streaming.
Transient retry
Retry only recognized transient Responses failures, such as overload or temporary service unavailability.
Retry only before any client-visible Anthropic event has been committed.
Never retry invalid requests, authentication errors, or other permanent failures.
Share the existing request timeout and provider-attempt budget; retries must not create an independent unbounded wait.
Use a small bounded retry count and capped backoff.
Once output has been committed, surface the failure without replaying the request.
Explicit non-goals
Implementing web browsing or fetching inside cc-switch.
Changing Claude Code's domain-safety checks for Fetch.
Supporting arbitrary or undocumented provider extensions.
Treating partial or failed WebSearch output as successful content.
Changing the behavior of providers that do not use openai_responses.
Including provider-specific URLs, model names, credentials, or captured private payloads in tests.
Proposed delivery
I propose small, reviewable PRs rather than one combined patch:
Bounded pre-commit retries for transient Responses failures.
Reasoning-continuation transport, if maintainers agree that it belongs in this bridge; otherwise this remains a separate proposal.
Every PR would include its own sanitized unit/integration fixtures and would pass the repository's formatting, lint, and test requirements. No PR would depend on live credentials or network access.
Acceptance criteria
Existing ordinary Claude-to-Responses text and function-tool tests remain unchanged and pass.
Streaming and downstream non-streaming Anthropic requests both use a valid Responses upstream path.
Search, open, and find actions produce valid Anthropic server-tool blocks.
Result sources and URL citations survive the current turn, including Chinese and emoji text.
Valid follow-up history can be transformed back to Responses input.
HTTP/JSON/SSE failures are not mistaken for successful output.
Transient failures retry only before client commit and stop at the shared timeout/retry limit.
A failure after the first client-visible output is never replayed.
Malformed, conflicting, unsupported, or oversized streams fail deterministically.
Tests use local scripted upstreams and contain no private service information.
Questions for maintainers
Does this scope fit the intended openai_responses compatibility layer?
Is a WebSearch-only buffered path acceptable when completed items and citations can arrive late?
Would you prefer the retry work before or after the WebSearch PR?
Should encrypted reasoning continuity be included in this effort or discussed separately?
Summary
Claude Code sends Anthropic Messages requests, while a Claude provider configured with
api_format: "openai_responses"forwards them to an OpenAI Responses-compatible upstream. The existing bridge handles the common text and tool-call paths, but several protocol edges can still make otherwise compatible upstreams fail:stream: true, including when the downstream Anthropic request is non-streaming;web_search_callitems, and URL citations need an explicit round-trip contract;I would like to contribute a staged fix and am opening this issue first to confirm the intended scope and PR split.
Relation to existing work
9689abfehardened the baseline Responses-to-Anthropic stream lifecycle for empty or terminal-only streams. This proposal builds on that fix; it does not reopen or replace it. The lifecycle work below is limited to the additional terminal validation and client-commit boundary needed by hosted WebSearch and safe retries.I could not find an existing issue covering the Claude
server_tool_use/web_search_tool_resultround trip, URL citations, or retrying a transient Responses failure before any Anthropic output is committed.User-visible failures
Depending on the upstream and request shape, these gaps can appear as:
400requiringstreamto be enabled;This proposal is provider-agnostic. It does not depend on a particular relay, model name, base URL, or credential format.
Proposed invariants
Responses request and terminal handling
openai_responsesalways use the upstream request shape required by the Responses streaming path.output_index; partial events may enrich an item but must not silently replace a conflicting completed item.Hosted WebSearch
server_tool_useandweb_search_tool_resulthistory back into Responses input items so follow-up turns remain valid.server_tool_useandweb_search_tool_resultblocks inoutput_indexorder.Transient retry
Explicit non-goals
Fetch.openai_responses.Proposed delivery
I propose small, reviewable PRs rather than one combined patch:
Every PR would include its own sanitized unit/integration fixtures and would pass the repository's formatting, lint, and test requirements. No PR would depend on live credentials or network access.
Acceptance criteria
Questions for maintainers
openai_responsescompatibility layer?