AgnesCode agnest 本地 HTTP API 协议分析报告
协议端点: Main Process (Node.js) ↔ agnesd (Rust Backend)
通信方式: HTTPS (自签名证书) + HTTP API
报告日期: 2026-07-25
分析版本: v1.0.17
1. 架构概述
┌──────────────────────────────────────────────────────────────┐
│ Electron Main Process │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ bM() 函数: 启动/管理 agnesd 进程 │ │
│ │ ├── 查找 agnesd 二进制 │ │
│ │ ├── 分配随机端口 │ │
│ │ ├── 设置环境变量 │ │
│ │ ├── spawn("agnesd", ["agent"]) │ │
│ │ ├── 解析 stdout 中的 GOOSED_CERT_FINGERPRINT │ │
│ │ ├── 健康检查轮询 │ │
│ │ └── 创建 API 客户端 (X-Secret-Key 认证) │ │
│ └────────────────────────┬───────────────────────────────┘ │
│ │ HTTPS (localhost:随机端口) │
│ ┌────────────────────────▼───────────────────────────────┐ │
│ │ agnesd (Rust 二进制, 243MB) │ │
│ │ ├── 自签名 TLS 证书 │ │
│ │ ├── X-Secret-Key 认证 │ │
│ │ ├── SQLite 数据库 │ │
│ │ ├── ACP WebSocket 服务 │ │
│ │ └── HTTP API 路由 │ │
│ └────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘2. 进程管理
2.1 二进制查找
javascript
function mM(options) {
// 优先使用环境变量
const binary = process.env.AGNESD_BINARY ?? process.env.GOOSED_BINARY;
if (binary && fs.existsSync(binary)) return binary;
// 查找路径:
// 1. 打包资源: Resources/bin/agnesd
// 2. 开发目录: src/bin/agnesd
// 3. 构建目录: target/release/agnesd
// 4. target/debug/agnesd
const name = process.platform === "win32" ? "agnesd.exe" : "agnesd";
// ... 搜索多个路径
}2.2 启动参数
javascript
const spawnOptions = {
env: {
...process.env,
AGNES_PORT: port.toString(),
AGNES_SERVER__SECRET_KEY: secretKey,
AGNES_KEYRING_SERVICE: "com.agnes.code.secrets", // 或 dev 版本
HOME: homeDir,
PATH: systemPath,
// Windows 额外:
USERPROFILE: homeDir,
APPDATA: join(homeDir, "AppData", "Roaming"),
LOCALAPPDATA: join(homeDir, "AppData", "Local"),
},
cwd: workingDir,
windowsHide: true,
detached: process.platform === "win32",
shell: false,
stdio: ["ignore", "pipe", "pipe"]
};
// 启动命令: agnesd agent
const child = spawn("agnesd", ["agent"], spawnOptions);2.3 证书指纹解析
javascript
// 从 stdout 解析自签名证书指纹
const FINGERPRINT_MARKER = "GOOSED_CERT_FINGERPRINT=";
child.stdout.on("data", (data) => {
const text = data.toString();
if (text.includes(FINGERPRINT_MARKER)) {
// 提取指纹
const fingerprint = text.split(FINGERPRINT_MARKER)[1].split("\n")[0];
// 格式: sha256/{base64}
}
});2.4 健康检查
javascript
async function yM(client, options) {
const timeout = options.timeoutMs ?? 30000; // 总超时 30s
const requestTimeout = options.requestTimeoutMs ?? 2000; // 单次 2s
const interval = options.intervalMs ?? 250; // 间隔 250ms
const start = Date.now() + timeout;
while (Date.now() < start) {
try {
await client.GET("/health_check", { throwOnError: true });
return true; // 健康检查成功
} catch (error) {
if (isNonRetryable(error)) return false; // 4xx 或证书错误
}
await sleep(interval);
}
return false; // 超时
}3. API 客户端
3.1 客户端创建
javascript
const client = createClient({
baseUrl: 'https://127.0.0.1:{port}',
headers: {
'Content-Type': 'application/json',
'X-Secret-Key': secretKey
}
});3.2 认证方式
- Header:
X-Secret-Key - Secret Key 生成:
crypto.randomBytes(32).toString('hex') - 外部后端: 通过
AGNES_EXTERNAL_BACKEND环境变量配置
3.3 证书验证
javascript
// 自签名证书指纹验证
// 信任 127.0.0.1 和 localhost
// 存储已信任的指纹
// 首次连接: 记录并信任
// 后续连接: 验证指纹匹配
app.on("certificate-error", (event, url, error, certificate, callback) => {
const hostname = new URL(url).hostname;
if (!isLocalhost(hostname)) { callback(false); return; }
event.preventDefault();
callback(isTrusted(certificate, hostname));
});4. HTTP API 路由
从 agnesd 二进制字符串提取的 HTTP 路由:
4.1 健康检查
| 方法 | 路径 | 描述 |
|---|---|---|
| GET | /health_check | 健康检查 (用于启动轮询) |
4.2 代码相关
| 方法 | 路径 | 描述 |
|---|---|---|
| POST | /api/v1/code/image_search | 图片搜索 |
| POST | /api/v1/code/quota/settle | 配额结算 |
| POST | /api/v1/code/session/title | 会话标题生成 |
| POST | /api/v1/code/web_search | 网页搜索 |
| POST | /api/v1/file/presigned-url | 预签名上传 URL |
4.3 MCP 事件
| 方法 | 路径 | 描述 |
|---|---|---|
| POST | /api/v4/mcp/event | MCP 事件上报 |
4.4 OAuth
| 方法 | 路径 | 描述 |
|---|---|---|
| GET | /oauth/authorize | OAuth 授权 |
| POST | /oauth/token | OAuth Token 交换 |
| POST | /login/device/code | 设备码登录 |
| POST | /login/oauth/access_token | OAuth 访问令牌 |
4.5 AI 推理
| 方法 | 路径 | 描述 |
|---|---|---|
| POST | /v1/chat/completions | OpenAI 兼容聊天补全 |
| POST | /v1/messages | Messages API |
| GET | /v1/models | 模型列表 |
| POST | /v1/chunks/ | 文件分块 |
| POST | /v1/reconstructions/ | 文件重建 |
| POST | /v1/xorbs/ | XORB 存储操作 |
4.6 工具
| 方法 | 路径 | 描述 |
|---|---|---|
| GET | /tokenizers | 分词器 |
5. 数据库
从 agnesd 二进制提取的 SQLite 表结构:
5.1 sessions 表
sql
CREATE TABLE sessions (
id TEXT PRIMARY KEY,
title TEXT,
project_id TEXT,
parent_session_id TEXT,
provider_name TEXT NOT NULL,
model_config_json TEXT,
goose_mode TEXT NOT NULL DEFAULT 'auto',
session_type TEXT,
working_dir TEXT,
extension_data TEXT,
total_tokens INTEGER,
input_tokens INTEGER,
output_tokens INTEGER,
cache_read_tokens INTEGER,
cache_write_tokens INTEGER,
accumulated_total_tokens INTEGER,
accumulated_input_tokens INTEGER,
accumulated_output_tokens INTEGER,
accumulated_cache_read_tokens INTEGER,
accumulated_cache_write_tokens INTEGER,
schedule_id TEXT,
recipe_json TEXT,
user_recipe_values_json TEXT,
archived_at TEXT,
created_timestamp TEXT NOT NULL,
updated_at TEXT,
user_set_name TEXT
);5.2 provider_inventory_entries 表
sql
CREATE TABLE provider_inventory_entries (
id INTEGER PRIMARY KEY,
provider_id TEXT
);
CREATE INDEX idx_provider_inventory_provider_id ON provider_inventory_entries(provider_id);6. 外部后端支持
6.1 AGNES_EXTERNAL_BACKEND
通过环境变量支持外部后端:
javascript
if (process.env.AGNES_EXTERNAL_BACKEND) {
const baseUrl = `https://127.0.0.1:${process.env.AGNES_PORT || "3000"}`;
// 使用外部后端, 不启动本地 agnesd 进程
return {
baseUrl,
process: null, // 无本地进程
client: createClient(baseUrl, secretKey),
certFingerprint: null
};
}6.2 externalGoosed 配置
javascript
// 在设置中配置的外部后端
{
"externalGoosed": {
"enabled": true,
"url": "https://your-backend.com",
"secret": "your-secret-key"
}
}7. 密钥管理
7.1 密钥链服务名
| 模式 | 服务名 |
|---|---|
| 生产 | com.agnes.code.secrets |
| 开发 | com.agnes.code.dev.secrets |
7.2 环境变量传递
AGNES_SERVER__SECRET_KEY={random_32_byte_hex}
AGNES_KEYRING_SERVICE=com.agnes.code.secrets8. 启动流程
1. Renderer 发送 react-ready
2. Main Process 确定工作目录
3. 查找 agnesd 二进制
4. 分配随机端口
5. 设置环境变量 (AGNES_PORT, AGNES_SERVER__SECRET_KEY, etc.)
6. spawn("agnesd", ["agent"])
7. 解析 stdout 中的 GOOSED_CERT_FINGERPRINT
8. 健康检查轮询 (每 250ms, 最长 30s)
9. 标记后端就绪, 通知 Renderer
10. Renderer 获取 ACP URL, 建立 WebSocket 连接