交接单按归属约定(正文落文档库、工作区只放指针)归档至 归档/交接单-20260924-归档/,含逐件判定 README: - 16 件已被文档库正式版取代(T09–T21 + 覆盖网络-24/25/26) - 4 件主题已被覆盖网络线入口汇总 - 7 件历史接续包/规划件 CODEBUDDY §9:收口清本棒 tmp、tmp 保留期 7 天、禁「待清理」中间态、 工作区入库只放文档与文件、不保留脚本副本、>60 KB 单文件须逐个判。
11 KiB
规划方案 · 通过桌面客户端接入 Agent CLI
类型:规划方案(待排期,非执行棒) 产出:让 DSH 平台支持「dsh 实例经覆盖网络拨号到用户电脑上的 Agent CLI」,与接入模型 API 同构 状态:调研完成 · 待排期 创建:2026-09-23
§1 目标
一句话:用户在桌面客户端内启动 Agent CLI(Claude Code / Aider / Gemini CLI 等),dsh 实例经覆盖网络 dialer 拨号到桌面客户端上的 agent 端口,实现「平台只管接入、agent 在用户侧跑」的集成模式。
与接入模型 API 的同构性:
| 模型 API(现状) | Agent CLI(本方案) | |
|---|---|---|
| 谁连谁 | dsh 实例 → 模型 API | dsh 实例 → 桌面客户端上的 agent |
| 传输 | 公网 HTTP | 覆盖网络(dialer + relay) |
| 平台角色 | 配置入口 + 注入凭据 | 配置入口 + 注入 agent endpoint |
| 用户侧 | 填 API Key | 装桌面客户端 + 启动 agent |
四条可验收子目标:
- agent 适配层:桌面客户端内嵌一个轻量 HTTP/WS 服务,把 dsh 实例发来的请求转成 agent CLI 的 stdin,把 agent stdout 回传给 dsh 实例。
- dsh 实例侧调用:在现有「调模型 API」的代码路径旁,新增「调覆盖网络里的 agent endpoint」分支,按 provider 类型分发。
- 管理面配置:credential_vault 扩一个
kind=agent类型,用户填 agent 名称 + 选择已注册的桌面设备,平台写入实例 env。 - 端到端验证:用户在浏览器 chat 里发消息 → dsh 实例经覆盖网络拨到桌面客户端 → agent 处理 → 结果回传浏览器。
§2 前置条件(已就位 · ⛔ 不重做)
| 能力 | 现状 | 代码位置 |
|---|---|---|
| 覆盖网络 relay | relay server + relay client(WebSocket 长连接拨出,NAT 穿透) | src/net/relay/server.ts / client.ts |
| dialer 拨号 | dsh 实例侧经 RelayDialer 主动拨号到同网设备 (hostId, port) |
src/net/relay/dialer.ts |
| 用户网隔离 | u:<userId> 网络,用户设备与自己的实例同网 |
src/net/relay/network.ts |
| 桌面设备注册 | OverlayDeviceKind='desktop',私钥本机生成、公钥上送 |
src/net/relay/device-grant.ts |
| 多端同时登录 | 序47 S1 落地:sessions.kind 区分 browser/desktop,maxSessionsPerUser=20,不再无条件驱逐旧会话 |
src/web/routes/auth.ts L321-343 |
| 会话/设备管理 API | GET /api/auth/sessions + POST /api/auth/sessions/revoke + GET /api/overlay/my-devices |
src/web/routes/sessions.ts |
| 凭据注入机制 | spawn 时按 credential_vault 写 settings.yaml + .credentials.yaml + env |
src/db/types.ts CredentialKey |
结论:覆盖网络 + 多端登录 + 设备台账 + 凭据注入四层基础设施全部就位,本方案只做适配层 + 调用分支 + 管理面扩展。
§3 范围
本方案含
- 桌面客户端内嵌 agent 适配层(HTTP/WS 服务 + PTY 桥)
- dsh 实例侧新增 agent provider 调用分支
- credential_vault 扩
kind=agent类型 - 管理面 UI(选择已注册设备 + 启动/停止 agent)
- 审计日志(agent 调用记录)
本方案不含
- 改 dsh 官方包主程序(⛔ 红线:不改官方 dsh 主程序与缓存)
- 在平台沙箱内跑 agent(agent 跑在用户电脑上,不受 bwrap 限制)
- 覆盖网络本身改造(relay / dialer / 网络隔离已就位)
- 多端登录改造(序47 已落地)
§4 决策点
D1:agent 适配层协议(待拍板)
dsh 实例用什么协议调 agent?三个候选:
A. HTTP 请求/响应(类 OpenAI API 格式)
- 优点:与模型 API 调用路径同构,dsh 实例侧改动最小;无状态,简单
- 缺点:agent CLI 多为有状态长会话(工具循环),无状态 HTTP 需要适配层维护会话状态映射;不能实时看到 agent 的中间输出
B. WebSocket 双向流(PTY over WS)
- 优点:支持实时交互(agent 中间思考、工具调用过程可见);天然适配 CLI 的 stdin/stdout 模型
- 缺点:dsh 实例侧需新增 WS 客户端能力(现有只做 HTTP);连接管理更复杂
C. MCP(Model Context Protocol)
- 优点:Anthropic 开放标准(2024.11 发布,2025.12 移交 Linux Foundation),已有大量开源实现;Claude Code / Cursor / VS Code / Gemini CLI 等已支持或正在支持;标准化资源发现 + 工具调用 + 提示模板
- 缺点:MCP 是「agent 作为 server 暴露工具」的协议,不是「agent 作为 agent 跑」的协议——方向不完全匹配;标准化程度仍在快速演进(2025.10 三大平台才统一)
倾向 A 起步:最小改动跑通链路,后续按 agent 生态收敛情况再升级到 B 或 C。
D2:agent 适配层实现位置
A. 桌面客户端内嵌(推荐)
- agent 适配层作为桌面客户端的一个模块,与 relay client 同进程
- 优点:复用 relay 连接;agent 进程由客户端管理(启停/崩溃恢复)
- 缺点:桌面客户端需扩展(目前是纯文件管理 + 登录)
B. 独立 sidecar 进程
- agent 适配层作为独立进程跑,客户端只负责拉起它
- 优点:解耦,适配层崩溃不影响客户端
- 缺点:多一层进程管理
倾向 A:桌面客户端本来就在用户电脑上,内嵌适配层最自然。
D3:agent 进程管理
用户启动 agent 的方式:
A. 客户端 UI 一键启动:客户端界面提供「启动 Agent」按钮,用户选 agent 类型 + 模型,客户端拉起 agent 进程并绑定端口
B. 用户自行启动:用户自己在终端跑 agent(如 claude code --port 8080),客户端只负责把那个端口暴露到覆盖网络
倾向 B 起步:最小改动,用户自主控制 agent;后续再做 A。
§5 步骤(建议分三阶段)
阶段 1:最小链路打通(MVP)
| 步骤 | 内容 | 产出 |
|---|---|---|
| 1.1 | 桌面客户端加 agent 适配层:监听本地 HTTP 端口,收到请求 → spawn agent CLI → stdin 投递 → stdout 回传 | src/desktop/agent-bridge.ts |
| 1.2 | 客户端启动时把 agent 端口注册到 relay(类似 worker 注册实例端口) | 复用 RelayClient 的 ports 白名单 |
| 1.3 | dsh 实例侧加 agent provider 调用分支:检测到 kind=agent 的凭据 → 经 dialer 拨到设备 hostId:agentPort → HTTP 请求/响应 |
src/supervisor/ 新增 agent-call 分支 |
| 1.4 | 端到端测试:浏览器 chat → dsh 实例 → dialer → 客户端 agent 适配层 → agent CLI → 回传 | 手动验收 |
阶段 2:管理面 + 多 agent 类型
| 步骤 | 内容 | 产出 |
|---|---|---|
| 2.1 | credential_vault 加 kind 列(model / agent),agent 类型存设备 hostId + 端口而非 API key |
DB 迁移 v14 |
| 2.2 | 管理面 UI:agent provider 配置页(选设备 + 填端口 + 选 agent 类型) | portal.html 新增 section |
| 2.3 | 多 agent 类型适配:Claude Code / Aider / Gemini CLI 各自的启动参数 + stdin/stdout 格式适配 | 适配层配置文件 |
| 2.4 | 审计日志:agent 调用记录(时间 / 用户 / agent 类型 / 设备) | audit_log |
阶段 3:实时交互 + MCP(按生态收敛情况排期)
| 步骤 | 内容 | 产出 |
|---|---|---|
| 3.1 | 适配层升级到 WebSocket(PTY over WS),dsh 实例侧 WS 客户端 | 支持实时中间输出 |
| 3.2 | 评估 MCP 接入:如果 agent 生态收敛到 MCP 标准,适配层改为 MCP client | 跟随生态 |
| 3.3 | 客户端 UI 一键启动 agent(D3-A) | 桌面客户端新功能 |
§6 验收
阶段 1 验收
- 用户在桌面客户端登录(
kind=desktop会话),客户端 relay 连接 up - 用户在本地终端启动 agent CLI(如
aider --port 9090) - 客户端 agent 适配层监听 9090,并注册到 relay
- 用户在浏览器 chat 里发消息,dsh 实例经 dialer 拨到客户端 9090
- agent 处理消息,结果回传浏览器 chat
- dsh 实例同时仍可正常调模型 API(两条路径并存)
阶段 2 验收
- 管理面可配置 agent provider(选设备 + 填端口)
- 多种 agent 类型可切换(Claude Code / Aider / Gemini CLI)
- agent 调用有审计日志
§7 回滚
| 场景 | 回滚动作 |
|---|---|
| agent 适配层出问题 | 客户端停掉 agent 适配层进程;dsh 实例侧回退到只调模型 API(agent provider 不启用即可) |
| DB 迁移 v14 出问题 | 回滚迁移(删 kind 列);credential_vault 退回只有 model 类型 |
| 覆盖网络拨号失败 | 不影响模型 API 路径;agent 不可用但 dsh 实例正常 |
核心安全约束:agent provider 的 endpoint 恒为覆盖网络内的 hostId,不接受公网地址(与 relay client 的「目标恒为 127.0.0.1」同纪律)—— 防止把 dsh 实例变成任意公网请求转发器。
§8 技术附录
8.1 已查证的关键代码位置
| 文件 | 关键行 | 内容 |
|---|---|---|
src/net/relay/dialer.ts |
L9-17 | dialer 拨号机制:Manager 侧预绑口池,有连接 → client.openStream(hostId, port) → mux 流对接 |
src/net/relay/client.ts |
L4-14 | relay client 安全模型:端口白名单 + 目标恒为 127.0.0.1 |
src/net/relay/network.ts |
L17 | 用户网 u:<userId>,设备与实例同网 |
src/net/relay/device-grant.ts |
L18 | desktop 设备:私钥本机生成、公钥上送 |
src/web/routes/auth.ts |
L321-343 | 序47 S1:多端登录不驱逐旧会话,超限淘汰最旧 |
src/web/routes/sessions.ts |
L59-72 | 会话列表 API(含 kind 标签) |
src/db/types.ts |
L158-183 | CredentialKey 类型(route / baseUrl / api / models) |
src/db/schema.ts |
L97-104 | credential_vault 表结构 |
src/config.ts |
L383 | DEFAULT_MAX_SESSIONS_PER_USER = 20 |
8.2 MCP 生态现状(2026-09 查证)
- MCP(Model Context Protocol)由 Anthropic 于 2024.11 发布,2025.12 移交 Linux Foundation
- 已有开源实现:5ire(Electron 桌面 GUI)、ChatMCP(Flutter 桌面)、Goose(Rust CLI agent)、HyperChat
- 三大 CLI 平台(Google Gemini CLI / OpenAI / Anthropic Claude Code)已基于 MCP 构建插件生态
- MCP 定义 client-server 架构,JSON-RPC 2.0 over stdio 或 HTTP+SSE
- 核心概念:Resources(数据可读)、Tools(函数可执行)、Prompts(模板)
- 安全注意:2025.06 发现约 2000 个 MCP server 暴露无认证;spec 已加 OAuth 2.0 + RFC 8707
8.3 与之前讨论的路径对比
| 路径 | 评估 |
|---|---|
| 在 dsh 沙箱内跑 agent CLI | ❌ 碰红线(不改官方 dsh 主程序);沙箱封 loopback + 资源限;无终端层 |
| 平台侧新增 agent runner 实例类型 | ⚠️ 架构级改造,工作量大;用户需公网服务器 |
| 桌面客户端集成 agent(本方案) | ✅ 覆盖网络已就位;agent 在用户侧跑不受沙箱限制;改动量=适配层 |