80 lines
4.4 KiB
Markdown
80 lines
4.4 KiB
Markdown
# Task Plan: 新增用户输入历史 MCP
|
||
|
||
## Goal
|
||
|
||
为 cc-web 增加一个只读 MCP,可读取指定对话(默认当前来源对话)最近的用户输入,纳入引导表单提交内容,并把所有返回正文控制在合计 1000 个 Unicode 字符以内,供 LLM 作为验收参考。
|
||
|
||
## Current Phase
|
||
|
||
Phase 3
|
||
|
||
## Phases
|
||
|
||
### Phase 1: 代码发现与契约确认
|
||
|
||
- [x] 梳理会话消息存储与 ccweb MCP 注册链路
|
||
- [x] 明确用户输入筛选、默认会话与截断规则
|
||
- 必须确认普通用户输入与引导表单提交的持久化形态。
|
||
- 必须确认来源会话缺失、指定会话不存在时的错误语义。
|
||
- **Status:** complete
|
||
|
||
### Phase 2: 测试与实现
|
||
|
||
- [x] 编写新 MCP 的失败回归测试
|
||
- 覆盖默认当前对话、显式指定对话、默认最近 15 条、仅返回 user 内容。
|
||
- 覆盖引导表单提交消息、合计 1000 字预算、截断标记及缺失来源会话。
|
||
- [x] 实现指定/当前会话的用户输入读取与限制逻辑
|
||
- [x] 注册 MCP schema、描述与运行时上下文
|
||
- **Status:** complete
|
||
|
||
### Phase 3: 验证与交付
|
||
|
||
- [x] 运行针对性测试并修复发现的问题
|
||
- [x] 执行相关回归、核验接口并整理交付
|
||
- **Status:** complete
|
||
|
||
## Key Questions
|
||
|
||
1. 普通用户输入和引导表单提交在持久层中如何标记、是否都使用 `role=user`?(已确认:提交后经普通 `handleMessage` 持久化为 `role=user`;待提交卡是 `role=assistant`)
|
||
2. 当前来源对话 ID 从哪个线程级运行时上下文解析?(已确认:JSON-RPC/内部 HTTP 上下文把 `sourceSessionId` 传给 `callInternalMcpTool`)
|
||
3. MCP 工具注册、参数校验和权限边界由哪些模块负责?(已确认:`lib/ccweb-mcp-server.js` 的 `TOOLS`/`isCallableToolName` 与 `server.js` 的内部 MCP 分派)
|
||
|
||
## Decisions Made
|
||
|
||
| Decision | Rationale |
|
||
|----------|-----------|
|
||
| 默认返回最近 15 条,最终按时间从旧到新排列 | 兼顾最近性与作为验收标准时的可读性 |
|
||
| 所有返回正文合计默认且硬性最多 1000 个 Unicode 字符 | 避免 15 条输入最坏膨胀到约 15000 字,保证验收上下文可控 |
|
||
| 从最新输入向前消耗字数预算,最终按旧到新输出 | 优先保留最新验收要求,同时维持自然阅读顺序 |
|
||
| 预算导致内容或更早消息未完整返回时给出截断/更多标记 | 避免 LLM 将不完整历史误认为完整要求 |
|
||
| 仅返回用户输入,不混入 assistant/tool/system 内容 | 保持用户原始验收意图纯净 |
|
||
|
||
## MCP Contract
|
||
|
||
- 工具名为 `ccweb_list_user_inputs`。
|
||
- 入参:
|
||
- `conversationId?: string`:缺省时使用 MCP 来源会话 ID。
|
||
- `limit?: integer`:默认 15,允许 1–50。
|
||
- `maxChars?: integer`:默认 1000,允许 1–1000;约束所有 `items[].content` 的字符总和。
|
||
- 返回:
|
||
- `conversationId`、`requestedLimit`、`maxChars`、`totalChars`、`returnedCount`、`hasMore`。
|
||
- `items[]` 至少含 `content`、`createdAt`、`truncated`;若持久层有稳定消息 ID,则同时返回 `messageId`。
|
||
- 排序与预算:先选最近 `limit` 条用户输入,再从最新向前填充 `maxChars` 预算,最终将已选内容按旧到新返回。
|
||
- 默认当前会话但运行时没有来源会话 ID 时返回明确参数错误;显式指定不存在的会话时返回 not-found 错误。
|
||
|
||
## Errors Encountered
|
||
|
||
| Error | Attempt | Resolution |
|
||
|-------|---------|------------|
|
||
| 计划审查指出 1000 字是逐条还是合计存在歧义 | 1 | 收紧为所有返回正文合计硬上限 1000 字,并固化预算顺序 |
|
||
| codebase-memory 单次查询误报项目未索引 | 1 | 立即用 list_projects/index_status 复核,项目实际为 ready;后续收敛查询重试,不触发无谓重建 |
|
||
| codebase-memory 重试返回 Transport closed | 2 | 停止重复 MCP 调用,降级到本地 rg/sed 精确核验小函数 |
|
||
| 初版失败测试覆盖 HOME 且误排除提交表单标题 | 1 | 已退回测试代理修正环境隔离与角色/ID 断言后再验红灯 |
|
||
| 主线程生产补丁因代理并发落盘而校验失败 | 1 | apply_patch 安全拒绝覆盖;检查 git diff 后确认代理已完成目标改动,直接进入验证 |
|
||
|
||
## Notes
|
||
|
||
- 计划与根目录 CSV、`update_plan` 保持一一同步。
|
||
- 研究发现写入 `findings.md`,测试结果写入 `progress.md`。
|
||
- 当前运行进程尚未重载:发现另一个非当前对话仍为 running,按项目约定暂缓 `pm2 restart ccweb --update-env`。
|