AnthropicContentBlock / antigravity ClaudeContentItem serialized `signature`
with omitempty, so thinking blocks without an upstream signature (Chat
Completions reasoning_content, Responses reasoning without encrypted_content,
every streamed thinking content_block_start) went out with no `signature` key.
Anthropic always sends the key (`""` on content_block_start). Strict clients
such as Grok Build deserialize it as a required field and abort the response
or SSE stream with "missing field `signature`".
- apicompat: thinking MarshalJSON always emits `thinking` and `signature`
- antigravity: ClaudeContentItem MarshalJSON does the same; streamed thinking
content_block_start carries `signature: ""`
- tests: wire-shape regression tests; update TestStreamingReasoning expectation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chat Completions file parts already become Responses input_file, but the
Antigravity path dropped them when converting to Anthropic and then to
Gemini. Map data-URI input_file to a document block and emit it as
inlineData so Gemini receives the PDF.
Fixes#7583
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.
- 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>
- 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
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>
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.
Google released Gemini 3.7 Flash on 2026-08-13. Register it alongside 3.8
using the same shape as the existing 3.6 entries: bare id plus the
Antigravity -high/-low/-medium/-tiered thinking tiers, the model catalog,
the custom-mapping passthroughs, fallback pricing and the tier alias
normalizer.
Pricing matches 3.8 at $0.75 input / $3.75 output / $0.075 cached input
per MTok. Both are promotional through 2026-12-31 and double on
2027-01-01; the constants note this.
Also corrects the 3.8 catalog timestamps to the documented GA dates.
Google released Gemini 3.8 Flash on 2026-09-02. Register the model and its
Antigravity thinking tiers the same way Gemini 3.6 Flash is registered:
- DefaultAntigravityModelMapping: bare id plus -high/-low/-medium/-tiered
- geminiModels catalog exposed through /antigravity/v1/models
- ensureAntigravityDefaultPassthroughs so accounts with a custom
model_mapping still resolve the new ids
- fallback pricing and the thinking-tier alias normalizer, so the tiers
share the base model price card instead of failing pricing lookup
Fallback rates are Google's published prices: $0.75 input / $3.75 output /
$0.075 cached input per MTok. These are promotional through 2026-12-31 and
double on 2027-01-01; the constant carries a note to that effect.
Refs #6523
Add gateway.models_list_read_max_bytes with the existing 8 MiB behavior as its default, and apply it consistently to generic, Codex, and Antigravity model-list reads.
Read one sentinel byte for Codex manifests so oversized responses return an explicit bounded upstream error instead of malformed JSON.
The struct field alone never reached the wire: the raw passthrough
pipeline is covered by enableMixedGeminiToolInvocations (#5711), but
TransformClaudeToGeminiWithOptions builds GeminiToolConfig from scratch
and never set the flag, so gemini-* models entering through the Claude
format gateway could still hit the upstream 400 from issue #5709.
- Set IncludeServerSideToolInvocations=true when the built tool
declarations mix functionDeclarations with googleSearch, matching the
raw-path injection semantics.
- Replace the marshal-roundtrip-only test with behavior tests that
drive TransformClaudeToGeminiWithOptions: mixed tools set the flag,
function-only and web-search-only requests leave it unset.
- Add IncludeServerSideToolInvocations field to GeminiToolConfig to prevent dropping client tool settings.
- Fix HTTP 400 error when mixing built-in tools (e.g. Google Search) with function calling on Gemini 3.6/3.7 models.
- Add serialization/deserialization unit test TestGeminiToolConfig_IncludeServerSideToolInvocations.
Fixes#5709