feat(providers): add Antigravity provider for unified Claude/Gemini access
Some checks failed
Semantic Release / release (push) Has been cancelled
Some checks failed
Semantic Release / release (push) Has been cancelled
Implements a new provider that uses Google's Antigravity unified gateway API to access Claude, Gemini, and other models through a single OAuth2-authenticated endpoint. Features: - OAuth2 token management with automatic refresh - Multi-account rotation for rate limit distribution - Support for Claude Opus/Sonnet 4.5 (with/without thinking) - Support for Gemini 2.5/3 models (Pro/Flash variants) - Thinking mode support with configurable tokens - Image processing support - Dual quota pool tracking (antigravity vs gemini-cli) - Gemini-style API request format Authentication: - Reads from ANTIGRAVITY_REFRESH_TOKEN env var (priority) - Falls back to ~/.config/opencode/antigravity-accounts.json - Automatic token refresh with retry logic - Rate limit tracking per account and quota pool Files added: - providers/antigravity.py - Main provider implementation - providers/antigravity_auth.py - OAuth token manager - providers/registries/antigravity.py - Model registry - conf/antigravity_models.json - Model definitions (11 models) - docs/antigravity_provider.md - Setup and usage docs - tests/test_antigravity_provider.py - Unit tests (14 pass) Integration: - Added to provider priority order after ZEN - Registered in server.py with auto-detection - ToS warning logged on first use
This commit is contained in:
@@ -41,6 +41,7 @@ class ModelProviderRegistry:
|
||||
ProviderType.AZURE, # Azure-hosted OpenAI deployments
|
||||
ProviderType.XAI, # Direct X.AI GROK access
|
||||
ProviderType.ZEN, # OpenCode Zen curated models
|
||||
ProviderType.ANTIGRAVITY, # Antigravity unified gateway (Claude/Gemini via Google OAuth)
|
||||
ProviderType.DIAL, # DIAL unified API access
|
||||
ProviderType.CUSTOM, # Local/self-hosted models
|
||||
ProviderType.OPENROUTER, # Catch-all for cloud models
|
||||
@@ -140,6 +141,19 @@ class ModelProviderRegistry:
|
||||
azure_endpoint=azure_endpoint,
|
||||
api_version=azure_version,
|
||||
)
|
||||
elif provider_type == ProviderType.ANTIGRAVITY:
|
||||
# Antigravity uses OAuth tokens from file or env var
|
||||
# The provider handles token loading internally
|
||||
from pathlib import Path
|
||||
|
||||
# Check if refresh token is available from env or accounts file
|
||||
accounts_file = Path.home() / ".config" / "opencode" / "antigravity-accounts.json"
|
||||
if not api_key and not accounts_file.exists():
|
||||
logging.debug("Antigravity: No refresh token in env and no accounts file found")
|
||||
return None
|
||||
|
||||
# Initialize provider (it will load tokens internally)
|
||||
provider = provider_class(api_key=api_key or "")
|
||||
else:
|
||||
if not api_key:
|
||||
return None
|
||||
@@ -341,6 +355,7 @@ class ModelProviderRegistry:
|
||||
ProviderType.OPENROUTER: "OPENROUTER_API_KEY",
|
||||
ProviderType.CUSTOM: "CUSTOM_API_KEY", # Can be empty for providers that don't need auth
|
||||
ProviderType.DIAL: "DIAL_API_KEY",
|
||||
ProviderType.ANTIGRAVITY: "ANTIGRAVITY_REFRESH_TOKEN", # Uses OAuth refresh token, not API key
|
||||
}
|
||||
|
||||
env_var = key_mapping.get(provider_type)
|
||||
|
||||
Reference in New Issue
Block a user