2.9 KiB
Agent Note: todo 事件类型归其生产方所有
Status: implemented
English | 中文
问题
SessionEventMap 可通过声明合并扩展,使每个插件都能添加持久记录,而无需让核心会话包依赖所有事件生产方。todo/write 及其 TodoItem payload 由 todo 领域生产和解释;核心会话只提供通用的追加、回放、surface 与不变量扩展机制。在核心中声明 todo 专属类型或关系,会让会话主干拥有一个它既不生产、也无法完整校验的插件词汇。
决策
@deepseek-ai/dsh-tool-todo 在其仅类型出口中声明 TodoItem,并通过 @deepseek-ai/dsh-session/types 的声明合并加入 todo/write。包根入口和 /client 入口重新导出 TodoItem,使 host 与浏览器消费方共享同一处声明,而无需加载 todo 插件。
检查 todo 记录的消费方使用仅类型导入,并声明显式包依赖与 TypeScript 项目引用。产出的 JavaScript 不含 todo 导入;组合仅为了搜索、传输或渲染可能含有 todo/write 的日志时,无需挂载 todo 工具。
todo 不变量配套插件同时拥有 payload 规则和事件必须位于开放轮次内的关系。核心会话的可合并扩展 switch 对 todo/write 走默认分支;todo 配套插件会在追加前拒绝格式错误或位于开放轮次之外的快照。它会单次校验现有会话与新发布的会话,并为后续事件推进逐会话的已提交轮次追踪状态。todo 专属的追加、回放、投影和轮次封闭测试与 todo 包放在一起。面向模型的行为仍由 todo_write 功能决策负责。
验证
聚焦的 todo 工具、不变量、投影、集成和 Loader 组合测试覆盖生产方及其配套插件。session-query 提取与客户端 runtime/connection 测试证明仅类型消费方仍能保留 todo 的语义处理。全工作区类型检查证明声明合并通过显式项目图生效;重新生成的事件、持久化、API 与模块目录记录声明位置和依赖边。
曾考虑的替代方案
- 把 payload 类型留在核心中作为共享 UI 词汇——拒绝:渲染复用并不会让核心成为持久事件的生产方或语义所有方。
- 让每个消费方各自按结构收窄
todo/write——拒绝:重复的 payload 声明会漂移,并绕过可合并扩展的事件表。 - 要求每个消费方都挂载 todo 插件——拒绝:读取持久记录是类型和数据依赖,并不构成安装面向模型工具的授权。
后果
核心会话包不导出 TodoItem,也不强制 todo 关系。命名或收窄 todo/write 的包声明对 dsh-tool-todo 的仅类型依赖;只把未知合并事件作通用处理的消费方无需依赖它。todo 包是事件 payload、客户端类型、运行时校验和开放轮次规则的唯一来源。