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

8.5 KiB
Raw Blame History

Antigravity HTTP API 集成指南

架构

下游客户端IDE、工具、脚本
    ↓ (HTTP POST/GET)
sub2api HTTP API
    ↓ (内部调用)
LanguageServerService业务逻辑层
    ↓ (伪装 + 转发)
官方 APIAnthropic/Google

集成步骤

Step 1在服务器初始化代码中注册路由

编辑 backend/cmd/server/main.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 端点

启动会话

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"
# }

发送消息(流式)

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":"..."}

获取模型列表

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"
#     },
#     ...
#   ]
# }

健康检查

curl -X GET http://localhost:8080/api/v1/health

# 响应示例:
# {
#   "status": "running",
#   "version": "1.0.0"
# }

Step 3客户端连接示例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

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

请求体:

{
  "model": "claude-opus-4-6",      // 模型名称
  "system_prompt": "...",           // 系统提示(可选)
  "metadata": {                     // 伪装信息(可选)
    "user-agent": "...",
    "machine-id": "...",
    "mac-machine-id": "...",
    "dev-device-id": "...",
    "sqm-id": "..."
  }
}

响应:

{
  "cascade_id": "uuid"
}

POST /api/v1/cascade/message

发送用户消息到 Cascade流式

请求头:

  • Authorization: Bearer <oauth_token>(必需)
  • Content-Type: application/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 会话

请求体:

{
  "cascade_id": "uuid"
}

响应:

{
  "success": true
}

GET /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,
      "supports_images": true,
      "provider": "anthropic"
    },
    ...
  ]
}

GET /api/v1/health

健康检查

响应:

{
  "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                          # 服务器入口(需更新)