Adds a case with the real block layout (attribution block, identity sentence,
task instructions) and asserts that user content mentioning Claude Code and
claude-sonnet-4-6 is forwarded unchanged.
Stripping the x-anthropic-billing-header line is not enough. Claude Code's
Agent SDK prompts (session title generation, and other SDK-driven calls) open
a separate system block with
You are a Claude agent, built on Anthropic's Claude Agent SDK.
and the Google upstream still rejects those requests with 429 RESOURCE_EXHAUSTED.
Measured on Sub2API 0.2.7, which already contains the attribution fix, using an isolated single-account group, waiting for the per-model cooldown
to expire before every request so that a previous failure could not turn later
results into 503:
original request replayed 429 (8/8)
same request, generic system prompt 200 (8/8)
attribution also removed client-side 429 (3/3)
attribution removed + identity neutralized 200 (3/3)
only 'Claude' replaced in system 200 (2/2)
only 'Anthropic' removed from system 200 (2/2)
output_config / max_tokens / non-stream no effect
The rewrite is anchored at the start of a system block, so user instructions that
merely mention Claude or Anthropic, and model ids such as claude-sonnet-4-6, are
left untouched. Scoped to the Antigravity transformer, as with the existing
attribution handling.
Gemini/Antigravity delivers tool arguments as one complete object, so this
converter synthesizes the Responses tool-call stream itself and therefore owns
its self-consistency. The done event was built without Arguments, leaving it ""
while the preceding delta carried the entire JSON. Clients that reconcile the
done payload against the accumulated deltas (OpenAI Responses SDK); Qoder's
reconcileToolCall) reject that mismatch as inconsistent_tool_call and abort the
turn non-retryably, so every tool call through the gateway failed.
Emit state.CurrentArgs, which closeCurrentResponsesItem already uses for the
item, restoring sum(deltas) == done.arguments == item.arguments.
Regression test asserts the delta sum equals the done payload and fails closed
when Arguments is dropped.
DeepSeek native Responses rejects Codex view_image results when function_call_output.output contains input_image parts. Move media into a following user message and keep the tool output as a string so call_id pairing remains valid.
- Replace unchecked single-value type assertions with comma-ok form
guarded by require.True (errcheck check-type-assertions)
- Remove trailing blank line flagged by gofmt
Co-Authored-By: Claude Code <noreply@anthropic.com>
The Responses to Chat Completions bridge mapped both the instructions field and role developer items to system messages. Codex always sends both, and also injects developer notices mid-conversation when switching models, so the forwarded request contained consecutive leading system messages and mid-conversation system messages. Strict Qwen-family upstreams reject this with HTTP 400 "System message must be at the beginning."
Leading system/developer messages are now merged into a single leading system message, and later system/developer messages are downgraded to user so the content is preserved without violating upstream role ordering.
- Fix test assertion target location for whereItems prefixItems
- Support const keyword normalization to enum and infer scalar type
- Infer scalar type for enum-only schema to prevent object reason injection
- Recursively clean properties and items after anyOf/oneOf merge
- Ensure empty prefixItems is safely deleted
- Handle JSON Schema Draft 2020-12 prefixItems (tuple arrays) by converting to a best-match items schema
- Ensure array schema always defines a valid items schema to prevent Gemini 400 'missing field: items.items' error
- Fix recursive traversal when a schema defines both properties and items
- Add comprehensive unit test cases for tuple and array schemas
The streaming Responses-to-Anthropic converter emitted assistant text only
from output_text.delta, so a stream carrying its answer on
response.output_text.done or in the terminal response.output produced a
protocol-valid message with no text.
Record emitted text per output_text part in a ledger that survives content
block closure, and recover only the suffix a finished payload adds, as #6629
does for function-call arguments. Where the part a payload finishes cannot be
established, decline to recover rather than repeat delivered text: terminal
recovery runs only when nothing was emitted, and a done payload indexed
differently from every delta is ignored.
Give output_text.done its own handler so the shared block-closing helper and
its tool-path caller stay unchanged, and so a payload arriving after
message_stop cannot open a content block past the end of the message.
Keep always-on toolConfig from main (reasoning models without tools) while
retaining the PR behavior that drops mixed built-in tools when client
function tools are present, so includeServerSideToolInvocations stays unused.
Co-authored-by: Cursor <cursoragent@cursor.com>
Update the leftover buildTools unit test that still expected
googleSearch to coexist with client function declarations.
Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve three conflicts from main's #6680 (supplementUnmappedOpenAIModels):
1. gateway_handler.go — keep PR's allowlist refactoring (ModelAllowlistEnabled,
writeAllowlistedModelsList, modelListingSource); main's OpenAI branch in
writeModelsList was auto-merged.
2. group_models_list.go (modify/delete) — delete file per PR intent; relocate
supplementUnmappedOpenAIModels to group_model_allowlist.go where gateway_service
and openai_codex_models_service can still call it.
3. openai_codex_models_service.go — combine main's supplementUnmappedOpenAIModels
wrapping with PR's ModelAllowlistEnabled() guard.
Also fix two auto-merged test files that still referenced the old
GroupModelsListConfig / ModelsListConfig types.
- Resolve conflict in openai_codex_models_service_test.go: keep both
GPT-6 Astra instructions template assertion (from this PR) and ultra
reasoning level + multi_agent fields (from #6718 on main)
- Fix compilation error on main: add missing `group *Group` parameter
to buildCodexModelsManifestForAccounts calls in
openai_codex_model_metadata_test.go (lines 24, 32) — caused by #6688
changing the function signature while #6718 added new callers with
the old signature
Upstream returns 400 INVALID_ARGUMENT when toolConfig is absent. The guard
`if !isReasoning || len(tools) > 0` skipped it for reasoning models called
without tools, contradicting the intent stated in the comment above it.
Set toolConfig unconditionally and cover the three cases with a unit test.
The Antigravity service fingerprints clients by the version embedded in the User-Agent header. The built-in default (1.23.2) had drifted far behind current real client builds, so requests using the default UA started failing OAuth and probe flows.
Bump DefaultUserAgentVersion from 1.23.2 to 2.9.1 (current client build) and update the constant test accordingly. The default remains overridable via ANTIGRAVITY_USER_AGENT_VERSION and the admin setting.