Replace the restricted workspace_rg parameter mapping with native args and optional cwd. Preserve rg output and exit codes, and reuse process cancellation and output_read pagination so large search results remain accessible. Ask remains read-only within the workspace; Execute uses current-account permissions. Validation: focused regression 169 passed, 1 skipped; typecheck and lint passed. Real DeepSeek Ask and Execute pagination scenarios passed with six counted requests in the successful run; an earlier failed fixture run has no retained request count. Full-suite validation is not green: the recorded run had unrelated failures and the latest run timed out without a summary. The remote Agent does not use this local execution path. Release note: 直连模型可使用 ripgrep 原生参数搜索文件并保留原生结果,大输出可通过 output_read 完整续读。Ask 保持工作区只读,Execute 使用当前账号权限。
9.5 KiB
9.5 KiB
直连模型 Agent 能力功能逻辑设计
文档信息
| 项目 | 内容 |
|---|---|
| 状态 | 已实施 |
| 版本 | 0.4 |
| 日期 | 2026-09-09 |
| 关联 PRD | PRD |
| 关联故事 | User Stories |
1. 权威不变量
process_execute和subagent_delegate只属于直连文本模型。- Ask 永远不能启动命令、写入工作区或创建 Execute Subagent。
- 子级的项目、执行空间、工作模式、模型连接和能力范围只能继承或缩小。
- 子级工具清单不包含
subagent_delegate,最大深度固定为 1。 - 命令必须在父请求绑定的执行空间运行,禁止跨设备静默回退。
- 一个
process_execute调用只拥有自己创建的前台进程树,不能管理无关进程。 - 非零退出码是命令结果;启动失败、输入无效和后端不可用才是工具失败。
- 子任务是父请求内部 Job/Subjob,不创建顶层 Task 或独立 Conversation。
- 父请求取消、Runtime 释放或应用退出会传播到全部活动子级和进程。
- OpenCode、Continue 和 DeepSeek Harness 的原生能力不被本功能替换或包装。
- 直连模型只在尚未显示文本或推理内容时自动重试瞬时网络错误或请求超时,最多重试 3 次;用户取消和已显示的部分输出禁止重放。
- Ask 可调用
workspace_rg和workspace_read_text,但不能调用workspace_apply_patch;Execute 可调用三者。 - 搜索直接使用随包 rg 的原生参数和输出;Ask 的参数检查保持工作区内只读,Execute 使用账号权限。
- FR-7 / US-A6:预览之外的搜索、进程和 Subagent 输出保留在所属会话下,分页续读不启动新命令。 会话释放先停止活动工作,再删除输出;子会话结束不删除父会话拥有的 Subagent 结果。
2. 状态维度
| 维度 | 值 |
|---|---|
| Runtime | model、opencode、continue、deepseek-harness |
| 工作模式 | ask、execute |
| 执行空间 | local、ssh |
| 本机 Shell | available、unavailable |
| Subagent 深度 | 0、1 |
| 父请求 | active、cancelling、terminal |
| 模型请求重试 | initial、retry 1..3、terminal |
3. 工具可见性决策表
| Runtime | 模式 | 工作区读/搜索 | 补丁 | process_execute |
subagent_delegate |
|---|---|---|---|---|---|
model |
Ask | 提供 | 隐藏 | 隐藏 | 提供,只读继承 |
model |
Execute,本机 Shell 可用 | 提供 | 提供 | 提供 | 提供,Execute 继承 |
model |
Execute,本机 Shell 不可用 | 提供 | 提供 | 隐藏并报告诊断 | 提供 |
model |
SSH,远端后端未实现 | 当前入口不开放 | 当前入口不开放 | 隐藏 | 隐藏 |
| 其他 Runtime | 任意 | 不注入本功能工具 | 不注入 | 不注入 | 不注入 |
工具清单隐藏不是最终授权边界。callTool 仍须重新验证 Runtime、工作模式、执行空间和父请求
是否活动,以拒绝旧快照或伪造调用。
FR-4 / FR-12 / US-B0:Ask 工作区搜索和读取不依赖知识库、联网搜索或委派开关,不需要 切到 Execute 或额外批准。MCP 服务器失败也不改变本机只读工具的可用性。
output_read 在直连模型拥有搜索、进程或 Subagent 服务时提供,Ask/Execute 均可用,不取决于
本轮 Shell 可用性、是否允许再次委派或委派深度。读取只接受当前会话的句柄;其他 Runtime
不注册该工具,调用边界同样拒绝。
4. 进程状态机
validating
├─ invalid → failed
└─ valid → starting
├─ spawn_failed → failed
└─ running
├─ exit 0 → completed
├─ exit nonzero → completed_nonzero
├─ timeout → terminating → timed_out
├─ parent cancel → terminating → cancelled
└─ output/lifecycle failure → terminating → failed
规则:
completed_nonzero仍产生正常工具结果。- 超时和取消结果包含已取得输出的预览;超出预览的内容按 FR-7 继续保留,直到所属会话释放。
- 进入
terminating后不再接受新输入,也不启动替代命令。 - 终止只针对本次调用记录的进程树。
- 迟到的
close只用于清理,不得覆盖已提交的取消或超时原因。
5. 工作目录决策
| 输入 | 结果 |
|---|---|
| 未提供 | 当前工作区根目录 |
. 或相对路径 |
以当前工作区为基准解析,可指向工作区外目录 |
| 绝对路径 | 使用指定目录 |
.. 或指向工作区外的符号链接 |
解析到实际目标目录,按当前用户权限执行 |
| 不存在或不是目录 | 拒绝 |
| 当前工作区身份在验证期间变化 | 拒绝本次调用 |
工作区提供默认目录和相对路径基准,不是 Execute 命令的文件系统边界。单次命令选择其他
工作目录不会修改父请求绑定的项目或工作区,也不会影响后续未指定 cwd 的命令。
6. Shell 选择
| 平台 | 顺序 | 不可用结果 |
|---|---|---|
| Windows | pwsh → powershell.exe |
进程工具不注册,设置诊断显示 PowerShell 不可用 |
| macOS | /bin/bash → /bin/sh |
两者都不可用时不注册 |
| Linux | /bin/bash → /bin/sh |
两者都不可用时不注册 |
一次父请求冻结实际 Shell 描述。PATH 或工具环境设置变化只影响新创建的 Runtime/执行服务, 不在运行中的命令或 Subagent 中途切换。
7. Subagent 状态机
validating
├─ invalid/depth_exceeded → failed
└─ queued
├─ parent_cancelled → cancelled
└─ running
├─ model done → completed
├─ child failure → failed_with_partial_output
├─ timeout → cancelled
└─ parent cancel → cancelled
父模型收到结构化终态:
type SubagentDelegateResult = {
status: 'completed' | 'failed' | 'cancelled'
output: string
error?: string
modelUsage?: {
inputTokens?: number
outputTokens?: number
}
}
失败和取消是父模型可以解释的子任务结果。只有契约损坏、未知子任务身份或服务已经释放等 内部不变量失败才终止父工具循环。
8. 权限与能力继承
| 父请求 | 子级模式 | 子级能力 |
|---|---|---|
| Ask | Ask | 父级只读工具的子集,不含进程、写入和再次委派 |
| Execute | Execute | 父级已启用工具的子集,包含本机进程能力,不含再次委派 |
- 子级不能请求更高模式。
- 子级使用父请求开始时的工具与能力快照;运行中设置变化不重写快照。
- 子级调用 MCP、浏览器或知识能力时继续经过这些能力已有的作用域和生命周期边界。
- FR-5 / FR-7 / US-C1:Execute 子级使用父请求的浏览器标签页,不另开标签页或改变所有权; 子级结束后父模型仍可继续操作该页,父请求继续负责其使用租约。
- Execute 子级不弹出额外的“Subagent 执行授权”,也不获得父级没有的 MCP 分配。
9. 并发和顺序
- 全局编程 Subagent 最大并发为 3,额外请求进入有界队列。
- 单个父模型的工具调用仍按直连模型现有顺序结算,不为本功能改写全部工具并发语义。
- 不同父请求的 Subagent 可以并发;共享工作区的并发写入属于用户已授权的 Execute 行为, 活动记录必须保留实际顺序和结果。
- 首版不自动创建工作树、锁文件或回滚层。出现真实冲突时由父模型读取当前工作区事实并处理。
10. 结果优先级
当多个终止原因竞争时,使用以下优先级:
用户/父请求取消 > 工具超时 > 输出或协议边界 > 进程退出 > 普通工具错误
已经提交的正常终态不被稍后到达的取消覆盖。父请求进入终态后,迟到的子级文本和工具事件 只用于资源清理,不再写入会话。
11. 模型请求重试
attempt
├─ success → completed
├─ cancel → cancelled
├─ non-retryable failure → failed
├─ transient failure after visible output → failed_with_partial_output
└─ transient failure before visible output
├─ retry count < 3 → backoff → attempt
└─ retry count = 3 → failed
- 瞬时失败包括常见连接重置、连接/网络不可达、DNS 临时失败、连接管道中断和请求超时。
- 三次重试分别等待 500 ms、1 s 和 2 s;每次尝试重新建立请求并使用独立请求超时。
- 普通问答、工具模型轮次和上下文摘要使用同一规则。
- 重试不重复已经执行的工具;工具只会在模型完整返回一轮工具调用后开始执行。
- 退避等待绑定父请求取消信号,取消优先于启动下一次尝试。
12. 逻辑完整性评估
| 领域 | 结论 |
|---|---|
| Runtime 隔离 | 完整,工具只注入 model |
| Ask/Execute | 完整,清单过滤和调用边界双重检查 |
| 本机三平台 | 完整,统一契约和平台 Shell 决策已定义 |
| Subagent 递归 | 完整,深度固定为 1 |
| 取消与失败 | 完整,父子和进程传播及优先级已定义 |
| 模型网络恢复 | 完整,有限重试、输出重放和取消边界已定义 |
| 产品对象 | 完整,遵循 Task/Job 权威模型 |
| SSH 远端执行 | 明确不在首版;未来必须增加 Agent 后端后才能开放 |
当前没有需要在实施前由用户补充的产品决策。