Files
goodbuddy/docs/features/direct-model-agent/logic-design.md
T
mesalogo 56ebd40bd8 feat: unify execution and add workspace file imports
Remove Ask/Execute modes and general product tool approvals so requests use the selected runtime, enabled capabilities, and execution account permissions. Migrate retired application metadata while preserving user content.

Retire the Results page while retaining conversation images and stored artifacts. Add local and remote workspace file imports, timestamps and sorting, improve image discovery and saving, and refine workspace navigation and supervision responsiveness. Include the accompanying web-search changes, tests, probes, and product documentation.

Remote imports require an updated Agent. Existing artifacts are not automatically copied into project directories. Validation evidence and outstanding failures remain documented in feature progress files; no full test suite or real-model calls were rerun for this commit.

Release note: Run requests without switching work modes, import files into a selected local or remote workspace folder, sort workspace files by date, and keep using conversation images after removal of the Results page.
2026-10-04 20:02:59 +08:00

202 lines
9.2 KiB
Markdown

# 直连模型 Agent 能力功能逻辑设计
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 已实施 |
| 版本 | 0.4 |
| 日期 | 2026-09-09 |
| 关联 PRD | [PRD](./prd.md) |
| 关联故事 | [User Stories](./user-stories.md) |
## 1. 权威不变量
1. `process_execute` 和 `subagent_delegate` 只属于直连文本模型。
2. 正常请求按已注册工具和当前账号权限执行,不含产品工作模式或一般工具审批策略。
3. 子级的项目、执行空间、模型连接和能力范围只能继承或缩小。
4. 子级工具清单不包含 `subagent_delegate`,最大深度固定为 1。
5. 命令必须在父请求绑定的执行空间运行,禁止跨设备静默回退。
6. 一个 `process_execute` 调用只拥有自己创建的前台进程树,不能管理无关进程。
7. 非零退出码是命令结果;启动失败、输入无效和后端不可用才是工具失败。
8. 子任务是父请求内部 Job/Subjob,不创建顶层 Task 或独立 Conversation。
9. 父请求取消、Runtime 释放或应用退出会传播到全部活动子级和进程。
10. OpenCode、Continue 和 DeepSeek Harness 的原生能力不被本功能替换或包装。
11. 直连模型只在尚未显示文本或推理内容时自动重试瞬时网络错误或请求超时,最多重试
3 次;用户取消和已显示的部分输出禁止重放。
12. 本机正常工具请求可调用 `workspace_rg`、`workspace_read_text` 和 `workspace_apply_patch`。
13. 搜索直接使用随包 rg 的原生参数和输出,使用当前账号权限;读取和补丁保留工作区 API 语义。
14. FR-7 / US-A6:预览之外的搜索、进程和 Subagent 输出保留在所属会话下,分页续读不启动新命令。
会话释放先停止活动工作,再删除输出;子会话结束不删除父会话拥有的 Subagent 结果。
## 2. 状态维度
| 维度 | 值 |
| --- | --- |
| Runtime | `model`、`opencode`、`continue`、`deepseek-harness` |
| 执行空间 | `local`、`ssh` |
| 本机 Shell | `available`、`unavailable` |
| Subagent 深度 | `0`、`1` |
| 父请求 | `active`、`cancelling`、`terminal` |
| 模型请求重试 | `initial`、`retry 1..3`、`terminal` |
## 3. 工具可见性决策表
| Runtime | 执行条件 | 工作区读/搜索 | 补丁 | `process_execute` | `subagent_delegate` |
| --- | --- | --- | --- | --- | --- |
| `model` | 本机 Shell 可用 | 提供 | 提供 | 提供 | 按既有委派设置提供 |
| `model` | 本机 Shell 不可用 | 提供 | 提供 | 隐藏并报告诊断 | 按既有委派设置提供 |
| `model` | SSH,远端后端未实现 | 当前入口不开放 | 当前入口不开放 | 隐藏 | 隐藏 |
| 其他 Runtime | 任意 | 不注入本功能工具 | 不注入 | 不注入 | 不注入 |
工具清单隐藏不是最终授权边界。`callTool` 仍须重新验证 Runtime、执行空间和父请求
是否活动,以拒绝旧快照或伪造调用。
FR-4 / FR-12 / US-B0:工作区搜索和读取不依赖知识库、联网搜索或委派开关,不需要
额外批准。MCP 服务器失败也不改变本机工具的可用性。
`output_read` 在直连模型拥有搜索、进程或 Subagent 服务时提供,不取决于
本轮 Shell 可用性、是否允许再次委派或委派深度。读取只接受当前会话的句柄;其他 Runtime
不注册该工具,调用边界同样拒绝。
## 4. 进程状态机
```text
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. 工作目录决策
| 输入 | 结果 |
| --- | --- |
| 未提供 | 当前工作区根目录 |
| `.` 或相对路径 | 以当前工作区为基准解析,可指向工作区外目录 |
| 绝对路径 | 使用指定目录 |
| `..` 或指向工作区外的符号链接 | 解析到实际目标目录,按当前用户权限执行 |
| 不存在或不是目录 | 拒绝 |
| 当前工作区身份在验证期间变化 | 拒绝本次调用 |
工作区提供默认目录和相对路径基准,不是命令的文件系统边界。单次命令选择其他
工作目录不会修改父请求绑定的项目或工作区,也不会影响后续未指定 `cwd` 的命令。
## 6. Shell 选择
| 平台 | 顺序 | 不可用结果 |
| --- | --- | --- |
| Windows | `pwsh` → `powershell.exe` | 进程工具不注册,设置诊断显示 PowerShell 不可用 |
| macOS | `/bin/bash` → `/bin/sh` | 两者都不可用时不注册 |
| Linux | `/bin/bash` → `/bin/sh` | 两者都不可用时不注册 |
一次父请求冻结实际 Shell 描述。PATH 或工具环境设置变化只影响新创建的 Runtime/执行服务,
不在运行中的命令或 Subagent 中途切换。
## 7. Subagent 状态机
```text
validating
├─ invalid/depth_exceeded → failed
└─ queued
├─ parent_cancelled → cancelled
└─ running
├─ model done → completed
├─ child failure → failed_with_partial_output
├─ timeout → cancelled
└─ parent cancel → cancelled
```
父模型收到结构化终态:
```ts
type SubagentDelegateResult = {
status: 'completed' | 'failed' | 'cancelled'
output: string
error?: string
modelUsage?: {
inputTokens?: number
outputTokens?: number
}
}
```
失败和取消是父模型可以解释的子任务结果。只有契约损坏、未知子任务身份或服务已经释放等
内部不变量失败才终止父工具循环。
## 8. 权限与能力继承
子级继承父级已启用工具的子集,包含可用的本机进程能力,不含再次委派;不保存模式字段。
- 子级使用父请求开始时的工具与能力快照;运行中设置变化不重写快照。
- 子级调用 MCP、浏览器或知识能力时继续经过这些能力已有的作用域和生命周期边界。
- FR-5 / FR-7 / US-C1:子级使用父请求的浏览器标签页,不另开标签页或改变所有权;
子级结束后父模型仍可继续操作该页,父请求继续负责其使用租约。
- 子级不弹出额外的“Subagent 执行授权”,也不获得父级没有的 MCP 分配。
## 9. 并发和顺序
- 全局编程 Subagent 最大并发为 3,额外请求进入有界队列。
- 单个父模型的工具调用仍按直连模型现有顺序结算,不为本功能改写全部工具并发语义。
- 不同父请求的 Subagent 可以并发;共享工作区的并发写入使用当前账号权限,
活动记录必须保留实际顺序和结果。
- 首版不自动创建工作树、锁文件或回滚层。出现真实冲突时由父模型读取当前工作区事实并处理。
## 10. 结果优先级
当多个终止原因竞争时,使用以下优先级:
```text
用户/父请求取消 > 工具超时 > 输出或协议边界 > 进程退出 > 普通工具错误
```
已经提交的正常终态不被稍后到达的取消覆盖。父请求进入终态后,迟到的子级文本和工具事件
只用于资源清理,不再写入会话。
## 11. 模型请求重试
```text
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` |
| 统一执行 | 清单与调用均校验实际能力、资源归属和生命周期,无产品模式 |
| 本机三平台 | 完整,统一契约和平台 Shell 决策已定义 |
| Subagent 递归 | 完整,深度固定为 1 |
| 取消与失败 | 完整,父子和进程传播及优先级已定义 |
| 模型网络恢复 | 完整,有限重试、输出重放和取消边界已定义 |
| 产品对象 | 完整,遵循 Task/Job 权威模型 |
| SSH 远端执行 | 明确不在首版;未来必须增加 Agent 后端后才能开放 |
当前没有需要在实施前由用户补充的产品决策。