feat: 优化任务状态与图片 MCP 提示

This commit is contained in:
shiyue
2026-08-13 00:34:37 +08:00
parent 86231f0d97
commit 214ff4ec88
13 changed files with 1353 additions and 49 deletions

View File

@@ -0,0 +1,40 @@
# Codex App 任务状态自动分类发现
## 已确认事实
- 真实 tracked 会话能够看到并调用 `ccweb_task_update`,但多数主模型不会主动维护任务列,因此工具可见不等于自动机制有效。
- 用户明确拒绝新增“任务分类模型”配置,也拒绝 Hook 和 MCP reload。
- 最终方向是服务端复用当前 Codex App 会话已经解析的 Provider、模型和现有认证发起一次无工具结构化分类请求。
- 当前 Provider 若只有 Codex/ChatGPT 登录态而没有普通 API 凭据,则分类应安全跳过并保持原状态,不能提取或冒用登录令牌。
- 输出必须经过 JSON 解析、严格 Schema、动态启用列、expectedVersion 四层校验;任何失败都保持状态。
## 已落地结论
- 当前会话模型由 `codexAppModelSettings()` 解析local 模式读取当前 `model_provider` 的 Responses 配置及其普通 API Keycustom 模式只读激活 Profile。
- 分类客户端独立实现 `/responses` 严格 JSON 请求,不复用只支持 Chat Completions 的摘要客户端;请求明确 `tools: []``tool_choice: none`
- 分类事件只接在持久化成功的用户消息与成功主轮次完成;运行事件、失败、中断和回滚不分类。
- `TaskBoardService.updateStatus(expectedVersion)` 负责动态列验证和最终写入actor 使用独立 `classifier` 审计来源。
- 自动 turn 前 reload 已删除;人工 reload API 和动态任务 MCP 继续作为人工/调试能力存在。
- 普通会话保存必须保护磁盘上版本更高的 `taskTracking`,否则异步分类结果会被持有旧 session 的主轮次覆盖。
- 严格输出的长度限制由本地解析器执行,发给 Provider 的 JSON Schema 避免可选字符串长度关键字,以提升 OpenAI-compatible Responses 实现的兼容性。
- 当前环境的实际 `cch` Provider 支持普通 API Key 与 Responses SSE分类请求必须解析 `response.output_text.done/delta`,不能假定完成事件的 `output` 一定含文本,也不能等待服务端主动断开连接。
- 当前对话的一次真实请求已验证完整 Provider 链路:使用当前模型 `gpt-5.6-sol`、低推理强度和动态任务快照1465ms 返回严格结果并判定仍为 `in_progress / 处理中`;验收过程未写生产 session。
## 第一轮代码定位
- `session.model``codexAppModelSettings()` 解析为模型名与推理强度;这应作为分类请求的模型来源。
- Codex App custom Profile 可直接提供 `apiBase/apiKey`local 模式只有在当前 Responses Provider 存在普通 API Key 时才可分类,纯 OAuth/token 登录态安全跳过。
- 现有 `callSummaryApi()` 只实现 `/v1/chat/completions` 且没有严格 Schema不能直接拿来当分类器但其超时/HTTP 请求框架可参考。
- 当前 `startCodexAppTurn()` 仍在每轮调用 `ensureTaskBoardMcpToolsFresh()`,旧自动状态方案的 reload 接线确实存在。
- `TaskBoardService.updateStatus()` 已支持 `expectedVersion` 乐观并发与动态启用列校验,但 actor 目前只允许 `user/mcp`;分类器需要独立审计来源或明确复用内部来源契约。
- 生命周期服务目前只记录事件;需要继续确认轮次完成事件携带的最终助手文本入口,分类不应继续借生命周期事件自动迁移固定列。
## 触发与并发接线结论
- 普通用户消息在 `handleMessage()` 持久化后进入 Codex App分类可在保存后异步入队不阻塞主轮次。
- 运行中插入消息由 `handleCodexAppSteerMessage()` 异步持久化,只有 `turn/steer` 成功或旧 turn 已结束并转为新 turn 时才应入队;失败回滚的消息不得分类。
- 成功轮次的最终助手文本与清洗后的工具调用在 `handleCodexAppTurnComplete()` 已完整可用;仅 `!completionError && !interrupted && !userAborted` 时触发完成分类。
- `TaskBoardService.getTask()` 提供当前状态、摘要、version`getStatusDefinitions()` 提供动态列;`updateStatus(expectedVersion)` 可承担最终原子写入。
- 当前 actor source 允许 `user/mcp/hook/default`。自动分类需要新增明确的 `classifier` 审计来源,不能伪装成 MCP。
- 旧生命周期服务不自动迁移任务列,只负责反归档等确定性元数据;可以保留,但 `startCodexAppTurn()` 中的 MCP fingerprint/reload 必须从自动主链路移除。
- 分类请求使用当前 Codex `custom` 激活 profile 的 `apiBase/apiKey``session.model``local` 登录态没有普通 API 凭据时记录 unavailable 并保持状态。

View File

@@ -0,0 +1,20 @@
# Codex App 任务状态自动分类进度
- 2026-08-12用户确认直接落地并要求重点打磨动态分类提示词。
- 2026-08-12确认不新增分类模型配置复用当前 Codex App 会话 Provider/模型,认证不可用时安全保持状态。
- 2026-08-12恢复检查确认中断子对话未留下产品代码半成品保留现有跨对话运行态文件差异。
- 2026-08-12将旧 Hook/MCP 计划原地改写为 Provider 直连、严格结构化、双事件分类方案。
- 2026-08-12计划独立审查通过codebase-memory 索引 ready已定位 Provider、模型、Codex App 启动和任务写入核心函数。
- 2026-08-12完成阶段 1确定普通消息、运行中插入、成功轮次完成三个精确接线点以及 custom Provider/local 登录态的支持边界。
- 2026-08-12新增红灯契约service 因 classifier actor 无效失败classifier 因模块不存在失败,均退出 1。
- 2026-08-12只读认证形状检查确认本机 local Codex 使用 `responses` Provider`auth.json` 含对应 API Key 字段;实现可复用而不读取 OAuth tokens。
- 2026-08-12完成 `task-board-classifier`:无工具 Responses 请求、严格 JSON、动态列 enum、同会话串行、事件去重、定义与任务版本门禁。
- 2026-08-12完成 local/custom Provider 只读解析local 仅读取当前 Provider 对应 API Key 字段custom 直接读取激活 Profile不新增分类配置或运行时配置写入。
- 2026-08-12接入普通用户消息、成功 steer 和成功主轮次完成隐藏消息、steer 回滚、失败、中断、人工停止均不触发分类。
- 2026-08-12真实集成红灯发现旧 session 保存会覆盖异步分类写入;新增版本保护后,两次分类从自定义列连续迁移到完成列,版本连续 +1。
- 2026-08-12退役 turn 前 MCP reload 与 fingerprint 缓存;保留显式人工 reload 和 `ccweb_task_update` 调试接口。
- 2026-08-12专项单测、自动化集成与完整 regression 均退出 0非标准 JSON 集成验证保持状态和版本不变。
- 2026-08-12custom Profile 分类解析改为纯读取,不调用会写运行时配置的 app-server 辅助函数;自动化集成与完整 regression 重跑仍为 0。
- 2026-08-12OpenAI 官方 Structured Outputs 页面在当前网络被 403 拦截;为兼容 OpenAI-compatible Provider严格 schema 只使用必需字段、动态 enum 与 additionalProperties长度继续由本地解析器校验。
- 2026-08-12按用户要求直接对当前对话执行一次真实分类请求复用当前 `cch` Responses Provider、`gpt-5.6-sol` 和现有普通 API Key固定低推理强度、无工具、未写生产 session。请求 1465ms 成功,严格结果判定任务仍为 `in_progress / 处理中`
- 2026-08-12真实请求暴露 Provider 使用 SSE 且完成文本可能仅位于 `output_text.done/delta`;补齐 SSE 解析、完成即返回、60 秒绝对超时后,语法检查、四组专项单测、集成、完整 regression 与 `git diff --check` 全部退出 0。

View File

@@ -0,0 +1,36 @@
# Codex App 任务状态自动分类管道
## 目标
在不新增分类模型配置、不使用 Hook、不重载 MCP、也不依赖主模型主动调用工具的前提下复用当前 Codex App 会话已经解析的模型 Provider 与认证方式,在“用户消息进入”和“主对话本轮完成”两个事件点执行无工具、严格结构化的动态看板分类,并以版本门禁安全更新任务列。
## 阶段
- [x] 1. 固定工作区并定位当前 Codex App Provider、消息入口、轮次完成与任务写入链路
- [x] 2. 写出分类提示词、严格输出、触发时机与失败保持的红灯契约
- [x] 3. 实现复用当前会话 Provider 的无工具结构化分类客户端
- [x] 4. 接入用户消息进入与主对话完成事件,加入串行队列和版本门禁
- [x] 5. 退役自动主链路中的任务 MCP 重载与主动上报依赖,保留必要兼容接口
- [x] 6. 运行专项、自动化集成、当前对话真实 Provider 请求和完整回归并修复真实失败
- [x] 7. 清理临时跟踪文件并交付配置兼容性、测试与残余风险
## 已确认产品契约
- 系统范围仅包含 Codex App不为 Claude 或 Codex CLI 扩展任务分类。
- 动态看板列的 `id / label / prompt` 是唯一分类语义;禁止写死固定状态或用关键词、正则推断。
- 自动分类只在用户消息进入、Codex App 主轮次完成两个事件点发生;请求用户输入属于主轮次完成。
- 运行开始、运行停止、网络失败、人工中断均不自动改变任务列。
- 分类复用当前会话已解析的模型与 Provider不增加模型、密钥、Base URL 或管理界面配置。
- cc-web 不读取或复制 Codex 登录令牌;只有当前 Provider 具备现有普通 API 认证时才发请求。
- 分类请求不提供工具、项目文件、cwd 或 MCP只接受严格 JSON Schema 结果。
- 非标准 JSON、拒答、超时、非法列或版本变化时保持当前状态不做文本修复或兜底猜测。
- `ccweb_task_update` 可作为人工/调试兼容接口,但不再承担自动分类主链路。
- 不修改生产 sessions/config/logs不重启生产服务不覆盖用户已有工作区修改。
## 错误记录
- 旧计划基于 Hook、动态任务 MCP 与模型主动调用,真实环境证明可靠性不足;本轮按用户确认的 Provider 直连分类方案整体替换。
- 红灯 1service 单测退出 1`classifier` actor source 被拒绝。
- 红灯 2classifier 单测退出 1`lib/task-board-classifier` 尚不存在。
- 红灯 3真实集成中两次分类只留下一个版本增量定位为轮次完成保存旧 session覆盖了先完成的用户消息分类。`saveSession()` 现会保留磁盘上版本更高的 `taskTracking`
- 红灯 4当前 Provider 返回 SSE`response.completed.output` 可能为空、文本只出现在 `response.output_text.done/delta`;旧解析会等待连接关闭或拿不到结果。现已支持 SSE 增量、完成事件立即返回和 60 秒绝对超时。