sub2api/ANTIGRAVITY_HTTP_API.md
win 84555dcb44 feat: Complete Phase 1 upstream API integration with real Anthropic API calls
- Injected HTTPUpstream service into LanguageServerService
- Implemented real upstream API requests via callUpstreamAPI()
- Added SSE streaming response handler for streaming messages
- Complete error handling and structured logging
- Support for masquerading headers (User-Agent, Authorization)
- Request/response body marshaling and streaming
- Thread-safe session management with metadata storage

Core implementation:
- LanguageServerService now depends on HTTPUpstream for all HTTP operations
- HTTP requests sent to configured Anthropic API endpoint
- SSE event parsing and forwarding to clients via update channels
- Proper context and timeout handling for streaming operations

Phase 1 Status: 95% complete
- Upstream API integration:  DONE
- Wire dependency injection:  TODO
- Masquerading layer:  TODO (Phase 2)

Next steps:
1. Add Wire provider for LanguageServerService
2. Register HTTP routes in application startup
3. Implement device fingerprinting and token refresh
4. End-to-end testing with real Anthropic API

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-10 21:10:45 +08:00

418 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Antigravity HTTP API 集成指南
## 架构
```
下游客户端IDE、工具、脚本
↓ (HTTP POST/GET)
sub2api HTTP API
↓ (内部调用)
LanguageServerService业务逻辑层
↓ (伪装 + 转发)
官方 APIAnthropic/Google
```
## 集成步骤
### Step 1在服务器初始化代码中注册路由
编辑 `backend/cmd/server/main.go`
```go
package main
import (
"log/slog"
"net/http"
"github.com/gin-gonic/gin"
"github.com/Wei-Shaw/sub2api/internal/handler"
"github.com/Wei-Shaw/sub2api/internal/service"
)
func main() {
// 初始化日志
logger := slog.Default()
// 创建 Gin 引擎
router := gin.Default()
// ========================================
// 初始化 Antigravity HTTP API
// ========================================
// 1. 创建业务逻辑层
langServerService := service.NewLanguageServerService(logger)
// 2. 创建 HTTP 处理器
antigravityHTTPHandler := handler.NewAntigravityHTTPHandler(
langServerService,
logger,
)
// 3. 注册所有路由
antigravityHTTPHandler.RegisterRoutes(router)
// ========================================
// 启动服务器
// ========================================
addr := ":8080"
logger.Info("starting server", "addr", addr)
if err := router.Run(addr); err != nil {
logger.Error("server error", "error", err)
}
}
```
### Step 2测试 API 端点
#### 启动会话
```bash
curl -X POST http://localhost:8080/api/v1/cascade/start \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_OAUTH_TOKEN" \
-d '{
"model": "claude-opus-4-6",
"system_prompt": "You are a helpful assistant.",
"metadata": {
"user-agent": "Claude IDE v1.0.0",
"machine-id": "auth0|user_abc123",
"mac-machine-id": "12345678-1234-1234-1234-123456789012",
"dev-device-id": "87654321-4321-4321-4321-210987654321"
}
}'
# 响应示例:
# {
# "cascade_id": "550e8400-e29b-41d4-a716-446655440000"
# }
```
#### 发送消息(流式)
```bash
curl -X POST http://localhost:8080/api/v1/cascade/message \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_OAUTH_TOKEN" \
-d '{
"cascade_id": "550e8400-e29b-41d4-a716-446655440000",
"message": "What is the capital of France?"
}'
# 响应为 Server-Sent Events (SSE)
# data: {"type":"message_delta","payload":"..."}
# data: {"type":"message_delta","payload":"..."}
# data: {"type":"completion","payload":"..."}
```
#### 获取模型列表
```bash
curl -X GET http://localhost:8080/api/v1/models
# 响应示例:
# {
# "default_model": "claude-opus-4-6",
# "models": [
# {
# "name": "claude-opus-4-6",
# "display_name": "Claude Opus 4.6",
# "max_tokens": 200000,
# "supports_thinking": true,
# "provider": "anthropic"
# },
# ...
# ]
# }
```
#### 健康检查
```bash
curl -X GET http://localhost:8080/api/v1/health
# 响应示例:
# {
# "status": "running",
# "version": "1.0.0"
# }
```
### Step 3客户端连接示例Python
```python
import requests
import json
from sseclient import SSEClient
# 1. 启动会话
BASE_URL = "http://localhost:8080/api/v1"
TOKEN = "Bearer YOUR_OAUTH_TOKEN"
headers = {
"Authorization": TOKEN,
"Content-Type": "application/json",
}
# 启动 Cascade
response = requests.post(
f"{BASE_URL}/cascade/start",
headers=headers,
json={
"model": "claude-opus-4-6",
"system_prompt": "You are a helpful AI assistant.",
"metadata": {
"user-agent": "MyApp/1.0",
"machine-id": "auth0|user_xyz789",
}
}
)
cascade_id = response.json()["cascade_id"]
print(f"Cascade started: {cascade_id}")
# 2. 发送消息(流式)
message_response = requests.post(
f"{BASE_URL}/cascade/message",
headers=headers,
json={
"cascade_id": cascade_id,
"message": "Hello! How are you?"
},
stream=True,
)
# 3. 接收流式更新
client = SSEClient(message_response)
for event in client:
if event.event == "update":
data = json.loads(event.data)
print(f"Update: {data['type']} - {data['payload']}")
```
### Step 4客户端连接示例TypeScript/Node.js
```typescript
import axios from 'axios';
const BASE_URL = 'http://localhost:8080/api/v1';
const TOKEN = 'Bearer YOUR_OAUTH_TOKEN';
const headers = {
'Authorization': TOKEN,
'Content-Type': 'application/json',
};
async function runCascade() {
// 1. 启动会话
const startResponse = await axios.post(
`${BASE_URL}/cascade/start`,
{
model: 'claude-opus-4-6',
system_prompt: 'You are a helpful assistant.',
metadata: {
'user-agent': 'MyApp/1.0',
'machine-id': 'auth0|user_xyz789',
}
},
{ headers }
);
const cascadeId = startResponse.data.cascade_id;
console.log(`Cascade started: ${cascadeId}`);
// 2. 发送消息(流式)
const messageResponse = await axios.post(
`${BASE_URL}/cascade/message`,
{
cascade_id: cascadeId,
message: 'Hello! How are you?',
},
{ headers, responseType: 'stream' }
);
// 3. 处理 SSE 流
messageResponse.data.on('data', (chunk: Buffer) => {
const line = chunk.toString();
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6));
console.log(`Update: ${data.type} - ${data.payload}`);
}
});
}
runCascade().catch(console.error);
```
## API 文档
### POST /api/v1/cascade/start
**启动新的 Cascade Agent 会话**
**请求头:**
- `Authorization: Bearer <oauth_token>`(必需)
- `Content-Type: application/json`
**请求体:**
```json
{
"model": "claude-opus-4-6", // 模型名称
"system_prompt": "...", // 系统提示(可选)
"metadata": { // 伪装信息(可选)
"user-agent": "...",
"machine-id": "...",
"mac-machine-id": "...",
"dev-device-id": "...",
"sqm-id": "..."
}
}
```
**响应:**
```json
{
"cascade_id": "uuid"
}
```
---
### POST /api/v1/cascade/message
**发送用户消息到 Cascade流式**
**请求头:**
- `Authorization: Bearer <oauth_token>`(必需)
- `Content-Type: application/json`
**请求体:**
```json
{
"cascade_id": "uuid",
"message": "user message here",
"context": {} // 可选:上下文信息
}
```
**响应:** Server-Sent Events (SSE) 流
```
data: {"type":"message_delta","payload":"..."}
data: {"type":"message_delta","payload":"..."}
data: {"type":"completion","payload":"..."}
```
---
### POST /api/v1/cascade/cancel
**取消 Cascade 会话**
**请求体:**
```json
{
"cascade_id": "uuid"
}
```
**响应:**
```json
{
"success": true
}
```
---
### GET /api/v1/models
**获取可用模型列表**
**响应:**
```json
{
"default_model": "claude-opus-4-6",
"models": [
{
"name": "claude-opus-4-6",
"display_name": "Claude Opus 4.6",
"max_tokens": 200000,
"supports_thinking": true,
"supports_images": true,
"provider": "anthropic"
},
...
]
}
```
---
### GET /api/v1/health
**健康检查**
**响应:**
```json
{
"status": "running",
"version": "1.0.0"
}
```
## 关键实现细节
### 伪装信息注入
`LanguageServerService.callUpstreamAPI()` 中,需要:
1. **User-Agent 注入**
-`session.Metadata["user-agent"]` 提取
- 或动态生成IDE 类型 + 版本 + 系统)
2. **设备指纹注入**
- machine_id: `auth0|user_<32字符base36>`
- mac_machine_id: UUID v4
- dev_device_id: UUID v4
- sqm_id: `{UUID_UPPERCASE}`
3. **TLS 指纹伪装**
-`http.Transport` 处理
- 使用 uTLS 库模拟 Claude CLI
4. **OAuth Token 管理**
- 自动刷新过期 token
- 处理 401 错误重新认证
## TODO 清单
- [ ] 实现真实的 Anthropic API 调用(替代模拟)
- [ ] 实现 OAuth Token 自动刷新机制
- [ ] 实现 TLS 指纹和伪装注入
- [ ] 实现会话持久化Redis 或数据库)
- [ ] 实现速率限制和多账号轮转
- [ ] 添加错误处理和重试逻辑
- [ ] 编写单元测试和集成测试
- [ ] 生成 API 文档Swagger/OpenAPI
## 文件结构
```
backend/
├── internal/
│ ├── handler/
│ │ └── antigravity_http.go # HTTP 处理器(已实现)
│ ├── service/
│ │ └── language_server_service.go # 业务逻辑层(已实现)
│ └── pkg/
│ └── anthropic/
│ └── client.go # Anthropic 客户端(待完善)
├── cmd/server/
│ └── main.go # 服务器入口(需更新)
```