codex-antigravity-auth 2.2.0__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. {codex_antigravity_auth-2.2.0/codex_antigravity_auth.egg-info → codex_antigravity_auth-2.3.0}/PKG-INFO +90 -36
  2. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/README.md +89 -35
  3. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/account_state.py +13 -5
  4. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/accounts.py +147 -52
  5. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/cli.py +120 -7
  6. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/cli_doctor.py +37 -16
  7. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/cli_service.py +15 -2
  8. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/cli_setup.py +110 -42
  9. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/models.py +17 -7
  10. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/schema.py +12 -8
  11. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/server.py +907 -78
  12. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/service.py +47 -9
  13. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/SKILL.md +27 -17
  14. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/scripts/anti.py +2390 -346
  15. codex_antigravity_auth-2.3.0/codex_antigravity_auth/skills/anti/scripts/anti_lib/chunking.py +126 -0
  16. codex_antigravity_auth-2.3.0/codex_antigravity_auth/skills/anti/scripts/anti_lib/ledger.py +24 -0
  17. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/scripts/anti_lib/reflections.py +70 -31
  18. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/scripts/anti_lib/verifier.py +4 -1
  19. codex_antigravity_auth-2.3.0/codex_antigravity_auth/skills/anti/tests/fixtures/v5-lane-opus.json +20 -0
  20. codex_antigravity_auth-2.3.0/codex_antigravity_auth/skills/anti/tests/fixtures/v5-lane-sonnet.json +21 -0
  21. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/tests/test_anti.py +1405 -60
  22. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/transform.py +37 -17
  23. codex_antigravity_auth-2.3.0/codex_antigravity_auth/unified.py +413 -0
  24. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0/codex_antigravity_auth.egg-info}/PKG-INFO +90 -36
  25. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth.egg-info/SOURCES.txt +5 -1
  26. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/pyproject.toml +2 -1
  27. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_accounts.py +197 -1
  28. codex_antigravity_auth-2.3.0/tests/test_anti_new_features.py +833 -0
  29. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_cli.py +51 -0
  30. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_fidelity_edge_cases.py +31 -0
  31. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_regressions.py +77 -4
  32. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_release_workflow.py +1 -1
  33. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_schema_sanitization.py +5 -0
  34. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_server_streaming.py +695 -13
  35. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_service_manager.py +40 -1
  36. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_transform.py +19 -0
  37. codex_antigravity_auth-2.3.0/tests/test_unified_model_picker.py +490 -0
  38. codex_antigravity_auth-2.2.0/codex_antigravity_auth/skills/anti/scripts/anti_lib/chunking.py +0 -40
  39. codex_antigravity_auth-2.2.0/codex_antigravity_auth/skills/anti/scripts/anti_lib/ledger.py +0 -17
  40. codex_antigravity_auth-2.2.0/tests/test_anti_new_features.py +0 -351
  41. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/LICENSE +0 -0
  42. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/MANIFEST.in +0 -0
  43. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/__init__.py +0 -0
  44. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/byok.py +0 -0
  45. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/constants.py +0 -0
  46. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/google_transport.py +0 -0
  47. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/oauth.py +0 -0
  48. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/observability.py +0 -0
  49. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/onepassword.py +0 -0
  50. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/openai_transport.py +0 -0
  51. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/redaction.py +0 -0
  52. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/response_protocol.py +0 -0
  53. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/secure_store.py +0 -0
  54. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/service_manager.py +0 -0
  55. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/agents/openai.yaml +0 -0
  56. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/scripts/anti_lib/__init__.py +0 -0
  57. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/scripts/anti_lib/context.py +0 -0
  58. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/scripts/anti_lib/redaction.py +0 -0
  59. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/skills/anti/scripts/anti_lib/runner.py +0 -0
  60. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth/storage.py +0 -0
  61. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth.egg-info/dependency_links.txt +0 -0
  62. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth.egg-info/entry_points.txt +0 -0
  63. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth.egg-info/requires.txt +0 -0
  64. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/codex_antigravity_auth.egg-info/top_level.txt +0 -0
  65. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/setup.cfg +0 -0
  66. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/conftest.py +0 -0
  67. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_account_state.py +0 -0
  68. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_byok_providers.py +0 -0
  69. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_fidelity_transforms.py +0 -0
  70. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_google_transport.py +0 -0
  71. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_openai_transport.py +0 -0
  72. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_response_protocol.py +0 -0
  73. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_secure_store.py +0 -0
  74. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_security_hardening.py +0 -0
  75. {codex_antigravity_auth-2.2.0 → codex_antigravity_auth-2.3.0}/tests/test_storage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-antigravity-auth
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Google Antigravity OAuth model access for OpenAI Codex
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/Reedtrullz/codex-antigravity-auth
@@ -65,7 +65,7 @@ Use `$anti` only as an optional sidecar reviewer/planner after the gateway is wo
65
65
  - **OS-Native Keyring Encryption**: Encrypts Google account tokens and stored BYOK provider config at rest via macOS Keychain, Windows Credential Manager, Linux Secret Service, or a private local fallback key.
66
66
  - **Transaction-Safe Cooldown Rotations**: Automatically rotates accounts on backend failures (such as `401`, `403`, or `429` rate limiters) with clean exponential backoff.
67
67
  - **High-Fidelity SSE Translation**: Translates stream candidate envelopes, role alignments, reasoning-text deltas, function-call items, and VALIDATED tool parameter modes into Responses API events.
68
- - **BYOK Provider Routing**: Route model IDs like `deepseek:deepseek-v4-pro`, `bluesminds:grok-4.5`, `bluesminds:z-ai/glm-5.2`, `xai:grok-code-fast-1`, and custom OpenAI-compatible endpoints through encrypted API-key config.
68
+ - **BYOK Provider Routing**: Route model IDs like `deepseek:deepseek-v4-pro`, `xai:grok-code-fast-1`, `kimi:kimi-k2-0711-preview`, `ollama:gpt-oss:20b`, and custom OpenAI-compatible endpoints through encrypted API-key config.
69
69
 
70
70
  ## Installation
71
71
 
@@ -185,32 +185,19 @@ The skill also ships a helper-level panel mode inspired by MoA/Fusion workflows.
185
185
  python3 ~/.codex/skills/anti/scripts/anti.py panel --mode review --scope staged
186
186
  python3 ~/.codex/skills/anti/scripts/anti.py panel --mode plan --scope working-tree --prompt "Plan this PR"
187
187
  python3 ~/.codex/skills/anti/scripts/anti.py panel --mode ask --model sonnet --model openrouter:deepseek/deepseek-chat --judge opus --prompt "Compare these approaches"
188
- python3 ~/.codex/skills/anti/scripts/anti.py panel --mode ask --collab claude-grok --prompt "Compare these approaches"
189
- python3 ~/.codex/skills/anti/scripts/anti.py panel --mode ask --collab claude-grok --model sonnet --model opus --model grok-bluesminds --prompt "Compare these approaches"
190
188
  python3 ~/.codex/skills/anti/scripts/anti.py panel --mode review --scope staged --output findings
191
- python3 ~/.codex/skills/anti/scripts/anti.py moa --mode review --model deepseek-v4-pro --model glm-5.2 --judge opus --scope staged
192
- python3 ~/.codex/skills/anti/scripts/anti.py fusion --mode plan --model opus --model glm-5.2 --judge opus --scope working-tree --prompt "Plan this repository change"
189
+ python3 ~/.codex/skills/anti/scripts/anti.py moa --mode review --model deepseek-v4-pro --judge opus --scope staged
190
+ python3 ~/.codex/skills/anti/scripts/anti.py fusion --mode plan --model opus --model deepseek-v4-pro --judge opus --scope working-tree --prompt "Plan this repository change"
193
191
  ```
194
192
 
195
- Panel consensus is not proof and should not patch code directly. Structured findings include `id`, `claim`, `severity`, `lanes`, and `verify`; run the `verify` hint locally before acting. Text and JSON outputs include per-lane/judge usage and latency when the gateway/provider returns it. Broad review panels summarize oversized scopes once before fan-out instead of silently truncating raw context for every lane.
193
+ Panel consensus is not proof and should not patch code directly. Structured findings include `id`, `claim`, `severity`, `lanes`, and `verify`; run the `verify` hint locally before acting. Findings remain `unverified` until native/local checks confirm or reject them. Text and JSON outputs include per-lane/judge usage and latency when the gateway/provider returns it. Broad review panels summarize oversized scopes once before fan-out instead of silently truncating raw context for every lane.
196
194
 
197
- Panel JSON keeps requested and actual execution identities separate (`requestedModel`, `actualModel`, `provider`, `fallbackChain`, `primaryError`, and `fallbackReason`). The panel status is `complete_multi_model`, `partial_multi_model`, `degraded_single_model`, or `failed`; distinct actual provider/model identities, rather than repeated logical fallback lanes, satisfy `--min-successes`. `/v1/models` is only a catalog/readiness hint—the bounded generation call is the live model health check.
195
+ Panel JSON keeps requested and actual execution identities separate (`requestedModel`, `actualModel`, `provider`, `fallbackChain`, `primaryError`, and `fallbackReason`). The panel status is `complete_multi_model`, `partial_multi_model`, `same_provider_multi_model`, `degraded_single_model`, or `failed`; distinct actual provider/model identities, rather than repeated logical fallback lanes, satisfy `--min-successes`, and `--min-providers` can require provider diversity. `/v1/models` is only a catalog/readiness hint—the bounded generation call is the live model health check. Every saved run exposes top-level `runStatus`, `scopeStatus`, `panelStatus`, `coverage`, and `resultPath`.
198
196
  When the diversity minimum is not met, the panel fails closed before judge synthesis; `--json` and `--output findings` still return the lane evidence and status with a non-zero exit code.
199
197
 
200
- `--collab claude-grok` is an explicit collaboration profile for Claude plus Grok panels. It defaults to Sonnet, Opus, and `grok` (`xai-oauth:grok-build-0.1`), gives Claude and Grok complementary review instructions, and asks the Opus judge to compare Claude-backed and Grok-backed disagreements before recommending verification steps. `grok-oauth` selects that same OAuth route explicitly. To use BluesMinds deliberately, pass `--model sonnet --model opus --model grok-bluesminds`; `grok-bluesminds` and `grok-4.5` resolve to `bluesminds:grok-4.5`. The helper never silently fails over between the routes. If a requested Grok lane is not visible in `/v1/models`, it is recorded as a failed lane unless `--min-successes` makes the whole panel fail.
198
+ Panel lanes are selected explicitly from the native Sonnet/Opus defaults or from models advertised by the running gateway. BYOK examples include `openrouter:...`, `deepseek:...`, `xai:...`, `kimi:...`, `ollama:...`, and `opencode:...`; they require the corresponding API key or a key-optional local provider. When a BYOK lane receives repository, diff, or file context, the helper prints and records a disclosure naming the provider lane. Virtual picker models such as `panel:*`, `moa:*`, or `fusion:*` remain helper aliases rather than gateway-side fan-out.
201
199
 
202
- BYOK panel models such as `openrouter:...` or `xai-oauth:...` only work when the running gateway advertises them in `/v1/models`, which requires usable provider keys, key-optional local provider setup, or a refreshable OAuth login. When a BYOK lane receives repository, diff, or file context, the helper prints and records a disclosure naming the provider lanes. Virtual picker models such as `panel:*`, `moa:*`, or `fusion:*` are not supported; MoA/Fusion remains a helper workflow, not gateway-side orchestration.
203
-
204
- ### Choosing complementary reviewer lanes
205
-
206
- - DeepSeek V4 Flash is for a fast code second opinion, debugging, and an explicitly selected retryable fallback. It is never an automatic cross-provider fallback.
207
- - DeepSeek V4 Pro is for correctness, security, architecture, and deep code review. Treat it as unproven until the live V4 Pro generation, structured-output, and tool-loop gate passes.
208
- - xAI OAuth Grok is for adversarial assumptions, runtime surprises, and product/UX blind spots.
209
- - BluesMinds Grok/GLM aliases exist but remain unavailable/degraded until the requested route is advertised by `/v1/models` and the provider live-health gate passes. Every BluesMinds example is conditional on both checks.
210
-
211
- The normal service intentionally omits BluesMinds. The last bounded live checks returned a billing error for Grok 4.5 and an upstream 429 for GLM-5.2, so neither route is operationally enabled.
212
-
213
- A future enablement gate must pass first in a temporary process: catalog identity; non-streaming output and exact model identity; SSE completion and `[DONE]`; structured JSON; tool call and continuation; usage accounting; and bounded retries and no billing/capacity error. Only then may a later authorized task add `BLUESMINDS_API_KEY=op://...` to the durable service reference file and reinstall the service.
200
+ The current xAI preset is API-key based and uses `XAI_API_KEY`. Provider availability is determined by the gateway's `/v1/models` catalog; a catalog entry is not proof that a live generation will succeed.
214
201
 
215
202
  Repository context leaves the Google Antigravity lane only after explicit selection and the existing BYOK disclosure. Opus remains the default judge; native Codex remains the acting agent and must verify advisory output locally.
216
203
 
@@ -221,16 +208,13 @@ python3 ~/.codex/skills/anti/scripts/anti.py workflow review-ready --scope stage
221
208
  python3 ~/.codex/skills/anti/scripts/anti.py workflow plan-deep --scope working-tree --prompt "Plan this PR" --progress
222
209
  python3 ~/.codex/skills/anti/scripts/anti.py workflow ship-gate --scope diff --base origin/main --json
223
210
  python3 ~/.codex/skills/anti/scripts/anti.py workflow provider-compare --model sonnet --model openrouter:deepseek/deepseek-chat --prompt "Compare these approaches"
224
- python3 ~/.codex/skills/anti/scripts/anti.py workflow provider-compare --model deepseek-v4-pro --model glm-5.2 --prompt "Compare long-context planning approaches"
211
+ python3 ~/.codex/skills/anti/scripts/anti.py workflow provider-compare --model deepseek-v4-pro --prompt "Compare this approach with the native review lane"
225
212
  python3 ~/.codex/skills/anti/scripts/anti.py workflow security-review --scope staged --output findings
226
213
  python3 ~/.codex/skills/anti/scripts/anti.py workflow debug-consensus --prompt "Intermittent 502s after rotation"
227
- python3 ~/.codex/skills/anti/scripts/anti.py workflow claude-grok --panel-mode review --scope staged --output findings
228
- python3 ~/.codex/skills/anti/scripts/anti.py workflow claude-grok --panel-mode ask --prompt "Should this UX use route A or B?"
229
- python3 ~/.codex/skills/anti/scripts/anti.py workflow claude-grok --model sonnet --model opus --model grok-bluesminds --panel-mode ask --prompt "Stress-test this design"
230
214
  python3 ~/.codex/skills/anti/scripts/anti.py runs list
231
215
  ```
232
216
 
233
- Workflow runs save sanitized summaries under `~/.codex/anti-runs` by default; primitive `consult`, `plan`, `review`, and `panel` commands default to not writing a ledger unless `--save-output summary` or `--save-output full` is passed. Saved runs include the Anti run id, which is also sent as `metadata.run_id` to the gateway and appears in sanitized request logs for correlation. Raw prompts are not logged unless you explicitly choose full-output ledgers. `plan` and `review` use a conservative Claude safety budget with `--chunked auto`, so broad Opus/Sonnet work is split into bounded chunk calls before synthesis instead of being sent as one giant request; use `--chunked off` to intentionally bypass that safety budget, including when `--max-prompt-chars 0` is set. `--fallback-model sonnet --fallback-policy on-retryable` and `--progress` are available for long-running model calls that may otherwise fail silently or hit transient backend rotation errors.
217
+ Workflow runs save sanitized summaries under `~/.codex/anti-runs` by default; primitive `consult`, `plan`, `review`, and `panel` commands default to not writing a ledger unless `--save-output summary` or `--save-output full` is passed. Saved runs include the Anti run id, which is also sent as `metadata.run_id` to the gateway and appears in sanitized request logs for correlation. Run records never retain raw prompts: full mode keeps sanitized per-call output plus prompt hashes/counts, while summary mode keeps a short index and the complete sanitized answer in `result.json`. `plan` and `review` use a conservative Claude safety budget with `--chunked auto`, so broad Opus/Sonnet work is split into bounded chunk calls before synthesis instead of being sent as one giant request; `--chunked off` preserves exact scope and refuses when the request cannot fit, including when `--max-prompt-chars 0` is set. Partial results retain explicit non-zero exits and coverage; `--allow-partial` only permits the call, it does not make the result complete. Use `--required-file` to fail closed if priority files must be fully covered. `--fallback-model sonnet --fallback-policy on-retryable` and `--progress` are available for long-running model calls that may otherwise fail silently or hit transient backend rotation errors.
234
218
 
235
219
  Before running `codex-antigravity login`, create a Google OAuth desktop client. The local callback listener uses:
236
220
 
@@ -324,23 +308,19 @@ Overlay ids must be simple printable model ids, cannot shadow built-in ids, back
324
308
 
325
309
  ### BYOK providers
326
310
 
327
- Built-in presets are available for OpenRouter, BluesMinds, DeepSeek, xAI, Kimi/Moonshot, Ollama, OpenCode-compatible local servers, and custom OpenAI-compatible APIs:
311
+ Built-in presets are available for OpenRouter, DeepSeek, xAI, Kimi/Moonshot, Ollama, OpenCode-compatible local servers, and custom OpenAI-compatible APIs:
328
312
 
329
313
  ```bash
330
314
  codex-antigravity provider presets
331
- codex-antigravity provider set bluesminds --api-key-env BLUESMINDS_API_KEY --model grok-4.5 --model z-ai/glm-5.2
315
+ codex-antigravity provider set openrouter --api-key-env OPENROUTER_API_KEY --model openrouter/auto
332
316
  codex-antigravity provider set deepseek --api-key-env DEEPSEEK_API_KEY --model deepseek-v4-pro --model deepseek-v4-flash
333
- codex-antigravity provider set openrouter --api-key-env OPENROUTER_API_KEY --model deepseek/deepseek-chat
334
- codex-antigravity provider set xai --api-key-env XAI_API_KEY --model grok-build-0.1
335
- codex-antigravity provider login xai-oauth
317
+ codex-antigravity provider set xai --api-key-env XAI_API_KEY --model grok-code-fast-1
336
318
  codex-antigravity provider set kimi --api-key-env KIMI_API_KEY --model kimi-k2-0711-preview
337
319
  codex-antigravity provider set ollama --base-url http://localhost:11434/v1 --model gpt-oss:20b
338
320
  codex-antigravity provider list
339
321
  ```
340
322
 
341
- Provider presets show their supported auth modes. Grok has two explicit subscription/provider routes: `xai-oauth:grok-build-0.1` and `xai-oauth:grok-4.3` use the SuperGrok/X Premium OAuth store, while `bluesminds:grok-4.5` uses a BluesMinds API key. The existing `grok` and `supergrok` Anti aliases remain OAuth-backed; no automatic cross-provider failover occurs. Use `codex-antigravity provider login xai-oauth` for the browser callback flow, or `codex-antigravity provider login xai-oauth --device` for a headless/device-code flow.
342
-
343
- BluesMinds uses the gateway's mature OpenAI Chat Completions adapter, not the native Responses transport. Its authenticated model catalog advertised `grok-4.5` and `z-ai/glm-5.2`, but successful Responses streaming, structured output, tool calls, usage, and identity fidelity have not been proven. GLM-5.2 is therefore documented as an advisory long-context planning/repository-review lane, with Opus remaining the default Anti judge. DeepSeek V4 uses the official DeepSeek Chat Completions API as `deepseek:deepseek-v4-pro` and `deepseek:deepseek-v4-flash`.
323
+ Provider presets show their supported API-key modes and model defaults. The xAI preset uses `XAI_API_KEY` and exposes `xai:grok-build-0.1`, `xai:grok-4.3`, and `xai:grok-code-fast-1`; no provider-specific OAuth flow is part of the current preset catalog. DeepSeek exposes `deepseek-v4-flash`, `deepseek-v4-pro`, `deepseek-chat`, and `deepseek-reasoner`.
344
324
 
345
325
  For BYOK-only use, point Codex at a BYOK model when writing the provider block:
346
326
 
@@ -350,8 +330,8 @@ codex-antigravity configure-codex --write --model deepseek:deepseek-chat
350
330
  codex-antigravity doctor --byok-only
351
331
  ```
352
332
 
353
- `--api-key-env` avoids persisting provider keys and reads them from the gateway process environment. It may name an existing environment variable instead of the preset default, for example `codex-antigravity provider set bluesminds --api-key-env api_bluesminds_com`. If you intentionally want a provider key stored locally, pass `--api-key`; stored provider keys are encrypted in `~/.codex/antigravity-providers.json`. Use `--auth-mode api-key` explicitly only when you want an API-key provider config to record that mode. Built-in provider env vars include `OPENROUTER_API_KEY`, `BLUESMINDS_API_KEY`, `DEEPSEEK_API_KEY`, `XAI_API_KEY`, `KIMI_API_KEY`, `MOONSHOT_API_KEY`, `OLLAMA_API_KEY`, and `OPENCODE_API_KEY`.
354
- The `/v1/models` catalog only advertises BYOK models when the provider has a usable stored/env key, a refreshable OAuth login, or explicitly supports key-optional loopback/local use. The generic `custom` preset is not auto-enabled; run `codex-antigravity provider set custom --base-url ... --model ...` before routing `custom:model`.
333
+ `--api-key-env` avoids persisting provider keys and reads them from the gateway process environment. It may name an existing environment variable instead of the preset default, for example `codex-antigravity provider set deepseek --api-key-env DEV_DEEPSEEK_KEY`. If you intentionally want a provider key stored locally, pass `--api-key`; stored provider keys are encrypted in `~/.codex/antigravity-providers.json`. Use `--auth-mode api-key` explicitly only when you want an API-key provider config to record that mode. Built-in provider env vars include `OPENROUTER_API_KEY`, `DEEPSEEK_API_KEY`, `XAI_API_KEY`, `KIMI_API_KEY`, `MOONSHOT_API_KEY`, `OLLAMA_API_KEY`, and `OPENCODE_API_KEY`.
334
+ The `/v1/models` catalog only advertises BYOK models when the provider has a usable stored/env key or explicitly supports key-optional loopback/local use. The generic `custom` preset is not auto-enabled; run `codex-antigravity provider set custom --base-url ... --model ...` before routing `custom:model`.
355
335
  When `provider set` is given `--api-key-env`, models are configured but remain hidden from `/v1/models` until that environment variable is available to the running gateway.
356
336
  Provider ids reserve model-name separators and may only contain letters, numbers, underscores, and hyphens; model ids themselves may still contain `/` or `:`, but not whitespace or control characters. Unknown `provider:model` prefixes are rejected as BYOK routing errors before any Google account selection.
357
337
  Custom provider and Codex gateway base URLs must be absolute `http` or `https` URLs without embedded credentials, whitespace/control characters, query strings, fragments, invalid ports, or malformed bracketed hosts. Plain `http` base URLs are accepted only for loopback/local hosts; remote BYOK providers and remote gateway URLs must use `https`. Non-preset custom BYOK providers must provide a base URL before models are exposed. Stored/env BYOK API keys and extra BYOK provider header values must be printable ASCII without control characters; model-picker display names must not contain control characters. Provider API-key env var names must contain only letters, numbers, and underscores and must not start with a number. Extra headers may not override gateway-managed auth, content, host, or transport headers. Invalid BYOK provider URLs, API keys, env vars, model ids, display names, and headers are rejected before config writes; invalid BYOK provider URLs, timeouts, headers, API keys, and missing API keys are also rejected before streaming starts so Codex gets a normal HTTP error instead of a partial SSE response. Key-optional BYOK providers are only treated as keyless on loopback/local base URLs; remote custom or cloud URLs need a usable stored or env API key before they appear in Codex's picker or route requests. Function/tool names and forced `tool_choice` function names must contain only letters, numbers, underscores, and hyphens, and be 1-64 characters; malformed names are rejected or dropped before routing. Non-streaming Google failure responses use a structured `detail` object with `message` and sanitized `diagnostics`; clients should handle both this shape and older string details. BYOK streams surface provider error frames as failed Responses API streams instead of successful empty completions, ignore never-named tool-call deltas, and wait for complete valid streamed function names instead of emitting empty, partial, or malformed function names. BYOK structured tool outputs are serialized to JSON text before being sent as Chat Completions tool messages.
@@ -397,6 +377,64 @@ model_provider = "antigravity"
397
377
  wire_api = "responses"
398
378
  ```
399
379
 
380
+ ## Unified Codex model picker
381
+
382
+ Allows Codex to display and use OpenAI, Claude and Gemini models from a
383
+ single configured provider by routing requests through the local gateway.
384
+
385
+ This is opt-in and does not change classic behaviour unless you enable it:
386
+
387
+ ```bash
388
+ export OPENAI_API_KEY="sk-..."
389
+ codex-antigravity configure-codex --write --unified-model-picker --model gpt-5.6
390
+ codex-antigravity start --unified-model-picker
391
+ # Or durably:
392
+ codex-antigravity service install --port 51122 --host 127.0.0.1 --unified-model-picker
393
+ ```
394
+
395
+ Unified mode writes a separate provider block so classic configs are preserved:
396
+
397
+ ```toml
398
+ [model_providers.antigravity-unified]
399
+ name = "Antigravity Unified"
400
+ base_url = "http://localhost:51122/v1"
401
+ wire_api = "responses"
402
+ ```
403
+
404
+ ```toml
405
+ model = "gpt-5.6"
406
+ model_provider = "antigravity-unified"
407
+ wire_api = "responses"
408
+ ```
409
+
410
+ When enabled, `GET /v1/models` advertises Antigravity native models, OpenAI/Codex
411
+ ids (`gpt-5.6`, `gpt-5.6-codex`, …), and configured BYOK `provider:model` ids in
412
+ one picker. The gateway routes per model (BYOK → existing provider, OpenAI →
413
+ OpenAI upstream, Claude/Gemini → Antigravity) and returns provider-qualified
414
+ errors for unknown models, missing OpenAI auth, or unreachable upstreams. OpenAI
415
+ requests never fall through to Antigravity and vice versa.
416
+
417
+ OpenAI authentication, in order of preference:
418
+
419
+ 1. Explicit `OPENAI_API_KEY` (env) proxied to `https://api.openai.com/v1/responses`
420
+ (override base with `OPENAI_BASE_URL`; file alternative
421
+ `~/.codex/antigravity-openai.json` with `{"api_key": ...}`).
422
+ 2. Optional ChatGPT-subscription reuse: `ANTIGRAVITY_OPENAI_USE_CODEX_AUTH=1`
423
+ reads `~/.codex/auth.json` (or `$CODEX_HOME/auth.json`) read-only after
424
+ `codex login` and proxies to `https://chatgpt.com/backend-api/codex/responses`.
425
+ No token refresh is attempted; an expired token returns a clear 401 telling
426
+ you to run `codex login` again. This path is explicit because the auth file
427
+ format is owned by Codex and may change.
428
+
429
+ Extend the OpenAI registry without code changes:
430
+
431
+ ```bash
432
+ export ANTIGRAVITY_OPENAI_MODELS="gpt-5.6,gpt-5.6-codex,my-codex-model"
433
+ ```
434
+
435
+ Disable unified mode at any time to restore historical behaviour
436
+ (`ANTIGRAVITY_UNIFIED_MODEL_PICKER` unset, classic `antigravity` provider).
437
+
400
438
  ## Verification
401
439
 
402
440
  To run connection check diagnostics and verify token security:
@@ -462,6 +500,22 @@ codex-antigravity doctor --codex-ready
462
500
  codex-antigravity start --port 51122
463
501
  ```
464
502
 
503
+ ### Unified picker: OpenAI 401 / unknown model
504
+
505
+ If `gpt-5.6` returns 401, the OpenAI upstream has no credentials:
506
+
507
+ ```bash
508
+ export OPENAI_API_KEY="sk-..."
509
+ codex-antigravity start --unified-model-picker
510
+ curl http://127.0.0.1:51122/health
511
+ ```
512
+
513
+ If it returns 404 `Unknown model`, the id is not in the OpenAI registry,
514
+ native catalog, or BYOK config. Check `/v1/models`, extend
515
+ `ANTIGRAVITY_OPENAI_MODELS` if needed, and ensure the gateway was restarted
516
+ with `--unified-model-picker`. Classic mode never advertises OpenAI ids; use
517
+ the `antigravity-unified` provider block for unified pickers.
518
+
465
519
  ## Release Automation
466
520
 
467
521
  Tagged releases are prepared for PyPI Trusted Publishing. The `.github/workflows/publish.yml` workflow runs on `v*` tags, requires the full Ubuntu Python 3.10/3.11/3.12/3.14 plus Windows Python 3.12 test matrix and a checked sdist/wheel build, then publishes with `pypa/gh-action-pypi-publish@release/v1` using OIDC (`id-token: write`) in the `pypi` environment. The tag must exactly match the package version.
@@ -32,7 +32,7 @@ Use `$anti` only as an optional sidecar reviewer/planner after the gateway is wo
32
32
  - **OS-Native Keyring Encryption**: Encrypts Google account tokens and stored BYOK provider config at rest via macOS Keychain, Windows Credential Manager, Linux Secret Service, or a private local fallback key.
33
33
  - **Transaction-Safe Cooldown Rotations**: Automatically rotates accounts on backend failures (such as `401`, `403`, or `429` rate limiters) with clean exponential backoff.
34
34
  - **High-Fidelity SSE Translation**: Translates stream candidate envelopes, role alignments, reasoning-text deltas, function-call items, and VALIDATED tool parameter modes into Responses API events.
35
- - **BYOK Provider Routing**: Route model IDs like `deepseek:deepseek-v4-pro`, `bluesminds:grok-4.5`, `bluesminds:z-ai/glm-5.2`, `xai:grok-code-fast-1`, and custom OpenAI-compatible endpoints through encrypted API-key config.
35
+ - **BYOK Provider Routing**: Route model IDs like `deepseek:deepseek-v4-pro`, `xai:grok-code-fast-1`, `kimi:kimi-k2-0711-preview`, `ollama:gpt-oss:20b`, and custom OpenAI-compatible endpoints through encrypted API-key config.
36
36
 
37
37
  ## Installation
38
38
 
@@ -152,32 +152,19 @@ The skill also ships a helper-level panel mode inspired by MoA/Fusion workflows.
152
152
  python3 ~/.codex/skills/anti/scripts/anti.py panel --mode review --scope staged
153
153
  python3 ~/.codex/skills/anti/scripts/anti.py panel --mode plan --scope working-tree --prompt "Plan this PR"
154
154
  python3 ~/.codex/skills/anti/scripts/anti.py panel --mode ask --model sonnet --model openrouter:deepseek/deepseek-chat --judge opus --prompt "Compare these approaches"
155
- python3 ~/.codex/skills/anti/scripts/anti.py panel --mode ask --collab claude-grok --prompt "Compare these approaches"
156
- python3 ~/.codex/skills/anti/scripts/anti.py panel --mode ask --collab claude-grok --model sonnet --model opus --model grok-bluesminds --prompt "Compare these approaches"
157
155
  python3 ~/.codex/skills/anti/scripts/anti.py panel --mode review --scope staged --output findings
158
- python3 ~/.codex/skills/anti/scripts/anti.py moa --mode review --model deepseek-v4-pro --model glm-5.2 --judge opus --scope staged
159
- python3 ~/.codex/skills/anti/scripts/anti.py fusion --mode plan --model opus --model glm-5.2 --judge opus --scope working-tree --prompt "Plan this repository change"
156
+ python3 ~/.codex/skills/anti/scripts/anti.py moa --mode review --model deepseek-v4-pro --judge opus --scope staged
157
+ python3 ~/.codex/skills/anti/scripts/anti.py fusion --mode plan --model opus --model deepseek-v4-pro --judge opus --scope working-tree --prompt "Plan this repository change"
160
158
  ```
161
159
 
162
- Panel consensus is not proof and should not patch code directly. Structured findings include `id`, `claim`, `severity`, `lanes`, and `verify`; run the `verify` hint locally before acting. Text and JSON outputs include per-lane/judge usage and latency when the gateway/provider returns it. Broad review panels summarize oversized scopes once before fan-out instead of silently truncating raw context for every lane.
160
+ Panel consensus is not proof and should not patch code directly. Structured findings include `id`, `claim`, `severity`, `lanes`, and `verify`; run the `verify` hint locally before acting. Findings remain `unverified` until native/local checks confirm or reject them. Text and JSON outputs include per-lane/judge usage and latency when the gateway/provider returns it. Broad review panels summarize oversized scopes once before fan-out instead of silently truncating raw context for every lane.
163
161
 
164
- Panel JSON keeps requested and actual execution identities separate (`requestedModel`, `actualModel`, `provider`, `fallbackChain`, `primaryError`, and `fallbackReason`). The panel status is `complete_multi_model`, `partial_multi_model`, `degraded_single_model`, or `failed`; distinct actual provider/model identities, rather than repeated logical fallback lanes, satisfy `--min-successes`. `/v1/models` is only a catalog/readiness hint—the bounded generation call is the live model health check.
162
+ Panel JSON keeps requested and actual execution identities separate (`requestedModel`, `actualModel`, `provider`, `fallbackChain`, `primaryError`, and `fallbackReason`). The panel status is `complete_multi_model`, `partial_multi_model`, `same_provider_multi_model`, `degraded_single_model`, or `failed`; distinct actual provider/model identities, rather than repeated logical fallback lanes, satisfy `--min-successes`, and `--min-providers` can require provider diversity. `/v1/models` is only a catalog/readiness hint—the bounded generation call is the live model health check. Every saved run exposes top-level `runStatus`, `scopeStatus`, `panelStatus`, `coverage`, and `resultPath`.
165
163
  When the diversity minimum is not met, the panel fails closed before judge synthesis; `--json` and `--output findings` still return the lane evidence and status with a non-zero exit code.
166
164
 
167
- `--collab claude-grok` is an explicit collaboration profile for Claude plus Grok panels. It defaults to Sonnet, Opus, and `grok` (`xai-oauth:grok-build-0.1`), gives Claude and Grok complementary review instructions, and asks the Opus judge to compare Claude-backed and Grok-backed disagreements before recommending verification steps. `grok-oauth` selects that same OAuth route explicitly. To use BluesMinds deliberately, pass `--model sonnet --model opus --model grok-bluesminds`; `grok-bluesminds` and `grok-4.5` resolve to `bluesminds:grok-4.5`. The helper never silently fails over between the routes. If a requested Grok lane is not visible in `/v1/models`, it is recorded as a failed lane unless `--min-successes` makes the whole panel fail.
165
+ Panel lanes are selected explicitly from the native Sonnet/Opus defaults or from models advertised by the running gateway. BYOK examples include `openrouter:...`, `deepseek:...`, `xai:...`, `kimi:...`, `ollama:...`, and `opencode:...`; they require the corresponding API key or a key-optional local provider. When a BYOK lane receives repository, diff, or file context, the helper prints and records a disclosure naming the provider lane. Virtual picker models such as `panel:*`, `moa:*`, or `fusion:*` remain helper aliases rather than gateway-side fan-out.
168
166
 
169
- BYOK panel models such as `openrouter:...` or `xai-oauth:...` only work when the running gateway advertises them in `/v1/models`, which requires usable provider keys, key-optional local provider setup, or a refreshable OAuth login. When a BYOK lane receives repository, diff, or file context, the helper prints and records a disclosure naming the provider lanes. Virtual picker models such as `panel:*`, `moa:*`, or `fusion:*` are not supported; MoA/Fusion remains a helper workflow, not gateway-side orchestration.
170
-
171
- ### Choosing complementary reviewer lanes
172
-
173
- - DeepSeek V4 Flash is for a fast code second opinion, debugging, and an explicitly selected retryable fallback. It is never an automatic cross-provider fallback.
174
- - DeepSeek V4 Pro is for correctness, security, architecture, and deep code review. Treat it as unproven until the live V4 Pro generation, structured-output, and tool-loop gate passes.
175
- - xAI OAuth Grok is for adversarial assumptions, runtime surprises, and product/UX blind spots.
176
- - BluesMinds Grok/GLM aliases exist but remain unavailable/degraded until the requested route is advertised by `/v1/models` and the provider live-health gate passes. Every BluesMinds example is conditional on both checks.
177
-
178
- The normal service intentionally omits BluesMinds. The last bounded live checks returned a billing error for Grok 4.5 and an upstream 429 for GLM-5.2, so neither route is operationally enabled.
179
-
180
- A future enablement gate must pass first in a temporary process: catalog identity; non-streaming output and exact model identity; SSE completion and `[DONE]`; structured JSON; tool call and continuation; usage accounting; and bounded retries and no billing/capacity error. Only then may a later authorized task add `BLUESMINDS_API_KEY=op://...` to the durable service reference file and reinstall the service.
167
+ The current xAI preset is API-key based and uses `XAI_API_KEY`. Provider availability is determined by the gateway's `/v1/models` catalog; a catalog entry is not proof that a live generation will succeed.
181
168
 
182
169
  Repository context leaves the Google Antigravity lane only after explicit selection and the existing BYOK disclosure. Opus remains the default judge; native Codex remains the acting agent and must verify advisory output locally.
183
170
 
@@ -188,16 +175,13 @@ python3 ~/.codex/skills/anti/scripts/anti.py workflow review-ready --scope stage
188
175
  python3 ~/.codex/skills/anti/scripts/anti.py workflow plan-deep --scope working-tree --prompt "Plan this PR" --progress
189
176
  python3 ~/.codex/skills/anti/scripts/anti.py workflow ship-gate --scope diff --base origin/main --json
190
177
  python3 ~/.codex/skills/anti/scripts/anti.py workflow provider-compare --model sonnet --model openrouter:deepseek/deepseek-chat --prompt "Compare these approaches"
191
- python3 ~/.codex/skills/anti/scripts/anti.py workflow provider-compare --model deepseek-v4-pro --model glm-5.2 --prompt "Compare long-context planning approaches"
178
+ python3 ~/.codex/skills/anti/scripts/anti.py workflow provider-compare --model deepseek-v4-pro --prompt "Compare this approach with the native review lane"
192
179
  python3 ~/.codex/skills/anti/scripts/anti.py workflow security-review --scope staged --output findings
193
180
  python3 ~/.codex/skills/anti/scripts/anti.py workflow debug-consensus --prompt "Intermittent 502s after rotation"
194
- python3 ~/.codex/skills/anti/scripts/anti.py workflow claude-grok --panel-mode review --scope staged --output findings
195
- python3 ~/.codex/skills/anti/scripts/anti.py workflow claude-grok --panel-mode ask --prompt "Should this UX use route A or B?"
196
- python3 ~/.codex/skills/anti/scripts/anti.py workflow claude-grok --model sonnet --model opus --model grok-bluesminds --panel-mode ask --prompt "Stress-test this design"
197
181
  python3 ~/.codex/skills/anti/scripts/anti.py runs list
198
182
  ```
199
183
 
200
- Workflow runs save sanitized summaries under `~/.codex/anti-runs` by default; primitive `consult`, `plan`, `review`, and `panel` commands default to not writing a ledger unless `--save-output summary` or `--save-output full` is passed. Saved runs include the Anti run id, which is also sent as `metadata.run_id` to the gateway and appears in sanitized request logs for correlation. Raw prompts are not logged unless you explicitly choose full-output ledgers. `plan` and `review` use a conservative Claude safety budget with `--chunked auto`, so broad Opus/Sonnet work is split into bounded chunk calls before synthesis instead of being sent as one giant request; use `--chunked off` to intentionally bypass that safety budget, including when `--max-prompt-chars 0` is set. `--fallback-model sonnet --fallback-policy on-retryable` and `--progress` are available for long-running model calls that may otherwise fail silently or hit transient backend rotation errors.
184
+ Workflow runs save sanitized summaries under `~/.codex/anti-runs` by default; primitive `consult`, `plan`, `review`, and `panel` commands default to not writing a ledger unless `--save-output summary` or `--save-output full` is passed. Saved runs include the Anti run id, which is also sent as `metadata.run_id` to the gateway and appears in sanitized request logs for correlation. Run records never retain raw prompts: full mode keeps sanitized per-call output plus prompt hashes/counts, while summary mode keeps a short index and the complete sanitized answer in `result.json`. `plan` and `review` use a conservative Claude safety budget with `--chunked auto`, so broad Opus/Sonnet work is split into bounded chunk calls before synthesis instead of being sent as one giant request; `--chunked off` preserves exact scope and refuses when the request cannot fit, including when `--max-prompt-chars 0` is set. Partial results retain explicit non-zero exits and coverage; `--allow-partial` only permits the call, it does not make the result complete. Use `--required-file` to fail closed if priority files must be fully covered. `--fallback-model sonnet --fallback-policy on-retryable` and `--progress` are available for long-running model calls that may otherwise fail silently or hit transient backend rotation errors.
201
185
 
202
186
  Before running `codex-antigravity login`, create a Google OAuth desktop client. The local callback listener uses:
203
187
 
@@ -291,23 +275,19 @@ Overlay ids must be simple printable model ids, cannot shadow built-in ids, back
291
275
 
292
276
  ### BYOK providers
293
277
 
294
- Built-in presets are available for OpenRouter, BluesMinds, DeepSeek, xAI, Kimi/Moonshot, Ollama, OpenCode-compatible local servers, and custom OpenAI-compatible APIs:
278
+ Built-in presets are available for OpenRouter, DeepSeek, xAI, Kimi/Moonshot, Ollama, OpenCode-compatible local servers, and custom OpenAI-compatible APIs:
295
279
 
296
280
  ```bash
297
281
  codex-antigravity provider presets
298
- codex-antigravity provider set bluesminds --api-key-env BLUESMINDS_API_KEY --model grok-4.5 --model z-ai/glm-5.2
282
+ codex-antigravity provider set openrouter --api-key-env OPENROUTER_API_KEY --model openrouter/auto
299
283
  codex-antigravity provider set deepseek --api-key-env DEEPSEEK_API_KEY --model deepseek-v4-pro --model deepseek-v4-flash
300
- codex-antigravity provider set openrouter --api-key-env OPENROUTER_API_KEY --model deepseek/deepseek-chat
301
- codex-antigravity provider set xai --api-key-env XAI_API_KEY --model grok-build-0.1
302
- codex-antigravity provider login xai-oauth
284
+ codex-antigravity provider set xai --api-key-env XAI_API_KEY --model grok-code-fast-1
303
285
  codex-antigravity provider set kimi --api-key-env KIMI_API_KEY --model kimi-k2-0711-preview
304
286
  codex-antigravity provider set ollama --base-url http://localhost:11434/v1 --model gpt-oss:20b
305
287
  codex-antigravity provider list
306
288
  ```
307
289
 
308
- Provider presets show their supported auth modes. Grok has two explicit subscription/provider routes: `xai-oauth:grok-build-0.1` and `xai-oauth:grok-4.3` use the SuperGrok/X Premium OAuth store, while `bluesminds:grok-4.5` uses a BluesMinds API key. The existing `grok` and `supergrok` Anti aliases remain OAuth-backed; no automatic cross-provider failover occurs. Use `codex-antigravity provider login xai-oauth` for the browser callback flow, or `codex-antigravity provider login xai-oauth --device` for a headless/device-code flow.
309
-
310
- BluesMinds uses the gateway's mature OpenAI Chat Completions adapter, not the native Responses transport. Its authenticated model catalog advertised `grok-4.5` and `z-ai/glm-5.2`, but successful Responses streaming, structured output, tool calls, usage, and identity fidelity have not been proven. GLM-5.2 is therefore documented as an advisory long-context planning/repository-review lane, with Opus remaining the default Anti judge. DeepSeek V4 uses the official DeepSeek Chat Completions API as `deepseek:deepseek-v4-pro` and `deepseek:deepseek-v4-flash`.
290
+ Provider presets show their supported API-key modes and model defaults. The xAI preset uses `XAI_API_KEY` and exposes `xai:grok-build-0.1`, `xai:grok-4.3`, and `xai:grok-code-fast-1`; no provider-specific OAuth flow is part of the current preset catalog. DeepSeek exposes `deepseek-v4-flash`, `deepseek-v4-pro`, `deepseek-chat`, and `deepseek-reasoner`.
311
291
 
312
292
  For BYOK-only use, point Codex at a BYOK model when writing the provider block:
313
293
 
@@ -317,8 +297,8 @@ codex-antigravity configure-codex --write --model deepseek:deepseek-chat
317
297
  codex-antigravity doctor --byok-only
318
298
  ```
319
299
 
320
- `--api-key-env` avoids persisting provider keys and reads them from the gateway process environment. It may name an existing environment variable instead of the preset default, for example `codex-antigravity provider set bluesminds --api-key-env api_bluesminds_com`. If you intentionally want a provider key stored locally, pass `--api-key`; stored provider keys are encrypted in `~/.codex/antigravity-providers.json`. Use `--auth-mode api-key` explicitly only when you want an API-key provider config to record that mode. Built-in provider env vars include `OPENROUTER_API_KEY`, `BLUESMINDS_API_KEY`, `DEEPSEEK_API_KEY`, `XAI_API_KEY`, `KIMI_API_KEY`, `MOONSHOT_API_KEY`, `OLLAMA_API_KEY`, and `OPENCODE_API_KEY`.
321
- The `/v1/models` catalog only advertises BYOK models when the provider has a usable stored/env key, a refreshable OAuth login, or explicitly supports key-optional loopback/local use. The generic `custom` preset is not auto-enabled; run `codex-antigravity provider set custom --base-url ... --model ...` before routing `custom:model`.
300
+ `--api-key-env` avoids persisting provider keys and reads them from the gateway process environment. It may name an existing environment variable instead of the preset default, for example `codex-antigravity provider set deepseek --api-key-env DEV_DEEPSEEK_KEY`. If you intentionally want a provider key stored locally, pass `--api-key`; stored provider keys are encrypted in `~/.codex/antigravity-providers.json`. Use `--auth-mode api-key` explicitly only when you want an API-key provider config to record that mode. Built-in provider env vars include `OPENROUTER_API_KEY`, `DEEPSEEK_API_KEY`, `XAI_API_KEY`, `KIMI_API_KEY`, `MOONSHOT_API_KEY`, `OLLAMA_API_KEY`, and `OPENCODE_API_KEY`.
301
+ The `/v1/models` catalog only advertises BYOK models when the provider has a usable stored/env key or explicitly supports key-optional loopback/local use. The generic `custom` preset is not auto-enabled; run `codex-antigravity provider set custom --base-url ... --model ...` before routing `custom:model`.
322
302
  When `provider set` is given `--api-key-env`, models are configured but remain hidden from `/v1/models` until that environment variable is available to the running gateway.
323
303
  Provider ids reserve model-name separators and may only contain letters, numbers, underscores, and hyphens; model ids themselves may still contain `/` or `:`, but not whitespace or control characters. Unknown `provider:model` prefixes are rejected as BYOK routing errors before any Google account selection.
324
304
  Custom provider and Codex gateway base URLs must be absolute `http` or `https` URLs without embedded credentials, whitespace/control characters, query strings, fragments, invalid ports, or malformed bracketed hosts. Plain `http` base URLs are accepted only for loopback/local hosts; remote BYOK providers and remote gateway URLs must use `https`. Non-preset custom BYOK providers must provide a base URL before models are exposed. Stored/env BYOK API keys and extra BYOK provider header values must be printable ASCII without control characters; model-picker display names must not contain control characters. Provider API-key env var names must contain only letters, numbers, and underscores and must not start with a number. Extra headers may not override gateway-managed auth, content, host, or transport headers. Invalid BYOK provider URLs, API keys, env vars, model ids, display names, and headers are rejected before config writes; invalid BYOK provider URLs, timeouts, headers, API keys, and missing API keys are also rejected before streaming starts so Codex gets a normal HTTP error instead of a partial SSE response. Key-optional BYOK providers are only treated as keyless on loopback/local base URLs; remote custom or cloud URLs need a usable stored or env API key before they appear in Codex's picker or route requests. Function/tool names and forced `tool_choice` function names must contain only letters, numbers, underscores, and hyphens, and be 1-64 characters; malformed names are rejected or dropped before routing. Non-streaming Google failure responses use a structured `detail` object with `message` and sanitized `diagnostics`; clients should handle both this shape and older string details. BYOK streams surface provider error frames as failed Responses API streams instead of successful empty completions, ignore never-named tool-call deltas, and wait for complete valid streamed function names instead of emitting empty, partial, or malformed function names. BYOK structured tool outputs are serialized to JSON text before being sent as Chat Completions tool messages.
@@ -364,6 +344,64 @@ model_provider = "antigravity"
364
344
  wire_api = "responses"
365
345
  ```
366
346
 
347
+ ## Unified Codex model picker
348
+
349
+ Allows Codex to display and use OpenAI, Claude and Gemini models from a
350
+ single configured provider by routing requests through the local gateway.
351
+
352
+ This is opt-in and does not change classic behaviour unless you enable it:
353
+
354
+ ```bash
355
+ export OPENAI_API_KEY="sk-..."
356
+ codex-antigravity configure-codex --write --unified-model-picker --model gpt-5.6
357
+ codex-antigravity start --unified-model-picker
358
+ # Or durably:
359
+ codex-antigravity service install --port 51122 --host 127.0.0.1 --unified-model-picker
360
+ ```
361
+
362
+ Unified mode writes a separate provider block so classic configs are preserved:
363
+
364
+ ```toml
365
+ [model_providers.antigravity-unified]
366
+ name = "Antigravity Unified"
367
+ base_url = "http://localhost:51122/v1"
368
+ wire_api = "responses"
369
+ ```
370
+
371
+ ```toml
372
+ model = "gpt-5.6"
373
+ model_provider = "antigravity-unified"
374
+ wire_api = "responses"
375
+ ```
376
+
377
+ When enabled, `GET /v1/models` advertises Antigravity native models, OpenAI/Codex
378
+ ids (`gpt-5.6`, `gpt-5.6-codex`, …), and configured BYOK `provider:model` ids in
379
+ one picker. The gateway routes per model (BYOK → existing provider, OpenAI →
380
+ OpenAI upstream, Claude/Gemini → Antigravity) and returns provider-qualified
381
+ errors for unknown models, missing OpenAI auth, or unreachable upstreams. OpenAI
382
+ requests never fall through to Antigravity and vice versa.
383
+
384
+ OpenAI authentication, in order of preference:
385
+
386
+ 1. Explicit `OPENAI_API_KEY` (env) proxied to `https://api.openai.com/v1/responses`
387
+ (override base with `OPENAI_BASE_URL`; file alternative
388
+ `~/.codex/antigravity-openai.json` with `{"api_key": ...}`).
389
+ 2. Optional ChatGPT-subscription reuse: `ANTIGRAVITY_OPENAI_USE_CODEX_AUTH=1`
390
+ reads `~/.codex/auth.json` (or `$CODEX_HOME/auth.json`) read-only after
391
+ `codex login` and proxies to `https://chatgpt.com/backend-api/codex/responses`.
392
+ No token refresh is attempted; an expired token returns a clear 401 telling
393
+ you to run `codex login` again. This path is explicit because the auth file
394
+ format is owned by Codex and may change.
395
+
396
+ Extend the OpenAI registry without code changes:
397
+
398
+ ```bash
399
+ export ANTIGRAVITY_OPENAI_MODELS="gpt-5.6,gpt-5.6-codex,my-codex-model"
400
+ ```
401
+
402
+ Disable unified mode at any time to restore historical behaviour
403
+ (`ANTIGRAVITY_UNIFIED_MODEL_PICKER` unset, classic `antigravity` provider).
404
+
367
405
  ## Verification
368
406
 
369
407
  To run connection check diagnostics and verify token security:
@@ -429,6 +467,22 @@ codex-antigravity doctor --codex-ready
429
467
  codex-antigravity start --port 51122
430
468
  ```
431
469
 
470
+ ### Unified picker: OpenAI 401 / unknown model
471
+
472
+ If `gpt-5.6` returns 401, the OpenAI upstream has no credentials:
473
+
474
+ ```bash
475
+ export OPENAI_API_KEY="sk-..."
476
+ codex-antigravity start --unified-model-picker
477
+ curl http://127.0.0.1:51122/health
478
+ ```
479
+
480
+ If it returns 404 `Unknown model`, the id is not in the OpenAI registry,
481
+ native catalog, or BYOK config. Check `/v1/models`, extend
482
+ `ANTIGRAVITY_OPENAI_MODELS` if needed, and ensure the gateway was restarted
483
+ with `--unified-model-picker`. Classic mode never advertises OpenAI ids; use
484
+ the `antigravity-unified` provider block for unified pickers.
485
+
432
486
  ## Release Automation
433
487
 
434
488
  Tagged releases are prepared for PyPI Trusted Publishing. The `.github/workflows/publish.yml` workflow runs on `v*` tags, requires the full Ubuntu Python 3.10/3.11/3.12/3.14 plus Windows Python 3.12 test matrix and a checked sdist/wheel build, then publishes with `pypa/gh-action-pypi-publish@release/v1` using OIDC (`id-token: write`) in the `pypi` environment. The tag must exactly match the package version.
@@ -151,7 +151,13 @@ class AccountState:
151
151
  def state(self) -> dict[str, Any]:
152
152
  return self.data["accountState"]
153
153
 
154
- def _select(self, family: str, *, acquire: bool) -> Lease | None:
154
+ def _select(
155
+ self,
156
+ family: str,
157
+ *,
158
+ acquire: bool,
159
+ exclude_emails: set[str] | None = None,
160
+ ) -> Lease | None:
155
161
  if family not in FAMILIES:
156
162
  raise ValueError(f"unsupported model family: {family}")
157
163
  with self._lock:
@@ -170,6 +176,8 @@ class AccountState:
170
176
  if not isinstance(account, dict) or not account.get("email"):
171
177
  continue
172
178
  email = str(account["email"])
179
+ if exclude_emails and email in exclude_emails:
180
+ continue
173
181
  scoped = self.state["cooldowns"].get(email, {})
174
182
  if scoped.get("account", 0) > now or scoped.get(family, 0) > now:
175
183
  continue
@@ -187,11 +195,11 @@ class AccountState:
187
195
  self._in_flight[email] = self._in_flight.get(email, 0) + 1
188
196
  return Lease(account=account, family=family)
189
197
 
190
- def select(self, family: str) -> Lease | None:
191
- return self._select(family, acquire=False)
198
+ def select(self, family: str, *, exclude_emails: set[str] | None = None) -> Lease | None:
199
+ return self._select(family, acquire=False, exclude_emails=exclude_emails)
192
200
 
193
- def acquire(self, family: str) -> Lease | None:
194
- return self._select(family, acquire=True)
201
+ def acquire(self, family: str, *, exclude_emails: set[str] | None = None) -> Lease | None:
202
+ return self._select(family, acquire=True, exclude_emails=exclude_emails)
195
203
 
196
204
  def release(self, lease: Lease | None) -> None:
197
205
  if lease is not None: