669 lines
32 KiB
Markdown
669 lines
32 KiB
Markdown
# GoodBuddy 自维护 DeepSeek Harness Runtime 设计
|
||
|
||
## 1. 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 文档状态 | 实现与发布验收基线 |
|
||
| 设计目标 | 将 DeepSeek Harness 作为 GoodBuddy 的第三个 Agent Runtime |
|
||
| Runtime 标识 | `deepseek-harness` |
|
||
| 首版依赖基线 | 实际使用的 `@deepseek-ai/dsh-*` 底层库,精确锁定 `0.1.0-rc.6` |
|
||
| 上游状态 | Developer Preview,允许出现破坏性变更 |
|
||
| 上游许可证 | MIT |
|
||
| GoodBuddy 目标平台 | Windows、macOS、Linux,x64 与 arm64 |
|
||
| 本文性质 | 设计与发布验收约定 |
|
||
|
||
本文定义 DeepSeek Harness 在 GoodBuddy 中的架构边界、协议、执行策略、界面、打包和验收要求。实现必须继续遵守 GoodBuddy 已有的 Main 进程安全边界、Ask/Execute 语义、授权、取消、超时、有界输出和资源回收约定。
|
||
|
||
## 2. 摘要
|
||
|
||
DeepSeek Harness 的底层库使用 Cordis 组合服务。GoodBuddy 不采用官方产品 profile、插件安装或市场机制,也不让用户配置覆盖安全服务,而是增加一个实验性的第三 Runtime,并完全自行维护 Host、控制协议、生命周期和兼容层。上游 DSH 包只是精确锁定并逐次审查的实现依赖,不构成 GoodBuddy 对 DSH 插件 ABI、插件目录或产品路线的承诺。
|
||
|
||
GoodBuddy 并不迫切于把该能力做成 DSH 插件或进入插件市场。当前优先级是向用户提供稳定、可靠、可审计且可完整回收的 Runtime;只有未来真实用户需求和成熟度证明插件化确有价值时,才重新评估该形态。
|
||
|
||
整体分成两个互相约束的部分:
|
||
|
||
1. **GoodBuddy Main Control Plane**
|
||
- 运行在 Electron Main 进程。
|
||
- 持有加密设置、模型连接选择、Ask 只读策略、Runtime 生命周期和审计归属。
|
||
- 通过 Electron `utilityProcess` 启动受控 Harness 子进程。
|
||
- 对环境、输入、输出、超时、取消和进程树执行强制限制。
|
||
|
||
2. **GoodBuddy Harness Control Plane**
|
||
- 运行在 Harness 子进程内,是 Host 私有的内部控制组件,不导出 Cordis 插件入口。
|
||
- 使用 ACP 兼容的 JSON-RPC stdio 作为基础控制面。
|
||
- 增加 GoodBuddy 所需的能力握手、每轮权限准备、会话释放、工具事件、推理、用量和安全凭据请求扩展。
|
||
- 与 GoodBuddy Host 一起维护、构建和发布,不设计为独立 npm 包、`dsh.bundle` 或市场插件。
|
||
|
||
DeepSeek Harness 不替换 OpenCode、Continue 或直连模型 Runtime。用户可以按全局、项目、会话或消息通道继续选择现有 Runtime。
|
||
|
||
## 3. 背景与上游能力
|
||
|
||
### 3.1 已确认的官方能力
|
||
|
||
- `@deepseek-ai/dsh` 是官方 profile 启动器。
|
||
- Harness 插件是导出 `apply(ctx, config)` 的 Cordis 模块。
|
||
- npm 包可通过 `dsh.bundle` 声明配置补丁,再通过 `dsh plugin --profile <name> add <package>` 安装。
|
||
- ACP 支持:
|
||
- 初始化。
|
||
- 创建多个会话。
|
||
- 发送 Prompt。
|
||
- 按会话取消。
|
||
- 一次性权限选择。
|
||
- 已提交的助手文本。
|
||
- 官方本地沙箱支持:
|
||
- Linux:Bubblewrap,或 Landlock 降级。
|
||
- macOS:Seatbelt。
|
||
- Windows:ACL 受限令牌,官方明确标记为部分强制执行。
|
||
|
||
GoodBuddy 不组合上述 Runtime OS 沙箱。当前产品选择 DSH 本地 Shell 与
|
||
Filesystem Provider,以 GoodBuddy 客户端进程的当前用户权限运行工具。
|
||
|
||
### 3.2 官方通道的缺口
|
||
|
||
官方 ACP 插件有意只输出已提交文本,不输出推理、工具进度、计划、标题和用量。它也没有标准的会话关闭方法。SDK JSON-RPC 的展示事件更完整,但缺少 GoodBuddy 需要的单轮取消和权限回传。
|
||
|
||
因此,首版不单独选用其中一个官方通道作为完整实现。GoodBuddy Harness Control Plane 以 ACP 语义为基础,补充有命名空间的扩展方法和事件。
|
||
|
||
### 3.3 自维护边界
|
||
|
||
GoodBuddy 不急于把该 Runtime 包装成标准 DSH 插件,也不以进入官方或第三方插件市场为近期目标。所有入口都随 GoodBuddy 发布,只有 GoodBuddy Main 可以启动并使用内部 Host。是否采用上游新版本或未来重新评估插件形态,只由真实用户价值、安全审查和六平台稳定性决定,不跟随市场机制或上游发布节奏。
|
||
|
||
## 4. 目标与非目标
|
||
|
||
### 4.1 首版目标
|
||
|
||
- 增加 `deepseek-harness` Runtime,并在设置、聊天和消息通道中可选择。
|
||
- 使用 GoodBuddy 管理的模型连接,不在 Renderer 或持久化 Harness 配置中写入 API Key。
|
||
- Ask 模式在 Runtime 工具分发边界强制只读,阻止 Shell、写入和编辑工具。
|
||
- Execute 模式使用 DSH 本地 Provider,以当前用户权限执行文件与命令工具;工作区是默认工作目录,不是 OS 权限边界。
|
||
- 支持多会话、同会话串行、跨会话并行。
|
||
- 支持按请求取消、超时、会话释放和应用退出时完整回收。
|
||
- 输出文本、推理、工具参数、工具结果、stderr 和协议队列全部有界。
|
||
- 使用真实 OpenAI 兼容 Chat Completions 模型验证调用,而不在日志、测试产物或提交中暴露凭据。
|
||
- 保留 Windows、macOS、Linux 的 x64 和 arm64 发布能力。
|
||
|
||
### 4.2 首版非目标
|
||
|
||
- 不替换 OpenCode、Continue 或直连模型 Runtime。
|
||
- 不开放用户 Cordis profile、cordis.patch.yml 或 $DSH_HOME 全局补丁覆盖。
|
||
- 不提供外部 Host、自定义 Harness Control Plane、DSH 插件安装或市场入口。
|
||
- 不加载 Harness Web UI、HMR、遥测、自动更新或目录选择器。
|
||
- 不提供 Runtime OS 沙箱模式或相关持久设置。
|
||
- 不向 Utility 暴露 MCP 凭据或建立直连 MCP Client。只有用户明确分配给 Harness 的 MCP 工具可以通过 Main 代理调用。
|
||
- 不在首版向 Harness 暴露 GoodBuddy 浏览器控制、知识库或 Magic Notes。
|
||
- 不在首版支持图像输入、会话恢复、Harness Subagent、后台 Job、Hook、Web Search 或 Workflow。
|
||
- 不发布独立 npm 包,也不创建上游 PR。
|
||
|
||
## 5. 核心设计决策
|
||
|
||
### 5.1 第三个独立 Runtime
|
||
|
||
`deepseek-harness` 是明确的 Runtime 类型,不伪装成 `model`、`opencode` 或 `continue`。共享契约、设置迁移、Runtime 选择、检测、聊天标签、消息通道和模型用量都使用同一个稳定标识。
|
||
|
||
### 5.2 受控组合,不启动用户 profile
|
||
|
||
GoodBuddy 使用自己固定的 Harness Host 入口和只读组合模板,不调用 `dsh web`,也不启动用户已有 profile。运行时禁止以下来源参与组合:
|
||
|
||
- 当前工作目录的 `.env`。
|
||
- 用户 Harness Home 的 `.env`。
|
||
- `$DSH_HOME/cordis.patch.yml`。
|
||
- 用户 profile 的 `cordis.patch.yml`。
|
||
- 任意 `--patch`。
|
||
- HMR 和动态插件安装。
|
||
|
||
模型名称、服务地址、工作区和非秘密策略通过严格校验的 Main 配置传给 Host。API Key 只通过受控凭据通道按需提供,不写入 YAML、命令行、Renderer 或日志。
|
||
|
||
### 5.3 双层内部控制面
|
||
|
||
Harness 子进程内控制面不能取代 Main 控制面,Main 控制面也不能代替进程内的 Session/Tool 适配层:
|
||
|
||
- Harness Control Plane 最接近 Session、Agent、Tool 和 Usage seam,适合做内部协议转换与 Ask 工具拦截。
|
||
- Main 控制面是可信安全边界,适合持有模式授权策略、加密设置、进程控制和 IPC。
|
||
|
||
任何一侧缺失能力握手时,Runtime 必须报告不可用,不能降级为不受控执行。
|
||
|
||
### 5.4 GoodBuddy 继续拥有持久会话
|
||
|
||
首版不启用 Harness JSONL 会话持久化和 SQLite 会话索引。原因如下:
|
||
|
||
- GoodBuddy 已经持久化对话、消息、活动、工具事件和用量。
|
||
- 再写一份 Harness 日志会扩大敏感数据副本和清理范围。
|
||
- GoodBuddy 在 Runtime 重启后可以用现有的有界历史创建新 Harness Session。
|
||
|
||
Harness Session 只在当前 Runtime 进程生命周期内存在。释放 GoodBuddy 会话时必须同步释放对应 Harness Agent。
|
||
|
||
## 6. 总体架构
|
||
|
||
```text
|
||
Renderer
|
||
│ 显式、经 schema 验证的 preload API
|
||
▼
|
||
Electron Main
|
||
├─ RuntimeSettingsStore
|
||
├─ AgentRuntimeController
|
||
├─ RuntimeAuthorizer(Ask 拒绝 / Main 代理工具授权)
|
||
└─ DeepSeekHarnessRuntime / Main Control Plane
|
||
│ ACP + goodbuddy/* 扩展,stdin/stdout
|
||
▼
|
||
Electron utilityProcess
|
||
└─ GoodBuddy Harness Host
|
||
├─ 固定 Cordis 组合
|
||
├─ GoodBuddy Harness Control Plane(内部组件)
|
||
├─ DSH Agent 与 LLM seam
|
||
├─ 本地 Shell / Filesystem Provider
|
||
└─ 最小工具集
|
||
│ HTTPS
|
||
▼
|
||
用户选择的 OpenAI 兼容模型连接
|
||
```
|
||
|
||
### 6.1 信任边界
|
||
|
||
| 区域 | 信任级别 | 允许持有的内容 |
|
||
| --- | --- | --- |
|
||
| Renderer | 不可信展示层 | 脱敏设置、状态、用户可见事件 |
|
||
| Preload | 窄桥 | 明确方法和共享 schema |
|
||
| Electron Main | 可信控制面 | 加密设置、模式授权策略、Runtime 生命周期 |
|
||
| Harness utilityProcess | 不可信执行面 | 当前请求、临时凭据、受控工具和当前用户权限 |
|
||
| Harness 工具子进程 | 最低信任 | 单次命令所需的最小环境和当前用户权限 |
|
||
|
||
Harness 子进程崩溃、输出异常、拒绝协议或加载错误时,Main 必须失败关闭。
|
||
|
||
## 7. GoodBuddy Harness Control Plane
|
||
|
||
### 7.1 内部组件职责
|
||
|
||
控制面负责:
|
||
|
||
- 启动 ACP 兼容的 JSON-RPC stdio 服务。
|
||
- 创建、查找和释放 Harness Agent。
|
||
- 在 Prompt 前应用 GoodBuddy 指定的 Ask/Execute 权限。
|
||
- 将 DSH Session 事件转换为有界的 GoodBuddy 事件。
|
||
- 将 LLM 用量转换为稳定的模型用量事件。
|
||
- 在 dispose 时先取消 Agent,再等待子 Agent 和工具清理。
|
||
- 保证 stdout 只包含协议帧,诊断只写 stderr。
|
||
|
||
控制面不负责:
|
||
|
||
- 保存 GoodBuddy 设置。
|
||
- 持久保存 API Key。
|
||
- 决定 Main 的模式授权结果。
|
||
- 直接访问 Renderer 或 Electron API。
|
||
- 接受用户提供的插件、Host 或 profile 覆盖。
|
||
- 自行上传遥测。
|
||
|
||
### 7.2 非插件约束
|
||
|
||
控制面不导出 `apply(ctx, config)`,不提供默认 stdin/stdout 入口,不包含 `dsh.bundle`、`cordis.patch.yml` 或可安装 manifest,也不接受 Host 之外创建的 transport。它可以保留清晰的内部模块边界以便测试和维护,但该边界不是公开扩展点。
|
||
|
||
若未来确有来自 GoodBuddy 真实用户、经过研究验证的扩展需求,应先重新完成产品需求、威胁模型和兼容策略评审;不得因为上游已经提供插件或市场机制而默认开放。
|
||
|
||
## 8. 协议设计
|
||
|
||
### 8.1 传输
|
||
|
||
- stdin/stdout 使用换行分隔 JSON-RPC。
|
||
- stdout 不得出现日志、Banner、进度条或调试输出。
|
||
- stderr 只允许有界诊断,不得包含 Prompt、工具完整输出或凭据。
|
||
- 每一帧、每一字段和每个请求累计输出都必须在解析前或接收时限流。
|
||
|
||
### 8.2 标准 ACP 方法
|
||
|
||
首版保留 ACP 的初始化、`session/new`、`session/prompt` 和 `session/cancel` 语义。标准 ACP 客户端可以使用只读默认行为,但只有完成 GoodBuddy 能力握手的客户端才能启用 Execute。
|
||
|
||
### 8.3 GoodBuddy 扩展
|
||
|
||
扩展统一使用 `goodbuddy/` 命名空间:
|
||
|
||
| 方法或事件 | 方向 | 用途 |
|
||
| --- | --- | --- |
|
||
| `goodbuddy/handshake` | Main → Control Plane | 交换控制协议、Harness、ACP 版本和能力 |
|
||
| `goodbuddy/session/prepare` | Main → Control Plane | 在下一次 Prompt 前设置工作模式和请求标识 |
|
||
| `goodbuddy/session/release` | Main → Control Plane | 取消并释放指定 Session |
|
||
| `goodbuddy/session/event` | Control Plane → Main | 文本、推理、工具、状态和用量事件 |
|
||
| `goodbuddy/credential/resolve` | Control Plane → Main | 按已登记引用请求当前 Runtime 的临时凭据 |
|
||
| `goodbuddy/tools/list` | Control Plane → Main | 取得用户分配给 Harness 的有界 MCP 工具 schema |
|
||
| `goodbuddy/tools/call` | Control Plane → Main | 通过当前 Execute 请求、schema 校验和既有 RuntimeAuthorizer 调用 MCP |
|
||
| `goodbuddy/shutdown` | Main → Control Plane | 停止接收新请求并有序清理 |
|
||
|
||
扩展版本独立于 ACP 版本。握手响应至少包含:
|
||
|
||
```ts
|
||
type GoodBuddyHarnessCapabilities = {
|
||
controlProtocolVersion: 1
|
||
harnessVersion: string
|
||
acpProtocolVersion: number
|
||
supports: {
|
||
cancellation: true
|
||
sessionRelease: true
|
||
reasoningEvents: boolean
|
||
toolEvents: boolean
|
||
usageEvents: boolean
|
||
credentialResolution: true
|
||
}
|
||
execution: {
|
||
mode: 'host'
|
||
}
|
||
}
|
||
```
|
||
|
||
版本不兼容、必需能力缺失或 `execution.mode` 不是 `host` 时,Main 不得开始模型请求。
|
||
|
||
### 8.4 每轮权限准备
|
||
|
||
GoodBuddy 的工作模式属于每个请求,不属于 Runtime 进程全局状态。同一对话可以在 Ask 和 Execute 之间切换。因此:
|
||
|
||
1. `session/new` 后默认是 Ask。
|
||
2. 每个 Prompt 前,Main 发送一次 `goodbuddy/session/prepare`。
|
||
3. Harness Control Plane 将准备状态绑定到 `sessionId + requestId`。
|
||
4. `session/prompt` 只能消费匹配且尚未使用的准备状态。
|
||
5. 缺少准备状态、重复使用、请求标识不匹配时,Control Plane 直接拒绝请求。
|
||
6. 同一 Session 只允许一个 Prompt 在途。
|
||
|
||
### 8.5 事件模型
|
||
|
||
Harness Control Plane 只发送 GoodBuddy 能稳定解释的字段:
|
||
|
||
- `status`:简短运行状态。
|
||
- `text`:已提交的助手文本分片。
|
||
- `reasoning`:可选的有界推理摘要分片。
|
||
- `tool`:工具 ID、名称、状态和有界输入/输出摘要。
|
||
- `model-usage`:模型、提供方、输入、输出和缓存 Token。
|
||
- `done`:停止原因和 Session ID。
|
||
|
||
禁止发送原始 Cordis Context、完整环境、内部对象、堆栈中的凭据或无界 Session 日志。
|
||
|
||
## 9. Runtime 生命周期
|
||
|
||
### 9.1 进程模型
|
||
|
||
- 每个活动的 DeepSeek Harness Runtime 实例拥有一个 `utilityProcess`。
|
||
- 一个进程可以承载多个 Harness Session。
|
||
- 同一 GoodBuddy 对话的 Prompt 串行执行。
|
||
- 不同对话可以并行,但受全局并发上限控制。
|
||
- Runtime 设置变化时创建新实例,旧实例等待在途请求结束或在宽限期后被取消。
|
||
|
||
### 9.2 会话映射
|
||
|
||
Main 保存内存映射:
|
||
|
||
```text
|
||
GoodBuddy conversationId -> Harness sessionId + process generation
|
||
```
|
||
|
||
- 首次请求创建 Session。
|
||
- 已有 Session 只发送当前 Prompt。
|
||
- 进程重启或映射失效时,创建新 Session,并只在这一次加入 GoodBuddy 提供的有界历史。
|
||
- 历史以明确的“不可信会话数据”结构传入,不能拼接成系统指令。
|
||
- 用户分配的 Skill 只通过 Main 校验的包路径进入 Host,并在 Agent scope 注册;不得把 Skill 内容伪装成用户 Prompt。
|
||
|
||
### 9.3 取消与超时
|
||
|
||
- 用户取消时立即发送 `session/cancel`。
|
||
- 取消等待有界,超时后关闭连接并终止整个 Harness 进程。
|
||
- 初始化、握手、Session 创建、Prompt、权限回传和关闭分别使用独立超时。
|
||
- Prompt 超时与用户取消使用不同错误类型,不能被宽泛 catch 抹平。
|
||
- 取消后仍可接收并丢弃该请求的最终协议结算帧,但不得写入下一请求。
|
||
|
||
### 9.4 释放与退出
|
||
|
||
- 删除或释放对话时调用 `goodbuddy/session/release`。
|
||
- Runtime dispose 时先拒绝新请求,再取消所有 Session。
|
||
- Harness Control Plane 完成 Agent、工具和会话清理,Host 完成 Cordis Fiber 与子进程的反向清理。
|
||
- Main 在宽限期内等待正常退出。
|
||
- 超时后终止 utilityProcess,并在平台允许时清理完整进程树。
|
||
- 应用退出不得因 Harness 清理无限阻塞。
|
||
|
||
## 10. 权限与主机执行
|
||
|
||
### 10.1 模式映射
|
||
|
||
| GoodBuddy 模式 | 本地工具 | GoodBuddy MCP 工具 | 行为 |
|
||
| --- | --- | --- | --- |
|
||
| Ask | 只开放读取;分发边界阻止 `write`、`edit`、`bash` 和 `pwsh` | 不注册 | 保持只读 |
|
||
| Execute | 全部固定工具可用 | 按分配注册并经过既有 RuntimeAuthorizer | 以当前用户权限运行 |
|
||
|
||
### 10.2 Ask 模式
|
||
|
||
- Harness Control Plane 在 `tools/execute` 分发边界识别当前 Session 和在途请求。
|
||
- `write`、`edit`、`bash` 与 `pwsh` 固定拒绝,不能仅靠系统提示词保持只读。
|
||
- Ask 不注册 Main 代理的 MCP 工具。
|
||
- 只读不等于无限输出,读取仍受字节和工具结果上限控制。
|
||
- 首版不向 Ask 暴露 GoodBuddy 的可变数据工具。
|
||
|
||
### 10.3 Execute 模式
|
||
|
||
- 工作区来自 Session 创建时的规范化绝对路径,并作为文件与命令工具的默认工作目录。
|
||
- DSH 本地 Filesystem、Bash 或 PowerShell Provider 直接使用 GoodBuddy 客户端当前用户的 OS 权限。
|
||
- 工作区不是 containment 边界;绝对路径和命令可访问当前用户本来有权访问的主机资源。
|
||
- Main 代理的 MCP 工具继续执行分配、schema、活动请求、模式和 RuntimeAuthorizer 校验。
|
||
- 所有工具调用仍作为活动事件记录;Ask 和 delegation 路径继续固定拒绝。
|
||
|
||
### 10.4 Runtime OS 沙箱
|
||
|
||
- GoodBuddy 不加载 DSH 平台 Sandbox Provider,也不执行启动沙箱探测。
|
||
- “安全与数据”不提供 Runtime OS 沙箱开关。
|
||
- 握手明确报告 `execution.mode = 'host'`,状态文案明确说明工具使用当前用户权限。
|
||
- Electron Renderer、Preload、Browser Session 等应用安全沙箱不在本设计变更范围内。
|
||
|
||
### 10.5 环境与凭据
|
||
|
||
- 使用环境变量白名单构造 utilityProcess 环境。
|
||
- 不继承 `NODE_OPTIONS`、调试端口、任意 npm 配置、用户 `DSH_*` 覆盖或白名单之外的凭据。
|
||
- `DSH_TELEMETRY_DISABLED=1` 必须固定设置。
|
||
- Harness Home 指向 GoodBuddy 管理的隔离目录。
|
||
- 不调用官方 `loadEnv` 或 `loadLayeredEnv`。
|
||
- API Key 由 Main 从加密设置中解析。
|
||
- Harness Control Plane 只能用已握手登记的引用通过 `goodbuddy/credential/resolve` 请求当前 Runtime 的凭据。
|
||
- 凭据只在模型请求所需的子进程内存中短暂存在,不写磁盘、不进入工具环境、不打印。
|
||
|
||
## 11. 受控 Harness 组合
|
||
|
||
首版只加载完成文本对话、受控代码操作和用户明确分配能力所需的固定服务:
|
||
|
||
- Agent、Session、LLM 和 Tool Registry 基础服务。
|
||
- GoodBuddy Harness Control Plane。
|
||
- OpenAI 兼容 Chat Completions LLM 适配器。
|
||
- DSH 本地 Subprocess、Filesystem 和平台 Shell Provider。
|
||
- Token Meter 和必要的上下文压缩。
|
||
- 有界的读取、写入、编辑和 Shell 工具。
|
||
- Agent scope 的 Skill Registry 与 `skill` 工具。Skill 目录由 Main 选择并在 Launcher 和 Host 两次规范化、校验。
|
||
- Main 代理的 MCP schema 工具。Utility 不持有 MCP URL 凭据或 Transport。
|
||
|
||
首版明确不加载:
|
||
|
||
- Web UI、HMR、Host API 和目录选择器。
|
||
- Harness 遥测。
|
||
- Settings File 和 Local Credentials。
|
||
- 用户 profile 与全局补丁。
|
||
- Web Search、Fetch、Utility 直连 MCP、Hooks。
|
||
- Subagent、Workflow、Ralph、后台 Job。
|
||
- JSONL Session Persistence 和 SQLite Session Query。
|
||
- 自动技能发现和市场技能加载。
|
||
|
||
如果某个首版工具依赖被排除服务,启动审计必须失败,而不是自动加载更大的默认 bundle。
|
||
|
||
## 12. 模型配置
|
||
|
||
### 12.1 配置来源
|
||
|
||
DeepSeek Harness 首版只使用符合下列边界的 GoodBuddy 模型连接:
|
||
|
||
- 协议必须是 `openai-chat-completions`。
|
||
- 认证必须是 API Key。
|
||
- 公网服务地址必须使用 HTTPS;`localhost`、`127.0.0.1` 和 `::1` 回环地址可以使用 HTTP。
|
||
- 服务地址可以使用自定义主机、端口和部署路径,但不得包含用户名、密码、查询参数或片段。
|
||
- 模型名称不限制为 DeepSeek 品牌,由所选 OpenAI 兼容服务决定。
|
||
- 模型名称和服务地址由 Main 传入受控 Host。
|
||
- API Key 继续保存在 GoodBuddy 加密设置中。
|
||
- 启动环境提供的部署连接只由 Main 自动解析,不在 Renderer 中显示为可选来源。
|
||
|
||
不允许选择 Harness 自有的用户配置文件或自定义 Host。Runtime 始终使用随当前 GoodBuddy 版本发布的内置 Host,并通过完整内部能力握手。
|
||
|
||
### 12.2 设置变化
|
||
|
||
模型、凭据、Skill 或 MCP 分配变化时,GoodBuddy 创建新 Runtime 实例。Harness Host 路径始终由当前 GoodBuddy 构建提供,不能由设置或环境变量替换。旧实例按现有 Runtime Controller 语义退役,不在一个活动进程内热替换安全配置。
|
||
|
||
### 12.3 输入限制
|
||
|
||
- 首版只支持文本。
|
||
- 图片输入应在发起网络调用前返回明确错误。
|
||
- GoodBuddy 历史、Prompt、系统指令分别保持不同信任层。
|
||
- 任何用户文本都不能进入 Cordis 配置表达式或模块名。
|
||
|
||
## 13. 输出和资源边界
|
||
|
||
建议首版默认限制:
|
||
|
||
| 项目 | 默认上限 |
|
||
| --- | --- |
|
||
| 单个 JSON-RPC 帧 | 1 MiB |
|
||
| 单个文本或推理事件 | 64 KiB |
|
||
| 单次请求累计协议输出 | 4 MiB |
|
||
| 工具输入摘要 | 4,000 字符 |
|
||
| 工具输出摘要 | 4,000 字符 |
|
||
| 待处理事件数 | 1,000 |
|
||
| stderr 累计 | 64 KiB |
|
||
| 初始化 | 10 秒 |
|
||
| 单次 Prompt | 10 分钟 |
|
||
| 有序关闭宽限期 | 2 秒 |
|
||
|
||
超过限制时应取消当前请求。协议帧、队列或 stderr 持续异常时,应终止 Runtime 进程,避免继续信任已失控的通道。
|
||
|
||
## 14. Runtime 检测与状态
|
||
|
||
### 14.1 检测
|
||
|
||
检测只验证:
|
||
|
||
- 内置 Host 路径是规范化文件。
|
||
- 版本可读取且在支持范围内。
|
||
- 内部控制面能力握手成功。
|
||
|
||
检测不得调用付费模型,也不得读取或输出 API Key。真实模型测试是单独的显式操作。
|
||
|
||
### 14.2 设置界面
|
||
|
||
Agent Runtime 使用共享 `SegmentedControl` 展示 OpenCode、Continue 和 DeepSeek Harness。DeepSeek Harness 必须标记为“开发者预览”,并说明上游 RC 可能发生破坏性变更。
|
||
|
||
Runtime 的概览、模型配置和检测信息放在同一张详情卡中。当前单独显示的一行“已就绪”应移入卡片,与路径、版本号归为同一组:
|
||
|
||
```text
|
||
Runtime: GoodBuddy 内置 DeepSeek Harness
|
||
模型配置: 跟随 GoodBuddy · 企业网关(qwen-plus)
|
||
状态: 已就绪
|
||
路径: <受控 Host 路径>
|
||
版本: 0.1.0-rc.6
|
||
执行权限: 当前用户权限
|
||
|
||
Host 始终由当前 GoodBuddy 版本提供,不存在自定义 Host 入口。
|
||
```
|
||
|
||
界面要求:
|
||
|
||
- 不再在卡片外重复一行检测结果。
|
||
- 使用语义化键值结构,路径允许换行,不截断关键信息。
|
||
- 状态不能只依靠绿色表达,必须同时有文字。
|
||
- 检测中和不可用分别显示明确文案。
|
||
- 高级设置默认收起。
|
||
|
||
聊天顶栏只显示简短 Runtime 状态,不显示文件路径和版本。完整诊断只在设置页展示。
|
||
|
||
## 15. IPC 与共享契约
|
||
|
||
共享 schema 需要覆盖:
|
||
|
||
- `deepseek-harness` provider 和 Runtime ID。
|
||
- Runtime 选择中的 `deepseekHarness` 分支。
|
||
- 检测结果中的路径、版本、详情和主机执行模式。
|
||
- GoodBuddy 模型连接选择。
|
||
- DeepSeek Harness 模型用量归属。
|
||
- Skill 与 MCP 对 `deepseek-harness` 的显式分配。
|
||
|
||
Renderer 只接收脱敏状态。任何凭据、完整环境、启动参数或内部 Cordis 配置都不能进入共享契约。
|
||
|
||
已有设置迁移必须:
|
||
|
||
- 对没有新字段的用户使用安全默认值。
|
||
- 保留 OpenCode、Continue 和模型连接选择。
|
||
- 修复失效的 DeepSeek Harness 模型引用时给出可报告的迁移警告。
|
||
- 不把旧 Runtime 自动迁移为 DeepSeek Harness。
|
||
|
||
## 16. 打包与供应链
|
||
|
||
### 16.1 版本策略
|
||
|
||
- 官方 RC 包全部精确锁定,不使用 `^` 或 `~`。
|
||
- 同一 Harness 核心包族必须保持同一 RC 版本。
|
||
- 升级前检查 release diff、协议 diff、工具执行语义和依赖闭包。
|
||
- 内部握手同时检查锁定的 Harness 基线和 GoodBuddy 控制协议版本。
|
||
|
||
### 16.2 原生依赖
|
||
|
||
受控组合可能需要:
|
||
|
||
- `node-pty`,用于受管理的工具子进程。
|
||
- `koffi`,用于本地 Filesystem 在 Windows 上保持文件 ACL 和原子替换。
|
||
|
||
不得广泛批准所有安装脚本。只允许生产组合实际需要、来源已审查、版本已锁定的脚本。六个平台的构建必须验证:
|
||
|
||
- 对应架构的原生文件存在。
|
||
- Electron Utility Process 可加载原生模块。
|
||
- spawn helper 的权限正确。
|
||
- 包中没有混入其他平台不需要的可执行内容,除非上游包无法拆分且已记录。
|
||
|
||
### 16.3 生产闭包
|
||
|
||
发布包只包含受控 Host 需要的插件和许可证。应尽量避免把 Harness Web profile、HMR 和其他未加载产品面带入生产闭包。若 npm 依赖结构无法拆分,必须:
|
||
|
||
- 确认这些模块不会被加载。
|
||
- 评估它们带来的 audit 和体积风险。
|
||
- 在后续上游版本允许时改为最小包族。
|
||
- 确认 `tests/fixtures` 以及 Web3D 测试 Skill/MCP 不进入正式发布资源。
|
||
|
||
### 16.4 漏洞门禁
|
||
|
||
当前安装后的 `npm audit` 报告不能直接用 `npm audit fix --force` 处理。每项漏洞需要区分:
|
||
|
||
- GoodBuddy 既有依赖。
|
||
- Harness 新增生产依赖。
|
||
- 仅开发或打包依赖。
|
||
- 未加载但被带入的 Web 依赖。
|
||
|
||
进入 Harness 执行路径且有可利用条件的高危问题必须在发布前修复、替换或移出生产闭包。
|
||
|
||
### 16.5 发布验证
|
||
|
||
`build/build-release.cjs` 需要验证:
|
||
|
||
- Harness Host 和受控配置存在。
|
||
- GoodBuddy Host、内部控制协议与 Harness 依赖版本清单存在。
|
||
- 平台原生 PTY/Koffi 依赖架构正确。
|
||
- Harness、ACP SDK 和其他新增第三方许可证已打包。
|
||
- `app.asar` 外需要执行或动态加载的资源位于预期目录。
|
||
- Web3D Skill/MCP 等测试 fixture 不在 `app.asar` 或 `extraResources` 中。
|
||
|
||
## 17. 测试策略
|
||
|
||
### 17.1 单元测试
|
||
|
||
- Runtime 选择、设置迁移和失效引用修复。
|
||
- 二进制检测、版本解析和路径规范化。
|
||
- ACP 握手、事件转换和请求关联。
|
||
- 每个会话单请求、跨会话并行。
|
||
- Ask 在工具分发边界固定拒绝 Shell、写入和编辑。
|
||
- 握手只接受明确的 `execution.mode = 'host'`。
|
||
- 未分配 Skill/MCP 不可见;分配后的 Skill catalog 可调用 `skill` 加载。
|
||
- Ask 不注册 MCP 工具;Execute 每轮刷新有界 schema,并在调用前再次校验活动请求、模式、参数和 RuntimeAuthorizer 结果。
|
||
- MCP URL、启动命令和凭据不进入 Utility 启动配置或协议结果。
|
||
- 未知授权结果失败关闭。
|
||
- 超时、取消、迟到帧和进程意外退出。
|
||
- 协议帧、事件队列、工具摘要和 stderr 上限。
|
||
- release 和 dispose 的幂等性。
|
||
- 状态卡中的状态、路径、版本和当前用户执行权限。
|
||
|
||
### 17.2 本地集成测试
|
||
|
||
使用无网络的假控制面/模型验证:
|
||
|
||
- utilityProcess 管道。
|
||
- 多 Session。
|
||
- Session 释放。
|
||
- Runtime 替换。
|
||
- 进程树回收。
|
||
- 本地 Filesystem 与 Shell Provider 使用规范化工作区作为默认工作目录,且不报告沙箱强制模式。
|
||
- 受控配置不会读取工作区 `.env` 和用户 DSH 配置。
|
||
|
||
### 17.3 真实模型测试
|
||
|
||
真实测试已经获得用户授权,但必须由显式环境门禁启用。Web3D Skill 和 MCP 仅作为 `tests/fixtures` 下的测试资产使用,不属于内置发布能力。至少验证:
|
||
|
||
1. 文本问答成功,并记录正确 Runtime 和模型用量。
|
||
2. Ask 可以读取工作区,但写入被拒绝,且不会弹出权限对话框。
|
||
3. Execute 可以在工作区创建测试文件。
|
||
4. Execute 工具确实以当前用户权限运行,且状态和握手不宣称 OS 隔离。
|
||
5. Ask、delegation 和无活动请求不能绕过工具分发检查。
|
||
6. 取消长请求后不再产生文本,并可继续使用其他 Session。
|
||
7. 两个 Session 可并行,事件不会串线。
|
||
8. 释放会话和关闭应用后没有残留 Harness 或工具进程。
|
||
9. 从全新用户设置流程启用一个 3D 游戏 Skill 和实际本地或开放 MCP,工具事件能够证明二者确实被调用。
|
||
10. Harness 生成的 3D 游戏项目可以安装、启动和实际游玩,包含 3D 渲染、玩家控制、目标和反馈,浏览器无关键错误。
|
||
|
||
测试不得打印、快照或提交 API Key。测试创建的文件只能位于专用临时工作区,并在确认可再现后清理。
|
||
|
||
### 17.4 项目验证
|
||
|
||
源码完成后必须运行:
|
||
|
||
```text
|
||
npm test
|
||
npm run typecheck
|
||
npm run lint
|
||
npm run build
|
||
```
|
||
|
||
涉及发布资源后,还要按可用原生平台运行聚焦的 `release:package` 验证。无法在当前主机执行的目标必须由六平台 CI 验证。
|
||
|
||
## 18. 验收标准
|
||
|
||
功能只有同时满足以下条件才算完成:
|
||
|
||
- `deepseek-harness` 可被保存、选择、检测和显示。
|
||
- Runtime 详情卡内显示状态、路径、版本和当前用户执行权限。
|
||
- Skills 与 MCP 设置页可把能力分配给 DeepSeek Harness,布局、键盘语义、文案和保存回显通过真机检查。
|
||
- Ask 写入测试在 Runtime 边界失败。
|
||
- Execute 工作区内写入成功。
|
||
- Runtime OS 沙箱设置、平台 Runner、启动探测和原生沙箱打包产物均不存在。
|
||
- 取消、超时、切换 Runtime 和退出应用均能回收进程。
|
||
- 多会话不串流、不串权限请求、不串用量。
|
||
- 用户 DSH 配置、`.env`、遥测和 Web UI 未被加载。
|
||
- API Key 不进入 Renderer、配置文件、日志、错误文本或测试产物。
|
||
- 全量测试、类型检查、Lint 和生产构建通过。
|
||
- 真实 OpenAI 兼容 Chat Completions 请求成功。
|
||
- 真实请求调用已分配 Skill 和 MCP,并生成、启动和实际游玩一个可用的 3D 游戏项目。
|
||
- 新增第三方许可证和发布校验完整。
|
||
|
||
## 19. 已知限制
|
||
|
||
- DeepSeek Harness 底层库当前是 RC,但 GoodBuddy 不自动跟随升级;每次升级都可能要求同步修改内部控制面。
|
||
- Harness 文件和命令工具没有 Runtime OS 隔离,会继承 GoodBuddy 客户端当前用户能够访问的主机资源。
|
||
- 首版不恢复 Harness 原生 Session,Runtime 重启后由 GoodBuddy 历史重建。
|
||
- 首版不支持图片、知识库、浏览器工具和 Harness Subagent;MCP 仅支持用户分配、Main 代理和 Execute 自动单次授权路径。
|
||
- 推理、工具和用量扩展属于 GoodBuddy 协议,不是标准 ACP 保证。
|
||
- 不支持 DSH 插件、市场包、用户 profile 或自定义 Host。
|
||
|
||
## 20. 自维护与升级策略
|
||
|
||
GoodBuddy 对该 Runtime 采用内部维护策略:
|
||
|
||
1. 当前通过验证的 Host、控制协议和依赖锁定随 GoodBuddy 一起版本化。
|
||
2. 不自动跟随 DSH RC、插件 ABI、profile 格式或市场元数据变化。
|
||
3. 升级前审查实际用户收益、上游 diff、主机工具语义、协议行为、依赖闭包和许可证。
|
||
4. 六个平台的单元、假模型、UtilityProcess、主机执行和真实模型门禁全部通过后才能更新基线。
|
||
5. 若上游方向不再满足 GoodBuddy 用户需求或安全边界,允许维护兼容补丁、替换单个底层包,或逐步移除 DSH 依赖;`goodbuddy/*` 内部协议保持由 GoodBuddy 控制。
|
||
6. 不以进入官方插件目录、适配市场机制或服务非 GoodBuddy 客户端作为目标。
|
||
|
||
## 21. 备选方案记录
|
||
|
||
### 21.1 每次调用 `dsh --profile headless`
|
||
|
||
未采用。它适合一次性任务,但不能满足流式事件、多会话、细粒度取消、权限回传和低延迟复用。
|
||
|
||
### 21.2 只使用官方 ACP 插件
|
||
|
||
未采用。取消和一次性权限选择符合需求,但缺少工具、推理、用量和会话释放事件。
|
||
|
||
### 21.3 只使用官方 SDK JSON-RPC
|
||
|
||
未采用。事件更完整,但单轮取消和权限回传能力不足。
|
||
|
||
### 21.4 把全部安全逻辑放进 Harness 子进程
|
||
|
||
未采用。Harness 子进程属于不可信执行面,不能拥有最终模式授权策略、加密设置和进程回收权限。
|
||
|
||
### 21.5 把全部控制适配放在 Main
|
||
|
||
未采用。Main 无法可靠观察 Cordis 内部 Session、Tool、Usage 和权限 seam,只能得到不完整的外部进程行为。
|
||
|
||
当前选择的双层内部控制面放弃标准 DSH 插件形态,只复用锁定的底层库,并维持 GoodBuddy 的可信 Main 控制权。 |