diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 4043e4a5dd..4722e45e76 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -20,6 +20,37 @@ jobs: run: | git fetch --depth 1 https://github.com/router-for-me/models.git main git show FETCH_HEAD:models.json > internal/registry/models/models.json + - name: Strip Claude entries from antigravity catalog (ampeco Patch 4) + # Antigravity's published catalog advertises Claude models served by + # Google's cloudcode-pa.googleapis.com. With those entries present, an + # antigravity OAuth becomes eligible alongside the Anthropic OAuth pool + # for `claude-*` selector picks. Session-affinity then pins entire + # Claude Code sessions (parent + sub-agents) to the antigravity OAuth + # whenever the parent request was a Gemini call, exhausting + # Antigravity's small Sonnet quota within hours. Strip them post-refresh + # so the antigravity OAuth is Gemini-only. + run: | + python3 - <<'PY' + import json + p = "internal/registry/models/models.json" + with open(p) as f: + d = json.load(f) + if "antigravity" in d: + before = len(d["antigravity"]) + d["antigravity"] = [ + m for m in d["antigravity"] + if not ( + m.get("id", "").startswith("claude-") + or m.get("type", "") == "claude" + or m.get("owned_by", "") == "anthropic" + ) + ] + after = len(d["antigravity"]) + print(f"antigravity catalog: {before} -> {after} entries ({before - after} claude stripped)") + with open(p, "w") as f: + json.dump(d, f, indent=2) + f.write("\n") + PY - run: git fetch --force --tags - uses: actions/setup-go@v4 with: diff --git a/README.md b/README.md index 9d6ce7d505..df9e32d00e 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,20 @@ Remove `cache_control` from `messages[].content[]`, `system[]`, `tools[]`, and m When the credential's API key starts with `sk-ant-oat01-`, route via `Authorization: Bearer …` instead of `x-api-key`. Real `sk-ant-api03-*` API keys keep the existing `x-api-key` routing. +### Patch 4 — strip Claude entries from the `antigravity` model catalog + +`internal/registry/models/models.json` and `.github/workflows/release.yaml` (post-refresh step). + +Antigravity's published catalog includes `claude-opus-4-6-thinking` and `claude-sonnet-4-6` because Google's AI Code Assist tier resells Claude models via `cloudcode-pa.googleapis.com`. With those entries present, an antigravity OAuth becomes eligible alongside the Anthropic OAuth pool when the selector picks for `claude-*` routes. Session-affinity then pins entire Claude Code sessions (parent + sub-agents) to the antigravity OAuth whenever the parent request was a Gemini call, exhausting Antigravity's small Sonnet quota within hours. + +Strip every entry whose `id` starts with `claude-`, whose `type` is `claude`, or whose `owned_by` is `anthropic` from the `antigravity` array. Applied both to the in-tree `models.json` (so `go test ./...` and local dev see the patched shape) and to the release workflow's post-refresh step (so upstream catalog refreshes during tagged builds re-apply the strip automatically). After the patch the antigravity OAuth is Gemini-only and Claude requests fall through to the Anthropic OAuth pool. + ## Tests ```bash go test ./internal/translator/openai/claude/... # Patches 1 + 2 go test ./internal/runtime/executor/ -run 'OAuthAccessTokenUsesBearerAuth|ApiKeyStillUsesXApiKey' # Patch 3 +go test ./internal/registry/... # Patch 4 (catalog integrity) ``` ## Rebase diff --git a/internal/registry/models/models.json b/internal/registry/models/models.json index fa56bb42a2..1d374e1f27 100644 --- a/internal/registry/models/models.json +++ b/internal/registry/models/models.json @@ -1874,40 +1874,6 @@ } ], "antigravity": [ - { - "id": "claude-opus-4-6-thinking", - "object": "model", - "owned_by": "antigravity", - "type": "antigravity", - "display_name": "Claude Opus 4.6 (Thinking)", - "name": "claude-opus-4-6-thinking", - "description": "Claude Opus 4.6 (Thinking)", - "context_length": 200000, - "max_completion_tokens": 64000, - "thinking": { - "min": 1024, - "max": 64000, - "zero_allowed": true, - "dynamic_allowed": true - } - }, - { - "id": "claude-sonnet-4-6", - "object": "model", - "owned_by": "antigravity", - "type": "antigravity", - "display_name": "Claude Sonnet 4.6 (Thinking)", - "name": "claude-sonnet-4-6", - "description": "Claude Sonnet 4.6 (Thinking)", - "context_length": 200000, - "max_completion_tokens": 64000, - "thinking": { - "min": 1024, - "max": 64000, - "zero_allowed": true, - "dynamic_allowed": true - } - }, { "id": "gemini-3-flash", "object": "model",