initial commit
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Badri Narayanan S
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
265
README.md
265
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Antigravity Claude Proxy
|
# Antigravity Claude Proxy
|
||||||
|
|
||||||
A proxy server that exposes an **Anthropic-compatible API** backed by **Antigravity's Cloud Code**, letting you use Claude models like `claude-sonnet-4-5` with any Anthropic client including Claude Code CLI.
|
A proxy server that exposes an **Anthropic-compatible API** backed by **Antigravity's Cloud Code**, letting you use Claude models like `claude-sonnet-4-5-thinking` and `claude-opus-4-5-thinking` with **Claude Code CLI**.
|
||||||
|
|
||||||
## How It Works
|
## How It Works
|
||||||
|
|
||||||
@@ -13,15 +13,17 @@ A proxy server that exposes an **Anthropic-compatible API** backed by **Antigrav
|
|||||||
```
|
```
|
||||||
|
|
||||||
1. Receives requests in **Anthropic Messages API format**
|
1. Receives requests in **Anthropic Messages API format**
|
||||||
2. Extracts OAuth token from Antigravity's local database
|
2. Uses OAuth tokens from added Google accounts (or Antigravity's local database)
|
||||||
3. Transforms to **Google Generative AI format** with Cloud Code wrapping
|
3. Transforms to **Google Generative AI format** with Cloud Code wrapping
|
||||||
4. Sends to Antigravity's Cloud Code API (`v1internal:streamGenerateContent`)
|
4. Sends to Antigravity's Cloud Code API
|
||||||
5. Converts responses back to **Anthropic format**
|
5. Converts responses back to **Anthropic format** with full thinking/streaming support
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- **Antigravity** installed and running (you must be logged in)
|
|
||||||
- **Node.js** 18 or later
|
- **Node.js** 18 or later
|
||||||
|
- **Antigravity** installed (for single-account mode) OR Google account(s) for multi-account mode
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
@@ -31,7 +33,38 @@ A proxy server that exposes an **Anthropic-compatible API** backed by **Antigrav
|
|||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Start the Proxy Server
|
### 2. Add Account(s)
|
||||||
|
|
||||||
|
You have two options:
|
||||||
|
|
||||||
|
**Option A: Use Antigravity (Single Account)**
|
||||||
|
|
||||||
|
If you have Antigravity installed and logged in, the proxy will automatically extract your token. No additional setup needed.
|
||||||
|
|
||||||
|
**Option B: Add Google Accounts via OAuth (Recommended for Multi-Account)**
|
||||||
|
|
||||||
|
Add one or more Google accounts for round-robin load balancing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run accounts:add
|
||||||
|
```
|
||||||
|
|
||||||
|
This opens your browser for Google OAuth. Sign in and authorize access. Repeat for multiple accounts.
|
||||||
|
|
||||||
|
Manage accounts:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List all accounts
|
||||||
|
npm run accounts:list
|
||||||
|
|
||||||
|
# Verify accounts are working
|
||||||
|
npm run accounts:verify
|
||||||
|
|
||||||
|
# Interactive account management
|
||||||
|
npm run accounts
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Start the Proxy Server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm start
|
npm start
|
||||||
@@ -39,96 +72,131 @@ npm start
|
|||||||
|
|
||||||
The server runs on `http://localhost:8080` by default.
|
The server runs on `http://localhost:8080` by default.
|
||||||
|
|
||||||
### 3. Test It
|
### 4. Verify It's Working
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Health check
|
# Health check
|
||||||
curl http://localhost:8080/health
|
curl http://localhost:8080/health
|
||||||
|
|
||||||
# Simple message (non-streaming)
|
# Check account status
|
||||||
curl http://localhost:8080/v1/messages \
|
curl http://localhost:8080/accounts
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"model": "claude-sonnet-4-5",
|
|
||||||
"messages": [{"role": "user", "content": "Say hello!"}],
|
|
||||||
"max_tokens": 100
|
|
||||||
}'
|
|
||||||
|
|
||||||
# Streaming
|
|
||||||
curl http://localhost:8080/v1/messages \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"model": "claude-sonnet-4-5",
|
|
||||||
"messages": [{"role": "user", "content": "Say hello!"}],
|
|
||||||
"max_tokens": 100,
|
|
||||||
"stream": true
|
|
||||||
}'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Using with Claude Code CLI
|
## Using with Claude Code CLI
|
||||||
|
|
||||||
Configure Claude Code to use this proxy:
|
### Configure Claude Code
|
||||||
|
|
||||||
```bash
|
Create or edit the Claude Code settings file:
|
||||||
# Set the API base URL
|
|
||||||
export ANTHROPIC_BASE_URL=http://localhost:8080
|
|
||||||
|
|
||||||
# Use any API key (it's not actually used - auth comes from Antigravity)
|
**macOS:** `~/.claude/settings.json`
|
||||||
export ANTHROPIC_API_KEY=dummy-key
|
**Linux:** `~/.claude/settings.json`
|
||||||
|
**Windows:** `%USERPROFILE%\.claude\settings.json`
|
||||||
|
|
||||||
# Run Claude Code
|
Add this configuration:
|
||||||
claude
|
|
||||||
```
|
|
||||||
|
|
||||||
Or in your Claude Code config:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"apiBaseUrl": "http://localhost:8080",
|
"env": {
|
||||||
"apiKey": "dummy-key"
|
"ANTHROPIC_AUTH_TOKEN": "test",
|
||||||
|
"ANTHROPIC_BASE_URL": "http://localhost:8080",
|
||||||
|
"ANTHROPIC_MODEL": "claude-opus-4-5-thinking",
|
||||||
|
"ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4-5-thinking",
|
||||||
|
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-5-thinking",
|
||||||
|
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-sonnet-4-5-thinking",
|
||||||
|
"CLAUDE_CODE_SUBAGENT_MODEL": "claude-opus-4-5-thinking"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Run Claude Code
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Make sure the proxy is running first
|
||||||
|
npm start
|
||||||
|
|
||||||
|
# In another terminal, run Claude Code
|
||||||
|
claude
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Available Models
|
## Available Models
|
||||||
|
|
||||||
| Model ID | Description |
|
| Model ID | Description |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
| `claude-sonnet-4-5` | Claude Sonnet 4.5 via Antigravity |
|
|
||||||
| `claude-sonnet-4-5-thinking` | Claude Sonnet 4.5 with extended thinking |
|
| `claude-sonnet-4-5-thinking` | Claude Sonnet 4.5 with extended thinking |
|
||||||
| `claude-opus-4-5-thinking` | Claude Opus 4.5 with extended thinking |
|
| `claude-opus-4-5-thinking` | Claude Opus 4.5 with extended thinking |
|
||||||
|
|
||||||
You can also use standard Anthropic model names - they'll be automatically mapped:
|
Standard Anthropic model names are automatically mapped:
|
||||||
- `claude-3-5-sonnet-20241022` → `claude-sonnet-4-5`
|
- `claude-sonnet-4-5-20250514` → `claude-sonnet-4-5-thinking`
|
||||||
- `claude-3-opus-20240229` → `claude-opus-4-5-thinking`
|
- `claude-opus-4-5-20250514` → `claude-opus-4-5-thinking`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Multi-Account Load Balancing
|
||||||
|
|
||||||
|
When you add multiple accounts, the proxy automatically:
|
||||||
|
|
||||||
|
- **Round-robin rotation**: Each request uses the next available account
|
||||||
|
- **Rate limit handling**: Automatically switches to next account on 429 errors
|
||||||
|
- **Smart cooldown**: Rate-limited accounts become available after cooldown expires
|
||||||
|
- **Invalid account detection**: Accounts needing re-authentication are marked and skipped
|
||||||
|
|
||||||
|
Check account status anytime:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8080/accounts
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
| Endpoint | Method | Description |
|
| Endpoint | Method | Description |
|
||||||
|----------|--------|-------------|
|
|----------|--------|-------------|
|
||||||
| `/health` | GET | Health check and token status |
|
| `/health` | GET | Health check |
|
||||||
|
| `/accounts` | GET | Account pool status |
|
||||||
| `/v1/messages` | POST | Anthropic Messages API |
|
| `/v1/messages` | POST | Anthropic Messages API |
|
||||||
| `/v1/models` | GET | List available models |
|
| `/v1/models` | GET | List available models |
|
||||||
| `/refresh-token` | POST | Force token refresh |
|
| `/refresh-token` | POST | Force token refresh |
|
||||||
|
|
||||||
## Files
|
---
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Run the test suite (requires server running):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start server in one terminal
|
||||||
|
npm start
|
||||||
|
|
||||||
|
# Run tests in another terminal
|
||||||
|
npm test
|
||||||
```
|
```
|
||||||
src/
|
|
||||||
├── index.js # Entry point
|
Individual tests:
|
||||||
├── server.js # Express server with Anthropic API endpoints
|
|
||||||
├── cloudcode-client.js # Cloud Code API client with proper wrapping
|
```bash
|
||||||
├── format-converter.js # Anthropic ↔ Google format conversion
|
npm run test:signatures # Thinking signatures
|
||||||
├── constants.js # Endpoints, headers, model mappings
|
npm run test:multiturn # Multi-turn with tools
|
||||||
└── token-extractor.js # Extracts OAuth token from Antigravity
|
npm run test:streaming # Streaming SSE events
|
||||||
|
npm run test:interleaved # Interleaved thinking
|
||||||
|
npm run test:images # Image processing
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### "Could not extract token from Antigravity"
|
### "Could not extract token from Antigravity"
|
||||||
|
|
||||||
Make sure:
|
If using single-account mode with Antigravity:
|
||||||
1. Antigravity app is running
|
1. Make sure Antigravity app is installed and running
|
||||||
2. You're logged in to Antigravity
|
2. Ensure you're logged in to Antigravity
|
||||||
|
|
||||||
|
Or add accounts via OAuth instead: `npm run accounts:add`
|
||||||
|
|
||||||
### 401 Authentication Errors
|
### 401 Authentication Errors
|
||||||
|
|
||||||
@@ -137,16 +205,101 @@ The token might have expired. Try:
|
|||||||
curl -X POST http://localhost:8080/refresh-token
|
curl -X POST http://localhost:8080/refresh-token
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or re-authenticate the account:
|
||||||
|
```bash
|
||||||
|
npm run accounts
|
||||||
|
```
|
||||||
|
|
||||||
### Rate Limiting (429)
|
### Rate Limiting (429)
|
||||||
|
|
||||||
Antigravity enforces rate limits on Cloud Code requests. Wait and retry, or switch to a different model.
|
With multiple accounts, the proxy automatically switches to the next available account. With a single account, you'll need to wait for the rate limit to reset.
|
||||||
|
|
||||||
|
### Account Shows as "Invalid"
|
||||||
|
|
||||||
|
Re-authenticate the account:
|
||||||
|
```bash
|
||||||
|
npm run accounts
|
||||||
|
# Choose "Re-authenticate" for the invalid account
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── index.js # Entry point
|
||||||
|
├── server.js # Express server with Anthropic API endpoints
|
||||||
|
├── cloudcode-client.js # Cloud Code API client with retry/failover
|
||||||
|
├── format-converter.js # Anthropic ↔ Google format conversion
|
||||||
|
├── account-manager.js # Multi-account management
|
||||||
|
├── accounts-cli.js # Account management CLI
|
||||||
|
├── oauth.js # Google OAuth implementation
|
||||||
|
├── constants.js # Endpoints, headers, model mappings
|
||||||
|
└── token-extractor.js # Legacy token extraction from Antigravity
|
||||||
|
|
||||||
|
tests/
|
||||||
|
├── run-all.cjs # Test runner
|
||||||
|
├── test-thinking-signatures.cjs # Thinking block tests
|
||||||
|
├── test-multiturn-thinking-tools.cjs # Multi-turn tests
|
||||||
|
├── test-multiturn-thinking-tools-streaming.cjs
|
||||||
|
├── test-interleaved-thinking.cjs
|
||||||
|
└── test-images.cjs
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Safety, Usage, and Risk Notices
|
||||||
|
|
||||||
|
### Intended Use
|
||||||
|
|
||||||
|
- Personal / internal development only
|
||||||
|
- Respect internal quotas and data handling policies
|
||||||
|
- Not for production services or bypassing intended limits
|
||||||
|
|
||||||
|
### Not Suitable For
|
||||||
|
|
||||||
|
- Production application traffic
|
||||||
|
- High-volume automated extraction
|
||||||
|
- Any use that violates Acceptable Use Policies
|
||||||
|
|
||||||
|
### Warning (Assumption of Risk)
|
||||||
|
|
||||||
|
By using this software, you acknowledge and accept the following:
|
||||||
|
|
||||||
|
- **Terms of Service risk**: This approach may violate the Terms of Service of AI model providers (Anthropic, Google, etc.). You are solely responsible for ensuring compliance with all applicable terms and policies.
|
||||||
|
|
||||||
|
- **Account risk**: Providers may detect this usage pattern and take punitive action, including suspension, permanent ban, or loss of access to paid subscriptions.
|
||||||
|
|
||||||
|
- **No guarantees**: Providers may change APIs, authentication, or policies at any time, which can break this method without notice.
|
||||||
|
|
||||||
|
- **Assumption of risk**: You assume all legal, financial, and technical risks. The authors and contributors of this project bear no responsibility for any consequences arising from your use.
|
||||||
|
|
||||||
|
**Use at your own risk. Proceed only if you understand and accept these risks.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Legal
|
||||||
|
|
||||||
|
- **Not affiliated with Google or Anthropic.** This is an independent open-source project and is not endorsed by, sponsored by, or affiliated with Google LLC or Anthropic PBC.
|
||||||
|
|
||||||
|
- "Antigravity", "Gemini", "Google Cloud", and "Google" are trademarks of Google LLC.
|
||||||
|
|
||||||
|
- "Claude" and "Anthropic" are trademarks of Anthropic PBC.
|
||||||
|
|
||||||
|
- Software is provided "as is", without warranty. You are responsible for complying with all applicable Terms of Service and Acceptable Use Policies.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
Based on insights from:
|
This project is based on insights and code from:
|
||||||
|
|
||||||
- [opencode-antigravity-auth](https://github.com/NoeFabris/opencode-antigravity-auth) - Antigravity OAuth plugin for OpenCode
|
- [opencode-antigravity-auth](https://github.com/NoeFabris/opencode-antigravity-auth) - Antigravity OAuth plugin for OpenCode
|
||||||
- [claude-code-proxy](https://github.com/1rgs/claude-code-proxy) - Anthropic API proxy using LiteLLM
|
- [claude-code-proxy](https://github.com/1rgs/claude-code-proxy) - Anthropic API proxy using LiteLLM
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
|
|||||||
Reference in New Issue
Block a user