Gemini API rejects uniqueItems in tool schemas with 400. Add it to
unsupportedConstraints alongside minItems/maxItems where it belongs.
Same class of fix as #1424 and #1531.
1. Claude translator: add CleanJSONSchemaForGemini() to sanitize tool
input schemas (removes $schema, anyOf, const, format, etc.) and
delete eager_input_streaming from tool declarations. Remove fragile
bytes.Replace for format:"uri" now covered by schema cleaner.
2. Gemini native translator: filter out content entries with empty or
missing parts arrays to prevent Gemini API 400 error "required
oneof field 'data' must have one initialized field".
Both fixes align gemini-cli with protections already present in the
antigravity translator.
when Amp or Claude Code sends functionResponse with an empty name in Gemini
conversation history, the Gemini API rejects the request with 400
"Name cannot be empty". this fix backfills empty names from the
corresponding preceding functionCall parts using positional matching.
covers all three Gemini translator paths:
- gemini/gemini (direct API key)
- antigravity/gemini (OAuth)
- gemini-cli/gemini (Gemini CLI)
also switches fixCLIToolResponse pending group matching from LIFO to
FIFO to correctly handle multiple sequential tool call groups.
fixes#1903
feat(proxy): centralize proxy handling with `proxyutil` package and enhance test coverage
- Added `proxyutil` package to simplify proxy handling across the codebase.
- Refactored various components (`executor`, `cliproxy`, `auth`, etc.) to use `proxyutil` for consistent and reusable proxy logic.
- Introduced support for "direct" proxy mode to explicitly bypass all proxies.
- Updated tests to validate proxy behavior (e.g., `direct`, HTTP/HTTPS, and SOCKS5).
- Enhanced YAML configuration documentation for proxy options.
The Gemini v1internal (cloudcode-pa) and Antigravity Manager endpoints
require camelCase "systemInstruction" in request JSON. The current
snake_case "system_instruction" causes system prompts to be silently
ignored when routing through these endpoints.
Replace all "system_instruction" JSON keys with "systemInstruction" in
chat-completions and responses request translators.
test(translator): add unit tests for OpenAI to Claude requests and tool result handling
- Introduced tests for converting OpenAI requests to Claude with text, base64 images, and URL images in tool results.
- Refactored `convertClaudeToolResultContent` and related functionality to properly handle raw content with images and text.
- Updated conversion logic to streamline image handling for both base64 and URL formats.
- Simplified connection logic by removing `connCreateSent` and related state handling.
- Updated `buildCodexWebsocketRequestBody` to always use `response.create`.
- Added unit tests to validate `response.create` behavior and beta header preservation.
- Dropped unsupported `response.append` and outdated `response.done` event types.
- Add model to GetGeminiModels()
- Add model to GetGeminiVertexModels()
- Add model to GetGeminiCLIModels()
- Add model to GetAIStudioModels()
- Add to AntigravityModelConfig with thinking levels
- Update gemini-3-flash-preview description
Registers the new lightweight Gemini model across all provider
endpoints for cost-effective high-volume usage scenarios.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SetOAuthSessionError previously sent generic messages to the management
panel (e.g. "Failed to complete Gemini CLI onboarding"), hiding the
actual error returned by Google APIs. The specific error was only
written to the server log via log.Errorf, which is often inaccessible
in headless/Docker deployments.
Include the upstream error in all 8 OAuth error paths so the
management panel shows actionable messages like "no Google Cloud
projects available for this account" instead of a generic failure.
normalizeCacheControlTTL unconditionally re-serializes the entire request
body through json.Unmarshal/json.Marshal even when no TTL normalization
is needed. Go's json.Marshal randomizes map key order and HTML-escapes
<, >, & characters (to \u003c, \u003e, \u0026), producing different raw
bytes on every call.
Anthropic's prompt caching uses byte-prefix matching, so any byte-level
difference causes a cache miss. This means the ~119K system prompt and
tools are re-processed on every request when routed through CPA.
The fix adds a bool return to normalizeTTLForBlock to indicate whether
it actually modified anything, and skips the marshal step in
normalizeCacheControlTTL when no blocks were changed.