Compaction 上下文压缩
compaction.ts + pi-embedded-runner/compact.ts 实现了上下文压缩机制。
触发条件
- 上下文溢出: LLM 返回 context overflow 错误
- 最大重试:
MAX_OVERFLOW_COMPACTION_ATTEMPTS = 3 - 非压缩失败: 如果错误是
compaction_failure,不再尝试压缩
压缩策略 (compaction.ts)
核心算法:summarizeInStages()
1. 消息少或 token 少 → 直接 summarizeWithFallback()
2. 否则 → splitMessagesByTokenShare() 按 token 均分
3. 每个分片独立 summarize
4. 合并多个 summary → MERGE_SUMMARIES_INSTRUCTIONS自适应分块:computeAdaptiveChunkRatio()
- 基础比例:
BASE_CHUNK_RATIO = 0.4 - 最小比例:
MIN_CHUNK_RATIO = 0.15 - 安全边距:
SAFETY_MARGIN = 1.2(20% buffer) - 如果平均消息 > 10% 上下文窗口 → 减小分块比例
渐进降级:summarizeWithFallback()
1. 尝试完整 summarization
2. 失败 → 过滤掉过大消息(>50% context),summarize 剩余部分,注明被忽略的大消息
3. 再失败 → 纯文本描述 "Context contained X messages (Y oversized)"历史修剪:pruneHistoryForContextShare()
- 预算:
maxContextTokens * maxHistoryShare(0.5) - 循环丢弃最早的分块
- 每次丢弃后执行
repairToolUseResultPairing()修复孤立的 tool_result
实际压缩执行 (compact.ts)
compactEmbeddedPiSessionDirect() — 完整的压缩流程:
- 解析模型、获取 API key
- 设置 workspace 和 sandbox
- 加载技能、构建 system prompt
- 打开 session →
session.compact(customInstructions) - 估算压缩后 token 数
Lane 安全
compactEmbeddedPiSession() 使用双层 lane 队列,compactEmbeddedPiSessionDirect() 在已持有 lane 时使用,避免死锁。