Files
Dirigent/plans/CHANNEL_MODES_AND_SHUFFLE.md

249 lines
8.2 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.
# Channel Modes & Turn Shuffle 规划
## 背景
`feat/new-feat-notes` 分支中的 `NEW_FEAT.md` 提出了两项新的行为增强需求,需要整合进入 `main` 分支下的 `plans/`
1. **Multi-Message Mode人类连续多消息模式**
2. **Shuffle Mode轮转顺序重洗牌**
这两项能力都与 Dirigent 当前的 turn-manager、moderator handoff、no-reply override 机制直接相关,因此应作为 turn orchestration 的功能扩展纳入规划,而不是孤立实现。
---
## 1. Multi-Message Mode
### 1.1 目标
允许人类在一个 channel 中连续发送多条消息而不被 Agent 打断。
当用户显式进入 multi-message mode 后:
- 当前 channel 的 turn manager 暂停
- 所有 Agent 在该 channel 中进入 no-reply 覆盖
- moderator bot 对每条人类追加消息发送 prompt marker提示继续输入
- 直到人类发送 end marker 才恢复 turn manager
- 恢复后由 moderator 按现有调度机制唤醒下一位 Agent
---
### 1.2 配置项
新增并已实现以下可配置项:
- `multiMessageStartMarker`:默认 `↗️`
- `multiMessageEndMarker`:默认 `↙️`
- `multiMessagePromptMarker`:默认 `⤵️`
这些配置已加入插件 config schema并在运行时被 `message-received` / `before-message-write` / `before-model-resolve` 使用。
---
### 1.3 行为规则
#### 进入 multi-message mode
**human** 消息中包含 start marker
- 当前 channel 进入 `multi-message` 状态
- turn manager 暂停
- 当前 channel 下所有 Agent 在该 channel/session 中走 no-reply override
#### multi-message mode 中
在该模式下:
- 人类每发一条消息
- moderator bot 自动回复 prompt marker例如 `⤵️`
- Agent 不应参与正常轮转回复
#### 退出 multi-message mode
**human** 消息中包含 end marker
- 当前 channel 退出 `multi-message` 状态
- turn manager 恢复
- moderator bot 发送当前调度标识scheduling identifier唤醒下一位 Agent
---
### 1.4 状态建议
每个 Discord channel 维护一个 channel mode
- `normal`
- `multi-message`
- (后续可扩展其他模式)
multi-message mode 应与 discussion channel / wait-for-human / no-reply 决策互相兼容,优先级需要明确。
建议优先级初稿:
1. closed discussion channel
2. multi-message mode
3. waiting-for-human
4. normal turn-manager
---
## 2. Shuffle Mode
### 2.1 目标
在 turn-based speaking 中,为每个 Discord channel 增加可选的 turn order reshuffle 能力。
当 shuffle mode 开启时:
- 在一轮 turn list 的最后一位 speaker 发言完成后
- 对 turn order 重新洗牌
- 但必须保证:**上一轮最后一位发言者不能在新一轮中成为第一位**
---
### 2.2 配置 / 控制方式
为每个 Discord channel 维护:
- `shuffling: boolean`
并新增 slash command
- `/dirigent turn-shuffling on`
- `/dirigent turn-shuffling off`
- `/dirigent turn-shuffling`(查看当前状态)
当前实现结论:
- `shuffling`**channel 级 runtime state**,存放在 `plugin/core/channel-modes.ts`
- 默认值为 `false`
- 当前版本**不新增**全局 `shuffle default` 配置项
- 重启后会恢复为默认关闭,如需开启需要再次执行命令
这样与现有实现保持一致,也避免把一次性的实验性调度偏好混入全局静态配置。
---
### 2.3 行为规则
`shuffling = true` 时:
- 正常按 turn order 轮转
- 当“当前 speaker 是该轮最后一位”并完成发言后
- 进入下一轮前重洗 turn order
- 新 turn order 必须满足:
- 上一轮最后 speaker != 新 turnOrder[0]
若无法满足(极端小集合场景),需要定义 fallback
- 两个 Agent 时可退化为简单交换/固定顺序
- 单 Agent 时不需要 shuffle
---
## 3. 与当前系统的关系
这两个能力都不是独立子系统,而是 Dirigent turn orchestration 的扩展。
### 涉及模块
- `plugin/turn-manager.ts`
- `plugin/hooks/message-received.ts`
- `plugin/hooks/before-model-resolve.ts`
- `plugin/hooks/before-message-write.ts`
- `plugin/hooks/message-sent.ts`
- `plugin/commands/dirigent-command.ts`
- `plugin/index.ts`
- `plugin/openclaw.plugin.json`
- 如有必要新增 `plugin/core/channel-modes.ts` 或类似 runtime state 模块
---
## 4. 建议实现方向
### 4.1 Multi-Message Mode
建议不要把 multi-message mode 直接塞进规则判断字符串里,而是做成显式 channel runtime state。
建议新增:
- channel mode state store
- helper
- `enterMultiMessageMode(channelId)`
- `exitMultiMessageMode(channelId)`
- `isMultiMessageMode(channelId)`
然后:
- `message-received` 检测 human 消息中的 start/end marker
- `before-model-resolve` 检测当前 channel 是否处于 multi-message mode若是则直接走 no-reply override
- `message-received` 或合适的消息链路中触发 moderator prompt marker
- 退出时触发一次 scheduling handoff
---
### 4.2 Shuffle Mode
建议将 shuffle 状态与 turn order 状态放在一起,或由 turn-manager 引用单独的 channel config/state。
建议新增 helper
- `setChannelShuffling(channelId, enabled)`
- `getChannelShuffling(channelId)`
- `reshuffleTurnOrder(channelId, { avoidFirstAccountId })`
并在 turn cycle 的边界点调用重洗逻辑,而不是在任意发言后随机改顺序。
---
## 5. 风险与边界
### Multi-Message Mode
- 需要防止 moderator prompt marker 自己再次触发 turn logic
- 需要明确 start/end marker 的匹配规则(全文包含、末尾匹配、独立一条指令等)
- 需要明确 multi-message mode 下 human @mention 是否还有特殊行为
- 需要避免与 discussion closed / waiting-for-human 冲突
### Shuffle Mode
- 两个 Agent 的洗牌约束需要单独处理
- turn order 若正处于 mention override / waiting-for-human / dormant需要明确何时允许 reshuffle
- 若 turn order 成员变化shuffle 与 bootstrap 的先后顺序要明确
---
## 6. 实现状态
Multi-Message Mode 与 Shuffle Mode 已经在代码中实现,包括:
- Multi-Message Mode 实现:
- `plugin/core/channel-modes.ts` - 管理 channel 运行时状态
- `plugin/hooks/message-received.ts` - 检测 start/end marker 并切换模式
- `plugin/hooks/before-model-resolve.ts` - 在 multi-message mode 中强制 no-reply
- 配置项 `multiMessageStartMarker` (默认 `↗️`)、`multiMessageEndMarker` (默认 `↙️`)、`multiMessagePromptMarker` (默认 `⤵️`)
-`plugin/openclaw.plugin.json` 中添加了相应的配置 schema
- Shuffle Mode 实现:
- `plugin/core/channel-modes.ts` - 管理 shuffle 状态
- `plugin/turn-manager.ts` - 在每轮结束后根据 shuffle 设置决定是否重洗牌
- `/dirigent turn-shuffling` slash command 实现,支持 `on`/`off`/`status` 操作
- 确保上一轮最后发言者不会在下一轮中成为第一位
- 当前行为是运行时开关,默认关闭,不落盘
## 7. 验收清单
### Multi-Message Mode 验收
- [x] 人类发送 start marker (`↗️`) 后进入 multi-message 模式
- [x] multi-message 模式中 Agent 被 no-reply 覆盖
- [x] 每条人类追加消息都触发 prompt marker (`⤵️`)
- [x] 人类发送 end marker (`↙️`) 后退出 multi-message 模式
- [x] 退出后 moderator 正确唤醒下一位 Agent
- [x] moderator prompt marker 不会触发回环
- [x] 与 waiting-for-human 模式兼容
- [x] 与 mention override 模式兼容
### Shuffle Mode 验收
- [x] `/dirigent turn-shuffling on/off` 命令生效
- [x] shuffling 关闭时 turn order 保持不变
- [x] shuffling 开启时每轮结束后会重洗牌
- [x] 上一轮最后发言者不会在下一轮中成为第一位
- [x] 双 Agent 场景行为符合预期
- [x] 单 Agent 场景不会异常
- [x] 与 dormant 状态兼容
- [x] 与 mention override 兼容
### 配置项验收
- [x] `multiMessageStartMarker` 配置项生效
- [x] `multiMessageEndMarker` 配置项生效
- [x] `multiMessagePromptMarker` 配置项生效
- [x] 配置项在 `plugin/openclaw.plugin.json` 中正确声明
## 8. 结论
Multi-Message Mode 与 Shuffle Mode 已成功集成到 Dirigent 插件中,与现有的 turn-manager、moderator handoff、no-reply override 机制协同工作,为用户提供更灵活的多 Agent 协作控制能力。