move runtime_workspace and agent_tool_route stages to completed

This commit is contained in:
2026-08-07 17:10:01 +08:00
parent 10840909ab
commit e94fbc4fb4
20 changed files with 0 additions and 0 deletions
@@ -0,0 +1,17 @@
# 04A.agent_tool_route 阶段摘要
**状态:** 已完成
**来源:** `lineup-app/迭代/04A.agent_tool_route/04A.agent_tool_route.md`
## 1. 结论
本阶段不是重做 Runtime 工作区,而是补齐 Agent / Adapter 一半链路:
- Runtime 发布 Tool inventory
- Hermes Adapter 负责协议转换和平台兼容;
- 用户通过自然语言真正触发合法 Tool invoke
- Hermes 的 approval / clarify / update prompt 收敛为 LineUp 标准协议。
## 2. 当前角色
该阶段已于 2026-08-07 完成当前定义下的联合验收,是第一个明确的跨项目迭代样板。
@@ -0,0 +1,111 @@
# 04A.agent_tool_route 设计评审(一)
**评审编号:** 01
**日期:** 2026-08-07
**评审对象:** [04A.agent_tool_route.md](04A.agent_tool_route.md)(实施权威)、[04.runtime_workspace.md](../04.runtime_workspace/04.runtime_workspace.md)、[05.technical_implementation_spec.md](../04.runtime_workspace/05.technical_implementation_spec.md)、[运行时与智能体工具.md](../../设计/02.正式方案/运行时与智能体工具.md)、[lineup-runtime-sdk-architecture.md](../../设计/02.正式方案/lineup-runtime-sdk-architecture.md)。
**评审方法:** 独立以 `04A.agent_tool_route.md` 作为唯一实施权威,核对它与 `04.runtime_workspace` 已冻结的 Tool 调用 / 回程语义是否一致,并检查 Hermes Adapter 新增边界是否足以让协议、实现与验收得到唯一结论。
**总体结论:** `04A` 已成功收敛为 Adapter 层的两个核心目标:一是补齐 `applications[].tools``lineup.v1.miniapp.tool.call` 的 MiniApp Tool 通路,二是把 Hermes 内置审批 / 澄清 / 更新提示等交互收口到 LineUp 协议。评审中确认了两个必须冻结的边界:`miniapp.tool.call` 不新增第二套专用 result 协议,而是继续复用既有 Agent Tool 回程语义;Hermes `clarify` 在本轮仅兼容单选、`other -> input` 和纯文本,`multi_select` 稳定拒绝。上述决议已回填实施权威,当前无未解决的 P0~P3 问题,设计可进入技术实施规范阶段。
## 问题清单(Outline
状态标记:🔴 未解决,必须处理;🟡 已提出修复方向,尚未确认或未回填实施权威;✅ 已解决;⚪ 可延期但必须保留记录。P0~P3 必须在当前迭代处理;P4~P5 可以延期,但必须记录延期原因和重新评估条件。
| 状态 | 优先级 | 编号 | 问题 | 当前结论 / 下一步 |
|---|---:|---|---|---|
| ✅ | P1 | D04A-01 | `lineup.v1.miniapp.tool.call` 已新增请求信封,但主定义未明确它的协议回执、进度和最终业务结果是否复用既有 Agent Tool 回程语义。 | 已确认并回填:不新增 `lineup.v1.miniapp.tool.result``miniapp.tool.call` 的 receipts / progress / final result 全部继续复用 `04.runtime_workspace` 已冻结的 Agent Tool 回程语义,并始终以同一 `call_id` 关联。 |
| ✅ | P2 | D04A-02 | Hermes `clarify` 已纳入兼容范围,但未说明 `multi_select = true` 的处理规则,存在实现静默降级或行为分叉风险。 | 已确认并回填:`04A` 只兼容单选、`other -> input` 和纯文本澄清;`multi_select = true` 稳定拒绝,不静默降级成单选或自由文本。 |
## 已确认的一致性
### `04A` 是 Adapter 补齐,不是重写 Runtime
主定义已经把边界写清:`04.runtime_workspace` 继续是 Runtime、Lifecycle、Inventory revision、Tool schema 与 Pomodoro 裁决语义的权威;`04A` 只补齐 Agent / Adapter 如何消费这些事实、如何发起合法调用、以及如何把 Hermes 私有交互收口到 LineUp 协议。
这意味着本轮不应在 Runtime 中新增 Hermes 特判,也不应为 `miniapp.tool.call` 重新发明一套业务状态机。
### `lineup-app-server` 继续是透明传输层
主定义将 `lineup-app-server` 明确排除在本轮核心改造范围之外,这与当前代码角色一致:服务端负责消息收发与传输,不承担 `lineup.v1` 业务语义解析。
因此,本轮实现责任应集中在 Hermes Adapter、Prompt 约束、协议规范化与测试证据,不应让实施误入 Go 服务端语义改造。
### Hermes 的平台私有交互兼容责任位于 Adapter 层
主定义已经吸收了飞书模式的关键点:不是让模型生成平台私有协议,也不是让 Runtime 理解 Hermes 私有 prompt kind,而是由 Adapter 把 Hermes 内部审批 / 澄清 / 更新提示转换成 LineUp 标准交互,再把用户回传 resolve 回 Hermes 内部状态。
这条边界对未来 Open Claw 等其他 Agent 平台同样成立,因此本次评审认为该分层方向正确,且应继续保持。
## D04A-01`miniapp.tool.call` 缺少明确的回程协议归属
**已解决(2026-08-07,收敛决议)。** 主定义已回填:`lineup.v1.miniapp.tool.call` 只新增请求信封,不新增 `lineup.v1.miniapp.tool.result`。与之关联的协议回执、进度和最终业务结果,全部继续复用 `04.runtime_workspace` 已冻结的 Agent Tool 回程语义,并始终按同一 `call_id` 相关联。
### 为什么这是 P1
`04.runtime_workspace` 已经明确冻结了 Agent Tool 的回程模型:
- 请求被接受后可先收到 `accepted / starting` 等协议回执;
- 激活完成后可收到 `started` 或其他受控进度;
- 最终只回传一次符合 Tool result schema 的业务结果;
- 同一 `call_id` 的重放返回已持久化的最新回执、进度或最终结果。
`04A` 在新增 `lineup.v1.miniapp.tool.call` 时,如果只定义请求信封而不定义回程归属,就会出现至少三种实现分叉:
```text
实现 A:为 miniapp.tool.call 再发明一套 miniapp.tool.result
-> Hermes Adapter、Runtime、验收脚本都要多维护一套协议。
实现 B:沿用既有回程语义,但不写进主定义
-> 各模块只能靠口头共识实现,验收口径不唯一。
实现 C:把 MiniApp Tool 的 started / progress 当成最终业务结果
-> 直接破坏 04.runtime_workspace 已冻结的 Tool result 语义。
```
这会影响 Hermes Adapter 的协议白名单、回程解析、幂等与验收证据,因此必须在实现前冻结。
### 收敛决议
本轮已确认:
1. `lineup.v1.miniapp.tool.call` 只负责表达“Agent 要调用某个 MiniApp Tool”;
2. 不新增 `lineup.v1.miniapp.tool.result` 或其他第二套 MiniApp 专用回程协议;
3. 该调用的 receipts / progress / final result 全部继续复用 `04.runtime_workspace` 已冻结的 Agent Tool 回程语义;
4. Hermes Adapter 必须把这些回程都视作“同一条 Tool 调用”的不同阶段,而不是新的协议族。
该结论已回填 [04A.agent_tool_route.md](04A.agent_tool_route.md) 的“协议冻结”和“完成标准”。
## D04A-02`clarify` 的 `multi_select` 变体没有唯一处理规则
**已解决(2026-08-07,收敛决议)。** 主定义已回填:本轮 `clarify` 只兼容单选、`other -> input` 和纯文本澄清;若 Hermes 发起 `multi_select = true`,Adapter 必须稳定拒绝,不得静默降级成单选或自由文本。
### 为什么这是 P2
Hermes 的 `clarify` 并不只有一种形态。当前 `04A` 已决定兼容 `clarify`,但如果不明确 `multi_select` 的处理方式,至少会出现以下风险:
```text
实现 A:把 multi_select 静默改成单选
-> 用户损失语义,Agent 得到错误决策结果。
实现 B:改成自由文本输入,让用户自己拼多个选项
-> Host、Adapter 和 Hermes 对返回值结构无法形成唯一约定。
实现 C:某些平台支持,某些平台直接忽略
-> 同一协议在不同 Adapter 上表现不一致,验收不可复现。
```
这虽然不影响本轮 MiniApp Tool 通路的最小闭环,但会直接影响 Hermes 交互兼容层的实现一致性与验收,因此必须在迭代设计阶段给出唯一规则。
### 收敛决议
本轮已确认:
1. `clarify` 的兼容范围冻结为单选 `choice``other -> input` 的二段式澄清,以及纯文本输入型澄清;
2. `multi_select = true` 不属于 `04A` 的兼容范围;
3. 若 Hermes 发起该变体,Adapter 必须返回受控 unsupported / not_supported 结果;
4. 不允许静默降级、隐式拆分成多轮单选,或把多选伪装成自由文本。
该结论已回填 [04A.agent_tool_route.md](04A.agent_tool_route.md) 的“兼容层上限”“冻结规则”“范围内”和“完成标准”。
## 评审关闭条件
1. D04A-01 与 D04A-02 已回填 [04A.agent_tool_route.md](04A.agent_tool_route.md)
2. 后续 `02.technical_implementation_spec.md` 必须把这两项设计决议继续落到协议解析、白名单、错误码、测试夹具与验收证据;
3. 本评审未发现需要延期保留的 P4 / P5 事项;后续若出现新的平台私有交互类型,应通过新的评审记录进入,而不是直接扩充 `04A` 主定义;
4. 本评审结论不替代主定义,实施仍以 [04A.agent_tool_route.md](04A.agent_tool_route.md) 为唯一权威。
@@ -0,0 +1,116 @@
# 04A.agent_tool_route 设计评审(二)
**评审编号:** 02
**日期:** 2026-08-07
**评审对象:** [04A.agent_tool_route.md](04A.agent_tool_route.md)(实施权威)、[02.technical_implementation_spec.md](02.technical_implementation_spec.md)、[04.runtime_workspace.md](../04.runtime_workspace/04.runtime_workspace.md)、[05.technical_implementation_spec.md](../04.runtime_workspace/05.technical_implementation_spec.md)、[运行时与智能体工具.md](../../设计/02.正式方案/运行时与智能体工具.md)、[lineup-runtime-sdk-architecture.md](../../设计/02.正式方案/lineup-runtime-sdk-architecture.md)、[app_final_design.md](../../设计/02.正式方案/app_final_design.md)、[lineup-ui-surface-protocol.md](../../设计/02.正式方案/lineup-ui-surface-protocol.md)。
**评审方法:**`04A` 主定义与实施规范为当前候选方案,联合对照 `04.runtime_workspace` 已冻结的实现边界,以及 `02.正式方案` 中 Runtime / Tool / Inventory / Surface 的正式契约,重点检查协议命名、Inventory 结构、Tool 回程语义与分层责任是否一致。
**总体结论:** 联合评审确认 `04A` 的方向正确,仍然是 Adapter 层补齐而不是重写 Runtime;但原稿中有两处会和正式方案产生实现分叉的 P1 冲突:其一,把 Agent Tool 绑定到 `client.inventory.payload.applications[].tools`,与正式方案“Inventory 同时包含 App、Tool、Surface、Capability,且 Tool 是独立投影”的方向不一致;其二,新增 `lineup.v1.miniapp.tool.call`,会把正式方案中的统一 Agent Tool 模型拆成第二套 MiniApp 私有调用协议。两项问题均已在本次评审中回填:`04A` 现改为消费独立 Tool inventory 投影,并以 `lineup.v1.tool.invoke` 作为正式方案统一 Agent Tool invoke 的当前版本化落地;标准交互兼容入口 `lineup.v1.tool.call(choice | confirm | input)` 继续保留,但不再承担 Runtime Agent Tool invoke 语义。当前无未解决的 P0~P3 问题,`04A` 可以继续进入实现或验收准备。
## 问题清单(Outline
状态标记:🔴 未解决,必须处理;🟡 已提出修复方向,尚未确认或未回填实施权威;✅ 已解决;⚪ 可延期但必须保留记录。P0~P3 必须在当前迭代处理;P4~P5 可以延期,但必须记录延期原因和重新评估条件。
| 状态 | 优先级 | 编号 | 问题 | 当前结论 / 下一步 |
|---|---:|---|---|---|
| ✅ | P1 | D04A-03 | `04A` 原稿把 MiniApp Tool 绑定到 `client.inventory.payload.applications[].tools`,与正式方案中 Inventory 的 App / Tool / Surface / Capability 独立边界不一致。 | 已确认并回填:`applications` 继续只表达 App / Surface 可见性;Agent Tool 改为独立 Tool 投影进入 inventoryHermes Adapter 只消费该最小 Tool 投影。 |
| ✅ | P1 | D04A-04 | `04A` 原稿新增 `lineup.v1.miniapp.tool.call`,会把正式方案中的统一 Agent Tool 模型拆成第二套 MiniApp 私有调用协议。 | 已确认并回填:不再引入 `miniapp.tool.call`;本轮以 `lineup.v1.tool.invoke` 作为正式方案统一 Agent Tool invoke 的版本化落地。`lineup.v1.tool.call` 继续仅作为 Interact 标准交互兼容入口。 |
## 已确认的一致性
### `04A` 继续服从 `04.runtime_workspace` 已冻结的 Tool / Runtime 边界
`04.runtime_workspace` 和其技术实施规范已经冻结:Pomodoro 的 `pomodoro.start` / `pomodoro.interrupt` 都是 Runtime 发布给 Agent 的统一 Agent ToolRuntime 负责 Tool Router、activation、foreground gating、operation 终态和 outboxMiniApp 只声明 Tool、接收投影、写自己的 session data。
本次联合评审确认,`04A` 不应重新发明第二套 MiniApp Tool 平面,而应只补 Hermes 如何理解和调用这套已存在的 Runtime Tool 模型。
### 标准交互与 Agent Tool 仍是两条不同的协议语义
`03.sdk_and_coreapp` 已经把 `lineup.v1.tool.call(choice | confirm | input)` 冻结为 Interact 的标准交互兼容入口。
正式方案中的 Agent Tool invoke 则是 Runtime 面向 Agent 的统一工具调用模型。两者都可复用 `call_id`、receipt、result 等概念,但不能混成同一种“Tool Call”来让实现自行猜测。
### `lineup-app-server` 仍不需要进入本轮语义改造
本次联合评审没有发现必须让 `lineup-app-server` Go 服务理解 Hermes 私有协议、Inventory Tool 投影或 Tool invoke 语义的证据。
因此,`04A` 仍然应把改动集中在 Hermes Adapter、Prompt 约束、协议校验与测试证据,不扩大到传输层。
## D04A-03Inventory 把 Tool 塞进 `applications[].tools` 与正式方案冲突
**已解决(2026-08-07,收敛决议)。** `04A.agent_tool_route.md``02.technical_implementation_spec.md` 已回填:Hermes Adapter 不再把 Agent Tool 绑定到 `applications[].tools`Inventory 中的 `applications` 继续只表达 App / Surface 可见性,Tool 改为独立顶层投影发布。
### 为什么这是 P1
正式方案已经给出清晰方向:
- [lineup-ui-surface-protocol.md](../../设计/02.正式方案/lineup-ui-surface-protocol.md) 当前把 `applications` 定义为“已启用 app 的 surface 可见性”,不含 Tool
- [lineup-runtime-sdk-architecture.md](../../设计/02.正式方案/lineup-runtime-sdk-architecture.md) 与 [app_final_design.md](../../设计/02.正式方案/app_final_design.md) 明确 Runtime Inventory 同时包含 App、Tool、Surface 与 Capability
- [04.runtime_workspace/05.technical_implementation_spec.md](../04.runtime_workspace/05.technical_implementation_spec.md) 则已经把 Tool 作为从 Registry 独立投影到 Runtime Tool Registry / Agent Inventory 的对象。
如果 `04A` 继续把 Tool 内嵌进 `applications[].tools`,就会产生三种实现分叉:
```text
实现 AHermes Adapter 按 applications[].tools 解析
-> 与正式方案中的独立 Tool Inventory 不一致。
实现 BRuntime 继续按独立 Tool Registry / Inventory 发布
-> Hermes Adapter 看不到 Tool,退回 revision=none。
实现 C:为适配 Hermes 再改 Runtime Inventory shape
-> 会反向破坏 04.runtime_workspace 已冻结的 Registry / Tool Router 方向。
```
这属于会直接导致模块间协议不兼容的 P1。
### 收敛决议
本轮已确认:
1. `applications` 继续只承载 App / Surface 可见性;
2. Agent Tool 改为独立 Tool 投影进入 inventory
3. Hermes Adapter 只保存规划与出站校验所需的最小 Tool 投影;
4. `04A` 不要求修改 `04.runtime_workspace` 已冻结的 Runtime Tool Registry / Agent Inventory 方向。
该结论已回填 [04A.agent_tool_route.md](04A.agent_tool_route.md) 与 [02.technical_implementation_spec.md](02.technical_implementation_spec.md)。
## D04A-04`miniapp.tool.call` 会把统一 Agent Tool 平面拆成两套协议
**已解决(2026-08-07,收敛决议)。** `04A` 主定义与实施规范已回填:不再引入 `lineup.v1.miniapp.tool.call`,而是以 `lineup.v1.tool.invoke` 作为正式方案统一 Agent Tool invoke 的当前版本化落地;`lineup.v1.tool.call(choice | confirm | input)` 继续只承载标准交互兼容入口。
### 为什么这是 P1
正式方案和 `04.runtime_workspace` 一直在强调同一个事实:
- Agent Tool 是 Runtime 面向远端 Agent 的统一调用模型;
- Tool invoke、receipt、progress、result、activation_ready 等都属于这条统一调用链;
- `choice / confirm / input` 是 Interact 标准交互原语,不等于 MiniApp 业务 Tool。
如果 `04A` 为 MiniApp Tool 新增 `lineup.v1.miniapp.tool.call`,就会把“统一 Agent Tool”拆成以下两套协议:
```text
一套:标准交互兼容入口 lineup.v1.tool.call
一套:MiniApp 业务 Tool lineup.v1.miniapp.tool.call
```
这样会直接带来三类分叉风险:
1. Hermes Adapter、Runtime、验收脚本要同时维护两套 Agent Tool 调用语义;
2. `04.runtime_workspace` 已冻结的 Tool receipt / progress / result 语义会被误解成“只对 miniapp.tool.call 生效”;
3. 后续非 MiniApp 但仍属于 Runtime Agent Tool 的能力,会不知道该走哪条调用协议。
这同样属于必须在实现前冻结的 P1。
### 收敛决议
本轮已确认:
1. 不再新增 `lineup.v1.miniapp.tool.call`
2. Runtime Agent Tool 统一走 `lineup.v1.tool.invoke`
3. `lineup.v1.tool.call(choice | confirm | input)` 继续只作为 `03.sdk_and_coreapp` 遗留兼容入口;
4. `tool.invoke` 的 receipts / progress / final result 继续完全复用 `04.runtime_workspace` 已冻结的 Agent Tool 回程语义。
这等价于把正式方案中的统一 Agent Tool invoke 模型,在 Adapter 当前实现中落成一个版本化 envelope,而不是再分出一条 MiniApp 私有通路。
## 评审关闭条件
1. D04A-03 与 D04A-04 已回填 [04A.agent_tool_route.md](04A.agent_tool_route.md) 与 [02.technical_implementation_spec.md](02.technical_implementation_spec.md)
2. 后续实现必须同步更新 Hermes Adapter 的协议常量、Prompt 文案、inventory parser 与测试夹具,避免代码层仍遗留 `applications[].tools``miniapp.tool.call`
3. 若后续需要修改正式方案中的 Inventory JSON shape 或 Agent Tool invoke 命名,应先回写 `02.正式方案`,而不是在迭代文档中继续引入第三套局部协议;
4. 本评审未发现需要延期保留的 P4 / P5 事项;当前无未解决 P0~P3。
@@ -0,0 +1,344 @@
# 04A.agent_tool_route 技术实施规范
**状态:** 开发实施基线
**日期:** 2026-08-07
**实施权威:** [04A.agent_tool_route.md](04A.agent_tool_route.md)
**评审基线:** [01.design_review.md](01.design_review.md)
**前置实现:** [04.runtime_workspace.md](../04.runtime_workspace/04.runtime_workspace.md)、[05.technical_implementation_spec.md](../04.runtime_workspace/05.technical_implementation_spec.md)
## 1. 目的、边界与强制约束
本规范将 `04A.agent_tool_route` 已冻结的设计映射为“**Hermes Adapter 为主、Runtime 请求侧最小兼容补丁为辅**”的开发任务。实现必须以本文件和主迭代定义共同为准;若两者出现冲突,以主迭代定义为准,并先补充设计评审,不能在代码中自行发明新的协议分支。
`04A` 的目标不是重写 Runtime,而是补齐 Agent / Adapter 入口,使 `04.runtime_workspace` 已实现的 Runtime / Pomodoro / Host 能通过 Hermes 稳定使用。
以下约束不可违反:
1. Runtime Agent Tool 必须继续使用统一的 invoke 通路,不再为 MiniApp Tool 另起第二套协议;本轮以 `lineup.v1.tool.invoke` 作为 Adapter 侧的版本化落地,它统一的是**请求入口**。回程继续复用 `04.runtime_workspace` 已冻结且当前 Runtime 仍在发送的 Agent Tool 回程事实,并始终以同一个 `call_id` 关联。
2. Hermes Adapter 只能基于当前 conversation 最近一次有效 inventory 中声明的独立 Tool 投影发出 `tool.invoke`;不允许模型伪造 `instance_id``operation_id``app_session_id` 或其他 Runtime 内部目标字段。
3. `app.call` 继续只表示 Host capability 请求;MiniApp Tool 不得复用 `app.call`,也不得通过 capability 语义绕过 Runtime 的 Tool schema 与 lifecycle 裁决。
4. Hermes 私有 approval / clarify / update prompt 的兼容责任位于 Adapter 层;Runtime 和 `lineup-app-server` 不新增 Hermes 特判,但 Runtime 允许补最小的 `tool.invoke` 请求兼容,不视为 Hermes 特判。
5. `clarify` 在本轮只兼容单选、`other -> input` 的二段式澄清和纯文本澄清;若 Hermes 发起 `multi_select = true`,Adapter 必须稳定拒绝,不得静默降级。
6. 用户交互回传必须继续走现有 `tool.result` / `tool.cancel` / `app.result` 消息链路;不设计公网 webhook 或平台回调 URL。
7. 现有 `lineup.v1.tool.call``lineup.v1.app.call``lineup.v1.ui.open / patch / close``lineup.v1.artifact.offer` 路径不得回归;其中 `lineup.v1.tool.call` 继续只承担 Interact 标准交互兼容入口,不与 Runtime Agent Tool invoke 混同。
8. 正式方案中出现的 `tool.invoke` / `tool.result` 若未带 `lineup.v1.*` 前缀,应按“统一 Agent Tool 概念名”理解;本轮实际实现、fixture、prompt 示例和验收证据一律以 `lineup.v1.*` 当前兼容信封为准,不得再并行引入裸 `tool.invoke` 变体。
9. `client.inventory` 中 Tool 独立投影的权威来源是 Runtime 正式方案与 `04.runtime_workspace` 已冻结实现;`lineup-ui-surface-protocol.md` 中较早的 inventory 示例只可视作 Surface / Capability 最小示意,不能据此否定 `tools[]` 顶层投影。
10. 若某类 Hermes contract 在当前接入路径下缺少安全、稳定、可重复的真实触发源,则验收必须将其记录为“结构性证据限制”,而不是继续当作当前代码缺陷无限挂起;不得为补证据而把 Hermes 私有语义下沉到 Runtime 或 `lineup-app-server`
## 2. 现有基线与改动边界
本轮实现主场在 `lineup-adapter/hermes/lineup/`,并允许对 `lineup-app/tauri/src/runtime/` 做最小请求兼容补丁。`lineup-app-server` Go 服务不承担本轮协议语义改造,除非后续验收证据证明传输层存在硬性阻塞。
| 模块 | 当前责任 | 04A 必须补齐 |
|---|---|---|
| `protocol.py` | LineUp envelope 常量、出站白名单、`client.inventory` / `tool.result` / `app.result` 等协议校验 | 扩展 inventory 解析以接受独立 Tool 投影;新增 `TOOL_INVOKE` 常量、解析与规范化;定义 Agent Tool 最小投影与严格字段校验。 |
| `core.py` | Prompt 组装、Agent 出站内容收敛、用户输入回注、ACP 会话驱动 | 将 Agent Tool 注入 prompt;允许并规范化 `tool.invoke` 出站;接收既有 Tool 回程作为同一 `call_id` 的 receipts / progress / final result;增加 Hermes 私有交互到 LineUp 标准交互的路由。 |
| `acp_client.py` | ACP stdio transport;当前对 `session/request_permission` 直接取消 | 将稳定的 Hermes 交互请求转成 Adapter 内部的受控 interactive request,而不是一律 `cancelled`。 |
| `state.py` | inbox / outbox、standard interaction ledger、capability ledger | 视实现需要增加一张 Hermes interactive request 账本或复用现有 Tool/App call ledger,保证 approval / clarify / confirm 是 one-shot、可过期、可拒绝、可恢复的。 |
| `tests/test_protocol.py` | 协议解析与规范化测试 | 覆盖 inventory tools 投影、`tool.invoke` 严格校验、非法字段拒绝、`clarify multi_select` 拒绝。 |
| `tests/test_core.py` | Adapter 运行时行为与隔离测试 | 覆盖 prompt 中 Agent Tool 注入、`tool.invoke` 出站收敛、Hermes 交互兼容闭环、过期 / 重复回传与恢复路径。 |
| `tests/test_acp_client.py` | ACP transport 与更新流测试 | 覆盖 `session/request_permission`、clarify / confirm / update prompt 的内部事件投影和受控拒绝。 |
| `tauri/src/runtime/inventory/client-inventory.ts``app-management/miniapp-sdk.ts``app-management/app-registry.ts` 及对应测试 | Runtime 把已启用且 Agent 可见的声明投影为 `client.inventory` | `applications[]` 只保留 App / Surface 可见性;从 SDK Declaration 经 Manifest / Registry 发布顶层 `tools[]`,其中必须包含 `app_scope``tool_id`、受控 description、`input_schema`、handling、delivery 与 activation requirement。 |
| `tauri/src/runtime/protocol/lineup-v1.ts``coordination/tool-router.ts` 及对应测试 | Runtime 当前协议解析与 Agent Tool 路由 | 最小化接受 `lineup.v1.tool.invoke` 请求入口;保持既有 `04.runtime_workspace` 执行、持久化与回程行为不变。 |
## 3. 目标 AMiniApp Tool 通路补齐
### 3.1 `client.inventory` 的 Adapter 投影
`protocol.py` 中的 `parse_client_inventory(...)` 必须从“只接受 App / Surface / Capability 的旧投影”扩展为接受与正式方案一致的**独立 Tool inventory 投影**。
解析后仍然只保留供 Hermes 规划和出站校验使用的**最小投影**,不得把 Bundle、路径、handler、secret 或宿主实现细节放进 prompt 或持久上下文。
建议冻结的最小投影结构如下:
```ts
type AdapterMiniAppToolProjection = {
app_scope: string;
tool_id: string;
description: string;
input_schema: JsonObject;
handling: "direct" | "interactive" | "launch" | "foreground" | "operation";
delivery: "miniapp_sdk" | "runtime";
activation_requirement: "activation_not_required" | "foreground_required" | "app_ready";
};
```
实现约束:
1. `applications[]` 继续只保留 `id``version``surfaces` 等 App / Surface 可见性信息;
2. `tools[]` 作为独立顶层投影发布;每个 tool 只接受受控字段集合;
3. 任意未知字段、可执行内容、URL、bundle path、内部 handler key、输出 schema、secret 都必须拒绝;
4. 任意 inventory 解析失败时,整个 inventory 视为无效,Hermes 继续退回 `revision = none` 默认上下文;
5. 任意成功解析的 inventory 都必须带着其 `revision` 一起进入 conversation 级上下文缓存。
### 3.2 `lineup.v1.tool.invoke` 的协议规范化
`protocol.py` 新增:
```python
TOOL_INVOKE = "lineup.v1.tool.invoke"
```
并将其纳入 Agent 允许输出的受控协议集合,但仅在通过严格校验后才能真正出站。
建议冻结的最小 payload
```json
{
"v": 1,
"type": "lineup.v1.tool.invoke",
"payload": {
"call_id": "call_...",
"inventory_revision": "inv_...",
"app_scope": "pomodoro",
"tool_id": "pomodoro.start",
"input": {
"duration_seconds": 300
}
}
}
```
Adapter 必须执行的首层校验:
1. 顶层只允许 `call_id``inventory_revision``app_scope``tool_id``input`
2. `call_id` 必须符合既有 identifier 规则;
3. `inventory_revision` 必须与当前 conversation 最近一次有效 inventory 一致;
4. `app_scope + tool_id` 必须存在于当前 inventory 投影中;
5. `input` 必须是 JSON object
6. 顶层禁止 `sender``target``instance_id``operation_id``app_session_id``conversation_id``delivery` 覆盖等模型可伪造元数据;
7. Adapter 只做**顶层结构和 inventory 绑定校验**,不复制 Runtime 的最终 input schema、lifecycle 或业务状态机。
`core.py` 中对 Agent 输出的收敛逻辑必须新增一条:
```text
raw model output
-> parse as tool.invoke
-> validate against current inventory projection
-> if valid: emit canonical lineup.v1.tool.invoke
-> if invalid: degrade to lineup.v1.text
```
### 3.3 Prompt 注入规则
`core.py` 组装 Hermes prompt 时,必须把当前 conversation 的 inventory 中可见的 Agent Tool 作为独立通路明确告知模型,至少覆盖以下规则:
1. 只有 inventory 中声明的 MiniApp Tool 才可调用;
2. 必须使用最新 `inventory_revision`
3. `app.call` 是 Host capability 请求,不是 MiniApp Tool 调用;
4. 当用户请求开始或停止专注时,应优先考虑 `pomodoro.start` / `pomodoro.interrupt`
5. 不得猜测 Runtime 内部目标字段;
6. 不得把 approval / clarify 伪装成 `tool.invoke`
建议在 prompt 中以“你可以返回的唯一结构化协议类型”方式列出三类请求:
```text
lineup.v1.tool.call
lineup.v1.app.call
lineup.v1.tool.invoke
```
并对每种协议分别给出字段级示例,避免模型把三类 payload 混写。
### 3.4 回程协议归属
`04A` 不为 MiniApp Tool 再新增第三套结果协议。
因此 `core.py` 与相关解析逻辑必须明确:
1. `tool.invoke` 发出后,Runtime 返回的 `accepted / starting``started`、最终业务结果,继续按既有 Agent Tool 回程语义处理;
2. 这些回程全都以同一 `call_id` 关联;
3. Adapter 不得再发明新的本地回程 envelope 分支;
4. Runtime 当前已经存在的 MiniApp Tool 回程 envelope 继续按兼容事实处理,是否统一改名不属于本轮;
5. 验收证据中必须能证明:同一 `call_id` 在 start / interrupt 流程下可看到既有 receipts / progress / final result 行为。
### 3.5 Runtime 请求兼容补丁
`04.runtime_workspace` 已完成的 Runtime 代码与测试,当前主要按旧请求类型接收 MiniApp Tool 调用。
为使 `04A``lineup.v1.tool.invoke` 真正端到端可用,本轮允许对 Runtime 增加一个窄兼容层,但必须满足以下约束:
1. 只补 `lineup.v1.tool.invoke` 的 parser / router 接受能力;
2. 兼容层必须继续接受 `04.runtime_workspace` 既有请求类型,避免回归历史验收路径;
3. 不改写 Tool Router 的 schema / revision / lifecycle / persistence / outbox 语义;
4. 不借此把 Hermes 私有交互引入 Runtime
5. 不在本轮把既有 MiniApp Tool 回程 envelope 大规模迁移到新名字。
## 4. 目标 BHermes 交互兼容层补齐
### 4.1 兼容层总原则
Hermes 私有交互在 Adapter 内部统一收口为两类:
1. **标准交互**:发起 `lineup.v1.tool.call`,接收 `lineup.v1.tool.result` / `lineup.v1.tool.cancel`
2. **宿主能力授权**:发起 `lineup.v1.app.call`,接收 `lineup.v1.app.result`
Runtime 不理解 Hermes 私有 `prompt kind`Host 也不接触 Hermes 内部 callback token。
Adapter 必须自己维护“LineUp 交互 call_id / option_id”到“Hermes 内部待决请求”的受控映射。
### 4.2 Hermes contract 到 LineUp 协议的冻结映射
本轮只实现下表中的四类 Hermes contract
| Hermes contract | LineUp 发起协议 | 用户可见交互 | 用户回传协议 | Adapter 内部 resolve |
|---|---|---|---|---|
| `exec_approval` | `lineup.v1.tool.call` | `choice` | `tool.result` / `tool.cancel` | `once / session / always / deny` |
| `slash_confirm` | `lineup.v1.tool.call` | `choice`,必要时退化 `confirm` | `tool.result` / `tool.cancel` | `once / always / cancel` |
| `clarify` | `lineup.v1.tool.call` | 单选 `choice``other -> input`、纯文本 `input` | `tool.result` / `tool.cancel` | choice text / free text |
| `update_prompt` | `lineup.v1.tool.call` | `confirm` | `tool.result` / `tool.cancel` | `y / n` |
不在本轮范围内的 Hermes 变体:
- `clarify multi_select = true`
- 任意平台特有按钮布局 / 卡片视觉细节
- 任意无法映射到上述四类 contract 的 Hermes 私有 system message
### 4.3 `acp_client.py` 的内部事件投影
当前 `acp_client.py``session/request_permission` 直接取消。
04A 需要把稳定的 Hermes 交互请求改投影为 Adapter 内部事件,供 `core.py` 消费。
建议引入受控内部结构:
```ts
type PendingHermesInteraction =
| { kind: "exec_approval"; request_id: string; session_id: string; title: string; prompt: string; options: [...] }
| { kind: "slash_confirm"; request_id: string; session_id: string; title: string; prompt: string; options: [...] }
| { kind: "clarify"; request_id: string; session_id: string; title: string; prompt: string; choices?: [...]; allow_other: bool; expects_text: bool; multi_select: bool }
| { kind: "update_prompt"; request_id: string; session_id: string; title: string; prompt: string };
```
实现要求:
1. `acp_client.py` 只做 transport 与 Hermes 请求的最小投影,不在该层拼装 LineUp 协议;
2. 任意不属于四类已冻结 contract 的请求,直接返回稳定拒绝;
3. 任意 `clarify` 若为 `multi_select = true`,直接返回稳定拒绝;
4. 日志中仍不得落 Hermes 原始敏感参数、命令、路径或自由文本;
5. 所有投影都必须带有一个 Adapter 可追踪的内部 request id。
### 4.4 `core.py` 的交互收口与 resolve
`core.py` 负责把内部 `PendingHermesInteraction` 转成真正对外的 LineUp 消息:
```text
Hermes internal interactive request
-> adapter builds controlled lineup.v1.tool.call / app.call
-> host renders it
-> user returns tool.result / tool.cancel / app.result
-> adapter validates response against its own ledger
-> adapter resolves the original Hermes request
```
实现细则:
1. `choice` 的 option id 由 Adapter 生成,不能复用 Hermes 或平台原生 callback token
2. `clarify` 若用户选择 `other`Adapter 必须主动发起第二轮 `input`,而不是把“等待自由文本”状态泄露给 Runtime;
3. `tool.result` / `tool.cancel` 回来后,Adapter 只把最小结果注入 Hermes
- approval / confirm 注入受控选项值
- clarify 注入选中的 choice text 或用户输入文本
4. 用户输入自由文本仍不得写入持久审计表;如需校验,只做内存内 schema / shape 校验;
5. 任意重复、过期或未知 `call_id` 的回传继续沿用现有 Tool/App ledger 的 one-shot 语义。
Host 对单选交互的标准结果可以使用 `result.action_id` 表示唯一选项;Adapter
必须在验证通过后将其规范化为内部 `action_ids: [action_id]` 形状,再执行既有
映射和 Hermes resolve。对于多选、缺失选项、未知选项、重复选项或非字符串选项,
仍必须拒绝,不能因为兼容 Host 形状而放宽交互边界。
### 4.5 状态与持久化
`state.py` 现有 `tool_calls` / `app_calls` 账本已经覆盖 standard interaction 和 Host capability 的 one-shot 语义。
本轮有两种可接受实现方式:
1. **推荐**:兼容层发起的所有 Hermes 交互都继续复用现有 `tool_calls` / `app_calls` 账本,只新增一张轻量映射表保存 `call_id -> pending Hermes request metadata`
2. **备选**:新增独立 `hermes_interactions` 表,但仍复用现有 `tool_calls` / `app_calls` 处理用户回传的幂等、过期和审计
无论采用哪种方式,都必须满足:
1. Adapter 重启后,不会把已发出的 approval / clarify 交互重复 resolve
2. 未完成交互会按现有 `expires_at` 语义过期;
3. 审计表不保存用户自由文本、文件路径、URL、命令或 Hermes 原始私有 token
4. 同一 `call_id` 至多 resolve 一次。
### 4.6 当前 ACP 接入路径的证据边界
本轮真实实现与联调基线是 `1420 页面 + hermes acp`
在这条路径下,Adapter 当前可以稳定接收到的 Hermes server request 已证明包括 `session/request_permission`,并可据此完成 `exec_approval` 的投影与闭环;同时,Adapter 主回复通路也已证明能够稳定发出 `choice / input`,从而覆盖 `clarify` 的单选、`other -> input` 与纯文本输入。
但截至 2026-08-07`slash_confirm``update_prompt` 的原生触发源仍主要存在于 Hermes gateway / native platform adapter 路径:
1. `slash_confirm` 由 gateway 的 `_request_slash_confirm(...)` 驱动,再调用平台 adapter 的 `send_slash_confirm(...)`
2. `update_prompt` 由 gateway watcher 监听 `.update_prompt.json`,再调用平台 adapter 的 `send_update_prompt(...)` 或回退文本提示;
3. 当前 ACP client 没有与这两类 contract 对应的稳定 server request method 投影入口。
因此本规范要求:
1. `slash_confirm``update_prompt` 继续保留在 Adapter 目标映射表中;
2. 但若当前 ACP 路径缺少稳定触发源,不得为了本轮验收临时向 Runtime 或 `lineup-app-server` 注入 Hermes 私有桥接;
3. 验收应输出结构性限制记录,并给出后续 bridge / trigger 承接建议;
4. 只有在新增可控触发源后,才重新要求这两项的 fresh runtime evidence。
## 5. 测试与验收实现要求
### 5.1 `protocol.py` 自动化测试
至少新增以下用例:
1. `client.inventory` 接受包含独立 `tools[]` 投影的受控定义;
2. inventory 中含未知 tool 字段、handler、bundle/path/secret 时整体拒绝;
3. 合法 `tool.invoke` 能被规范化;
4. `tool.invoke` 缺少 revision、tool 不存在、顶层多字段、伪造内部 target 字段时拒绝;
5. `tool.invoke` 不会升级成 `app.call` 或其他 envelope
6. `clarify multi_select = true` 被稳定拒绝。
### 5.2 `core.py` 自动化测试
至少新增以下用例:
1. prompt 中包含当前 inventory 的 Agent Tool 投影;
2. 用户请求开始 / 停止专注时,模型合法输出可被收敛为 `lineup.v1.tool.invoke`
3. 非法 `tool.invoke` 降级为 `text`
4. approval / slash confirm / clarify / update prompt 能映射成标准 `tool.call`
5. `clarify other -> input` 走二段式闭环;
6. `multi_select` 请求被稳定拒绝;
7. 既有 `tool.call``app.call``ui.*``artifact.offer` 路径不回归。
### 5.3 `acp_client.py` 自动化测试
至少新增以下用例:
1. `session/request_permission` 不再一律直接取消,而是被投影为受控内部交互请求;
2. 不支持的 Hermes 请求会稳定拒绝;
3. ACP reader 线程不会把原始敏感参数写进日志;
4. adapter 关闭、超时、Hermes 退出时,pending request 能稳定收口。
### 5.4 Runtime 兼容测试
至少新增以下用例:
1. Runtime 协议 parser 接受 `lineup.v1.tool.invoke`
2. Tool Router 能把 `lineup.v1.tool.invoke` 路由到与旧请求类型相同的 MiniApp Tool 路径;
3. 至少一条普通 MiniApp Tool 路径和一条 Pomodoro 路径通过 `lineup.v1.tool.invoke` 跑通;
4. 旧请求类型的兼容测试不回归。
### 5.5 Fresh Evidence
`03.acceptance_review.md` 必须至少记录以下 fresh evidence
1. 真实用户语言触发 `pomodoro.start`Hermes 输出 `tool.invoke`Runtime 成功执行;
2. 真实用户语言触发 `pomodoro.interrupt`Hermes 输出 `tool.invoke`Runtime 成功执行;
3. 至少一种 Hermes approval / confirm / clarify 交互通过 LineUp 消息链路完成闭环;
4. 至少一种不在本轮范围内的 Hermes 请求被稳定拒绝,且未形成隐式授权。
补充约束:
- `slash_confirm` / `update_prompt` 只有在当前接入路径存在稳定触发源时,才要求 fresh runtime evidence
- 若当前接入路径不存在稳定触发源,则必须在验收文档中记录源码对照、运行期现象与后续 bridge 建议,作为关闭本轮验收时的正式结论之一。
## 6. 实施顺序建议
建议按以下顺序推进,避免多模块同时漂移:
1. 先改 `protocol.py`,冻结 inventory tools 投影和 `tool.invoke` 校验;
2. 再改 `core.py` prompt 与出站收敛,让 Pomodoro start / interrupt 通路能先跑通;
3. 再补 Runtime 对 `lineup.v1.tool.invoke` 的最小 parser / router 兼容与对应测试;
4. 再改 `acp_client.py``core.py` 的交互兼容层,完成 approval / clarify / confirm 闭环;
5. 最后补 `state.py`、自动化测试和 fresh evidence。
本阶段不要求改动 `lineup-app-server`。若联调时发现传输层对新 envelope 有硬阻塞,应先补设计评审,再决定是否将其升级为 `04A` 范围内改动。
@@ -0,0 +1,163 @@
# 04A.agent_tool_route 验收评审(中间记录,已被后续评审收敛)
**状态:** 中间记录;最终以 [05.acceptance_review.md](05.acceptance_review.md) 为准
**日期:** 2026-08-07
**评审对象:** `lineup-adapter/hermes/lineup/` 当前实现、[04A.agent_tool_route.md](04A.agent_tool_route.md)、[02.technical_implementation_spec.md](02.technical_implementation_spec.md)
**评审口径:**`04A` 主定义和实施规范为准,先记录当时已经拿到的自动化证据与已闭环子能力,再明确尚未满足的最终验收项。本文不是最终完成声明;后续 fresh runtime evidence、结构性限制记录与最终关闭结论,均已收敛到 [05.acceptance_review.md](05.acceptance_review.md)。
## 1. 当前已验证的实现
### 1.1 Runtime Agent Tool invoke 的 Adapter 侧基线已通过自动化测试
已具备并已由自动化测试覆盖的能力:
- `client.inventory` 接受独立 `tools[]` 顶层投影;
- `lineup.v1.tool.invoke` 已进入 Hermes Adapter 允许输出集合;
- `tool.invoke` 会绑定当前 conversation 的最新 `inventory_revision`
- 非法 `tool.invoke` 会被拒绝或降级,不允许伪造 Runtime 内部目标字段。
对应测试命令:
```bash
npm test -- \
src/runtime/app-management/miniapp-sdk.test.ts \
src/runtime/app-management/reference-miniapps.test.ts \
src/runtime/app-management/app-registry.test.ts \
src/runtime/inventory/client-inventory.test.ts \
src/runtime/coordination/tool-router.test.ts \
src/runtime/coordination/lineup-runtime.test.ts
```
2026-08-07 当前结果:
```text
Test Files 6 passed (6)
Tests 71 passed (71)
```
当前已通过自动化测试验证的点:
- Runtime `client.inventory` 以顶层 `tools[]` 发布 Agent Tool,不再把 Tool 塞进 `applications[].tools`
- Tool projection 从 MiniApp SDK Declaration 经 Manifest / Registry 产生,保留 `app_scope``tool_id`、description、`input_schema`、handling、delivery 与 activation requirement
- Pomodoro 的 `pomodoro.start` / `pomodoro.interrupt` 会进入顶层投影;禁用、升级、卸载会递增 revision 并撤销对应 Tool
- inventory 不泄露 `output_schema`、permissions、handler、bundle 或本地实现信息。
### 1.2 Hermes Adapter 已通过自动化测试消费同一顶层 Tool projection
对应测试命令:
```bash
python3 -m unittest \
lineup-adapter/hermes/lineup/tests/test_protocol.py \
lineup-adapter/hermes/lineup/tests/test_core.py \
lineup-adapter/hermes/lineup/tests/test_acp_client.py
```
2026-08-07 当前结果:
```text
Ran 32 tests in 0.022s
OK
```
已具备并已由自动化测试覆盖的能力:
- `client.inventory` 接受独立 `tools[]` 顶层投影;
- `lineup.v1.tool.invoke` 已进入 Hermes Adapter 允许输出集合;
- `tool.invoke` 会绑定当前 conversation 的最新 `inventory_revision`
- 非法 `tool.invoke` 会被拒绝或降级,不允许伪造 Runtime 内部目标字段。
### 1.3 Runtime 已接受 `lineup.v1.tool.invoke` 作为最小请求兼容入口
当前已拿到的 Runtime 自动化证据表明,`04A` 不再只是 Adapter 内部自洽,而是已经把新的请求入口真正接到了 `04.runtime_workspace` 既有执行链路上。
当前已通过自动化测试验证的点:
- Runtime parser 接受 `lineup.v1.tool.invoke`
- Tool Router 会把 `lineup.v1.tool.invoke` 路由到与旧请求类型相同的 MiniApp Tool 路径;
- 至少一条普通 bundled MiniApp Tool 路径已经通过 `lineup.v1.tool.invoke` 跑通;
- `pomodoro.start` 已通过 `lineup.v1.tool.invoke` 跑通 activation、foreground 确认、deadline 结算与最终结果;
- `pomodoro.interrupt` 已通过 `lineup.v1.tool.invoke` 跑通短 Tool 自身结果,以及对长 `pomodoro.start` 的中断收口;
- Runtime 对旧请求类型的兼容测试没有因此回归。
### 1.4 Hermes 交互兼容层的统一状态机已落地
本轮已在 Adapter 内实现并通过自动化测试验证以下兼容闭环:
```text
Hermes ACP session/request_permission
-> Adapter 投影为内部 permission request
-> Adapter 发出 lineup.v1.tool.call(choice)
-> 用户回传 lineup.v1.tool.result
-> Adapter resolve 回 ACP permission outcome
Adapter 内部 interactive request
-> Adapter 发出 lineup.v1.tool.call(choice | confirm | input)
-> 用户回传 lineup.v1.tool.result / tool.cancel
-> Adapter resolve 回 Hermes 内部 interaction outcome
```
当前已通过自动化测试验证的点:
- ACP permission request 会被解析为受控请求,而不是一律 `cancelled`
- Adapter 会为该请求生成标准 `tool.call(choice)`
- `tool.result` 中的受控选项会被映射回 ACP `optionId`
- 该交互会复用现有 `tool_calls` one-shot ledger,并配套持久化 `hermes_interactions` 映射;
- Adapter 重启恢复时,未完成的 Hermes 交互会被过期收口,而不是在新进程里继续假定可 resolve。
- `slash_confirm` 已能通过 `tool.call(choice)` 生成并回收 `once / always / cancel` 一类受控结果;
- `update_prompt` 已能通过 `tool.call(confirm)` 生成并回收 `y / n` 一类受控结果;
- `clarify` 已能覆盖单选 `choice`、纯文本 `input`、以及 `other -> input` 的二段式路径;
- `clarify multi_select = true` 当前会被 Adapter 稳定拒绝,不向 Host 发出不受支持的交互请求。
### 1.5 当前已新增的实现文件
- [acp_client.py](/home/gao/Development/lineup/lineup-adapter/hermes/lineup/acp_client.py)
- [core.py](/home/gao/Development/lineup/lineup-adapter/hermes/lineup/core.py)
- [state.py](/home/gao/Development/lineup/lineup-adapter/hermes/lineup/state.py)
- [test_acp_client.py](/home/gao/Development/lineup/lineup-adapter/hermes/lineup/tests/test_acp_client.py)
- [test_core.py](/home/gao/Development/lineup/lineup-adapter/hermes/lineup/tests/test_core.py)
- [client-inventory.ts](/home/gao/Development/lineup/lineup-app/tauri/src/runtime/inventory/client-inventory.ts)
- [miniapp-sdk.ts](/home/gao/Development/lineup/lineup-app/tauri/src/runtime/app-management/miniapp-sdk.ts)
- [app-registry.ts](/home/gao/Development/lineup/lineup-app/tauri/src/runtime/app-management/app-registry.ts)
- [tool-router.ts](/home/gao/Development/lineup/lineup-app/tauri/src/runtime/coordination/tool-router.ts)
- [lineup-v1.ts](/home/gao/Development/lineup/lineup-app/tauri/src/runtime/protocol/lineup-v1.ts)
- [tool-router.test.ts](/home/gao/Development/lineup/lineup-app/tauri/src/runtime/coordination/tool-router.test.ts)
- [lineup-runtime.test.ts](/home/gao/Development/lineup/lineup-app/tauri/src/runtime/coordination/lineup-runtime.test.ts)
### 1.6 Fresh Runtime / Browser Evidence2026-08-07
在重新安装当前工作树的 Hermes Adapter、重启 Adapter 并对 Host 执行强制刷新后,取得了新的真实运行期证据。该证据不是历史截图或旧消息:
- Host 新发送的 `client.inventory` 消息序号为 `1201``revision = catalog-1`
- 该 inventory 使用独立顶层 `tools[]` 投影,包含 `pomodoro.start``pomodoro.interrupt``task-dashboard.open/update``whiteboard.open/submit`
- 用户消息序号 `1202` 为真实用户输入:`开始一个 5 分钟的专注`
- 同一条启动调用 `call_id = call_5f9c2a7d1e` 收到 `accepted` 进度回执(消息序号 `1207`);
- 随后收到 `started` 进度回执(消息序号 `1209`),其中 `operation_id = pomodoro:operation_msiet305_zwa4ckb9f2`,并绑定到前台 Pomodoro instance
- 用户提供的页面截图显示“专注工作区”“5分钟专注”,倒计时从 `05:00` 进入 `04:56`,证明前台工作区已真实打开并运行;
- 用户消息序号 `1219` 为真实用户输入:`停止当前专注`
- 停止后收到两个 `lineup.v1.miniapp.tool.result` 终态:
- `call_id = call_7d3e9f2a1b`Pomodoro interrupt 短工具结果为 `status = interrupted`
- `call_id = call_5f9c2a7d1e`:原始 start 调用结果为 `state = interrupted`,同一个 `operation_id``pomodoro:operation_msiet305_zwa4ckb9f2``interruption_reason = agent_interrupt`
- 两个终态均由 Runtime 发送并被 Adapter 收到,证明 start / interrupt 的请求、进度、终态和 operation 关联在真实消息链路中闭环。
## 2. 当前尚未证明完成的验收项
以下项目仍未被当前证据证明完成,因此 `04A` 不能视为已验收通过:
- 虽然 `slash_confirm``clarify``update_prompt` 已具备 Adapter 侧自动化测试证据,但 Hermes ACP 当前是否会以可直接消费的真实请求形态发出这些 contract,尚未拿到运行期 fresh evidence
- 至少一种“本轮范围外 Hermes 请求被稳定拒绝”的运行证据尚未补入。
## 3. 当前结论
`04A` 已从“仅完成协议设计和 invoke parser”推进到“Runtime 已发布 Adapter 可消费的顶层 Tool inventoryAdapter 侧 invoke 基线完成,Runtime 已接受 `lineup.v1.tool.invoke` 请求入口,Hermes 交互兼容层已有统一状态机并具备多类自动化证据”的阶段。
但按主定义与实施规范的最终完成标准来看,本轮只能判定为:
```text
Runtime Tool inventory:已从 SDK / Manifest / Registry 端到端发布顶层 tools[],并有 71 个 Runtime 定向测试证据
MiniApp Tool invoke 基线:已具备 Adapter 侧实现与 32 个 Adapter 定向测试证据
Runtime 请求兼容:已具备 lineup.v1.tool.invoke 的 parser / router / 高价值集成测试证据
Hermes 交互兼容层:已完成 exec_approval、slash_confirm、clarify、update_prompt 的 Adapter 侧统一桥接与自动化覆盖
Hermes ACP 真源验证:当前仍需补充除 request_permission / exec_approval 外的 contract,及一种范围外请求的真实拒绝证据
真实 Pomodoro fresh evidence:已完成 start / interrupt;见 1.6
整体 04ARuntime inventory 与 Pomodoro start / interrupt 已完成真实 Host 验证;仍需补齐 Hermes 权限/交互真源和范围外请求拒绝证据,尚未完成最终验收
```
@@ -0,0 +1,87 @@
# 04A.agent_tool_route 联合评审(三)
**评审编号:** 03
**日期:** 2026-08-07
**评审对象:** [04A.agent_tool_route.md](04A.agent_tool_route.md)、[02.technical_implementation_spec.md](02.technical_implementation_spec.md)、[04.runtime_workspace.md](../04.runtime_workspace/04.runtime_workspace.md)、[05.technical_implementation_spec.md](../04.runtime_workspace/05.technical_implementation_spec.md)、[运行时与智能体工具.md](../../设计/02.正式方案/运行时与智能体工具.md)、[lineup-runtime-sdk-architecture.md](../../设计/02.正式方案/lineup-runtime-sdk-architecture.md)、[app_final_design.md](../../设计/02.正式方案/app_final_design.md)、[lineup-ui-surface-protocol.md](../../设计/02.正式方案/lineup-ui-surface-protocol.md)。
**评审方法:**`04A` 主定义与技术实施规范为候选实现基线,联合对照 `04.runtime_workspace` 已冻结实现,以及 `02.正式方案` 中涉及 Runtime、Inventory、Tool invoke、Compatibility Adapter 的条目,重点检查是否仍存在命名分叉、Inventory shape 误读或责任边界回退。
**总体结论:** 本轮联合评审未发现新的 Runtime / Adapter 架构冲突,`04A` 继续可以按 Adapter 侧补齐推进;但正式方案文档中还存在两处“历史表述与当前兼容实现并存”的误导点,需要在 `04A` 文档中明确消歧,否则实现者容易在协议名和 inventory shape 上走回旧分支。两项问题均已在本次评审中回填到 `04A` 主定义与技术实施规范:一是正式方案中的概念名 `tool.invoke` 需要在当前实现中统一落到 `lineup.v1.tool.invoke`;二是较早 `client.inventory` 示例未展示 `tools[]`,不能再被当作当前 Tool 投影的权威 shape。当前无未解决的 P0~P3 问题。
## 问题清单(Outline
状态标记:🔴 未解决,必须处理;🟡 已提出修复方向,尚未确认或未回填实施权威;✅ 已解决;⚪ 可延期但必须保留记录。P0~P3 必须在当前迭代处理;P4~P5 可以延期,但必须记录延期原因和重新评估条件。
| 状态 | 优先级 | 编号 | 问题 | 当前结论 / 下一步 |
|---|---:|---|---|---|
| ✅ | P2 | D04A-05 | 正式方案文档同时出现概念名 `tool.invoke` 与当前兼容信封 `lineup.v1.tool.invoke`,若 `04A` 不主动消歧,Adapter 实现、fixture 与验收可能各自使用不同名字。 | 已回填:`04A` 明确正式方案中的 `tool.invoke` 仅表示统一 Agent Tool 概念名;本轮实现、prompt、fixture、验收一律使用 `lineup.v1.tool.invoke`。 |
| ✅ | P2 | D04A-06 | `lineup-ui-surface-protocol.md` 的较早 `client.inventory` 示例未包含 `tools[]`,容易让实现者误以为 `04A` 的独立 Tool 投影 shape 与正式方案冲突。 | 已回填:`04A` 明确 Tool 独立投影的权威来源是 Runtime 正式方案和 `04.runtime_workspace`;较早 Surface 协议示例只作为 Surface / Capability 最小示意,不再作为 Tool shape 权威。 |
## 已确认的一致性
### `04A` 与 `04.runtime_workspace` 的 Runtime 事实保持一致
`04.runtime_workspace` 已冻结:Runtime 是 Tool Router、activation、lifecycle、outbox、Tool receipt / progress / final result 的唯一裁决者;Adapter 只做 inventory 绑定、顶层结构校验和 Hermes 私有交互收口。
本次复核没有发现 `04A` 重新把业务语义拉回 Adapter 或 `lineup-app-server` 的迹象。
### 正式方案允许当前实现继续使用 `lineup.v1.*` 兼容信封
[app_final_design.md](../../设计/02.正式方案/app_final_design.md) 已明确:当前 Tauri 实现与 golden fixture 仍使用 `lineup.v1.*` 类型,Runtime Compatibility Adapter 负责把旧实现映射到新 Runtime 边界。
因此 `04A``lineup.v1.tool.invoke` 作为当前 Adapter 落地,与正式方案并不冲突;真正需要避免的是在当前实现里再并行制造“裸 `tool.invoke`”第二种 envelope。
### Tool 独立投影与较早 Surface inventory 示例不再矛盾
[lineup-runtime-sdk-architecture.md](../../设计/02.正式方案/lineup-runtime-sdk-architecture.md) 和 [app_final_design.md](../../设计/02.正式方案/app_final_design.md) 都已把 Inventory 收敛为同时包含 App、Tool、Surface、Capability,且 Tool 调用必须携带 `inventory_revision`
[lineup-ui-surface-protocol.md](../../设计/02.正式方案/lineup-ui-surface-protocol.md) 中未展示 `tools[]``client.inventory` 示例,现应视作较早阶段围绕 Surface / Capability 的最小示意,而不是 04A 当前 Tool 投影的最终 JSON shape。
## D04A-05`tool.invoke` 概念名与 `lineup.v1.tool.invoke` 当前信封并存,易造成实现分叉
**已解决(2026-08-07,收敛决议)。** `04A.agent_tool_route.md``02.technical_implementation_spec.md` 已补充说明:正式方案中的 `tool.invoke` / `tool.result` 若未带前缀,应按统一 Agent Tool 概念名理解;`04A` 代码、prompt、fixture、验收证据统一采用当前兼容信封 `lineup.v1.*`
### 为什么这是 P2
如果不消歧,至少会出现以下风险:
```text
实现 AAdapter 代码使用 lineup.v1.tool.invoke
实现 B:测试夹具或 prompt 示例使用裸 tool.invoke
实现 C:验收人员按正式方案字面再补第三套命名解释
```
这不会推翻 Runtime 架构,但会直接影响自动化测试、联调日志、验收口径和后续迁移路径,因此需要在当前迭代关闭。
### 收敛决议
1. 当前实现、prompt、fixture、验收证据统一使用 `lineup.v1.tool.invoke`
2. 正式方案中的 `tool.invoke` 只作为“统一 Agent Tool invoke”概念名引用;
3. 若未来正式迁移到去前缀的新 Runtime Envelope,必须先回写正式方案和兼容迁移计划,不能在 `04A` 期间并行引入第二套可执行名字。
## D04A-06:较早 `client.inventory` 示例未展示 `tools[]`,容易误导 `04A` 的 Tool 投影判断
**已解决(2026-08-07,收敛决议)。** `04A.agent_tool_route.md``02.technical_implementation_spec.md` 已明确:`tools[]` 顶层投影的权威来源是 Runtime 正式方案与 `04.runtime_workspace` 已冻结实现;`lineup-ui-surface-protocol.md` 中较早示例不再作为 Tool shape 权威。
### 为什么这是 P2
当前正式方案文档内部其实存在时间差:
- Runtime 架构和最终方案已经收敛到 “Inventory 同时包含 App、Tool、Surface、Capability”;
- 较早 Surface 协议示例仍只展示了 `standard_components + applications + capabilities`
如果不明确权威顺序,后续实现者很容易错误得出以下结论:
```text
04A 新增 tools[] = 偏离正式方案
```
这会直接干扰 Adapter parser、测试夹具、评审判断和后续 Runtime 文档演进。
### 收敛决议
1. `04A` 当前以独立 `tools[]` 顶层投影为准;
2. `applications[]` 继续只表达 App / Surface 可见性;
3. 若后续要统一正式方案中的 inventory 示例,应在正式方案文档中统一回填,而不是让 `04A` 回退到 `applications[].tools` 或无 `tools[]` 的旧分支。
## 评审关闭条件
1. D04A-05 与 D04A-06 已回填 [04A.agent_tool_route.md](04A.agent_tool_route.md) 和 [02.technical_implementation_spec.md](02.technical_implementation_spec.md)
2. 后续代码实现、测试夹具和验收记录必须统一使用 `lineup.v1.*` 当前兼容信封;
3. 后续若补正式方案文档示例,应把 `client.inventory` 的 Tool 顶层投影同步回填到正式方案,而不是在 `04A` 再引入本地例外;
4. 本评审当前无未解决的 P0P3。
@@ -0,0 +1,103 @@
# 04A.agent_tool_route 联合评审(四)
**评审编号:** 04
**日期:** 2026-08-07
**评审对象:** [04A.agent_tool_route.md](04A.agent_tool_route.md)、[02.technical_implementation_spec.md](02.technical_implementation_spec.md)、[04.runtime_workspace.md](../04.runtime_workspace/04.runtime_workspace.md)、[05.technical_implementation_spec.md](../04.runtime_workspace/05.technical_implementation_spec.md)、[运行时与智能体工具.md](../../设计/02.正式方案/运行时与智能体工具.md)、[lineup-runtime-sdk-architecture.md](../../设计/02.正式方案/lineup-runtime-sdk-architecture.md)、[app_final_design.md](../../设计/02.正式方案/app_final_design.md),以及当前 `tauri/src/runtime/` 中与 Tool invoke / Tool Router / 回程 outbox 相关的实现。
**评审方法:**`04A` 主定义和实施规范为候选基线,联合对照 `04.runtime_workspace` 已冻结的 Runtime 行为、`02.正式方案` 中 Runtime Tool 模型的正式边界,以及当前 Tauri Runtime 的协议 parser / router / outbox 代码,重点检查“文档是否把 04A 的真实改动边界写实”以及“请求侧统一与回程侧兼容是否被错误混写”。
**总体结论:** 本轮联合评审发现两处新的 P2 级口径冲突,都会直接影响实现范围和验收判断,但都不是架构方向错误:第一,`04A` 文档先前把工作描述成“仅 Adapter 补齐”,与当前 Runtime 仍主要按旧请求类型接收 MiniApp Tool 调用的实现事实不符;要让 `lineup.v1.tool.invoke` 真正打通,必须补一个最小 Runtime 请求兼容层。第二,`04A` 文档先前把“统一 Agent Tool invoke”表述得过宽,容易让实现者误以为本轮还要把 Runtime 既有 MiniApp Tool 回程 envelope 一并收敛。结合 `04.runtime_workspace` 已冻结实现与当前代码现状,更准确的结论应是:`04A` 统一的是**请求入口**,回程仍沿用 Runtime 已冻结的兼容事实,并由 Adapter 解释为同一条 `call_id` 的 receipts / progress / final result。两项问题均已在本次评审中回填到主定义与实施规范;当前无未解决的 P0~P3 问题。
## 问题清单(Outline
状态标记:🔴 未解决,必须处理;🟡 已提出修复方向,尚未确认或未回填实施权威;✅ 已解决;⚪ 可延期但必须保留记录。P0~P3 必须在当前迭代处理;P4~P5 可以延期,但必须记录延期原因和重新评估条件。
| 状态 | 优先级 | 编号 | 问题 | 当前结论 / 下一步 |
|---|---:|---|---|---|
| ✅ | P2 | D04A-07 | `04A` 文档把实现口径写成“仅 Adapter 补齐”,但当前 Runtime 仍主要按旧请求类型接收 MiniApp Tool 调用;若不补一层 Runtime 请求兼容,`lineup.v1.tool.invoke` 无法真正端到端生效。 | 已回填:`04A` 改为“Adapter 为主、附带最小 Runtime 请求兼容补丁”;允许仅在 Runtime parser / router / 测试夹具上补 `lineup.v1.tool.invoke` 接受能力,不改写 `04.runtime_workspace` 已冻结的业务语义。 |
| ✅ | P2 | D04A-08 | `04A` 文档把“统一 Agent Tool invoke”描述得过宽,容易误导为本轮还要把 Runtime 既有 MiniApp Tool 回程 envelope 一并统一。 | 已回填:`04A` 当前统一的是请求入口;回程仍沿用 Runtime 已冻结且当前代码仍在发送的兼容事实,Adapter 只按同一 `call_id` 解释,不再新增第三套协议分支。 |
## 已确认的一致性
### `app-server` 仍可保持透明传输层
本次复核没有发现 `lineup-app-server` 需要理解 `lineup.v1.tool.invoke` 业务语义的证据。当前阻塞并不在传输层,而在 Runtime 本地 parser / router 对新请求类型的接受能力。
因此,用户此前关于“是否涉及 app-server”的判断仍成立:`04A` 不应扩大为 Go 服务端语义改造。
### `04A` 的 Runtime 改动属于兼容补丁,不是边界回退
`04.runtime_workspace` 已冻结的权威仍然是 Runtime 对 revision、schema、activation、foreground gating、operation、outbox 与恢复的唯一裁决。
这次要求的 Runtime 变更,只是让它在**请求入口**上接受 `lineup.v1.tool.invoke`;不改变 Tool Router 的核心裁决,也不把 Hermes 私有 contract 拉进 Runtime。
### 正式方案与当前实现可以通过“概念层 / 兼容层”两级解释保持一致
`02.正式方案` 中的 `tool.invoke / tool.result / progress` 描述的是统一 Agent Tool 模型。当前 Tauri Runtime 则仍保留 `lineup.v1.*` 兼容信封和已验收的 MiniApp Tool 回程 envelope。
因此,本轮正确做法不是宣称“现有代码已经和正式方案一字不差”,而是明确:
1. `lineup.v1.tool.invoke` 是当前实现中的统一请求入口;
2. 当前回程仍是 `04.runtime_workspace` 已冻结的兼容事实;
3. 未来若做回程统一迁移,需要单独立项,不应在 `04A` 中顺手扩大。
## D04A-07:若不补 Runtime 请求兼容,`tool.invoke` 只会停留在 Adapter 内部
**已解决(2026-08-07,收敛决议)。** `04A.agent_tool_route.md``02.technical_implementation_spec.md` 已明确:本轮实现主场仍在 Hermes Adapter,但允许在 `lineup-app/tauri/src/runtime/` 中补最小请求兼容层,使 Runtime 接受 `lineup.v1.tool.invoke`
### 为什么这是 P2
当前冲突并不只是“代码还没写”,而是文档口径会直接误导实施范围:
```text
文档口径:04A 仅改 Adapter
实际代码:Runtime 主要仍按旧请求类型接收 MiniApp Tool
结果:Adapter 即使正确发出 lineup.v1.tool.invoke,也无法端到端命中既有 Tool Router
```
这会让实现者在联调时误判为:
1. 需要回退到旧请求类型;
2. 需要让 Adapter 同时发两种请求;
3. 需要扩大到 app-server 语义改造。
这三种方向都偏离了本轮已经收敛的架构结论,因此必须在当前迭代文档里把 Runtime 的最小兼容补丁正名。
### 收敛决议
本轮已确认:
1. `04A` 仍是 Adapter 主导迭代;
2. Runtime 允许补 parser / router / 测试夹具级别的最小请求兼容;
3. 该兼容层必须同时保留 `04.runtime_workspace` 既有请求路径,避免回归历史验收;
4. 该兼容层不改变 Runtime 的 schema / lifecycle / persistence / result 语义;
5. `lineup-app-server` 仍不进入本轮范围。
## D04A-08:请求统一不等于本轮已完成回程统一
**已解决(2026-08-07,收敛决议)。** `04A.agent_tool_route.md``02.technical_implementation_spec.md` 已把描述收窄为:`lineup.v1.tool.invoke` 统一的是请求入口;回程继续沿用 Runtime 已冻结且当前实现仍在发送的兼容事实,Adapter 以同一 `call_id` 解释,不再新增第三套协议分支。
### 为什么这是 P2
如果不收窄这层表述,会出现两个危险后果:
```text
后果 A:实现者误以为 04A 必须顺手重构 Runtime 全部 miniapp.tool.progress/result/cancel
-> 范围扩张到超出本轮验收与回归预算。
后果 B:验收者误以为只要代码里仍出现 miniapp.tool.result,就说明 04A 与正式方案冲突
-> 会把“兼容事实尚在”误判成“架构方向错误”。
```
这不是语义吹毛求疵,而是直接关系到本轮是否还能保持“最小补丁闭环”的实现策略。
### 收敛决议
本轮已确认:
1. `04A` 不新增新的本地回程协议族;
2. Adapter 需要能把现有回程解释为同一条 Agent Tool 调用的 receipts / progress / final result
3. Runtime 既有回程 envelope 是否重命名,不在 `04A` 范围内;
4. 若未来推进回程统一,应以新的迭代和新的设计评审承接,而不是在 `04A` 中隐式扩大。
## 评审关闭条件
1. D04A-07 与 D04A-08 已回填 [04A.agent_tool_route.md](04A.agent_tool_route.md) 与 [02.technical_implementation_spec.md](02.technical_implementation_spec.md)
2. 后续实现与验收必须按“Adapter 主导 + Runtime 最小请求兼容 + app-server 不动”的边界推进;
3. 后续若要推动 Runtime 回程 envelope 统一,必须新增独立设计评审记录,不能在 `04A` 中以顺手修正方式扩容;
4. 本评审当前无未解决的 P0P3。
@@ -0,0 +1,417 @@
# LineUp App 迭代定义:04A Agent Tool 通路补齐
**迭代编号:** 04A.agent_tool_route
**状态:** 开发实施中,核心实现已完成,待最终验收
**日期:** 2026-08-07
**前置基线:** [04.runtime_workspace.md](../04.runtime_workspace/04.runtime_workspace.md)、[05.technical_implementation_spec.md](../04.runtime_workspace/05.technical_implementation_spec.md)、[09.acceptance_review.md](../04.runtime_workspace/09.acceptance_review.md)
**总体计划:** [plan.md](../plan.md)
**权威架构:** [运行时与智能体工具.md](../../设计/02.正式方案/运行时与智能体工具.md)、[lineup-runtime-sdk-architecture.md](../../设计/02.正式方案/lineup-runtime-sdk-architecture.md)
## 1. 迭代定位与目标总览
`04.runtime_workspace` 已经完成了 Runtime、Pomodoro MiniApp、Host 工作区、Lifecycle、Inventory 发布与端到端 Host 验收;
但它证明的是“Runtime 这一侧怎样工作”,并没有真正补齐 “Agent 如何拿到这些 Tool,并把它们变成稳定可执行调用”。
因此 `04A` 不是重做 Pomodoro,也不是继续扩展 Host 工作区,而是补齐 **Agent / Adapter 这一半链路**,让用户能在真实会话中:
- 通过自然语言启动 / 中断 Pomodoro
- 通过标准交互完成 Hermes 需要的确认、澄清与审批;
- 全程只暴露 LineUp 自己定义的协议,不把 Hermes 私有 system message 直接暴露到产品面。
本次会话已将 `04A` 的工作收敛为 **以 Adapter 为主、附带最小 Runtime 请求兼容补丁的两个核心目标**
1. **MiniApp Tool 通路补齐**
- 让 Hermes Adapter 正确消费 Runtime 发布的 Agent Tool inventory
- 让 Agent 能生成合法的统一 Agent Tool invoke 请求;
- 让 Runtime 接受 `lineup.v1.tool.invoke` 这一新的请求入口,并继续基于 `inventory_revision`、schema、scope 与 lifecycle 执行 `pomodoro.start` / `pomodoro.interrupt`
2. **Hermes 交互兼容层补齐**
- 让 Hermes 内置的 approval / clarify / update prompt 等交互意图,不再依赖 Hermes 私有 permission request
- 让它们被 Adapter 收敛为 LineUp 已定义的 `tool.call` / `tool.result` / `app.call` / `app.result`
- 让用户的选择通过 LineUp 自己的可靠消息链路回传给 Hermes Adapter,再 resolve 回 Hermes 内部状态。
为便于后续评审与实施,本文按以下层次展开:
1. 先冻结 `04A` 的架构边界与分层原则;
2. 再分别定义目标 A 与目标 B 的当前缺口、协议结论与责任分界;
3. 最后给出范围、完成标准与交付物。
## 2. 架构边界与分层原则
本迭代后续的设计评审、技术规范与实现,都以以下分层原则为准。
### 2.1 Runtime 仍是执行权威
- `04.runtime_workspace` 已冻结的 `inventory revision``app_scope`、schema、lifecycle 与 Pomodoro 裁决语义继续作为权威;
- `04A` 不重新定义 `pomodoro.start` / `pomodoro.interrupt` 的运行规则;
- Adapter 不复制 Runtime 的业务状态机,只负责把 Agent 侧输入收敛到 Runtime 可接受的协议边界;
- 但为让 `lineup.v1.tool.invoke` 真正打通,本轮允许对 Runtime 做**最小请求兼容补丁**:只补 parser / router / 测试夹具对新请求信封的接受能力,不重写 `04.runtime_workspace` 已冻结的 Tool 执行、持久化或结果语义。
### 2.2 Agent 平台私有协议兼容责任位于 Adapter 层
- Hermes、未来的 Open Claw 或其他 Agent 平台,可能各自带有不同的 system message、approval 流程或工具调用约定;
- 这些差异属于“具体 Agent 平台如何适配 LineUp 协议”的问题,应在对应平台的插件 / Adapter 层完成收敛;
- Runtime 只接收已经进入 LineUp 协议边界的受控消息,不承担理解各家 Agent 私有协议的责任。
这一原则与 Hermes 既有飞书接入经验一致:
- 飞书 approval 不是让模型自己产出飞书协议;
- 而是 Hermes gateway / Feishu adapter 把内部 approval 事件转换成飞书 interactive card
- 再把按钮回调解析为 Hermes 内部 approval 结果。
`04A` 对飞书的借鉴,是 **adapter 负责转换与 resolve 的分层模式**,不是 webhook 或卡片 schema 本身。
### 2.3 LineUp 内部不依赖公网 webhook 回传
- LineUp 当前不是一个可被公网平台回调的 Bot 平台;
- 因此 04A 不设计 “平台回调 URL -> Adapter 收到 HTTP webhook” 这一链路;
- 用户选择应走现有 IM 长连接 / 消息同步链路回传。
对于 LineUp 内部交互,统一采用如下闭环:
```text
Adapter 发起受控协议
-> Host / Interact 渲染
-> 用户选择
-> Host 通过 tool.result / tool.cancel / app.result 回写
-> Adapter 消费结果并 resolve 回 Hermes 内部状态
```
### 2.4 `lineup-app-server` 在本轮默认视为透明传输层
- 当前 `lineup-app-server` Go 服务主要负责消息收发、base64 编解码与 WuKongIM API 对接;
- 它不解析 `lineup.v1` 的业务语义;
- 因此 04A 默认不要求改动 `lineup-app-server` 服务端来适配 Agent Tool invoke 或 Tool inventory 投影。
### 2.5 Runtime 仅补“请求侧兼容”,不在本轮改写回程协议
- `04.runtime_workspace` 已冻结并已验收的 Runtime 代码,当前仍保留一套面向 MiniApp Tool 的兼容回程 envelope
- `04A` 当前要解决的是“Agent 如何以统一入口发起 Runtime Agent Tool 调用”,因此本轮只要求 Runtime 接受 `lineup.v1.tool.invoke` 请求;
- 对于回程,Adapter 必须继续兼容 Runtime 现有的 receipts / progress / final result 事实,并按同一 `call_id` 解释为同一条 Agent Tool 调用;
- 是否将现有回程 envelope 进一步统一为新的 `lineup.v1.tool.*` 族,不属于 `04A` 当前收敛范围,后续若要推进,必须单独立项并补设计评审。
### 2.6 正式方案中的“概念协议名”与当前 `lineup.v1.*` 信封兼容
- `02.正式方案` 中部分 Runtime 文档会用 `tool.invoke` / `tool.result` 这样的概念名描述统一 Agent Tool 模型;
- 但当前 Tauri / Runtime 兼容实现仍以 `lineup.v1.*` 作为真实线上信封,这是 [app_final_design.md](../../设计/02.正式方案/app_final_design.md) 已保留的兼容事实;
- 因此 `04A` 在 Adapter 侧的实际落地继续采用 `lineup.v1.tool.invoke`,其语义对齐正式方案中的统一 Agent Tool invoke,而不是新增第二套协议;
- 本轮不得在代码或验收中同时引入“裸 `tool.invoke`”与 `lineup.v1.tool.invoke` 两条并行通路。
## 3. 目标 AMiniApp Tool 通路补齐
### 3.1 当前缺口
当前与目标 A 直接相关的缺口如下。
1. **Hermes inventory 解析模型落后于 Runtime**
- 正式方案要求 Runtime Inventory 同时包含 App、Tool、Surface 与 Capability
- `04.runtime_workspace` 的具体实现也已明确 Tool 由 Registry 独立投影进入 Runtime Tool Registry / Agent Inventory
- 但 Hermes Adapter 仍主要按旧的 App / Surface 结构理解 `client.inventory`,无法稳定消费 Runtime 发布的 Tool 投影。
2. **Hermes 协议白名单缺少统一 Agent Tool invoke**
- 当前 Hermes 允许的结构主要是:
- `lineup.v1.tool.call`
- `lineup.v1.app.call`
- `lineup.v1.ui.open / patch / close`
- `lineup.v1.artifact.offer`
- 还没有面向 Runtime Agent Tool 的统一 invoke 输出路径。
3. **Prompt 与测试尚未把 MiniApp Tool 变成可规划对象**
- 当前 prompt 只约束 capability request,不指导模型基于 Runtime 发布的 Tool Inventory 生成
`pomodoro.start` / `pomodoro.interrupt`
- Adapter 测试也没有覆盖 “inventory -> tool.invoke -> revision-bound invoke” 这条链路。
### 3.2 目标说明
让 Hermes Adapter 真正具备以下能力:
- 读取由 Runtime 发布的最新 Tool Inventory
- 识别哪些 MiniApp Tool 当前可调用;
- 在用户自然语言触发时生成合法的统一 Agent Tool invoke 请求;
- 携带正确的 `inventory_revision``app_scope``tool_id` 与受 schema 约束的 `input`
- 由 Runtime 正确执行并回传进度 / 最终结果。
首个验收对象固定为 Pomodoro:
```text
“开始一个 5 分钟的专注”
-> Hermes 生成 pomodoro.start
-> Runtime 创建并启动 Pomodoro
-> 用户看到前台专注工作区
“停止当前专注”
-> Hermes 生成 pomodoro.interrupt
-> Runtime 中断当前 Pomodoro
-> 用户回到 Interact 并收到稳定结果
```
### 3.3 协议冻结
本轮不再为 MiniApp Tool 新增第二套独立协议,而是沿用正式方案的统一 Agent Tool 调用模型:
- `app.call` 继续只表示 Host capability 请求;
- Runtime Agent Tool 统一走 `lineup.v1.tool.invoke`
- 旧的 `lineup.v1.tool.call(choice | confirm | input)` 继续保留为 Interact 标准交互兼容入口,不承担 Runtime Agent Tool invoke 语义;
- `tool.invoke` 在本轮只统一**请求入口**;其回程继续复用 `04.runtime_workspace` 已冻结且当前 Runtime 仍在发送的 Agent Tool 回程事实,并始终以同一个 `call_id` 关联。
建议冻结的最小 payload 形态如下:
```json
{
"v": 1,
"type": "lineup.v1.tool.invoke",
"payload": {
"call_id": "call_...",
"inventory_revision": "inv_...",
"app_scope": "pomodoro",
"tool_id": "pomodoro.start",
"input": {
"duration_seconds": 300,
"activity": "冥想"
}
}
}
```
也就是说,对 `lineup.v1.tool.invoke`
- Runtime 仍可先回传 `accepted / starting` 一类协议回执;
- 在启动成功后继续回传 `started` 或其他已冻结的受控进度;
- 最终仍只回传一次符合该 Tool result schema 的业务结果;
- Hermes Adapter 需要把这些回程继续视作“同一条 Agent Tool 调用的 receipts / progress / final result”;
- 本轮不要求 Runtime 把既有 MiniApp Tool 回程 envelope 全量改名;Adapter 只是不再新增第三套协议分支。
### 3.4 Inventory 最小投影
Hermes 侧只保留用于规划与出站校验的最小 Tool 投影。
该投影在 Inventory 中应独立于 `applications` 发布;`applications` 继续只表达 App / Surface 可见性。
每个工具至少保留以下字段:
- `app_scope`
- `tool_id`
- `description`
- `input_schema`
- `handling`
- `delivery`
- `activation_requirement`
这里的权威来源依次是:
- `02.正式方案` 中 Runtime / Tool / Inventory 的正式边界;
- `04.runtime_workspace` 已冻结的 Runtime Tool Registry / Agent Inventory 落地;
- `lineup-ui-surface-protocol.md` 中较早的 `client.inventory` 示例只能视为 Surface / Capability 最小示意,不再作为 Tool 投影 shape 的权威。
以下内容不进入 Hermes prompt 或 Adapter 持久上下文:
- `output_schema`
- 内部 handler
- bundle / path / secret
- 宿主实现细节
### 3.5 Adapter 与 Runtime 的责任分界
Adapter 负责:
- 仅接受当前 conversation 最近一次有效 inventory 中存在的 MiniApp Tool
- 校验 `call_id / inventory_revision / app_scope / tool_id / input` 顶层结构;
- 拒绝模型伪造 `sender / target / instance_id / operation_id / app_session_id` 等字段;
- 把合法 `tool.invoke` 原样交给 Runtime。
Runtime 继续负责:
- 最新 revision 对账;
- schema 校验;
- lifecycle / activation / foreground_required / activation_not_required 语义;
- 幂等、持久化、进度与最终结果。
本轮 Runtime 额外需要补上的,只是让上述执行链路接受 `lineup.v1.tool.invoke` 这一请求入口;它不是一项新的业务责任。
## 4. 目标 BHermes 交互兼容层补齐
### 4.1 当前缺口
当前与目标 B 直接相关的缺口如下。
1. **Hermes 内置 permission / system message 尚未收敛到 LineUp 协议**
- 当前 ACP 通道会向 Adapter 发出 `session/request_permission` 一类 Hermes 内置请求;
- 现有 Adapter 为避免越权,直接返回 `cancelled`
- 用户无法稳定完成这类交互,也没有一个明确的产品化协议边界。
2. **Hermes 的通用 interactive contract 尚未在 LineUp 中落位**
- Hermes 现有平台适配已稳定使用若干通用交互语义:
- `exec_approval`
- `slash_confirm`
- `clarify`
- `update_prompt`
- 但 LineUp 侧还没有把它们统一映射到 `choice / confirm / input / app.call`
### 4.2 目标说明
让 Hermes 内置的确认、澄清与审批意图不再依赖 ACP 私有 permission prompt,而是通过 LineUp 已定义协议完成:
- 标准交互:`lineup.v1.tool.call`
- 标准交互结果:`lineup.v1.tool.result` / `lineup.v1.tool.cancel`
- 宿主能力调用:`lineup.v1.app.call`
- 宿主能力结果:`lineup.v1.app.result`
### 4.3 本轮一次性实现的兼容层上限
参考 Hermes 现有 Feishu / Relay / Telegram / Slack / WhatsApp 适配实现,本轮一次性抽象的“通用交互语义层”限定为四类:
1. `exec_approval`
2. `slash_confirm`
3. `clarify`
4. `update_prompt`
其中 `clarify``04A` 的兼容范围进一步冻结为:
- 单选 `choice`
- 单选后进入 `other -> input` 的二段式澄清
- 纯文本输入型澄清
当前不进入本轮兼容范围的 `clarify` 变体:
- `multi_select = true`
- 任意要求 Host 原生复选组件或一次回收多值的私有交互
不在本轮一起实现的内容:
- 平台特有卡片样式、按钮布局、reaction ack、thread 元数据;
- 任意 Hermes 私有 system message 的泛化透传;
- Runtime 侧对 Hermes 私有 prompt kind 的直接理解。
### 4.4 Hermes -> LineUp 映射表
| Hermes contract | 典型语义 | LineUp 发起协议 | 用户可见交互 | 用户回传协议 | Adapter resolve 目标 |
|---|---|---|---|---|---|
| `exec_approval` | 危险操作审批;典型选项 `once / session / always / deny` | `lineup.v1.tool.call` | `choice` | `lineup.v1.tool.result` / `lineup.v1.tool.cancel` | Hermes 内部 approval 结果:`once` / `session` / `always` / `deny` |
| `slash_confirm` | slash command 或系统级动作确认;典型选项 `once / always / cancel` | `lineup.v1.tool.call` | `choice`,必要时可退化为 `confirm` | `lineup.v1.tool.result` / `lineup.v1.tool.cancel` | Hermes 内部 slash-confirm / confirm resolve |
| `clarify` | 多项澄清选择;可包含 `other` | `lineup.v1.tool.call` | 首轮 `choice`;若选 `other`,再发 `input` | `lineup.v1.tool.result` / `lineup.v1.tool.cancel` | Hermes 内部 clarify resolve`other` 分支进入后续文本 / 输入回填 |
| `update_prompt` | 更新、重载、恢复等 `y / n` 询问 | `lineup.v1.tool.call` | `confirm` | `lineup.v1.tool.result` / `lineup.v1.tool.cancel` | Hermes 内部 update prompt resolve |
| Host capability approval | 打开链接、写剪贴板、选文件、保存 artifact 等宿主能力授权 | `lineup.v1.app.call` | Host 原生确认界面 / 受控授权组件 | `lineup.v1.app.result` | Hermes capability result / approval result |
### 4.5 交互兼容层冻结规则
- `exec_approval``slash_confirm``clarify``update_prompt` 都属于 Adapter 层把 Hermes 交互语义收口到 LineUp 标准协议的范畴;
- 这四类 contract 在 Runtime 看来都只是 LineUp 的标准交互或 capability 调用,不暴露 Hermes 私有 prompt kind
- `choice` 的 option id 必须由 Adapter 生成并受控映射,不能直接把 Hermes 或平台侧的任意 callback token 透传给 Host
- `clarify``other` 路径由 Adapter 显式驱动第二次 `input`,而不是要求 Runtime 理解 Hermes 的“等待自由文本”内部状态;
- Hermes `clarify` 若携带 `multi_select = true`,本轮必须稳定拒绝并返回受控 unsupported / not_supported 结果,不能静默降级成单选或自由文本;
- Host 对单选卡片回传唯一的 `action_id` 时,Adapter 必须将其严格规范化为内部的单元素 `action_ids`,再映射回 Hermes;未知、缺失、重复或多于一个选项仍必须拒绝;
- 若某个 Hermes 私有请求不能落在上表任一项中,则本轮默认稳定拒绝,而不是新增第五种临时协议。
### 4.6 当前接入路径下的验证边界
截至 2026-08-07,本轮真实联调采用的是 LineUp 1420 页面 + `hermes acp` 的接入路径。
在这条路径上,`exec_approval``clarify` 已有可重复的运行期事件源,因此完成了 fresh evidence;但 `slash_confirm``update_prompt` 的原生触发源仍主要位于 Hermes gateway / native platform adapter 路径,而不是当前 ACP server request 流。
因此本轮对这两类 contract 的结论冻结为:
- **设计上保留映射目标**:它们继续属于 Adapter 兼容层应该承接的通用 contract;
- **实现上不放到 Runtime / app-server**:不能为了补证据把 Hermes 私有语义下沉到 Runtime 或 `lineup-app-server`
- **验收上不继续做 1420 盲测**:若当前 ACP 路径没有稳定 trigger source,则记录为结构性证据限制,而不是把它当成 04A 尚未修复的代码缺陷;
- **后续若要补 fresh evidence**:需要单独增加 bridge / trigger path,或引入可控的 gateway-native 事件源再复验。
## 5. 本迭代范围
### 5.1 范围内
1. **扩展 Hermes inventory 解析**
- 接受独立的 Tool inventory 投影;
- 为每个工具保留最小声明信息;
- 收到包含 Tool 投影的有效 inventory 后,不再退回 `revision = none`
2. **补齐统一 Agent Tool invoke**
- 为 Hermes Adapter 增加受控 Agent Tool 输出通路;
- 完成顶层结构校验与 inventory 绑定;
- 禁止伪造 Runtime 内部目标字段。
3. **补全 prompt 约束**
- inventory 中的 MiniApp Tool 才可调用;
- 必须使用最新 revision
- capability 与 MiniApp Tool 是不同通路;
- `pomodoro.start` / `pomodoro.interrupt` 的输入形态与边界明确;
- 不得依赖 Hermes / ACP 私有 permission prompt 或 system message 完成用户授权。
4. **补全 Hermes 交互兼容层**
-`exec_approval``slash_confirm``clarify``update_prompt` 映射到 LineUp 协议;
- 让用户选择通过既有消息流回传,再由 Adapter resolve 回 Hermes
- 明确 `clarify` 当前只兼容单选 / `other -> input` / 纯文本,`multi_select` 稳定拒绝;
- 对当前协议无法安全表达的 Hermes 私有请求,稳定拒绝。
5. **补全联调测试与真实证据**
- inventory 解析测试;
- `tool.invoke` 规范化测试;
- prompt / adapter 输出约束测试;
- Runtime 对 `lineup.v1.tool.invoke` 的 parser / router 兼容测试;
- Hermes 内置 permission request 处置测试;
- approval / clarify / confirm 回传闭环测试;
- Pomodoro 开始 / 停止两条真实链路 fresh evidence。
-`slash_confirm` / `update_prompt`,若当前接入路径无稳定触发源,则必须输出结构性限制记录,而不是继续把它们列为“待盲测补证据”。
6. **补充文档与验收口径**
- 明确 `04A``04.runtime_workspace` 的关系;
- 明确 Adapter 校验边界,避免与 Runtime 的 schema / lifecycle 责任重复;
- 明确“Agent 平台私有协议的兼容责任位于各自 Adapter 层”的架构结论。
### 5.2 不在范围内
- 新的 MiniApp 业务功能;
- 应用市场、远程下载和签名安装链路;
- 多 Agent、语音或视频能力;
- Pomodoro 统计、历史分析、暂停 / 继续;
- 改写 `04.runtime_workspace` 的 Runtime 生命周期语义;
- 为适配 Agent Tool invoke 改造 `lineup-app-server` Go 服务端;
- 在本轮内把 Runtime 既有 MiniApp Tool 回程 envelope 全量重构为新的协议族;
- 为 Web Chat 参考前端增加新的协议可视化,除非后续验收证据明确要求;
- 在 Runtime 中增加面向 Hermes、Open Claw 等具体 Agent 平台的私有协议特判。
## 6. 完成标准
满足以下条件时,`04A` 可视为完成:
```text
Hermes Adapter 能正确解析包含独立 Tool 投影的 Runtime inventory
Hermes 不再把这类 inventory 退回 revision=none 的默认上下文;
模型在用户请求开始/停止专注时,可以合法产出统一 Agent Tool invoke 请求;
Adapter 能基于当前 conversation 的最新 inventory 校验并规范化 tool.invoke,再交给 Runtime
Runtime 能基于最新 inventory revision 执行 pomodoro.start / pomodoro.interrupt
Runtime 已接受 `lineup.v1.tool.invoke` 作为新的请求入口;
tool.invoke 的协议回执、进度与最终业务结果继续复用既有 Agent Tool 回程语义;本轮不再新增第三套协议分支,也不要求立即重构 Runtime 既有回程 envelope
Hermes 不再依赖 ACP 私有 permission/system message 作为 LineUp 产品中的主授权路径;
当前可由 LineUp 协议表达的 Hermes 交互意图,已明确收敛到 tool.call / app.call / tool.invoke 之一;
Hermes clarify 的单选、`other -> input` 与纯文本路径可稳定闭环;`multi_select` 请求会被稳定拒绝,不发生静默降级;
当前不可安全表达的 ACP permission request,会被稳定拒绝且不会形成隐式授权;
若 `slash_confirm` / `update_prompt` 在当前 ACP 接入路径下缺少安全、稳定、可重复的触发源,则需有明确的结构性限制记录与后续 bridge 承接建议,不能再被当作未修复代码缺陷挂起;
真实用户语言 -> Agent tool invoke -> Runtime -> Pomodoro 的“开始专注”和“停止专注”两条链路都至少完成一条 fresh evidence
现有 standard interaction、app.call、ui.* 和 artifact.offer 路径不回归;
所有新增 P0P3 评审问题清零。
```
## 7. 建议交付物
建议至少产生以下文档与实现产物:
```text
迭代/04A.agent_tool_route/
04A.agent_tool_route.md
01.design_review.md
02.technical_implementation_spec.md
03.acceptance_review.md
```
以及代码层面的对应修改:
```text
lineup-adapter/hermes/lineup/protocol.py
lineup-adapter/hermes/lineup/core.py
lineup-adapter/hermes/lineup/acp_client.py
lineup-adapter/hermes/lineup/tests/
lineup-app/tauri/(用于最小 Runtime 请求兼容补丁与对应测试)
```
## 8. 当前结论
`04.runtime_workspace` 没有失败,它已经完成了 Runtime / Host / Pomodoro 这一侧的设计与实现闭环。
`04A.agent_tool_route` 的任务是把这一闭环真正接到 Agent / Adapter 入口上,并把 Hermes 的必要交互收敛到
LineUp 自己定义的协议里,使用户能够通过自然语言稳定使用已实现的 Pomodoro Tool。
@@ -0,0 +1,498 @@
# 04A.agent_tool_route 验收评审(五)
**状态:** 已完成本轮联合验收,A04A-09 / A04A-10 / A04A-11 已通过 fresh runtime 验证;`slash_confirm` / `update_prompt` 已转为当前 ACP 接入路径下的结构性证据限制记录
**日期:** 2026-08-07
**评审对象:** `lineup-adapter/hermes/lineup/` 当前实现、[04A.agent_tool_route.md](04A.agent_tool_route.md)、[02.technical_implementation_spec.md](02.technical_implementation_spec.md)、实际 LineUp Host / Hermes Adapter 运行状态
**评审方法:** 将自动化测试与真实消息链路证据交叉核对;本轮重点复核 Hermes `session/request_permission` 投影后的单选结果是否与 Host 实际发送的 `lineup.v1.tool.result` 形状一致。
**总体结论:** 已发现并修复三个会破坏 04A 交互边界的 P2 缺陷。权限卡片闭环、`clarify other -> input`、纯文本 `clarify``multi_select` 稳定拒绝,以及至少一种范围外稳定拒绝的 fresh evidence 均已通过。结合 `02.正式方案``04.runtime_workspace` 与当前实际接入实现复核后,可以确认 `slash_confirm``update_prompt` 在本轮 1420 + `hermes acp` 接入路径下缺少安全、稳定、可重复的运行期触发源;它们当前不应继续按“未修复缺陷”处理,而应作为后续 bridge / trigger 能力的小迭代承接项记录。
## 问题清单(Outline
状态标记:🔴 未解决,必须处理;🟡 已修复但等待运行期确认;✅ 已解决;⚪ 可延期但必须保留记录。
| 状态 | 优先级 | 编号 | 问题 | 当前结论 / 下一步 |
|---|---:|---|---|---|
| ✅ | P2 | A04A-09 | Host 单选卡片实际回传 `result.action_id`Adapter 只接受 `result.action_ids[]`,导致用户点击允许后结果被拒绝,Hermes 交互保持 pending 并最终超时。 | 已在 `protocol.py` 增加严格单选规范化;真实 Host 验证通过,交互 `call_b9c089f04ec44e19bbffca63ddc66c17``resolved`Hermes 已收到 `allow_once`,目标文件已创建。 |
| ✅ | P2 | A04A-10 | `clarify other -> input` 的第二段输入卡片真实回传 `result.text`Adapter 只接受 `result.values.{field_id}`,导致用户提交后卡片失效但 Hermes 未被解除阻塞。 | 已在 `protocol.py` 增加单字段输入 `text -> values.{field_id}` 严格规范化;新的 1420 页面 fresh 复验已通过,`call_input_task_01``completed`Hermes 已确认收到 `验收 04A other-input`。 |
| ✅ | P2 | A04A-11 | 04A 要求 `clarify multi_select = true` 稳定拒绝,但 Hermes 主回复提示词和 `tool.call` 校验仍允许模型直接发出 `multi-choice` 卡片,导致多选请求被错误放行。 | 已移除 Adapter 出站层对 `multi-choice` 的接受并更新回归测试;新的 1420 页面 fresh 复验已确认“不再出现多选卡片”,Hermes 改为明确提示“LineUp 卡片只支持单选,不支持多选”。 |
## 1. 真实失败证据
测试请求为:
```text
请在 /tmp/lineup-permission-test.txt 写入一行内容:LineUp permission test
```
真实记录:
- 用户请求消息序号:`1267`
- Adapter 创建权限交互:`call_72f3571755a94aff909d40db4ef53936`
- 交互类型:`exec_approval`
- 选项映射:`action_01 -> allow_once``action_02 -> deny`
- 用户点击后的消息序号:`1270`
- Host 实际回传:
```json
{
"call_id": "call_72f3571755a94aff909d40db4ef53936",
"status": "completed",
"result": {
"action_id": "action_01"
}
}
```
修复前该消息被记录为 `invalid hermes interaction response``tool_audit`
`result / rejected`,交互仍为 `pending`,目标文件不存在,原始 Hermes 请求最终为
`Hermes ACP response timeout`。旧交互在 Adapter 重启恢复时已被正确标记为
`aborted`,不能继续重复操作。
## 2. 修复与自动化证据
修复内容:
- `validate_tool_response()``mode = single-choice` 且不存在 `action_ids` 时接受唯一字符串 `action_id`
- 统一规范化为内部 `action_ids = [action_id]`
- 保留 inventory/schema 边界,未知、缺失、非字符串、多选及重复选项继续拒绝;
- Hermes resolve 继续只消费规范化后的内部形状,因此不新增第二套 resolve 分支。
自动化证据:
```bash
PYTHONPATH=lineup-adapter/hermes python3 -m unittest \
lineup-adapter/hermes/lineup/tests/test_protocol.py \
lineup-adapter/hermes/lineup/tests/test_core.py \
lineup-adapter/hermes/lineup/tests/test_acp_client.py \
lineup-adapter/hermes/lineup/tests/test_state.py
```
结果:
```text
Ran 38 tests
OK
```
`git -C lineup-app diff --check` 已通过。修复后的插件已经安装到运行目录
`/home/gao/.hermes/plugins/lineup/`,当前 Adapter PID 为 `3895319`
## 3. 待完成的 fresh 验证
需要重新发起一次低风险 `/tmp` 写入请求,并确认:
1. 新权限卡片可以交互;
2. 点击 `Allow edit` 后,`hermes_interactions.state` 变为 `resolved`
3. ACP responder 收到 `allow_once`
4. 原始 Hermes 请求最终完成,不再出现权限超时;
5. `/tmp/lineup-permission-test.txt` 被创建且内容正确;
6. 同一结果重复回传不会二次 resolve。
上述 fresh evidence 已取得,`A04A-09` 已关闭;04A 整体仍保持未完成,直到其他
强制验收项补齐。
## 4. A04A-09 Fresh Runtime Evidence2026-08-07
修复后的 Adapter 重启为 PID `3895319`。用户重新发起同一低风险写入请求并点击
新权限卡片的 `Allow edit` 后,取得以下证据:
- 新的 `exec_approval` call`call_b9c089f04ec44e19bbffca63ddc66c17`
- `hermes_interactions.state = resolved`
- 对应 `tool_calls.state = completed`
- `tool_audit``result` disposition 为 `accepted`
- Hermes ACP 实际完成了 `write_file`,工具消息记录 `bytes_written = 22`
- Hermes 随后返回完成文本;
- `/tmp/lineup-permission-test.txt` 已创建,文件大小 `22` 字节,内容为:
```text
LineUp permission test
```
这证明真实 Host 的单选 `action_id` 回传已经被 Adapter 规范化并 resolve 回
Hermes,且没有再次出现 `Hermes ACP response timeout`
## 5. 当前验收结论
- `clarify` 单选、`other -> input`、纯文本输入、`multi_select` 稳定拒绝与至少一种范围外稳定拒绝均已具备 fresh evidence
- 当前自动化门禁:Adapter `39 tests`、Runtime 定向测试 `71 tests`、Tauri `tsc --noEmit + Vite build``git -C lineup-app diff --check` 均通过;
- 本轮已发现的 P0-P3 缺陷均已关闭;
- `slash_confirm``update_prompt` 不再作为 04A 当前实现的阻塞项,原因见第 13 节“当前 ACP 接入路径下的结构性证据限制”。
## 6. Clarify Single-Choice Fresh Runtime Evidence2026-08-07
Adapter 重启后,用户在 1420 页面实际发送:
```text
请先让我从“专注工作”和“休息”两个选项中选择一个,再继续后续操作。
```
Hermes 生成了真实标准交互:
- `call_id = call_8f3a2c91d4e6b7a0`
- `tool = choice`
- `mode = single-choice`
- `action_ids = ["focus", "rest"]`
- Host 回传消息序号:`1287`
- 实际回传 `result.action_id = "focus"`
- Adapter `tool_audit``call / accepted``result / accepted`
- 对应 `tool_calls.state = completed`
- Hermes 最终回复已明确收到“专注工作”选择。
这证明真实 Hermes -> LineUp `tool.call`、用户选择 -> `tool.result`
Adapter ledger -> Hermes resolve 的单选路径已闭环,并再次验证 Host 的
`action_id` 形状兼容。
同一次会话的 Hermes 回复指出当前 inventory 为 `revision:none`。这是因为 Adapter
重启后 Host 尚未重新下发新的 `client.inventory`,不属于 clarify 交互失败;但在
继续验证 `pomodoro.start` 之前,必须先刷新 1420 Host 或让 Host 重新发布 inventory。
## 7. A04A-10 Real Runtime Failure And Fix Pending Fresh Recheck2026-08-07
用户在 1420 页面实际发送:
```text
请先让我在“专注工作”和“其他”里选一个;如果我选“其他”,再让我输入具体要做的事情。
```
真实链路证据如下:
- 用户原始请求消息序号:`1304`
- 第一段 `choice` call`call_6e2f81a4c9d3b7`
- Host 单选回传消息序号:`1309`
- 第一段实际回传:
```json
{
"call_id": "call_6e2f81a4c9d3b7",
"status": "completed",
"result": {
"action_id": "other"
}
}
```
- Adapter 接受该结果后,发出第二段 `input` call`call_9c3d5e7f1a2b4c`
- 用户提交输入后的消息序号:`1315`
- 第二段实际回传:
```json
{
"call_id": "call_9c3d5e7f1a2b4c",
"status": "completed",
"result": {
"text": "验收 04A other-input"
}
}
```
失败时的 Adapter 账本状态:
- `tool_audit(call_6e2f81a4c9d3b7)``call / accepted``result / accepted`
- `tool_audit(call_9c3d5e7f1a2b4c)``call / accepted``result / rejected`
- `tool_calls(call_9c3d5e7f1a2b4c).state = emitted`
- 用户侧实际观察为第二张输入卡片提交后变为不可交互,但 Hermes 未完成 `clarify` resolve。
这证明真实 Host 对单字段 `input` 的结果回传 shape 为 `result.text`,而 Adapter 先前只接受 `result.values.{field_id}`,因此属于会阻断 `clarify other -> input` 闭环的 P2 兼容缺陷。
修复内容:
- `validate_tool_response()``tool = input` 且 schema 只有一个字段时,接受唯一字符串 `result.text`
- 规范化为内部 `values.{field_id}` 后再走原有 schema 校验;
- 保持严格边界:多字段表单仍必须使用 `values`,非字符串 `text` 继续拒绝。
自动化证据:
```bash
PYTHONPATH=lineup-adapter/hermes python3 -m unittest \
lineup-adapter/hermes/lineup/tests/test_protocol.py \
lineup-adapter/hermes/lineup/tests/test_core.py \
lineup-adapter/hermes/lineup/tests/test_acp_client.py \
lineup-adapter/hermes/lineup/tests/test_state.py
```
结果:
```text
Ran 39 tests
OK
```
修复后的插件已重新安装到 `/home/gao/.hermes/plugins/lineup/`,并重启为新的
Adapter PID `3913413`
## 8. A04A-10 Fresh Runtime Evidence2026-08-07
修复后,用户在 1420 页面重新执行同一条两段式澄清请求:
```text
请先让我在“专注工作”和“其他”里选一个;如果我选“其他”,再让我输入具体要做的事情。
```
新的真实链路证据如下:
- 用户原始请求消息序号:`1316`
- 第一段 `choice` call`call_choice_focus_other`
- 第一段 Host 回传消息序号:`1321`
- 第一段实际回传:
```json
{
"call_id": "call_choice_focus_other",
"status": "completed",
"result": {
"action_id": "other"
}
}
```
- 第二段 `input` call`call_input_task_01`
- 第二段 Host 回传消息序号:`1327`
- 第二段实际回传:
```json
{
"call_id": "call_input_task_01",
"status": "completed",
"result": {
"text": "验收 04A other-input"
}
}
```
修复后的账本状态:
- `tool_calls(call_choice_focus_other).state = completed`
- `tool_calls(call_input_task_01).state = completed`
- Hermes 最终回复消息已明确确认:
- 选择:`其他`
- 输入:`验收 04A other-input`
- 结论:两段式交互已跑通。
用户侧同步观察为:提交后输入卡片变为不可交互,且 Hermes 立即返回确认文本。
这证明单字段 `input``result.text` 已被 Adapter 严格规范化并成功 resolve 回 Hermes`A04A-10` 可以关闭。
## 9. Clarify Pure-Text Fresh Runtime Evidence2026-08-07
本项先经过一次失败尝试,再取得 fresh 成功证据:
第一次用户发送:
```text
先不要给我选项,直接问我一句开放式问题,让我用文字回答今天要处理的事项。
```
Hermes 仅返回普通文本追问:
```text
今天有什么要处理的事项?直接打给我,我一件件帮你安排。
```
该次未进入标准输入交互,不能记为 `clarify` 纯文本兼容成功。
随后用户改为发送更强约束提示:
```text
在继续之前,请不要直接文本追问;请必须通过 LineUp 的标准输入交互发起一个 input 卡片,让我填写“今天要处理的事项”。
```
新的真实链路证据如下:
- 强约束提示消息序号:`1380`
- Hermes 发出的标准 `input` call`call_input_today_tasks`
- Host 回传消息序号:`1385`
- 实际回传:
```json
{
"call_id": "call_input_today_tasks",
"status": "completed",
"result": {
"text": "验收 04A pure-text clarify"
}
}
```
账本状态:
- `tool_calls(call_input_today_tasks).state = completed`
- `tool_audit(call_input_today_tasks)``call / accepted``result / accepted`
- Hermes 最终确认文本明确回显:
- 交互方式:`input` 卡片(标准输入交互)
- 填写内容:`验收 04A pure-text clarify`
- 结论:卡片流程跑通。
这证明在明确要求下,Hermes 纯文本 `clarify` 已可通过 Adapter 投影为
LineUp 标准 `input` 交互,并通过现有消息链路闭环 resolve。
## 10. A04A-11 Real Runtime Failure And Fix Pending Fresh Recheck2026-08-07
`04A.agent_tool_route.md``02.technical_implementation_spec.md` 已明确规定:
- Hermes `clarify multi_select = true` 本轮必须稳定拒绝;
- 不得静默降级成单选、普通文本,或直接放行为多选卡片。
但在真实运行中,用户发送:
```text
请先让我同时从“专注工作”“休息”“学习”里多选两个,再继续后续操作。
```
取得如下失败证据:
- 用户请求消息序号:`1391`
- Hermes 最终实际发出的标准交互:
```json
{
"v": 1,
"type": "lineup.v1.tool.call",
"payload": {
"call_id": "call_choice_multi_02",
"tool": "choice",
"title": "选择两项",
"prompt": "请从以下选项中选择两项",
"expires_at": "2026-08-07T05:15:00Z",
"data": {
"action_group": {
"mode": "multi-choice",
"actions": [
{"id": "focus", "label": "专注工作"},
{"id": "rest", "label": "休息"},
{"id": "study", "label": "学习"}
]
}
}
}
}
```
- Adapter 账本记录:
- `tool_calls(call_choice_multi_02).state = emitted`
- `response_schema.mode = multi-choice`
- 用户侧实际观察为:1420 页面出现了多选提示卡。
这证明问题并不在 ACP clarify 投影层,而在 Hermes 主回复通路本身:
Adapter 的主提示词仍显式允许 `multi-choice``validate_tool_call_payload()` 也仍接受
`mode = multi-choice`,因此模型可以绕过“Hermes clarify 多选必须拒绝”的设计结论,
直接生成一张多选卡片。
修复内容:
- 从 Adapter `tool.call` 出站校验中移除 `multi-choice` 允许集;
- 更新 Hermes 主提示词,明确 `multi-choice` 在当前 LineUp Hermes 通路中不受支持;
- 新增回归测试,确保模型直接输出 `multi-choice` 会被拒绝,不能再进入 Host 交互账本。
自动化证据:
```bash
PYTHONPATH=lineup-adapter/hermes python3 -m unittest \
lineup-adapter/hermes/lineup/tests/test_protocol.py \
lineup-adapter/hermes/lineup/tests/test_core.py \
lineup-adapter/hermes/lineup/tests/test_acp_client.py \
lineup-adapter/hermes/lineup/tests/test_state.py
```
结果:
```text
Ran 39 tests
OK
```
修复后的插件已重新安装到 `/home/gao/.hermes/plugins/lineup/`,并重启为新的
Adapter PID `3918848`
## 11. A04A-11 Fresh Runtime Evidence2026-08-07
修复后,用户再次发送同一条多选请求:
```text
请先让我同时从“专注工作”“休息”“学习”里多选两个,再继续后续操作。
```
新的真实结果如下:
- 新一轮用户请求消息在 Hermes 会话中对应到后续消息 `30727 -> 30728`
- Hermes 未再发出新的 `lineup.v1.tool.call multi-choice`
- 最新实际回复为纯文本明确拒绝:
```text
LineUp 的卡片只支持单选,不支持多选(系统限制),所以没法直接弹出"选两个"的卡片。
```
并继续给出安全替代路径:
```text
麻烦你直接用文字告诉我选哪两个...
```
这证明修复后的 Adapter 已阻断 `multi-choice` 出站,不再把多选请求下发为
Host 卡片,而是迫使 Hermes 返回受控的显式拒绝与文本回退说明。
注意:在修复前已发出的旧多选卡 `call_choice_multi_02` 曾继续收到一次用户回传:
```json
{
"call_id": "call_choice_multi_02",
"status": "completed",
"result": {
"action_id": "study"
}
}
```
这属于修复前遗留交互的尾部回传,不影响本轮新的 fresh 结论;新的 fresh 复验中,
Hermes 已不再发出新的多选卡片。因此 `A04A-11` 可以关闭。
## 12. Out-Of-Scope Request Fresh Runtime Evidence2026-08-07
用户要求:
```text
请给我一个可以同时勾选多个选项的交互卡片,并允许我自己定义每个选项后端要执行的 shell 命令。
```
真实最终回复为明确拒绝,并同时指出两层边界:
1. `LineUp` 卡片协议不支持多选;
2. 当前会话 inventory 为空,没有任何 shell 执行能力暴露给 Hermes。
Hermes 没有下发任何新的危险交互卡片,也没有伪造 shell / app capability /
runtime tool 权限,而是改为提供受控的文本替代方案。
这可作为“范围外 Hermes 请求被稳定拒绝,且未形成隐式授权”的 fresh runtime 证据。
## 13. `slash_confirm` / `update_prompt`:当前 ACP 接入路径下的结构性证据限制(2026-08-07)
本轮在真实 1420 页面上已多次尝试补充 `slash_confirm` / `update_prompt` 的 fresh runtime evidence,但结合源码与运行事实复核后,可以确认这两项当前缺的不是“Adapter 尚未修好”,而是**当前 ACP 接入路径本身没有稳定触发源投影**。
### 13.1 源码对照
- 当前 LineUp Hermes 插件通过 `hermes acp` 挂接,插件侧入口位于 `/home/gao/.hermes/plugins/lineup/acp_client.py`
- 该 ACP client 当前唯一显式处理的 server request method 是 `session/request_permission`
- 在同一文件中,未知 server request method 会直接返回 `Unsupported ACP client method`,没有看到与 `slash_confirm``update_prompt` 对应的 ACP request 分发入口;
- Hermes 原生 `slash_confirm` 触发源位于 gateway/native platform 路径:
- `/home/gao/.hermes/hermes-agent/gateway/run.py` 中的 `_request_slash_confirm(...)`
- `/home/gao/.hermes/hermes-agent/gateway/slash_commands.py` 中对 `_request_slash_confirm(...)` 的调用
- 其交互依赖平台 adapter 的 `send_slash_confirm(...)`,失败时退回 gateway 文本确认;
- Hermes 原生 `update_prompt` 触发源同样位于 gateway watcher / native platform 路径:
- `/home/gao/.hermes/hermes-agent/gateway/run.py` 中对 `.update_prompt.json` 的轮询
- 再调用平台 adapter 的 `send_update_prompt(...)`,或退回 gateway 文本提示。
这说明:当前 LineUp 1420 页面走的是 **ACP stdio 接入链路**,而不是 Hermes gateway 的原生平台 adapter 按钮链路。两者属于不同事件源。
### 13.2 运行期事实
- `/reload-mcp` 在当前会话里因 `~/.hermes/config.yaml``mcp_servers: {}` 被短路为普通文本说明,没有进入可复用的确认交互;
- `/model custom/deepseek-v4-pro` 在当前会话里也没有稳定进入 `slash_confirm`,而是走成了“编辑 `config.yaml`”的写入审批路径,用户看到的是 `edit config.yaml` 审批卡;
- 已通过的 fresh evidence 全部来自当前 ACP 路径可稳定发出的两类来源:
- `session/request_permission` -> `exec_approval`
- Adapter 主回复 / `tool.call` -> `clarify` / `input`
因此,继续在 1420 页面上重复盲测,并不能合理提高 `slash_confirm` / `update_prompt` 的证据覆盖率。
### 13.3 评审结论
- `04A` 当前实现已经证明:Adapter 层可以把可达的 Hermes 内置交互收敛到 LineUp 协议,并通过现有消息链路完成用户选择回传;
- `slash_confirm` / `update_prompt` 仍应保留在 04A 的目标模型与映射表中,作为 Adapter 兼容层未来要承接的 contract;
- 但在当前 `1420 + hermes acp` 接入方式下,它们缺少安全、稳定、可重复的运行期触发源,不再作为本轮关闭验收的阻塞条件;
- 若后续需要 fresh runtime evidence,必须新增单独的 bridge / trigger 路径,或在后续小迭代中引入可控的 gateway-native event source,再重新立项验收。