主题
Agent HTTP API
本文引用的源码文件
本文引用的文件
更新摘要
变更内容
- 新增
/api/config/pick-directory端点,支持系统原生目录选择框 - 添加严格的回环地址访问验证,仅允许本机来源调用
- 实现跨平台原生对话框支持(macOS、Windows、Linux)
- 增加超时保护机制和错误降级处理
目录
简介
Agent HTTP API 是 Chrome 扩展(Manifest V3)与独立本地代理端之间的通信契约。扩展通过本地 HTTP/WebSocket 调用 Agent 的文件操作、命令执行、长期记忆、RAG 检索、技能与 MCP 管理等能力。文档以版本 2.3.1 为准,所有端点、安全策略、错误格式和示例均基于当前源码实现。
关键运行时约束:
- Agent 为独立 Node.js 进程,修改源码后必须重启进程,新接口才生效。
- 认证采用 Bearer Token;首次配对使用一次性配对码流程。
- 路径访问受白名单与硬阻止规则保护;命令执行走黑白灰名单分级控制。
- RAG 为可选依赖,不可用时对应接口返回 503。
- 新增:原生目录选择功能仅限本机回环地址访问,确保安全性。
项目结构
Agent 端入口为 agent/src/server.js,负责 HTTP 路由、CORS、请求体解析、认证、日志、WebSocket 升级以及各子系统分发。核心子模块包括:
- 认证:
agent/src/auth.js - 安全策略:
agent/src/security.js - 命令执行器:
agent/src/executor.js - 记忆管理:
agent/src/memory/routes.js - RAG 配置:
agent/src/rag/config.js - 新增:原生目录选择器:
agent/src/directory-picker.js
graph TB Client["客户端<br/>Chrome 扩展或本地脚本"] --> HTTP["HTTP 服务器<br/>server.js"] HTTP --> Auth["认证模块<br/>auth.js"] HTTP --> Security["安全策略<br/>security.js"] HTTP --> Executor["命令执行器<br/>executor.js"] HTTP --> Memory["记忆路由<br/>memory/routes.js"] HTTP --> RAG["RAG 路由<br/>动态加载"] HTTP --> DirectoryPicker["目录选择器<br/>directory-picker.js"] HTTP --> WS["WebSocket 执行流<br/>server.js"]
图表来源
章节来源
核心组件
- HTTP 路由器:统一处理 CORS、JSON body、multipart、路径匹配、认证拦截、业务分发与 404。
- 认证模块:维护配对码轮换、Token 验证、活跃连接窗口、失败锁定。
- 安全策略:路径规范化、工作目录放行、白名单前缀校验、realpath 防符号链接绕过、硬阻止敏感目录;命令黑白灰名单分级。
- 命令执行器:跨平台 shell 选择、子进程生命周期、超时预算、输出截断、WebSocket 广播、进程树终止。
- 记忆路由:store/recall/inject/reindex 等记忆操作,embedding 配置与探活。
- RAG 配置:知识库根目录、集合注册表、模型缓存、默认 embedding 与分块参数。
- 新增:原生目录选择器:跨平台系统对话框集成,包含超时保护和错误降级。
章节来源
- agent/src/server.js#L250-L303
- agent/src/auth.js#L30-L127
- agent/src/security.js#L33-L229
- agent/src/executor.js#L32-L91
- agent/src/memory/routes.js#L19-L27
- agent/src/rag/config.js#L11-L54
- agent/src/directory-picker.js#L1-L135
架构总览
Agent 的认证与安全边界如下:
- 无需认证的公开端点:
/api/pair、/api/status、/api/shutdown(远程来源仍需认证)。 - 需要认证的端点:除上述公开端点外的绝大多数业务接口。
- WebSocket
/ws/exec/{execId}:支持 Authorization Header 或 query token。 - 新增:
/api/config/pick-directory端点仅接受本机回环地址(127.0.0.1, ::1, localhost)请求。
sequenceDiagram
participant C as "客户端"
participant S as "HTTP 服务器"
participant A as "认证模块"
participant Sec as "安全策略"
participant DP as "目录选择器"
C->>S : POST /api/pair {code, extensionId}
S->>A : handlePairRequest(code, extensionId)
A-->>S : {success, token?}
S-->>C : 200/400 JSON
C->>S : GET /api/status
S-->>C : 200 JSON(平台信息)
C->>S : POST /api/fs/read {path}
S->>Sec : checkPath(path)
Sec-->>S : {allowed,resolved}
S-->>C : 200/403/404 JSON
C->>S : POST /api/exec {command,cwd,force,timeoutMs}
S->>Sec : checkCommand(command, force)
Sec-->>S : {level : 'allow'|'confirm'|'deny'}
alt level=deny
S-->>C : 403 JSON
else level=confirm
S-->>C : 200 JSON(level=confirm)
else level=allow
S->>Ex : executeCommand(...)
S-->>C : 200 JSON(execId, wsUrl)
end
C->>S : POST /api/config/pick-directory {title}
S->>S : 验证回环地址
S->>DP : pickDirectoryNative(title)
DP-->>S : {success, path, available}
S-->>C : 200 JSON
图表来源
- agent/src/server.js#L474-L548
- agent/src/server.js#L1037-L1087
- agent/src/server.js#L1605-L1674
- agent/src/server.js#L987-L1008
- agent/src/auth.js#L138-L179
- agent/src/security.js#L691-L758
详细接口规范
通用约定
- 响应格式:
{ success: boolean, ... }。成功时success=true,失败时success=false且包含error。 - 认证头:
Authorization: Bearer <token>。 - CORS:仅允许
chrome-extension://来源读取响应;非浏览器客户端可忽略 CORS。 - 语言:通过
Accept-Language影响错误消息文案。
章节来源
认证与配对
POST /api/pair- 用途:输入 6 位配对码与扩展 ID,成功后返回 Token。
- 安全:连续失败 5 次锁定 60 秒并轮换配对码;配对成功后立即轮换。
- 响应:
{ success, token?, message?, error? }。
GET /api/status- 用途:健康检查与平台信息,无需认证。
- 响应:
{ success, version, running, platform, platformName, arch, nodeVersion, searchTools, ragAvailable }。
GET /api/status/detail- 用途:需认证的状态详情,含 workdir、allowedPaths、资源使用、运行进程等。
- 响应:
{ success, version, pairCodeTTL, workdir, allowedPaths, commandTimeout, fileMaxSize, uploadMaxSize, runningProcesses, resourceUsage, ...PLATFORM_INFO, searchTools, ragAvailable }。
GET /api/heartbeat- 用途:心跳保活,刷新最近认证时间。
- 响应:
{ success, time }。
章节来源
- agent/src/auth.js#L30-L127
- agent/src/auth.js#L138-L179
- agent/src/server.js#L474-L553
- agent/src/server.js#L725-L749
配置管理 /api/config/*
配置相关端点用于管理工作目录、白名单和系统设置。
POST /api/config/workdir- 切换工作目录,同时追加到 allowedPaths(只增不减),禁止设为 Agent 系统目录。
- 响应:
{ success, workdir, allowedPaths, message }
POST /api/config/allowed-paths/remove- 从 allowedPaths 移除路径,禁止移除当前工作目录。
- 响应:
{ success, allowedPaths, message? }
- 新增
POST /api/config/pick-directory- 用途:弹出系统原生目录选择框,用户可选择目标目录。
- 安全限制:仅接受本机回环地址请求(127.0.0.1, ::1, ::ffff:127.0.0.1, localhost)。
- 请求体:
{ title?: string }- 可选的选择框标题。 - 行为:
- 远程来源:返回
{ success: false, path: null, available: false, error: 'remote-source' } - macOS:使用
osascript choose folder对话框 - Windows:使用 PowerShell FolderBrowserDialog
- Linux:优先 zenity,回退 kdialog
- 无 GUI 环境:返回
available: false - 用户取消:返回
{ success: true, path: null, available: true } - 超时(120秒):返回
{ success: false, path: null, available: true, error: 'timeout' }
- 远程来源:返回
- 响应:
{ success, path, available, error? }
章节来源
文件操作 /api/fs/*
所有文件类接口均经过 checkPath 路径沙箱校验,遵循工作目录放行、白名单前缀、realpath 校验与硬阻止规则。
POST /api/fs/search_files- 请求体:
{ path, pattern, recursive?, maxResults? } - 响应:
{ success, path, pattern, total, engine, results? }
- 请求体:
POST /api/fs/search_content- 请求体:
{ path, pattern, filePattern?, caseSensitive?, recursive?, contextLines? } - 响应:
{ success, path, pattern, total, engine, matches? }
- 请求体:
POST /api/fs/read- 请求体:
{ path } - 响应:
{ success, content, size, path }
- 请求体:
POST /api/fs/write- 请求体:
{ path, content, encoding?: 'utf-8'|'base64' } - 行为:自动创建父目录;脚本文件写入后剥离执行权限。
- 响应:
{ success, size, path }
- 请求体:
POST /api/fs/list- 请求体:
{ path } - 响应:
{ success, entries:[{name,type,size,mtime}], path }
- 请求体:
POST /api/fs/stat- 请求体:
{ path } - 响应:
{ success, info:{name,path,type,size,mtime,ctime,atime,mode,isDirectory,isFile,isSymbolicLink,uid?,gid?,mimeType?} }
- 请求体:
POST /api/fs/delete- 请求体:
{ path } - 行为:移至回收站,7 天后自动清理。
- 响应:
{ success, path, isDir, trashId, message }
- 请求体:
POST /api/fs/download- 请求体:
{ path } - 行为:单文件 base64;目录打包 zip base64。
- 响应:
{ success, type:'file'|'directory', name, size, content, mimeType }
- 请求体:
POST /api/fs/download-multi- 请求体:
{ paths:[string] } - 行为:后端打包为 zip base64。
- 响应:
{ success, type:'archive', name, size, content, mimeType }
- 请求体:
POST /api/fs/download-stream- 请求体:
{ path }或{ paths:[string] } - 行为:二进制流下载,避免 base64 膨胀;目录打包 zip 流式返回。
- 响应:二进制流或 ZIP 附件。
- 请求体:
POST /api/fs/upload- 内容类型:
multipart/form-data - 行为:文件名过滤危险字符,去重命名,写入工作目录。
- 响应:
{ success, path, name, size }
- 内容类型:
POST /api/fs/upload-stream- 查询参数:
?path=<目标路径> - 行为:原始二进制流上传,按 MAX_UPLOAD_SIZE 限制,脚本文件剥离执行权限。
- 响应:
{ success, size, path }
- 查询参数:
POST /api/fs/mkdir- 请求体:
{ path } - 响应:
{ success, path }
- 请求体:
POST /api/fs/rename- 请求体:
{ path, newName } - 行为:仅改文件名不跨目录;Windows 非法字符校验;目标存在返回 409。
- 响应:
{ success, newPath, newName }
- 请求体:
POST /api/fs/move- 请求体:
{ path, destDir } - 行为:源与目标均需白名单;目标不存在则创建;目标存在返回 409。
- 响应:
{ success, newPath }
- 请求体:
POST /api/fs/preview-xlsx- 请求体:
{ path } - 行为:服务端解析前若干行,返回结构化 JSON。
- 响应:
{ success, data:{sheets:[{name,index,colCount,totalRows,rows}]}}
- 请求体:
常见状态码:
- 200:成功
- 400:参数缺失、大小超限、路径不是目录等
- 403:路径不在白名单或命中硬阻止
- 404:文件或目录不存在
- 409:目标已存在
- 500:内部错误
章节来源
命令执行 /api/exec/*
命令执行先经 checkCommand 分级判定:
deny:黑名单命中,直接拒绝。confirm:灰名单命中,返回确认提示。allow:允许执行。POST /api/exec- 请求体:
{ command, cwd?, wait?, force?, timeoutMs? } - 行为:
wait=true:同步等待,返回完整 stdout/stderr。wait=false:异步执行,返回execId与 WebSocket URL。force=true:跳过灰名单(黑名单仍生效)。timeoutMs:受管模式协商超时预算。
- 响应:
- 同步:
{ success, level, execId, exitCode, stdout, stderr, killed, error? } - 异步:
{ success, level, execId, wsUrl }
- 同步:
- 请求体:
POST /api/exec/stop- 请求体:
{ execId } - 响应:
{ success, execId }
- 请求体:
POST /api/exec/detach- 请求体:
{ execId } - 行为:显式 daemon 化,豁免超时。
- 响应:
{ success, execId }
- 请求体:
WebSocket /ws/exec/{execId}:
- 认证:优先
Authorization: Bearer <token>,回退到?token=。 - 消息类型:
stdout、stderr、exit、error、stdout_truncated、stderr_truncated。
flowchart TD
Start(["收到 /api/exec"]) --> Validate["校验 command/cwd"]
Validate --> CheckCmd["checkCommand(command, force)"]
CheckCmd --> Level{"level"}
Level --> |deny| Deny["返回 403 deny"]
Level --> |confirm| Confirm["返回 200 confirm"]
Level --> |allow| Mode{"wait?"}
Mode --> |true| Sync["executeCommandSync"]
Mode --> |false| Async["executeCommand + 返回 wsUrl"]
Sync --> RespSync["返回 exitCode/stdout/stderr"]
Async --> WS["客户端连接 /ws/exec/{execId}"]
图表来源
章节来源
- agent/src/server.js#L1605-L1689
- agent/src/executor.js#L198-L386
- agent/src/executor.js#L429-L493
- agent/src/security.js#L691-L758
记忆管理 /api/memory/*
记忆路由由 memoryRouter 分发,支持 store/recall/inject/reindex 等业务动作,以及 embedding 配置与探活。
POST /api/memory/embedding-config- GET:返回掩码后的 embedding 配置。
- POST:保存 embedding 配置。
- 响应:
{ success, config }
POST /api/memory/test-embedding- 用途:测试 embedding provider 连通性。
- 响应:
{ success, dimensions }
GET /api/memory/vector-status- 用途:向量缓存状态(条数、指纹陈旧等)。
- 响应:
{ success, ...vectorStatus }
POST /api/memory/store- 请求体:记忆条目
- 行为:根据
X-Memory-Callerheader 区分 user/model 来源。 - 响应:
{ success, ...storeResult }
POST /api/memory/recall- 请求体:召回参数(可含 sessionId)
- 响应:
{ success, ...recallResult }
POST /api/memory/inject- 行为:注入选择结果。
- 响应:
{ success, ...injectResult }
POST /api/memory/reindex- 行为:重建向量缓存。
- 响应:
{ success, ...reindexResult }
未匹配路径或非 POST 业务方法返回 404,用于扩展探测旧版本 agent 是否支持记忆端点。
章节来源
- agent/src/memory/routes.js#L19-L27
- agent/src/memory/routes.js#L77-L137
- agent/src/memory/routes.js#L149-L192
RAG 检索 /api/rag/*
RAG 为可选依赖。依赖不可用时,除安装/检测相关端点外,其余 /api/rag/* 返回 503。
POST /api/rag/install- 用途:启动 RAG 依赖安装任务。
- 响应:
{ started, ...installStatus }
GET /api/rag/install/status- 用途:轮询安装进度。
- 响应:
{ ...installStatus }
POST /api/rag/detect- 用途:重新检测 RAG 依赖可用性。
- 响应:
{ success, available, error? }
- 其他
/api/rag/*- 行为:依赖不可用返回 503;可用时动态加载
rag/routes.js处理。
- 行为:依赖不可用返回 503;可用时动态加载
RAG 配置关键点:
- 数据根目录:
~/.ai-helper-agent/rag,可通过环境变量覆盖。 - 集合注册表:
collections.json。 - 模型缓存:
models/。 - 默认 embedding:本地 BGE 中文模型,支持 OpenAI 兼容模式。
- 分块参数:默认 chunkSize/overlap,单次批大小固定 10。
章节来源
其他重要端点
POST /api/agent/restart- 重启 Agent,带冷却与互斥保护。
- 响应:
{ success, message }
POST /api/agent/update- 更新并重启 Agent,与 RAG 安装互斥,npm 安装超时保护。
- 响应:
{ success, message }
POST /api/shutdown- 本机来源免认证;远程来源需认证。
- 响应:
{ success, message }
GET /api/trash/list- 列出回收站条目。
- 响应:
{ success, entries }
POST /api/trash/restore- 恢复回收站条目。
- 响应:
{ success, restoredPath?, error? }
GET /api/logs/query- 审计日志查询,默认最近 7 天,limit 上限 500。
- 响应:
{ success, entries, total, dates }
- Skill/MCP 管理端点:见 server.js 中
/api/skill/*与/api/mcp/*路由。
章节来源
- agent/src/server.js#L555-L720
- agent/src/server.js#L502-L535
- agent/src/server.js#L2006-L2021
- agent/src/server.js#L1693-L1725
依赖关系分析
server.js作为中心路由器,依赖:auth.js:配对码与 Token 验证。security.js:路径与命令安全检查。executor.js:命令执行与 WebSocket 流。memory/routes.js:记忆业务分发。rag/*:按需加载 RAG 路由。skill/*、mcp/*:技能与 MCP 管理。- 新增:
directory-picker.js:原生目录选择功能。
- 安全边界:
- 路径访问:workdir 永远放行,allowedPaths 前缀匹配,realpath 防绕过,硬阻止 Agent 敏感目录。
- 命令执行:黑名单绝对禁止,灰名单需确认,force 可跳过灰名单。
- 文件大小:JSON body 最大 200MB;流式上传最大 200MB;读取默认 50MB。
- 新增:目录选择仅允许本机回环地址访问。
graph LR Server["server.js"] --> Auth["auth.js"] Server --> Security["security.js"] Server --> Executor["executor.js"] Server --> Memory["memory/routes.js"] Server --> RAG["rag/routes.js(动态)"] Server --> Skill["skill/*"] Server --> MCP["mcp/*"] Server --> DirectoryPicker["directory-picker.js"]
图表来源
章节来源
- agent/src/server.js#L13-L56
- agent/src/security.js#L62-L100
- agent/src/security.js#L109-L229
- agent/src/security.js#L285-L384
- agent/src/directory-picker.js#L1-L135
性能与限制
- 请求体大小:MAX_BODY_SIZE = 200MB。
- 文件读取默认限制:DEFAULT_MAX_SIZE = 50MB,可通过配置调整。
- 流式上传限制:MAX_UPLOAD_SIZE = 200MB。
- 搜索最大结果:MAX_SEARCH_RESULTS = 5000。
- 命令输出缓冲:MAX_OUTPUT_BUFFER = 5MB,超限时广播 truncated 事件。
- 命令超时策略:受管模式下按输出心跳延长,最多延长次数与总预算封顶。
- RAG 批大小:EMBED_BATCH_SIZE = 10。
- 新增:目录选择超时:PICK_TIMEOUT_MS = 120秒。
优化建议:
- 大文件下载优先使用
/api/fs/download-stream。 - 长命令使用异步模式 + WebSocket 实时查看输出。
- 合理设置
timeoutMs,避免静默挂起导致频繁延长。 - 目录选择仅在本地开发环境中使用,生产环境应通过配置文件设置工作目录。
章节来源
- agent/src/server.js#L132-L136
- agent/src/executor.js#L96-L98
- agent/src/executor.js#L166-L186
- agent/src/rag/config.js#L52-L54
- agent/src/directory-picker.js#L7
故障排除指南
常见问题与定位:
- 401/403:认证缺失或 Token 无效。检查
Authorization头与配对流程。 - 403 路径拒绝:路径不在 allowedPaths 或命中硬阻止。检查工作目录与白名单配置。
- 403 命令拒绝:命令命中黑名单。无法通过 force 绕过。
- 200 confirm:命令命中灰名单。前端应弹出确认框后再调用
force=true。 - 503 RAG 不可用:RAG 依赖未安装或检测失败。调用
/api/rag/install与/api/rag/detect。 - 500 内部错误:查看审计日志
/api/logs/query,关注 category 为 system/error 的条目。 - 命令无输出:检查 WebSocket 是否连接成功,或查看
/api/exec返回的wsUrl。 - 文件过大:read/download 受 DEFAULT_MAX_SIZE 限制;使用 stream 接口或调整配置。
- 新增:目录选择不可用:检查是否为本机回环地址访问,或系统是否安装了必要的 GUI 工具(zenity/kdialog/osascript)。
- 新增:目录选择超时:用户长时间未选择,120秒后自动超时。
调试步骤:
- 调用
/api/status确认 Agent 在线与版本。 - 调用
/api/status/detail查看 workdir、allowedPaths、runningProcesses。 - 使用
/api/logs/query查询最近日志,过滤 category。 - 对文件操作,先用
/api/fs/stat确认路径存在与类型。 - 对命令执行,先调
/api/exec获取 level,再决定是否确认或调整命令。 - 新增:对目录选择,检查请求来源 IP 是否为回环地址,并确认系统 GUI 环境可用。
章节来源
- agent/src/server.js#L474-L548
- agent/src/server.js#L1037-L1087
- agent/src/server.js#L1605-L1674
- agent/src/server.js#L2025-L2067
- agent/src/server.js#L1705-L1725
- agent/src/server.js#L987-L1008
结论
Agent HTTP API 提供完整的本地代理能力,涵盖文件、命令、记忆、RAG、技能与 MCP。其安全模型以路径白名单与命令分级为核心,认证采用配对码+Bearer Token,WebSocket 支持命令流式输出。新增的原生目录选择功能进一步增强了用户体验,但严格限制了访问来源以确保安全性。使用时应严格遵循认证头、路径白名单、大小限制与超时策略,并结合审计日志进行故障定位。对于目录选择功能,应特别注意其仅限本机回环地址访问的安全限制。