Skip to content

AgnesCode 协议 & 认证深度分析报告

报告日期: 2026-07-24
分析版本: v1.0.17
分析范围: ACP 协议、认证流程、后端 API、MCP 集成、反向代理实现指南


1. ACP 协议详解

1.1 协议概述

ACP (Agent Client Protocol) 是 AgnesCode 的核心通信协议,基于 JSON-RPC 2.0,运行于 WebSocket 之上。

协议特征:

  • 传输层: WebSocket (WSS)
  • 消息格式: JSON-RPC 2.0
  • 认证: Token via URL 参数 + X-Secret-Key HTTP 头
  • 流式: 支持 SSE (Server-Sent Events) 进行流式传输
  • 双向: 支持 Request/Response 和 Notification (无响应)

1.2 连接建立

WebSocket URL 构造:

javascript
// 函数 Vj(e, t) 构造 ACP WebSocket URL
function Vj(baseUrl, token) {
    const r = new URL(baseUrl);
    r.pathname = `${r.pathname.replace(/\/+$/, "")}/acp`;
    r.protocol = r.protocol === "https:" ? "wss:" : "ws:";
    r.searchParams.set("token", token);
    return r.toString();
}
// 示例: wss://127.0.0.1:{port}/acp?token={secretKey}

HTTP 头:

  • Acp-Connection-Id: 连接级 SSE 流标识
  • Acp-Session-Id: 会话级 SSE 流标识
  • X-Secret-Key: API 认证密钥 (HTTP API 用)
  • Content-Type: application/json

1.3 消息格式 (JSON-RPC 2.0)

Request 消息

json
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "session/prompt",
    "params": { ... }
}

Response 消息

json
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": { ... }
}

错误响应

json
{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": -32601,
        "message": "Method not found: xxx",
        "data": { "method": "xxx" }
    }
}

Notification 消息 (无响应)

json
{
    "jsonrpc": "2.0",
    "method": "session/cancel",
    "params": { ... }
}

1.4 标准 ACP 方法

方法类型方向描述
session/newRequestClient→Server创建新会话
session/promptRequestClient→Server发送提示词
session/cancelNotificationClient→Server取消当前请求
session/closeRequestClient→Server关闭会话
session/forkRequestClient→Server分叉会话
session/listRequestClient→Server列出会话
session/loadRequestClient→Server加载会话
session/resumeRequestClient→Server恢复会话
session/set_modeRequestClient→Server设置模式 (smart/expert)
session/set_modelRequestClient→Server设置模型
session/set_config_optionRequestClient→Server设置配置项
session/request_permissionRequestServer→Client请求权限
session/updateNotificationServer→Client会话更新推送
initializeRequestClient→Server初始化连接
authenticateRequestClient→Server认证
logoutRequestClient→Server登出

1.5 扩展方法 (Agnes 自定义)

所有 Agnes 扩展方法以 _agnes/unstable/ 为前缀:

方法描述
_agnes/unstable/tools/list列出工具
_agnes/unstable/tools/call调用工具
_agnes/unstable/tools/permissions/set设置工具权限
_agnes/unstable/resources/read读取资源
_agnes/unstable/session/info获取会话信息
_agnes/unstable/session/export导出会话
_agnes/unstable/session/import导入会话
_agnes/unstable/session/history/load加载会话历史
_agnes/unstable/session/extensions/add添加会话扩展
_agnes/unstable/session/extensions/remove移除会话扩展
_agnes/unstable/session/extensions/list列出会话扩展
_agnes/unstable/session/system-prompt/set设置系统提示
_agnes/unstable/session/working-dir/update更新工作目录
_agnes/unstable/session/steer控制会话方向
_agnes/unstable/session/archive归档会话
_agnes/unstable/session/unarchive取消归档
_agnes/unstable/session/rename重命名会话
_agnes/unstable/session/share/nostr分享会话 (Nostr)
_agnes/unstable/session/conversation/truncate截断对话
_agnes/unstable/session/recipe/request-params请求配方参数
_agnes/unstable/session/project/update更新会话项目
_agnes/unstable/side-chat/start启动侧边聊天
_agnes/unstable/side-chat/cancel取消侧边聊天
_agnes/unstable/side-chat/dispose销毁侧边聊天
_agnes/unstable/config/read读取配置
_agnes/unstable/config/read-all读取所有配置
_agnes/unstable/config/upsert更新/插入配置
_agnes/unstable/config/remove删除配置
_agnes/unstable/config/prompts/list列出提示词
_agnes/unstable/config/prompts/get获取提示词
_agnes/unstable/config/prompts/save保存提示词
_agnes/unstable/config/prompts/reset重置提示词
_agnes/unstable/config/extensions/add添加扩展配置
_agnes/unstable/config/extensions/remove移除扩展
_agnes/unstable/config/extensions/list列出扩展
_agnes/unstable/config/extensions/set-enabled启用/禁用扩展
_agnes/unstable/defaults/read读取默认值
_agnes/unstable/defaults/save保存默认值
_agnes/unstable/defaults/clear清除默认值
_agnes/unstable/providers/list列出提供商
_agnes/unstable/providers/config/read读取提供商配置
_agnes/unstable/providers/config/save保存提供商配置
_agnes/unstable/providers/config/delete删除提供商配置
_agnes/unstable/providers/config/authenticate认证提供商
_agnes/unstable/providers/config/status提供商配置状态
_agnes/unstable/providers/secrets/list列出密钥
_agnes/unstable/providers/secrets/delete删除密钥
_agnes/unstable/providers/catalog/list列出提供商目录
_agnes/unstable/providers/catalog/template提供商模板
_agnes/unstable/providers/setup/catalog/list设置目录列表
_agnes/unstable/providers/custom/create创建自定义提供商
_agnes/unstable/providers/custom/read读取自定义提供商
_agnes/unstable/providers/custom/update更新自定义提供商
_agnes/unstable/providers/custom/delete删除自定义提供商
_agnes/unstable/providers/supported-models/list列出支持的模型
_agnes/unstable/providers/canonical-model-info规范模型信息
_agnes/unstable/providers/inventory/refresh刷新库存
_agnes/unstable/recipes/list列出配方
_agnes/unstable/recipes/delete删除配方
_agnes/unstable/recipes/encode编码配方
_agnes/unstable/recipes/decode解码配方
_agnes/unstable/recipes/parse解析配方
_agnes/unstable/recipes/save保存配方
_agnes/unstable/recipes/scan扫描配方
_agnes/unstable/recipes/schedule调度配方
_agnes/unstable/recipes/slash-command斜杠命令
_agnes/unstable/recipes/to-yaml配方转 YAML
_agnes/unstable/onboarding/import/scan扫描导入
_agnes/unstable/onboarding/import/apply应用导入
_agnes/unstable/tools/list列出工具
_agnes/unstable/tools/call调用工具
_agnes/unstable/tools/permissions/set设置工具权限
_agnes/unstable/resources/read读取资源
_agnes/unstable/apps/list列出应用
_agnes/unstable/apps/export导出应用
_agnes/unstable/apps/import导入应用
_agnes/unstable/apps/delete删除应用
_agnes/unstable/capabilities/list列出能力
_agnes/unstable/diagnostics/get获取诊断
_agnes/unstable/sources/list列出源
_agnes/unstable/sources/create创建源
_agnes/unstable/sources/update更新源
_agnes/unstable/sources/delete删除源
_agnes/unstable/sources/export导出源
_agnes/unstable/sources/import导入源
_agnes/unstable/extensions/available可用扩展
_agnes/unstable/local-inference/models/list本地推理模型列表
_agnes/unstable/local-inference/models/download下载模型
_agnes/unstable/local-inference/models/download/progress下载进度
_agnes/unstable/local-inference/models/download/cancel取消下载
_agnes/unstable/local-inference/models/delete删除模型
_agnes/unstable/local-inference/models/evict驱逐模型
_agnes/unstable/local-inference/models/settings/read读取本地推理设置
_agnes/unstable/local-inference/models/settings/update更新本地推理设置
_agnes/unstable/local-inference/huggingface/searchHuggingFace 搜索
_agnes/unstable/local-inference/huggingface/repo/variantsHuggingFace 仓库变体
_agnes/unstable/local-inference/chat-templates/builtin/list内置聊天模板列表
_agnes/unstable/dictation/config听写配置
_agnes/unstable/dictation/transcribe听写转写
_agnes/unstable/dictation/models/list听写模型列表
_agnes/unstable/dictation/models/download下载听写模型
_agnes/unstable/dictation/models/download/progress下载进度
_agnes/unstable/dictation/models/download/cancel取消下载
_agnes/unstable/dictation/models/delete删除听写模型
_agnes/unstable/dictation/models/select选择听写模型
_agnes/unstable/dictation/secret/save保存听写密钥
_agnes/unstable/dictation/secret/delete删除听写密钥
_agnes/unstable/dictation/models/cancel取消听写模型操作
_agnes/unstable/scheduled-tasks/create创建定时任务
_agnes/unstable/scheduled-tasks/delete删除定时任务
_agnes/unstable/scheduled-tasks/list列出定时任务
_agnes/unstable/scheduled-tasks/get获取定时任务
_agnes/unstable/scheduled-tasks/update更新定时任务
_agnes/unstable/scheduled-tasks/pause暂停定时任务
_agnes/unstable/scheduled-tasks/unpause恢复定时任务
_agnes/unstable/scheduled-tasks/run-now立即运行
_agnes/unstable/scheduled-tasks/runs/list运行记录列表
_agnes/unstable/scheduled-tasks/sessions/list任务会话列表
_agnes/unstable/scheduled-tasks/running-job/inspect检查运行中任务
_agnes/unstable/scheduled-tasks/running-job/kill终止运行中任务
_agnes/unstable/schedules/*日程管理 (同 scheduled-tasks)
_agnes/unstable/agent-mentions/list列出 Agent 提及
_agnes/unstable/slash-commands/list列出斜杠命令
_agnes/unstable/preferences/read读取偏好
_agnes/unstable/preferences/save保存偏好
_agnes/unstable/preferences/remove删除偏好

1.6 流式传输

ACP 支持两种流式传输方式:

1. 连接级 SSE 流 (Connection-scoped GET Stream)

GET /acp
Accept: text/event-stream
Acp-Connection-Id: {connectionId}

用于接收服务器推送事件。

2. 会话级 SSE 流 (Session-scoped GET Stream)

GET /acp
Accept: text/event-stream
Acp-Connection-Id: {connectionId}
Acp-Session-Id: {sessionId}

用于接收特定会话的推送事件。

1.7 错误码

代码名称描述
-32700Parse ErrorJSON 解析错误
-32600Invalid Request无效请求
-32601Method Not Found方法不存在
-32602Invalid Params无效参数
-32603Internal Error内部错误
-32000Auth Required需要认证
-32002Resource Not Found资源不存在
-32800URL Elicitation Required需要 URL 引导

2. 认证与授权完整流程

2.1 完整认证数据流

┌─────────────────────────────────────────────────────────────────────────┐
│  1. 用户点击"登录"                                                        │
│                                                                         │
│  2. 渲染进程调用:                                                        │
│     window.electron.startAuthLogin()                                     │
│                                                                         │
│  3. 主进程:                                                              │
│     a. 生成 32 字节随机 state (crypto.randomBytes(32).toString('hex'))     │
│     b. 构造登录 URL:                                                      │
│        const url = AGNES_SA_WEB_LOGIN_URL + '/login'                     │
│        url += '?client=agnes-code'                                       │
│        url += '&redirect_uri=agnes://auth/callback'                      │
│        url += '&state=' + state                                          │
│     c. 保存 state 和 windowId 的映射                                       │
│     d. shell.openExternal(url) 在系统浏览器中打开                           │
│     e. 返回 { state } 给渲染进程                                           │
│                                                                         │
│  4. 用户在浏览器中完成登录                                                 │
│                                                                         │
│  5. 浏览器重定向到:                                                       │
│     agnes://auth/callback?code={auth_code}&state={state}                │
│                                                                         │
│  6. 操作系统处理 agnes:// 协议,唤起 Electron 应用                          │
│     a. macOS: app.on('open-url', ...)                                    │
│     b. 其他平台: 通过命令行参数 / 自定义协议处理                              │
│                                                                         │
│  7. 主进程验证 state 匹配:                                                │
│     if (savedState !== receivedState) → 拒绝                              │
│                                                                         │
│  8. 主进程通过 IPC 发送 auth-deeplink 给渲染进程:                           │
│     webContents.send('auth-deeplink', { code, state })                   │
│                                                                         │
│  9. 渲染进程调用 eX() 函数交换 code 获取 token:                             │
│     POST {AGNES_API_URL}/api/v1/code/auth/exchange-code                 │
│     Body: {                                                              │
│       code: auth_code,                                                   │
│       redirect_uri: 'agnes://auth/callback',                             │
│       state: state,                                                      │
│       client_id: 'agnes-code'                                            │
│     }                                                                   │
│     Response: {                                                          │
│       code: 0,     // 成功时为 0 或 "000000"                              │
│       data: {                                                            │
│         access_token: '...',                                             │
│         user_info: { ... }                                               │
│       }                                                                  │
│     }                                                                   │
│                                                                         │
│  10. 渲染进程保存 token:                                                  │
│      a. localStorage.setItem('token', access_token)                      │
│      b. localStorage.setItem('userinfo', JSON.stringify(user_info))      │
│      c. 通过 IPC 将 token 同步到密钥链:                                    │
│         window.electron.setSetting('AGNES_AI_API_KEY', token)            │
│      d. 触发 'agnes:userinfo-updated' 事件                                │
│                                                                         │
│  11. 后续 API 调用:                                                      │
│      a. 本地 agnesd API: X-Secret-Key 头                                  │
│      b. 远程 Agnes API: Authorization: Bearer {token} 头                  │
└─────────────────────────────────────────────────────────────────────────┘

2.2 Agnes API 地址

Agnes API 基地址: https://api.agnes-ai.com

通过环境变量 AGNES_API_URL 配置,可在构建时由 scripts/brand-dev-electron.cjs 脚本注入。

认证端点:

POST {AGNES_API_URL}/api/v1/code/auth/exchange-code

订阅/信用端点:

GET  {AGNES_API_URL}/api/v2/subscription/credits-balance
POST {AGNES_API_URL}/api/v1/subscription/credits-transactions

2.3 Token 管理与存储

存储位置键名用途
localStoragetokenaccess_token,用于 API 认证
localStorageuserinfo用户信息 JSON
密钥链 (Keychain)AGNES_AI_API_KEY同步到密钥链

API 请求认证头:

javascript
Authorization: Bearer {access_token}
X-User-Language: {locale}

登出: 清除 localStorage 中的 tokenuserinfouserPptData,触发 agnes:userinfo-updated 事件。

2.4 401 处理

当 API 返回 401 时,自动清除 token 并触发登出。使用防抖机制(2秒内只触发一次):

javascript
let ff = false;
const dX = 2000;
function Iy(e) {
    !e || e.status !== 401 || ff || (ff = true, clearToken(), setTimeout(() => { ff = false }, dX));
}

2.5 订阅 URL 处理

订阅成功回调: agnes://subscription?status=successagnes://subscription/success


3. agnest 后端 API 全集

3.1 架构

agnest 是 Rust 编写的本地后端服务:

  • 二进制名称: agnesd (Linux/macOS) / agnesd.exe (Windows)
  • 通信协议: HTTPS (自签名证书)
  • 端口: 随机分配 (通过监听端口 0)
  • 认证: X-Secret-Key 请求头
  • 启动命令: agnesd agent

3.2 环境变量 (传递给 agnest)

javascript
AGNES_PORT={port}
AGNES_SERVER__SECRET_KEY={random_32_byte_hex}
AGNES_KEYRING_SERVICE=com.agnes.code.secrets  // 或 dev 版本
HOME={home_dir}
PATH={system_path}

3.3 API 客户端配置

javascript
const client = createClient({
    baseUrl: 'https://127.0.0.1:{port}',
    headers: {
        'Content-Type': 'application/json',
        'X-Secret-Key': secretKey
    }
});

3.4 健康检查

javascript
// 轮询 GET /health_check 端点
// 超时: 30秒
// 请求超时: 2秒
// 间隔: 250ms
// 成功条件: 返回 200
// 错误判断: 400-499 (非 408, 429) 或证书错误

3.5 启动流程

  1. 查找 agnesd 二进制 (优先打包资源中的 bin/agnesd)
  2. 在随机端口启动
  3. 解析 stdout 中的 GOOSED_CERT_FINGERPRINT=
  4. 验证自签名证书指纹
  5. 健康检查轮询
  6. 连接就绪后通知渲染进程

3.6 证书验证

javascript
// 自签名证书指纹验证
// 指纹格式: sha256/{base64}
// 信任策略: 只有 127.0.0.1 和 localhost 的连接被信任
// 首次连接: 记录指纹并信任
// 后续连接: 验证指纹匹配

4. MCP 工具集成分析

4.1 MCP 概述

AgnesCode 集成了 MCP (Model Context Protocol) 标准,支持:

  • 标准 MCP 工具定义
  • 自定义工具链
  • 扩展 (Extensions) 系统
  • 技能 (Skills) 引擎

4.2 MCP 方法

方法描述
tools/list列出工具
tools/call调用工具
notifications/tools/list_changed工具列表变更通知
resources/read读取资源
resources/list列出资源
resources/subscribe订阅资源变更
prompts/list列出提示词
prompts/get获取提示词
sampling/createMessage采样创建消息
completion/complete补全
logging/setLevel设置日志级别
notifications/message消息通知
roots/list列出根目录
notifications/roots/list_changed根目录变更通知
initialize初始化 MCP 连接
notifications/initialized初始化完成通知

4.3 MCP 工具定义

typescript
// 工具定义 schema
interface Tool {
    name: string;
    description?: string;
    inputSchema: {
        type: "object";
        properties: Record<string, any>;
        required?: string[];
    };
    outputSchema?: {
        type: "object";
        properties: Record<string, any>;
        required?: string[];
    };
    annotations?: {
        title?: string;
        readOnlyHint?: boolean;
        destructiveHint?: boolean;
        idempotentHint?: boolean;
        openWorldHint?: boolean;
    };
    execution?: {
        taskSupport: "required" | "optional" | "forbidden";
    };
}

4.4 内容类型

MCP 支持的内容块类型:

类型描述
text文本内容
image图片 (data: URI)
audio音频
tool_use工具调用
tool_result工具调用结果
resource资源引用
resource_link资源链接

4.5 扩展 (Extensions) 系统

扩展通过 MCP 协议集成,支持三种类型:

扩展类型传输方式描述
httpHTTP通过 HTTP 端点通信
sseSSE通过 Server-Sent Events 通信
terminal本地进程通过本地子进程通信

扩展配置:

typescript
interface Extension {
    name: string;
    type: "http" | "sse" | "terminal";
    // HTTP 类型
    url?: string;
    headers?: { name: string; value: string }[];
    // 终端类型
    command?: string;
    args?: string[];
    env?: { name: string; value: string }[];
}

4.6 工具权限

typescript
// 权限级别
type PermissionLevel = "always_allow" | "ask_before" | "never_allow";

// 工具权限设置
interface ToolPermission {
    name: string;
    permission: PermissionLevel;
}

4.7 本地工具

工具描述
fs/read_text_file读取文本文件
fs/write_text_file写入文本文件
terminal/create创建终端会话
terminal/kill终止终端
terminal/output终端输出
terminal/release释放终端
terminal/wait_for_exit等待终端退出
session/update更新会话
session/request_permission请求权限

5. 会话与会话管理

5.1 会话生命周期

创建 (session/new) → 活跃 (prompt) → 关闭 (session/close)
                                     → 分叉 (session/fork)
                                     → 归档 (session/archive)

5.2 会话上下文

会话模式:

  • smart: 自动路径选择
  • expert: 手动控制模型、参数、工具、上下文

会话配置选项:

typescript
interface SessionConfig {
    model?: string;
    mode?: 'smart' | 'expert';
    systemPrompt?: string;
    workingDir?: string;
    temperature?: number;
    maxTokens?: number;
    topP?: number;
    stopSequences?: string[];
    tools?: Tool[];
    toolChoice?: 'auto' | 'required' | 'none';
    extensions?: string[];
    project?: {
        id: string;
        name: string;
    };
}

5.3 会话历史

typescript
interface SessionHistory {
    sessionId: string;
    messages: Message[];
    // 消息结构
    interface Message {
        role: 'user' | 'assistant' | 'system' | 'tool';
        content: ContentBlock[];
    }
}

5.4 侧边聊天 (Side Chat)

支持在会话中启动侧边聊天:

typescript
interface SideChat {
    parentSessionId: string;
    sideChatId: string;
    runId: string;
    userMessage: Message;
    sideChatMessages: Message[];
    context: {
        includeRecentParentMessages: boolean;
        includeWorkbench: boolean;
    };
}

6. AI 提供商路由

6.1 支持的提供商

从渲染代码中提取的提供商列表:

提供商类型描述
Agnes 自有模型内置通过 Agnes API 访问
OpenAI外部GPT-4, o1, o3 等
Anthropic外部Claude 系列
DeepSeek外部DeepSeek 系列
Qwen外部Qwen 系列
MoonshotAI外部Moonshot 系列
Cohere外部Cohere 系列
HuggingFace外部HuggingFace 推理
Ollama本地本地模型
mesh-llm本地P2P 模型网络
腾讯云外部语音识别等

6.2 提供商配置

typescript
interface ProviderConfig {
    providerId: string;
    providerName: string;
    providerType: 'agent' | 'model';
    description: string;
    defaultModel: string;
    configured: boolean;
    configKeys: ConfigKey[];
    models: ModelInfo[];
    supportsRefresh: boolean;
}

interface ConfigKey {
    name: string;
    required: boolean;
    secret: boolean;
    default?: string | number | boolean;
}

interface ModelInfo {
    id: string;
    name: string;
    provider: string;
    description?: string;
    capabilities: string[];
}

6.3 提供商认证流程

  1. 渲染进程通过 ACP 调用 _agnes/unstable/providers/config/authenticate
  2. 用户输入 API Key 或其他凭证
  3. 凭证通过 _agnes/unstable/providers/config/save 保存
  4. 密钥通过 _agnes/unstable/providers/secrets/** 管理
  5. 提供商状态通过 _agnes/unstable/providers/config/status 查询

6.4 模型选择

typescript
interface ModelPreferences {
    hints?: { name?: string }[];
    costPriority?: number;     // 0-1
    speedPriority?: number;    // 0-1
    intelligencePriority?: number; // 0-1
}

7. 反向代理实现指南

7.1 方案比较

方案 A: AGNES_EXTERNAL_BACKEND (推荐)

难度: 低
控制粒度: 中
实现工作量: 中

原理:
1. 设置 AGNES_EXTERNAL_BACKEND=https://your-proxy-server.com
2. 设置 AGNES_SERVER__SECRET_KEY=your-secret-key
3. 实现符合 ACP 协议的后端服务
4. 后端处理认证、路由、工具调用

步骤:
a. 实现 ACP WebSocket 服务器 (JSON-RPC 2.0 over WebSocket)
b. 实现标准 ACP 方法 (session/new, session/prompt, session/cancel 等)
c. 实现 AI 提供商路由逻辑
d. 实现 MCP 工具调用
e. 启动后端服务
f. 设置环境变量启动 AgnesCode

方案 B: 本地代理 (中间人)

难度: 中
控制粒度: 高
实现工作量: 高

原理:
1. 在本地启动代理服务器
2. 修改 hosts 或证书以拦截流量
3. 代理分析 ACP 消息并转发

步骤:
a. 实现 WebSocket 代理
b. 解析 ACP JSON-RPC 消息
c. 修改或重定向 AI 请求
d. 转发响应

方案 C: 替换 agnesd 二进制

难度: 高
控制粒度: 高
实现工作量: 极高

原理:
1. 逆向 agnesd 二进制
2. 实现兼容的 Rust 后端
3. 替换打包的 agnesd 二进制

步骤:
a. 分析 agnesd 的 HTTP API
b. 实现兼容的 API 服务器
c. 处理自签名证书
d. 替换二进制

7.2 推荐方案: 外部后端 (AGNES_EXTERNAL_BACKEND)

服务端实现要求

1. WebSocket 端点: /acp

javascript
// 连接建立
WebSocket URL: wss://your-server.com/acp?token={secretKey}

2. 必须实现的方法:

initialize           - 初始化连接
session/new          - 创建新会话
session/prompt       - 发送提示词 (核心方法)
session/cancel       - 取消请求
session/close        - 关闭会话
session/list         - 列出会话
session/load         - 加载会话
authenticate         - 认证
logout               - 登出

3. 推荐实现的方法:

session/set_mode     - 设置模式
session/set_model    - 设置模型
session/set_config_option - 设置配置
session/fork         - 分叉会话
session/resume       - 恢复会话

4. 推送通知:

session/update       - 会话更新推送 (Server→Client)

5. 错误处理:

json
{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": -32601,
        "message": "Method not found",
        "data": { "method": "xxx" }
    }
}

7.3 session/prompt 消息格式

请求:

json
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "session/prompt",
    "params": {
        "sessionId": "session-uuid",
        "message": {
            "role": "user",
            "content": [
                { "type": "text", "text": "Hello" }
            ]
        },
        "model": "gpt-4o",
        "mode": "smart",
        "systemPrompt": "You are a helpful assistant",
        "tools": [
            {
                "name": "read_file",
                "description": "Read a file",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "path": { "type": "string" }
                    },
                    "required": ["path"]
                }
            }
        ]
    }
}

响应:

json
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "sessionId": "session-uuid",
        "message": {
            "role": "assistant",
            "content": [
                { "type": "text", "text": "Hello! How can I help?" }
            ]
        },
        "stopReason": "endTurn",
        "model": "gpt-4o",
        "usage": {
            "inputTokens": 10,
            "outputTokens": 5,
            "totalTokens": 15
        }
    }
}

7.4 认证代理

如果要绕过 Agnes OAuth 认证,可以直接在 authenticate 方法中返回成功:

typescript
// 服务端实现
async handleAuthenticate(params) {
    // 直接返回成功,绕过 OAuth
    return { success: true };
}

7.5 最小反向代理实现示例

python
# Python 示例: 最小 ACP 代理
import asyncio
import json
import websockets
from typing import Any

class ACPProxy:
    def __init__(self, host="0.0.0.0", port=8765):
        self.host = host
        self.port = port
        self.sessions = {}
    
    async def handle_message(self, websocket, message: dict):
        method = message.get("method")
        msg_id = message.get("id")
        params = message.get("params", {})
        
        if method == "initialize":
            return await self.handle_initialize(msg_id)
        elif method == "session/new":
            return await self.handle_session_new(msg_id, params)
        elif method == "session/prompt":
            return await self.handle_session_prompt(websocket, msg_id, params)
        elif method == "session/cancel":
            return await self.handle_session_cancel(msg_id, params)
        elif method == "authenticate":
            return await self.handle_authenticate(msg_id, params)
        else:
            return {
                "jsonrpc": "2.0",
                "id": msg_id,
                "error": {
                    "code": -32601,
                    "message": f"Method not found: {method}"
                }
            }
    
    async def handle_authenticate(self, msg_id, params):
        # 绕过 OAuth 认证
        return {
            "jsonrpc": "2.0",
            "id": msg_id,
            "result": {
                "success": True,
                "user": {
                    "id": "proxy-user",
                    "name": "Proxy User"
                }
            }
        }
    
    async def handle_session_prompt(self, websocket, msg_id, params):
        # 转发到 AI API (例如 OpenAI)
        messages = self._convert_to_api_format(params)
        api_key = "your-api-key"
        
        # 调用 AI API 并流式返回
        response = await self._call_ai_api(messages, api_key)
        
        return {
            "jsonrpc": "2.0",
            "id": msg_id,
            "result": response
        }
    
    async def handler(self, websocket, path=None):
        async for raw_message in websocket:
            message = json.loads(raw_message)
            response = await self.handle_message(websocket, message)
            if response:
                await websocket.send(json.dumps(response))
    
    def start(self):
        return websockets.serve(self.handler, self.host, self.port)

7.6 关键配置

bash
# 启动 AgnesCode 使用外部后端
export AGNES_EXTERNAL_BACKEND=https://your-proxy-server.com
export AGNES_SERVER__SECRET_KEY=your-secret-key
export AGNES_PORT=3000

# 可选: 替换登录 URL
export AGNES_SA_WEB_LOGIN_URL=https://your-auth-server.com

# 可选: 默认提供商和模型
export AGNES_DEFAULT_PROVIDER=openai
export AGNES_DEFAULT_MODEL=gpt-4o

# 启动
./AgnesCode

8. 附录

8.1 关键代码路径

文件路径大小
主进程app.asar/.vite/build/main.js1.4 MB
预加载脚本app.asar/.vite/build/preload.js2 KB
渲染进程入口app.asar/.vite/renderer/main_window/assets/index-BXTNYseC.js320 KB
应用主代码app.asar/.vite/renderer/main_window/assets/renderer-main-C4wZ9GTi.js1.45 MB

8.2 关键函数索引

函数名位置描述
Oj()main.js构造 OAuth 登录 URL
Vj()main.js构造 ACP WebSocket URL
bs()main.js处理 Deep Link 回调
A0()main.js创建 API 客户端
bM()main.js启动 agnesd 后端
iy()main.js获取密钥
eX()renderer交换 auth code 获取 token
aX()renderer保存 token 到 localStorage
nX()renderer同步 API Key 到密钥链
$8()renderer初始化 ACP 连接
Z3rendererACP 传输层 (JSON-RPC)
$3rendererACP 客户端 (方法封装)
W3renderer扩展方法客户端

8.3 关键数据流图

用户输入 → React → ACP WebSocket → agnest → AI API
                 ↓                    ↓
            localStorage          Keychain
            (token)              (secrets)

8.4 安全注意事项

  1. 自签名证书: agnest 使用自签名证书,仅信任 localhost 连接
  2. Secret Key: 随机 32 字节 hex,用于本地 API 认证
  3. Token 存储: access_token 存储在 localStorage 和系统密钥链
  4. CSP: 严格的 Content-Security-Policy 限制脚本和外连
  5. OAuth State: 32 字节随机 state 防 CSRF 攻击
  6. Deep Link 验证: 验证 state 匹配后才处理回调

8.5 版本演进

版本日期变化
v1.0.152026-07-13初始版本
v1.0.172026-07-14新增 Intel Mac 支持
v1.0.192026-07-15优化
v1.0.232026-07-20最新版本

免责声明: 本报告仅供教育和研究目的使用。反向工程应遵守相关法律法规和软件许可协议。

基于 MIT 协议发布