
opencode-goal 插件的上下文自动压缩是如何工作的范围:opencode-goal 插件(src/server.ts)的自动压缩链路。实现以官方session.summarizeAPI 为唯一压缩手段,插件只负责何时压、压什么模型、压完如何收尾。下文 file:line 均指本仓库当前 main。1. 触发三门(should_auto_compact)一次评估必须同时满足,缺一不压:limit有效(context_limit,默认 400000,读:src/server.ts:122;null/0 不压缩);last_tokens已知且 limit;model已知(压缩要指明用哪个模型跑 summarize,模型未知绝不压)。2. 上下文大小的三个来源按优先级:事件写点:message.updated/experimental.chat.messages.transform把官方tokenTotal口径(inputoutputreasoningcache.readcache.write)写入session_last_tokens。兜底拉取:写点缺失或陈旧超 90s 时,TICK 主动调session.messages取最近普通助手消息用量(读:src/server.ts:2274),成功 30s 内不重拉,失败 5s 后重试。模型回填:用量回来了但模型未知时,再经session.get取模型;取不到本轮不压。只读缓存用量(cache.read/write)的 provider 永不触发——这是口径用全五项的原因。3. 状态机:pending / cooldown / 失败退避触发前先过两道时间窗(读:src/server.ts:2339):session_compact_pending:压缩进行中窗口,窗内禁止续推也禁止重压;session_compact_cooldown:触发后/成功后/失败后冷却。arm_compact_windows一次武装三件事:清掉压缩前的旧 token 缓存、设 pending、设 cooldown。失败走指数退避(C1):180s × 2^count,封顶 ×16,新进展重置计数。默认值:参数默认Envcontext_limit400000—compact_cooldown_ms60000GOAL_COMPACT_COOLDOWN_MScompact_fail_cooldown_ms60000GOAL_COMPACT_FAIL_COOLDOWN_MScompact_post_cooldown_ms60000GOAL_COMPACT_POST_COOLDOWN_MScompact_pending_floor_ms180000GOAL_COMPACT_PENDING_FLOOR_MS4. 执行:一次发后即忘的 summarizesummarize.call(session,{path:{id:session_id},body:{providerID,modelID,auto:true},})调用发后即忘,失败走on_fail(清 pending、武装失败冷却、记 error 日志),绝不抛错阻断 TICK。压缩进行中,run_auto_continue直接跳过续推——压缩中途塞入超大续推会污染上下文并饿死压缩。5. 完成信号与收尾权威成功信号是session.compacted事件:清 pending、清 token 缓存、武装成功后冷却、记账基线打-1哨兵重定基。压缩 agent 的中途消息(agent compaction)另行处理:失败则冷却翻倍(封顶 30 分钟),成功且带用量则同样收尾。6. 子代理:继承父阈值,自身配置优先auto_compact_children(读:src/server.ts:2457)每轮枚举父的全部子代理,不分 idle/busy,超限即压——idle 子恢复后续跑时上下文已超限会直接爆炸。阈值默认继承父的context_limit;子代理经update_plugin_config显式配置过自己的值(含null禁用)则以自身为准,父阈值不得覆盖。7. 手动路径共用同一状态机/goal compact(读:src/server.ts:3817):同样arm_compact_windows,只是auto: false;TICK 不会在手动压缩后立即补一次自动压缩。TUI 的压缩按钮(读:src/tui.ts:285)直接调session.summarize,跑在 UI 侧。8. 实战教训:summary token 污染致连压真机曾出现 3 分钟 3 连压。根因:官方 summary 消息的tokens字段计的是压缩前的旧上下文量(实测 357642),兜底拉取把它当成当前上下文,冷却一过立即重压。修复:抽公共is_summary_message(读:src/server.ts:359),兜底拉取、transform 上下文、extract_last_assistant_*三处统一跳过 summary/compaction 消息,只取最近普通助手消息。锁定测试:tests/test-server-helpers.mjssummary 跳过断言。9. 如何验证单元:tests/test-server-config.mjs(阈值解析)、test-server-helpers.mjs(用量提取与 summary 跳过)。集成:scripts/goal-compact-test.mjs(pending 抑制续推、成功后不立即重触发、窗口过后新超限重触发)、scripts/goal-child-compact-test.mjs(子继承/自身优先/事件缺位兜底)。线上:插件日志搜firing auto-compact看触发 token/limit/model;搜session.compacted确认完成;summarize failed则看失败冷却是否生效。