@@ -6,66 +6,62 @@
## 功能
注册一个工具 `todo_write(todos: [{ content, status }])` 到 `ctx.tools` 。模型每次调用都会发送完整列表,不存在部分更新或单项编辑。每次调用都会向调用 agent 的会话日志追加 `todo/write` 事件(完整列表快照),具体调用 `agent.session.append('todo/write', { todos })` ;当前列表是最新的该类事件(回放时后写覆盖先写 )。
注册一个工具 `todo_write(todos: [{ content, status }])` 到 `ctx.tools` 。模型每次调用都会发送完整列表,不存在部分更新或单项编辑。每次调用都会向调用 agent 的会话日志追加 `todo/write` 事件(完整列表快照),具体调用 `agent.session.append('todo/write', { todos })` ;当前列表是最新的该类事件(回放时后写者胜 )。
`status` 是 `pending` 、`in_progress` 或 `completed` 之一。
## 单一所有者
该列表属于调用工具的唯一 agent 会话。不存在 subagent/ 共享/ swarm scope: 非 agent 调用方(没有 `exec.agent` )无处写入列表,因此会被拒绝。这是有意设置的 scope 限制,详见 Agent Note( agent 决策记录) 。
该列表属于调用工具的唯一 agent 会话。不存在 subagent/ 共享/ swarm scope: 非 agent 调用方(没有 `exec.agent` )无处写入列表,因此会被拒绝。这是有意设置的 scope 限制,详见 Agent Note。
## 验证
除 schema 的类型/必填/枚举检查外,`execute` 还会拒绝空或重复的 `content` 、同时存在多个 `in_progress` 任务的情况(连贯计划最多只有一个活跃任务),以及 `content` /`status` 之外的任何条目键——扩展条目形状( id、嵌套) 会明确报错 而不是被静默压平,保证落日志的快照与模型自认为写入的内容一致。列表的顺序及及时更新 由模型依照 工具描述负责。
除 schema 的类型/必填/枚举检查外,`execute` 还会拒绝空或重复的 `content` 、同时存在多个 `in_progress` 任务的情况(连贯计划最多只有一个活跃任务),以及 `content` /`status` 之外的任何条目键——扩展条目形状( id、嵌套) 会响亮失败 而不是被静默压平,保证落日志的快照与模型自认为写入的内容一致。顺序与保持列表最新的纪律 由模型根据 工具描述负责。
## 渲染
<<<<<<< HEAD
规范结果为 `{ todos, counts: { pending, inProgress, completed } }` ;其 Native 渲染器返回精简的更新确认。工具还会写入完整 `todo/write` 会话事件。UI 订阅事件流,并自行渲染该持久化列表:[TUI 应用 ](../../examples/tui-demo )与 [web 客户端 ](../../client/ui-conversation )基于当前有效计划(其后没有更晚 `turn/start` 的最近一次 `todo/write` ) 显示计划条( web 另有专属工具行)([展示 ](../../../.agents/notes/implemented/feature/2026-07-23-web-todo-display.md )、[生命周期 ](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md ))。
=======
规范结果为 `{ todos, counts: { pending, inProgress, completed } }` ;其 Native 渲染器返回精简的更新确认。工具还会写入完整 `todo/write` 会话事件。UI 订阅事件流,并自行渲染该持久列表:[TUI 前端入口 ](../../ui/tui )与 [web 客户端 ](../../client/ui-conversation )基于站立计划(其后没有更晚 `turn/start` 的最近一次 `todo/write` ) 显示计划条( web 另有专属工具行)([展示 ](../../../.agents/notes/implemented/feature/2026-07-23-web-todo-display.md )、[生命周期 ](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md ))。
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)
## 会话投影
当组合挂载了 `ctx.sessionProjections` ( [`@deepseek-ai/dsh-session-projection` ](../../session-projection/session-projection/README.md ))时,本包在一个注入的 子插件中 注册 `todos` 投影单元:`init` = `null` (尚无写入)、`apply` = 从每个 `todo/write` 取整表,并在每个 `turn/start` 清为 `null` ( 当前有效 计划;`turn/end` 保留刚完成的清单;其余事件都返回同一个状态引用)、`view` = 恒等、`stateVersion` = 2。该键 在本包中 合并进 `SessionProjectionMap` (经接口包的 `/types` 出口);框架驱动该单元,载体通过 历史尾页与 `session/projection` 推送帧提供 该值。未挂载 注册表的组合不受影响。生命周期理由见 [在 下一轮次 清空 todo 计划 ](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md )。
当组合挂载了 `ctx.sessionProjections` ( [`@deepseek-ai/dsh-session-projection` ](../../session-projection/session-projection/README.md ))时,本包在一个注入式 子插件下 注册 `todos` 投影单元:`init` = `null` (尚无写入)、`apply` = 从每个 `todo/write` 取整表,并在每个 `turn/start` 清为 `null` ( 站立 计划;`turn/end` 保留刚完成的清单;其余事件都返回同一个状态引用)、`view` = 恒等、`stateVersion` = 2。key 在本包合并进 `SessionProjectionMap` (经接口包的 `/types` 出口);框架驱动该单元,载体在 历史尾页与 `session/projection` 推送帧上供给 该值。未装 注册表的组合不受影响。生命周期理由见 [下一轮清空 todo 计划条 ](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md )。
## 导出形状
函数/命名空间插件:导出 `name` /`inject` /`apply` ,不提供默认导出。意外的 `export default` 会被 Loader 的 `unwrapExports` 折叠为默认导出,并导致 `inject` 丢失 (参见 [docs/postmortem/0001 ](../../../docs/postmortem/0001-acp-default-export-drops-inject.md ))。
函数/命名空间插件:导出 `name` /`inject` /`apply` ,不提供默认导出。意外的 `export default` 会通过 Loader 的 `unwrapExports` 折叠模块并丢弃 `inject` (参见 [docs/postmortem/0001 ](../../../docs/postmortem/0001-acp-default-export-drops-inject.md ))。
## 模型体验
### 工具 schema
#### 模型看到的 内容
#### 模型所见 内容
模型会看到生成的 [`todo_write` schema ](../../../docs/tool-catalog.md#deepseek-aidsh-tool-todo )。
#### Token 影响
工具可见的每个请求都有固定的 schema token 开销 。
工具可见的每个请求都有固定 schema 成本 。
#### KV Cache 影响
只要定义和可见性不变,前缀就保持稳定。插件生命周期或 scope 限制可能会使从 此 schema 起的缓存 复用失效。
只要定义和可见性不变,前缀就保持稳定。插件生命周期或 scope 限制可能会使此 schema 之后的 复用失效。
### 工具调用历史与结果
#### 模型看到的 内容
#### 模型所见 内容
每个 assistant 工具调用都会在参数中保留整个替换列表。成功时原样 返回 `Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.` 。稳定失败文本为 ``Error: invalid todo: ` content` must be a non-empty string` `、` Error: invalid todos: duplicate content "<content>"`、` Error: invalid todos: at most one task may be in_progress, got <count>` 和 ` Error: todo_write requires an owning agent session`。完整 ` todo/write` 会话事件是 UI 与回放状态,而非第二条模型消息。
每个 assistant 工具调用都会在参数中保留整个替换列表。成功时精确 返回 `Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.` 。稳定失败文本为 ``Error: invalid todo: ` content` must be a non-empty string` `、` Error: invalid todos: duplicate content "<content>"`、` Error: invalid todos: at most one task may be in_progress, got <count>` 和 ` Error: todo_write requires an owning agent session`。完整 ` todo/write` 会话事件是 UI 与回放状态,而非第二条模型消息。
#### Token 影响
t oken 用量会随 模型每次提交的完整列表增长 , 且这些调用参数会保留到压缩( compaction) 。结果本身很小, 且形状固定。
T oken 增长与 模型每次提交的完整列表成比例 , 且这些调用参数会保留到压缩( compaction) 。结果本身很小, 且形状固定。
#### KV Cache 影响
仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV-cache 条目失效。
## 已知限制与暂缓事项
## 已知限制与延后工作
- **仅单一所有者 scope**:列表属于唯一调用 agent 会话; subagent/ 共享/ swarm scope 是有意设置的限制 (参见「单一所有者」一节),非 agent 调用方会被拒绝。
- **条 目形状有意保持最小**: ` content` 加三态 ` status`;整表替换不需要稳定 id、优先级或 active-form 字段。
- **仅单一所有者 scope**:列表属于唯一调用 agent 会话; subagent/ 共享/ swarm scope 是有意裁减 (参见「单一所有者」一节),非 agent 调用方会被拒绝。
- **项 目形状有意保持最小**: ` content` 加三态 ` status`;整表替换不需要稳定 id、优先级或 active-form 字段。
- **整表替换是唯一操作**:没有部分更新,也没有回读工具;模型每次调用都必须重新发送完整列表。