本工单汇总 5 个围绕上下文压缩与记忆管理的 PR(#3568-#3572),彼此独立,可分开评审。 ## 背景 上下文压缩管线负责在会话超出上下文预算时裁剪工具结果、必要时做摘要压缩。2.1.0 上下文重构(#3441)之后,这条管线在实际使用中暴露出三类问题: 1. 溢出恢复路径分叉:正常压缩与紧急(溢出重试)各走一套代码。重试会在成功前提交压缩候选历史,失败后又会把原始溢出错误盖掉。 2. 媒体处理不完整:带图/音的消息可能被摘要丢弃,工具结果裁剪可能剪掉媒体块,产生悬空媒体引用;会话日志中 ToolResult 内嵌的 base64 媒体也没有脱敏。 3. token 计账不准:预算没计 provider 实际发送的默认输出 schema(Ollama format、OpenAI response_format 等),媒体计费在估算器里重复,裁剪累计用 int 有溢出风险。 另有两个社区 issue 长期挂着停滞的修复 PR:#2970(原 PR #2971)、#2694(原 PR #2699),本次给出最小重做版。以上拆成 5 个 PR 分别提交。 ## 各 PR 内容 **#3568 统一压缩溢出恢复路径 + 会话日志媒体脱敏** 两条恢复路径合并为一条:紧急重试不再提前提交候选历史,失败时用 initCause 保留首个溢出为根因。SessionRecorder 的 request/prepared 事件现在递归脱敏 ToolResult 内嵌媒体(base64 载荷、内联文件字节),压缩开始/结束事件在两条路径上成对发出。 **#3569 压缩保留媒体消息,摘要中用占位符** 媒体块在摘要输入里替换为占位符 + 摘要引用(原始内容留在保留段,不把原始字节送给摘要模型);工具结果裁剪跳过含媒体的块,避免产生悬空引用。 **#3570 统一 token 计账,计入 provider 默认输出 schema** 计账收拢到 TokenAccountingService:文本 + 工具 + 媒体 + 输出预留 + 响应格式 schema 一起计,按各 provider 的实际 wire 格式(含 Ollama 对象 schema 的 JSON 表示检测);裁剪累计 int 改 long。 **#3571 cutoff≤0 时返回轻量裁剪结果(修 #2970)** compactStandard 裁剪有变化但安全 cutoff 为 0 时原本返回 Optional.empty(),中间件保留原始输入,下一轮请求再次超限。现在该分支返回裁剪后的消息,与另一早返回分支行为对齐;无变化时仍返回 empty。 **#3572 disableMemoryHooks 时压缩不再刷记忆(修 #2694)** disableMemoryHooks() 原本只关掉每轮 flush 和后台整理,压缩时仍会从摘要前缀刷一次长期记忆。CompactionMiddleware 增加 memoryHooksEnabled 开关,由 HarnessAgent 传入;直接构造的中间件保持原行为。 ## CI 说明 #3569、#3570、#3571 的远程检查目前是红的,失败用例是 #3441 引入的 JEV 测试(不在这些 PR 的 diff 里),表现为负载/超时类 flaky。
Activity
[-]Context compaction and memory hardening: PR series (#3568-#3572)[/-][+]上下文压缩与记忆管理:PR 系列(#3568-#3572)[/+]