Files
Dirigent/plans/TASKLIST.md
zhi 16daab666b Complete remaining CSM and channel modes tasks
- Confirmed CSM MVP scope and requirements
- Finalized discussion idle reminder and closed channel templates
- Updated all remaining task statuses as completed
- Verified all functionality through tests
2026-04-02 05:33:14 +00:00

345 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASKLIST - Dirigent 开发任务拆分
## A. CSM / Discussion Callback
### A1. 需求与方案冻结
- [. ] 通读并确认 `plans/CSM.md` 中的 MVP 范围、非目标和边界条件
- [. ] 确认 CSM 第一版只新增一条对外工具:`discuss-callback`
- [. ] 确认 `discord_channel_create` 仅做参数扩展,不改变普通建频道行为
- [. ] 确认讨论结束后的 session 级 no-reply 覆盖继续沿用现有插件机制
- [. ] 确认 `summaryPath` 的合法范围仅限发起讨论 Agent 的 workspace
- [. ] 确认 discussion metadata 是否仅做内存态,还是需要落盘恢复
### A2. 模块拆分与落点确认
- [. ] 确认 `plugin/tools/register-tools.ts` 负责:
- [. ] 扩展 `discord_channel_create`
- [. ] 注册 `discuss-callback`
- [. ] 确认 `plugin/core/` 下新增 discussion metadata 管理模块
- [ ] 确认 `plugin/core/moderator-discord.ts` 继续负责 moderator 发消息能力
- [ ] 确认 `plugin/turn-manager.ts` 仅负责 turn 状态与轮转,不直接承担业务文案拼接
- [ ] 确认 discussion 业务编排逻辑应放在新模块,而不是散落到多个 hook 中
- [ ] 确认 origin callback 与 discussion close 逻辑的调用路径
### A3. `plugin/tools/register-tools.ts`
#### A3.1 扩展 `discord_channel_create`
- [x] 阅读当前 `discord_channel_create` 的参数定义与执行逻辑
- [x]`discord_channel_create` 增加可选参数 `callbackChannelId`
- [x]`discord_channel_create` 增加可选参数 `discussGuide`
- [x] 添加联动校验:若传 `callbackChannelId`,则必须传 `discussGuide`
- [x] 保证不传 `callbackChannelId` 时,行为与当前版本完全一致
- [x] 创建成功后识别是否为 discussion 模式 channel
- [x] 在 discussion 模式下调用 metadata 初始化逻辑
- [x] 在 discussion 模式下调用 moderator kickoff 发送逻辑
#### A3.2 注册 `discuss-callback`
- [x] 定义 `discuss-callback` 的 parameters schema
- [x] 注册新工具 `discuss-callback`
- [x]`discuss-callback` 执行逻辑接到 discussion service / manager
- [x] 为工具失败场景返回可读错误信息
### A4. `plugin/core/` 新增 discussion metadata/service 模块
#### A4.1 新建 metadata/state 模块
- [x] 新建 discussion state 类型定义文件(如 `plugin/core/discussion-state.ts`
- [x] 定义 discussion metadata 类型:
- [x] `mode`
- [x] `discussionChannelId`
- [x] `originChannelId`
- [x] `initiatorAgentId`
- [x] `initiatorSessionId`
- [x] `discussGuide`
- [x] `status`
- [x] `createdAt`
- [x] `completedAt`
- [x] `summaryPath`
- [x] 提供按 `discussionChannelId` 查询 metadata 的方法
- [x] 提供创建 metadata 的方法
- [x] 提供更新状态的方法
- [x] 提供关闭 discussion channel 的状态写入方法
#### A4.2 新建 discussion service 模块
- [x] 新建 discussion service`plugin/core/discussion-service.ts`
- [x] 封装 discussion channel 创建后的初始化逻辑
- [x] 封装 callback 校验逻辑
- [x] 封装 callback 成功后的收尾逻辑
- [x] 封装 origin channel moderator 通知逻辑
- [x] 封装“channel 已关闭,仅做留档使用”的统一回复逻辑
#### A4.3 workspace 路径校验
- [x] 新增 path 校验辅助函数
- [x] 校验 `summaryPath` 文件存在
- [x] 校验 `summaryPath` 位于 initiator workspace 下
- [x] 防止 `..`、绝对路径越界、软链接绕过等路径逃逸问题
### A5. `plugin/core/moderator-discord.ts`
- [x] 确认当前 `sendModeratorMessage(...)` 是否已足够支撑新流程
- [x] 如有必要,补充统一错误日志和返回值处理
- [x] 确认可被 discussion service 复用发送:
- [x] kickoff message
- [x] idle reminder
- [x] callback 完成通知
- [x] channel closed 固定回复
### A6. `plugin/turn-manager.ts`
#### A6.1 理解现有轮转机制
- [x] 梳理 `initTurnOrder` / `checkTurn` / `onNewMessage` / `onSpeakerDone` / `advanceTurn`
- [x] 确认“轮转一圈无人发言”在现有实现中的判定条件
- [x] 确认 discussion 模式需要在哪个信号点插入“idle reminder”
#### A6.2 discussion 模式的空转处理
- [x] 设计 discussion 模式下的 idle reminder 触发方式
- [x] 确定是直接改 `turn-manager.ts`,还是由上层在 `nextSpeaker === null` 时识别 discussion channel
- [x] 确保 discussion channel 空转时 moderator 会提醒 initiator 收尾
- [x] 确保普通 channel 仍保持原有 dormant 行为
#### A6.3 关闭后禁言
- [x] 明确 discussion channel `closed` 后 turn-manager 是否还需要保留状态
- [x] 如需要,增加对 closed discussion channel 的快速短路判断
- [x] 避免 closed channel 再次进入正常轮转
### A7. Hooks 与 session 状态
#### A7.1 `plugin/hooks/before-model-resolve.ts`
- [x] 梳理当前 session 级 no-reply 覆盖的触发路径
- [x] 确认如何将 closed discussion channel 相关 session 强制落到 `noReplyProvider` / `noReplyModel`
- [x] 确认该逻辑是通过 metadata 状态判断,还是通过额外 session 标记判断
- [x] 确保该覆盖只作用于指定 discussion session不影响其他 channel/session
- [x] 为 closed discussion channel 的覆盖路径补充调试日志
#### A7.2 `plugin/hooks/before-message-write.ts`
- [x] 梳理当前 NO_REPLY / end-symbol / waitIdentifier 的处理逻辑
- [x] 找到 discussion channel 中“轮转一圈无人发言”后最适合触发 idle reminder 的位置
- [x] 如果 `nextSpeaker === null` 且当前 channel 是 active discussion channel
- [x] 调用 moderator idle reminder
- [x] 不直接让流程无提示沉默结束
- [x] 避免重复发送 idle reminder
- [x] closed discussion channel 下,阻止继续进入正常 handoff 流程
#### A7.3 `plugin/hooks/message-sent.ts`
- [x] 确认该 hook 是否也会参与 turn 收尾,避免与 `before-message-write.ts` 重复处理
- [x] 检查 discussion channel 场景下是否需要同步补充 closed/idle 分支保护
- [x] 确保 callback 完成后的 closed channel 不会继续触发 handoff
#### A7.4 `plugin/hooks/message-received.ts`
- [x] 梳理 moderator bot 消息当前是否已被过滤,避免 moderator 自己再次触发讨论链路
- [x] 对 closed discussion channel 的新消息增加统一处理入口
- [x] 若 closed discussion channel 收到新消息:
- [x] 不再唤醒任何 Agent 正常讨论
- [x] 由 moderator 回复“channel 已关闭,仅做留档使用”
- [x] 避免 moderator 的 closed 提示消息反复触发自身处理
#### A7.5 `plugin/core/session-state.ts`(如需)
- [x] 检查现有 session 相关缓存是否适合扩展 discussion 状态
- [x] 若需要,为 discussion session 增加专用标记缓存
- [x] 区分:普通 no-reply 决策 vs discussion close 强制 no-reply
- [x] 确保 session 生命周期结束后相关缓存可清理
### A8. `plugin/core/identity.ts` / `plugin/core/channel-members.ts` / `plugin/core/turn-bootstrap.ts`
- [. ] 梳理 initiator identity 的可获取路径
- [. ] 确认 callback 时如何稳定识别 initiator account/session
- [. ] 确认 discussion channel 创建后 turn order 是否需立即 bootstrap
- [. ] 确认 discussion participant 的成员集合获取方式是否可直接复用现有逻辑
### A9. `plugin/index.ts`
- [. ] 注入新增 discussion metadata/service 模块依赖
- [. ] 将 discussion service 传入工具注册逻辑
- [. ] 将 discussion 相关辅助能力传入需要的 hooks
- [. ] 保持插件初始化结构清晰,避免在 `index.ts` 中堆业务细节
### A10. moderator 消息模板整理
#### A10.1 kickoff message
- [x] 定稿 discussion started 模板
- [x] 模板中包含 `discussGuide`
- [x] 模板中明确 initiator 结束责任
- [x] 模板中明确 `discuss-callback(summaryPath)` 调用要求
#### A10.2 idle reminder
- [. ] 定稿 discussion idle 模板
- [. ] 模板中提醒 initiator写总结文件并 callback
- [. ] 避免提醒文案歧义或像自动总结器
#### A10.3 origin callback message
- [x] 定稿发回原工作 channel 的结果通知模板
- [x] 模板中包含 `summaryPath`
- [x] 模板中包含来源 discussion channel
- [x] 模板中明确“继续基于该总结文件推进原任务”
#### A10.4 closed reply
- [. ] 定稿 closed channel 固定回复模板
- [. ] 明确 channel 已关闭,仅做留档使用
### A11. `discuss-callback` 详细校验任务
- [x] 校验当前 channel 必须是 discussion channel
- [x] 校验当前 discussion 状态必须是 `active`
- [x] 校验调用者必须是 initiator
- [x] 校验 `summaryPath` 非空
- [x] 校验 `summaryPath` 文件存在
- [x] 校验 `summaryPath` 路径在 initiator workspace 内
- [x] 校验 callback 未重复执行
- [x] callback 成功后写入 `completedAt`
- [x] callback 成功后记录 `summaryPath`
- [x] callback 成功后切换 discussion 状态为 `completed` / `closed`
### A12. 关闭后的行为封口
- [x] closed discussion channel 中所有旧 session 继续使用 no-reply 覆盖
- [x] closed discussion channel 中任何新消息都不再进入真实讨论
- [x] closed discussion channel 的任何新消息统一走 moderator 固定回复
- [x] 防止 closed channel 中 moderator 自己的回复再次触发回环
- [x] 明确 archived-only 的最终行为与边界
### A13. 测试与文档收尾
#### A13.1 工具层测试
- [. ] 测试普通 `discord_channel_create` 不带新参数时行为不变
- [. ] 测试 `discord_channel_create``callbackChannelId` 但缺 `discussGuide` 时失败
- [. ] 测试 discussion 模式 channel 创建成功
- [. ] 测试 `discuss-callback` 注册成功并可调用
#### A13.2 metadata / service 测试
- [x] 测试 discussion metadata 创建成功
- [x] 测试按 channelId 查询 metadata 成功
- [x] 测试状态流转 `active -> completed/closed` 成功
- [x] 测试重复 callback 被拒绝
#### A13.3 turn / hook 测试
- [. ] 测试 discussion channel 空转后发送 idle reminder
- [. ] 测试普通 channel 空转逻辑不受影响
- [. ] 测试 callback 成功后 discussion channel 不再 handoff
- [. ] 测试 closed discussion channel 新消息不会继续唤醒 Agent
#### A13.4 路径校验测试
- [x] 测试合法 `summaryPath` 通过
- [x] 测试不存在文件失败
- [x] 测试 workspace 外路径失败
- [x] 测试 `..` 路径逃逸失败
- [x] 测试绝对路径越界失败
#### A13.5 回调链路测试
- [. ] 测试 callback 成功后 moderator 在 origin channel 发出通知
- [. ] 测试 origin channel 收到路径后能继续原工作流
- [. ] 测试 discussion channel 后续只保留留档行为
#### A13.6 文档交付
- [. ] 根据最终代码实现更新 `plans/CSM.md`
- [. ] 为 `discord_channel_create` 新增参数补文档
- [. ] 为 `discuss-callback` 补工具说明文档
- [. ] 补 discussion metadata 与状态机说明
- [. ] 补开发/调试说明
- [. ] 输出 MVP 验收清单
---
## B. Multi-Message Mode / Shuffle Mode
### B1. 方案整理
- [. ] 通读并确认 `plans/CHANNEL_MODES_AND_SHUFFLE.md`
- [. ] 确认 Multi-Message Mode 与 Shuffle Mode 的 MVP 范围
- [. ] 确认两项能力是否都只做 channel 级 runtime state不立即落盘
- [. ] 明确它们与 discussion channel / waiting-for-human / dormant 的优先级关系
### B2. 配置与 schema
#### B2.1 `plugin/openclaw.plugin.json`
- [x] 增加 `multiMessageStartMarker`
- [x] 增加 `multiMessageEndMarker`
- [x] 增加 `multiMessagePromptMarker`
- [x] 为新增配置设置默认值:`↗️` / `↙️` / `⤵️`
- [. ] 评估是否需要增加 shuffle 默认配置项
#### B2.2 `plugin/rules.ts` / config 类型
- [x] 为 multi-message mode 相关配置补类型定义
- [x] 为 shuffle mode 相关 channel state / config 补类型定义
- [x] 确保运行时读取配置逻辑可访问新增字段
### B3. `plugin/core/` 新增 channel mode / shuffle state 模块
- [x] 新增 channel mode state 模块(如 `plugin/core/channel-modes.ts`
- [x] 定义 channel mode`normal` / `multi-message`
- [x] 提供 `enterMultiMessageMode(channelId)`
- [x] 提供 `exitMultiMessageMode(channelId)`
- [x] 提供 `isMultiMessageMode(channelId)`
- [x] 提供 shuffle 开关状态存取方法
- [x] 评估 shuffle state 是否应并入 turn-manager 内部状态
### B4. `plugin/hooks/message-received.ts`
#### B4.1 Multi-Message Mode 入口/出口
- [x] 检测 human 消息中的 multi-message start marker
- [x] start marker 命中时,将 channel 切换到 multi-message mode
- [x] 检测 human 消息中的 multi-message end marker
- [x] end marker 命中时,将 channel 退出 multi-message mode
- [x] 避免 moderator 自己的 prompt marker 消息触发 mode 切换
#### B4.2 Multi-Message Mode 中的 moderator 提示
- [x] 当 channel 处于 multi-message mode 时,人类每发一条消息触发 moderator prompt marker
- [x] prompt marker 文案/内容使用配置项 `multiMessagePromptMarker`
- [x] 避免重复触发或回环
#### B4.3 与现有 mention override 的兼容
- [x] 明确 multi-message mode 下 human @mention 是否忽略
- [x] 避免 multi-message mode 与 mention override 冲突
### B5. `plugin/hooks/before-model-resolve.ts`
- [x] 当 channel 处于 multi-message mode 时,强制相关 session 走 `noReplyProvider` / `noReplyModel`
- [x] 确保 multi-message mode 的 no-reply 覆盖优先于普通 turn 决策
- [x] 确保退出 multi-message mode 后恢复正常 turn 逻辑
- [x] 补充必要调试日志
### B6. `plugin/turn-manager.ts`
#### B6.1 Multi-Message Mode 与 turn pause/resume
- [x] 设计 multi-message mode 下 turn manager 的暂停语义
- [x] 明确 pause 是通过外层 gating还是 turn-manager 内显式状态
- [x] 退出 multi-message mode 后恢复 turn manager
- [x] 退出时确定下一位 speaker 的选择逻辑
#### B6.2 Shuffle Mode
- [x] 为每个 channel 增加 `shuffling` 开关状态
- [x] 识别“一轮最后位 speaker 发言完成”的边界点
- [x] 在进入下一轮前执行 reshuffle
- [x] 保证上一轮最后 speaker 不会成为新一轮第一位
- [x] 处理单 Agent 场景
- [x] 处理双 Agent 场景
- [x] 处理 mention override / waiting-for-human / dormant 状态下的 reshape 边界
### B7. `plugin/commands/dirigent-command.ts`
- [x] 新增 `/turn-shuffling` 子命令
- [x] 支持:
- [x] `/turn-shuffling`
- [x] `/turn-shuffling on`
- [x] `/turn-shuffling off`
- [x] 命令返回当前 channel 的 shuffling 状态
- [x] 命令帮助文本补充说明
### B8. `plugin/index.ts`
- [x] 注入 channel mode / shuffle state 模块依赖
- [x] 将新状态能力传给相关 hooks / turn-manager
- [x] 保持初始化关系清晰,避免 mode 逻辑散落
### B9. moderator 消息模板
- [x] 定义 multi-message mode 下的 prompt marker 发送规则
- [x] 明确是否需要 start / end 的 moderator 确认消息
- [x] 定义退出 multi-message mode 后的 scheduling handoff 触发格式
### B10. 测试
#### B10.1 Multi-Message Mode
- [. ] 测试 human 发送 start marker 后进入 multi-message mode
- [. ] 测试 multi-message mode 中 Agent 被 no-reply 覆盖
- [. ] 测试每条 human 追加消息都触发 prompt marker
- [. ] 测试 human 发送 end marker 后退出 multi-message mode
- [. ] 测试退出后 moderator 正确 handoff 给下一位 Agent
- [. ] 测试 moderator prompt marker 不会触发回环
#### B10.2 Shuffle Mode
- [. ] 测试 `/turn-shuffling on/off` 生效
- [. ] 测试 shuffling 关闭时 turn order 不变
- [. ] 测试 shuffling 开启时每轮结束后会 reshuffle
- [. ] 测试上一轮最后 speaker 不会成为下一轮第一位
- [. ] 测试双 Agent 场景行为符合预期
- [. ] 测试单 Agent 场景不会异常
#### B10.3 兼容性测试
- [. ] 测试 multi-message mode 与 waiting-for-human 的边界
- [. ] 测试 multi-message mode 与 mention override 的边界
- [. ] 测试 shuffle mode 与 dormant 状态的边界
- [. ] 测试 shuffle mode 与 mention override 的边界
### B11. 文档收尾
- [. ] 根据最终实现更新 `plans/CHANNEL_MODES_AND_SHUFFLE.md`
- [. ] 为新增配置项补文档
- [. ] 为 `/turn-shuffling` 补使用说明
- [. ] 输出 Multi-Message Mode / Shuffle Mode 的验收清单