Files
cc-web/.trellis/tasks/08-17-user-input-history-mcp/prd.md

3.3 KiB
Raw Blame History

PRD:用户输入历史 MCP

目标

新增公开只读 MCP ccweb_list_user_inputs,让 LLM 在实现或验收前读取指定 cc-web 对话(默认当前来源对话)最近的用户输入,降低实现偏离用户原始要求的概率。

范围

  • 在正式 ccweb MCP tools/list 中暴露工具。
  • 在内部 MCP 分派中实现只读查询。
  • 从持久会话的 messages 中只筛选非空 role=user 文本。
  • 引导表单提交后形成的普通 user 消息必须自然包含;未提交的 assistant 引导卡必须排除。
  • 补 schema 契约测试、查询行为测试和相关回归。

不包含 UI、消息修改、全文搜索、assistant/tool/system 内容、附件正文解析或跨会话权限模型改造。

MCP 契约

入参

  • conversationId?: string:指定目标会话;缺省时使用 MCP 来源会话 ID。
  • limit?: integer:默认 15,最小 1,最大 50。
  • maxChars?: integer:默认 1000,最小 1,最大 1000;限制所有 items[].content 的 Unicode code point 总数。
  • additionalProperties: false。

选择与截断

  1. 只选择正文非空的 role=user 消息。
  2. 先取最近 limit 条候选。
  3. 从最新候选向更早候选分配 maxChars 预算。
  4. 若剩余预算不足,保留当前消息开头,设置 truncated=true,停止加入更早消息。
  5. 最终按旧到新排列,便于 LLM 理解要求演进。
  6. Unicode 字符使用 code point 计数,不能按 UTF-16 code unit 把 emoji 拆成两字。

返回

成功结果:

{
  "ok": true,
  "conversationId": "...",
  "requestedLimit": 15,
  "maxChars": 1000,
  "totalChars": 123,
  "returnedCount": 2,
  "hasMore": false,
  "items": [
    {
      "messageId": "...或 null",
      "createdAt": "...或 null",
      "content": "用户输入",
      "contentChars": 4,
      "originalChars": 4,
      "truncated": false
    }
  ]
}

hasMore=true 表示存在 limit 之外的更早用户输入,或字数预算截断/省略了候选。

错误

  • 默认模式缺少来源会话:missing_source_conversation。
  • 显式 conversationId 清洗后无效:invalid_conversation_id,不得回退来源会话。
  • 目标会话不存在:conversation_not_found。

验收标准

  • 工具 schema 与描述明确说明默认当前会话、最近 15 条、合计最多 1000 字和验收用途。
  • 默认当前来源会话与显式指定会话均可查询。
  • 默认只返回最近 15 条用户输入,并按旧到新排列。
  • assistant/tool/system、空白 user 消息和未提交引导卡不进入结果。
  • 引导表单提交产生的普通 user 消息进入结果。
  • limit 与 maxChars 被正确默认和限制;所有正文总字符数不超过 maxChars。
  • emoji 等非 BMP 字符按单个 code point 计数。
  • 截断项、hasMore、计数字段和错误码可由回归测试稳定断言。
  • 查询不修改会话文件、更新时间、未读状态或运行状态。
  • 针对性测试与项目相关 regression 均通过。

实施顺序

  1. 先写失败测试固定 schema、路由与行为。
  2. 实现最小查询和 Unicode 预算逻辑。
  3. 注册正式 MCP schema;仅在现有兼容策略确有需要时纳入旧 dynamic-tool 兼容集。
  4. 跑针对性测试,再跑相关完整回归。