Files
ycode/docs/上下文用量与分类修复-2026-10-18.md
T

42 lines
6.4 KiB
Markdown

# 上下文用量查询、恢复与分类修复
用户确认开发:修复用量无法获取、保存与时效问题,并显示系统提示词、工具、对话、连接器、技能的使用明细。此前[复核记录](上下文用量获取复核-2026-10-18.md)是诊断阶段,本文记录本轮实现。
## 已实现
- 新增 `session:context-usage` / `window.ycode.session.contextUsage(id)` 查询。优先使用当前消息的合法样本;旧记录可从对应 OMP 原生分支恢复最近请求输入数。查询不会创建、重建或切换 Agent,也不发送模型请求。
- 恢复校验 YCode 当前助手/请求、前一条用户消息的 nativeEntryId、应用自己的规范 transcript 路径及 native parent 链。兄弟分支有歧义、最终请求失败、最新回合尚未形成样本时不拾取更早的数字。扫描上限 16 MiB。
- 上游 input 与缓存 input 合计作为输入占用,output 不混入;工具循环使用最后一份样本,不能累加。未知历史窗口保持未知,仍展示已知 token 数;符合相同会话、模型与输入样本的已运行内核可补 runtime 窗口,读取超时最多约 1.8 秒。
- 恢复样本在原有 session 写锁内再次核对当前助手、请求和运行状态后缓存;不改变任务更新时间和侧栏顺序。查询期间新建回合、切分支或删除任务时,旧结果不能覆盖新状态。
- 增加 OMP `before_provider_request` 观测扩展,采集同一次实际 provider payload 的分类计数;只回传数字和来源元数据,不回传系统提示词正文。备用 Gateway 同样观察最终的 Chat Completions / Responses 请求体,不改变传输内容。
- 分组包含系统提示词、工具声明/调用/返回、对话、MCP、技能,另有非零才显示的“未归类”。来源采用本项目注入上下文和工具元数据;工具未调用时仍计入声明,历史工具结果仍计入当前请求。图像等无法计数的输入标记为部分统计。
- 分类是独立的 **UTF-8 字节估计**,不是供应商分项账单或模型专用 tokenizer 的精确结果。没有强制将分类之和缩放成上游总量。提供商隐藏封装、模型特定分词和多模态仍会造成差异。
- `context_breakdown` 与 `usage` 分别进入助手消息与 checkpoint,保留请求、顺序、采样时间、模型、窗口和来源。下一份准备输入使上一份总量失效;重复或较旧的分类事件不能抹掉较新的真实总量。非法或不属于该消息的持久化样本不复用。
- 界面保留原版 32px 入口和 280px 明细面板,显示分类的 `≈` 标记、来源、采样时间和刷新入口。缺分母显示“未知”;没有真实 usage 但已有分类时显示本地估计;换模型后保留的历史数据标记“上次请求”。查询结果与会话/最新消息/模型/采样身份绑定,防止迟到响应覆盖新输入。
- 每个回合的观测配置在结束后删除。长期保留的是计数快照;没有把 provider payload 或 API Key 写入统计结果。
## 实现边界与依据
新增主进程模块:`context-usage-service.ts`(查询与恢复)、`context-usage-estimator.ts`(来源分类及估计)、`omp-context-observer.ts`(请求前观测)。接入 `chat-turn-service.ts`、OMP 事件适配、备用 Gateway、共享消息投影、preload/IPC 和输入区明细。
扩展能力依据 OMP **v18.6.3** 的[公开扩展类型](https://github.com/can1357/oh-my-pi/blob/v18.6.3/packages/coding-agent/src/extensibility/extensions/types.ts)中 `before_provider_request` / `payload` 和[CLI 参数](https://github.com/can1357/oh-my-pi/blob/v18.6.3/packages/coding-agent/src/cli/args.ts)的扩展加载能力,并通过本机实际 OMP 请求验证。没有将旧 Ygent 文档当作当前实现证据,也没有读取或新采集 WorkBuddy。面板原有几何沿用固定 REA `ev_2569313a7a0aa901c5a3b8dc1d7fd190109b9006c915830109b62195f312376a`;新增来源说明是本地统计功能适配,不宣称全状态逐像素 1:1。
历史记录若未保留当次完整输入,只恢复有证据的总量;不使用今天的提示词、工具或模型窗口反推过去的分类。子 Agent 私有输入及服务端隐藏提示没有被虚构成已知明细。
## 验证
- `npm run test:context-usage`:原生缓存输入合计、最后工具轮次、兄弟分支拒绝、失败终态、非法路径、缺分母、已缓存样本、运行中不恢复、迟到查询与新回合竞争、来源分类、多模态部分统计、独立总量、重复事件及 Chat/Responses 最终请求体观察均通过。
- `npm run test:chat`、`npm run test:persistence`、`npm run test:conversation`、`npm run test:conversation-ipc` 通过。保存测试明确核对来源、请求/模型身份、采样时间与落盘一致。
- `npm run build` 包含 TypeScript 检查,生产构建通过;最终日志 `.tmp/context-usage-build-final.log`。
- 实际隔离 Electron / preload / IPC / OMP + 受控 localhost SSE 的最终专项报告 `.tmp/composer-context-X5SBih/report.json` **60 项通过、0 renderer 错误**,含实际请求前分类、上游用量、两套主题、模型窗口变化、重载、后续无 usage 请求、原生旧记录恢复、查询不创建内核及缓存元数据不重排任务。主上下文已查看明细浅色、深色截图;最终截图 `context-breakdown-light.png`、`context-breakdown-dark.png`、`context-native-recovered.png` 和 `context-usage-restored.png` 留存于同一报告目录。
测试使用隔离用户目录,没有修改用户实际会话、模型配置或向远端供应商发送测试消息。原生窗口查询也不因打开统计而重启内核。
中间测试记录:旧测试曾要求“最新无 usage 时取更早样本”和“缺分母隐藏所有数字”,本轮按修复后的语义更新断言;新 Responses 夹具曾遗漏合法成功终态的 status,修正夹具后双协议测试通过;暗色样式与请求几何仍保留检查,没有移除功能验收以绕过失败。
本轮子代理通道因模型切换后返回任务 sealed 错误,实施、集成与最终验收由主上下文接续完成。保留工作区其它未提交改动,没有新增提交。
## 用户窗口
生产资源已构建,当前用户窗口没有被强制终止,以免清空不可读取的未发送草稿。本次包含主进程、preload 和 renderer 改动,保存草稿后需要完整退出并重启 YCode;仅刷新界面不能加载全部修复。