92 lines
5.6 KiB
Markdown
92 lines
5.6 KiB
Markdown
# 发现与决策:统一 ccweb 消息回传接口
|
||
|
||
## 需求
|
||
|
||
- 将 `ccweb_send_message` 与 `ccweb_request_reply` 合并为一个公开工具。
|
||
- 使用显式参数选择单向投递或自动回传。
|
||
- 优化工具描述、目标对话提示和来源续跑提示。
|
||
- 保留旧调用的兼容能力,但不让新模型继续在两个公开工具间选错。
|
||
- 本次需要实际落地并通过回归。
|
||
|
||
## 已确认事实
|
||
|
||
- `requestCrossConversationReply()` 当前只是
|
||
`sendCrossConversationMessage(..., { expectReply: true })` 的薄包装。
|
||
- 正式 MCP 定义位于 `lib/ccweb-mcp-server.js`,Codex App 备用定义位于
|
||
`server.js`,两处描述已出现漂移。
|
||
- `ccweb_create_conversation` 已经使用 `requestReply` 参数,现有公开 API 风格不一致。
|
||
- `buildCrossConversationRuntimeText()` 当前只标注来源标题和 ID,不携带是否自动回传。
|
||
- `buildCrossConversationReplyAutoRunText()` 当前只包含目标标题和返回正文,缺少
|
||
`requestId`、原始请求和完整性检查指令。
|
||
- 真实会话中曾对明确要求“完成后汇报/最终验收”的任务误用
|
||
`ccweb_send_message`;同一会话此前使用过 `ccweb_request_reply`,说明问题不是工具
|
||
不可发现,而是选择语义不够强。
|
||
- 真实会话还出现过目标返回“完成定位、准备修改”后仍继续工作的情况;提示词可降低
|
||
概率,但“turn 完成是否等于任务完成”仍是协议级风险。
|
||
|
||
## 并发与工作树基线
|
||
|
||
- 当前另有两个非本对话的 `running` 对话:任务看板、失败插入卡片。
|
||
- `server.js`、`lib/ccweb-mcp-server.js`、`scripts/regression.js` 已有未提交改动,均与本任务重叠。
|
||
- `.planning/.active_plan` 指向 `2026-08-11-help`,`.trellis/.current-task` 指向
|
||
`.trellis/tasks/08-11-task-board`;不得覆盖。
|
||
- 本任务使用 `.planning/2026-08-11-unify-ccweb-message-reply/` 保存独立上下文。
|
||
- 已创建 Trellis 任务 `.trellis/tasks/08-11-unify-ccweb-message-reply/`,但不会执行
|
||
`task.py start`:全局 `.trellis/.current-task` 正被另一个运行中对话使用。后续实施与
|
||
审查子代理必须显式读取本任务路径,不能依赖全局 current-task。
|
||
|
||
## 技术决策
|
||
|
||
| 决策 | 理由 |
|
||
|---|---|
|
||
| `replyMode` 必填、无默认值 | 避免模型省略参数后静默失去回传 |
|
||
| 值为 `one_way`、`return_and_continue` | 名称直接表达真实副作用,不暗示同步等待 |
|
||
| 公开列表移除旧工具,内部 dispatcher 保留别名 | 兼顾新调用清晰度与存量线程兼容 |
|
||
| 共享工具定义为单一来源 | 防止 MCP 与备用 dynamic tools 文案/Schema 漂移 |
|
||
| 回传模式目标提示禁止手工回复 | 防止同一结果重复投递或形成环路 |
|
||
| 来源续跑先判断完整性 | 防止把“已返回”误判成“已完成” |
|
||
| 直接复用 `CCWEB_MCP_TOOLS` 生成 Codex App 备用定义 | `server.js` 已导入正式工具清单,无需新增第三个契约模块 |
|
||
|
||
## 最新代码基线
|
||
|
||
- `server.js` 顶部已导入 `{ TOOLS: CCWEB_MCP_TOOLS }`,但
|
||
`codexAppCommunicationDynamicTools()` 仍手写重复定义。
|
||
- 最小单一来源方案:正式定义继续留在 `lib/ccweb-mcp-server.js`;该模块同时导出
|
||
reply mode 常量;`server.js` 从 `CCWEB_MCP_TOOLS` 按通信工具白名单筛选并添加
|
||
`namespace: 'ccweb'`。
|
||
- 此方案同时统一所有既有通信工具描述,且不会把 task-board 工具意外加入备用列表。
|
||
- 公开 TOOLS 不能兼作唯一调用 allowlist;需要单独的 hidden legacy name 集合,避免
|
||
已缓存 `ccweb_request_reply` 的旧线程在到达 dispatcher 前失败。
|
||
- `scripts/regression.js` 现有 `assertCcwebListConversationsScopeContract()` 会从
|
||
`server.js` 的手写 dynamic tool 源码中截取 `ccweb_list_conversations` schema;改成
|
||
单一来源后该断言也必须改为调用 `codexAppCommunicationTools()` 并比较正式定义,
|
||
否则正确的去重实现会被旧静态断言误报。
|
||
- 当前任务看板对话不是陈旧运行标记:其 `codexapp-state.json` 持续更新,正在做隔离
|
||
浏览器验收并已发现新增列 `description` 契约缺陷。它后续可能修改 `server.js` 与
|
||
`scripts/regression.js`,本任务必须继续等待其生产改动闭环。
|
||
|
||
## 待验证
|
||
|
||
- 现有测试是否直接断言公开工具数量或旧工具名称。
|
||
- Codex App 备用 dynamic tool 路径是否仍有实际回归覆盖。
|
||
- 旧线程调用已不在工具列表中的旧名称时,内部 MCP dispatcher 是否仍可接收。
|
||
- 原始请求内容加入 pending 状态是否涉及持久化格式兼容。
|
||
- 正式 MCP 的 `tools/call` 是否在公开 TOOLS 之外保留隐藏旧名(必须保留)。
|
||
|
||
## Trellis 规范结论
|
||
|
||
- 仓库只声明 backend/frontend 两层;本任务属于 backend + 跨层协议,不需要加载前端组件规范。
|
||
- backend error handling 基本为空,现有 `mcpToolError` 行为应作为事实规范保留。
|
||
- backend quality 的已填内容仅针对部分 JSON 预览,与本任务无直接约束。
|
||
- `cross-layer-thinking-guide.md` 要求显式定义工具 Schema → dispatcher → pending 状态 →
|
||
目标运行提示 → 来源续跑提示的完整数据流,并在入口集中校验。
|
||
- `code-reuse-thinking-guide.md` 明确要求相同常量/定义单一来源;支持让 Codex App
|
||
备用工具列表直接派生自正式 MCP 定义。
|
||
|
||
## 资源
|
||
|
||
- `server.js`:跨对话发送、回传、运行提示、dynamic tool 定义。
|
||
- `lib/ccweb-mcp-server.js`:正式 MCP 工具清单与输入 Schema。
|
||
- `scripts/regression.js`:跨对话 MCP 端到端回归。
|
||
- `README.md`:公开工具说明。
|