统一运行时流式重构计划
目标
交付一条共享的流式管线,让 main、subagent 和 acp 所有运行时获得相同的合并、分块、投递排序和崩溃恢复行为。
为什么要做
- 当前行为分散在多个运行时专属的整形路径中。
- 格式/合并 bug 修了一个路径,其他路径还在。
- 投递一致性、重复抑制和恢复语义更难推理。
目标架构
单管线,运行时专属适配器:
- 运行时适配器只发出规范事件。
- 共享流式组装器负责合并和定稿 text/tool/status 事件。
- 共享频道投影器一次性应用频道专属的分块/格式化。
- 共享投递账本强制幂等的发送/回放语义。
- 出站频道适配器执行发送并记录投递检查点。
规范事件契约:
turn_startedtext_deltablock_finaltool_startedtool_finishedstatusturn_completedturn_failedturn_cancelled
工作流
1) 规范流式契约
- 在核心中定义严格的事件 schema + 验证。
- 添加适配器契约测试以保证每个运行时发出兼容的事件。
- 提前拒绝格式错误的运行时事件并呈现结构化诊断。
2) 共享流式处理器
- 用一个处理器替换运行时专属的合并器/投影器逻辑。
- 处理器拥有 text delta 缓冲、空闲刷新、最大块拆分和完成刷新。
- 将 ACP/main/subagent 的配置解析移到一个辅助中以防止漂移。
3) 共享频道投影
- 保持频道适配器简单:接受定稿块并发送。
- 将 Discord 专属的分块怪癖只移到频道投影器中。
- 投影前保持管线频道无关。
4) 投递账本 + 回放
- 添加每回合/每块的投递 ID。
- 在物理发送前后记录检查点。
- 重启时幂等回放待发送块并避免重复。
5) 迁移和切换
- 阶段 1:影子模式(新管线计算输出但旧路径发送;对比)。
- 阶段 2:按运行时切换(
acp,然后subagent,然后main,或按风险反向)。 - 阶段 3:删除遗留的运行时专属流式代码。
不做的事
- 本次重构不改变 ACP 策略/权限模型。
- 不在投影兼容性修复之外扩展频道专属功能。
- 不重新设计传输/后端(acpx 插件契约保持不变,除非需要事件对齐)。
风险和缓解
- 风险:现有 main/subagent 路径的行为回归。 缓解:影子模式对比 + 适配器契约测试 + 频道端到端测试。
- 风险:崩溃恢复期间的重复发送。 缓解:持久投递 ID + 投递适配器中的幂等回放。
- 风险:运行时适配器再次分化。 缓解:所有适配器必需的共享契约测试套件。
验收标准
- 所有运行时通过共享流式契约测试。
- Discord 上的 ACP/main/subagent 对微小 delta 产生等效的间距/分块行为。
- 崩溃/重启回放不为同一投递 ID 发送重复块。
- 遗留 ACP 投影器/合并器路径被移除。
- 流式配置解析是共享的且运行时无关。