mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
refactor(pi-compaction): 改为压力触发的观察遮蔽与空闲阈值整段摘要
原实现对所有工具结果(含 read)在下一次请求即替换为约 4K 的首尾存根, 不看上下文压力,导致模型看不到大文件中段;后台逐条语义摘要又反复改写 历史、打碎 prompt 缓存。参照 Anthropic 上下文编辑、Manus 与 JetBrains 观察遮蔽研究重构为: - L2:上下文达到阈值时在 turn_end 批量提交 Pi 原生 context_edit,把最近 keepRecentTurns 轮之外的旧 toolResult 换成确定性占位符;trigger/target 回差与 minClearTokens 保证少触发、一次清够;原始条目保留,可经 context_tree_query 取回 - L3:空闲 agent_settled 且超过绝对阈值时调用一次 ctx.compact - 阈值按绝对 token 计并受窗口比例约束,默认针对 1M 窗口(DeepSeek V4.1 Flash):遮蔽 200K→100K、整段摘要 400K - 删除逐条存根、语义 worker、soft/hard/target 比例与自行取消 Pi 压缩的门控; Pi 原生阈值压缩保留为最终安全网 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
a254d4fd68
commit
a6d8416c76
+34
-30
@@ -1,17 +1,20 @@
|
||||
# pi-compaction
|
||||
|
||||
High-performance unified context projection and compaction for Pi.
|
||||
Pressure-aware context masking and threshold compaction for Pi.
|
||||
|
||||
## Responsibilities
|
||||
|
||||
- incrementally index completed tool calls;
|
||||
- replace large tool results with deterministic bounded evidence stubs;
|
||||
- pass small tool results through unchanged whenever a stub would not be shorter;
|
||||
- refine large stubs with non-blocking semantic summaries;
|
||||
- expose one effective context projection to normal provider requests and Codex/SubAPI native compaction;
|
||||
- cancel Pi's raw threshold compaction until the effective lower-bound reaches the configured threshold;
|
||||
- retain original tool evidence through `context_tree_query`;
|
||||
- publish read-only effective metrics for the footer and context observer.
|
||||
Pi context management is layered; this extension owns the middle two layers:
|
||||
|
||||
- **L1 — entry truncation** (future `pi-overflow`): truncate new tool results as they are written. Not implemented here.
|
||||
- **L2 — observation masking** (this extension): under real context pressure, replace old tool results outside a protected recent window with deterministic one-line placeholders via Pi `context_edit` entries. Originals stay in the session untouched and are recoverable with `context_tree_query`.
|
||||
- **L3 — whole-context summary** (this extension): when the session idles (`agent_settled`) above the summary threshold, trigger `ctx.compact` once per leaf.
|
||||
- **Pi native threshold compaction** is the final safety net and is never blocked; this extension no longer cancels `session_before_compact` based on its own thresholds.
|
||||
|
||||
Additionally it:
|
||||
|
||||
- publishes one effective-context snapshot for normal provider requests and Codex/SubAPI native compaction;
|
||||
- maintains a masked-results ledger so `/context`, `/compaction-status`, the footer, and AutoReview see the same placeholders the model sees.
|
||||
|
||||
Context Mode remains responsible for preventing large external data from entering the session. RTK remains responsible for ordinary tool-output cleanup.
|
||||
|
||||
@@ -22,21 +25,21 @@ Configuration lives in the installed bundle's `config/pi-compaction.json` (the b
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"softRatio": 0.72,
|
||||
"hardRatio": 0.9,
|
||||
"targetRatio": 0.55,
|
||||
"deterministic": {
|
||||
"masking": {
|
||||
"enabled": true,
|
||||
"maxStubTokens": 1024
|
||||
"triggerTokens": 200000,
|
||||
"triggerRatio": 0.6,
|
||||
"targetTokens": 100000,
|
||||
"targetRatio": 0.35,
|
||||
"minClearTokens": 50000,
|
||||
"keepRecentTurns": 10,
|
||||
"minEntryTokens": 256,
|
||||
"excludeTools": ["ask_user_question"]
|
||||
},
|
||||
"semantic": {
|
||||
"enabled": true,
|
||||
"model": "default",
|
||||
"thinking": "low",
|
||||
"concurrency": 1,
|
||||
"minInputChars": 4000,
|
||||
"maxInputChars": 24000,
|
||||
"maxRetries": 2
|
||||
"summary": {
|
||||
"triggerTokens": 400000,
|
||||
"triggerRatio": 0.9,
|
||||
"thinking": "low"
|
||||
},
|
||||
"native": {
|
||||
"enabled": true
|
||||
@@ -44,7 +47,9 @@ Configuration lives in the installed bundle's `config/pi-compaction.json` (the b
|
||||
}
|
||||
```
|
||||
|
||||
Invalid or missing fields are normalized in memory.
|
||||
All thresholds are absolute token counts constrained by a context-window ratio: `effectiveThreshold = min(tokens, floor(ratio × contextWindow))`. Masking fires when `currentTokens ≥ triggerEff` and clears the oldest eligible results until `currentTokens - cleared ≤ targetEff`; if the clearable volume stays under `min(minClearTokens, triggerEff - targetEff)` nothing is masked, so masking is rare, batched, and hysteretic. `masking.target` is normalized below `masking.trigger` and `summary.trigger` above `masking.trigger` when a config would violate that ordering. Invalid or missing fields fall back to defaults in memory.
|
||||
|
||||
Masking never touches the most recent `keepRecentTurns` assistant turns, user/assistant messages, `excludeTools`, `SKILL.md` reads, entries already masked, or results smaller than `minEntryTokens`.
|
||||
|
||||
## Native providers
|
||||
|
||||
@@ -67,17 +72,16 @@ The gateway must have a compatible deployed version, model and available upstrea
|
||||
|
||||
## Session format
|
||||
|
||||
The only custom entry type is `pi-compaction`, version 1. Segment summary entries contain hashes, summaries, and source references; they never duplicate complete raw tool output. Native checkpoints use Pi compaction-entry details with the same kind/version.
|
||||
The extension writes no `segment-summary` or other custom entries for masking: L2 uses Pi's native `context_edit` entries (`{ type: "context_edit", targetId, replacement }`), which alter only future model context. The raw session entries — and therefore UI, exports, and the evidence ledger — are unchanged; every masked result remains recoverable through `context_tree_query`. Masking placeholders are deterministic single lines starting with `[pi-compaction] Earlier `.
|
||||
|
||||
Projection replaces a tool result only when the resulting summary plus its `Source:` recovery line is strictly shorter than the original text content. Small tool results are therefore passed through byte-for-byte and keep their original content parts, including any non-text parts. Because a stub is only larger than the text it would replace when the original is short, this comparison is the sole gate; no separate size option exists. Every indexed result remains recoverable through `context_tree_query` whether or not the message was replaced.
|
||||
|
||||
This implementation intentionally does not read legacy `context-prune-*` or `openai-codex-native-compaction` entries. Start a new session after switching to this extension.
|
||||
Compaction entries still carry `pi-compaction` version 1 details; native checkpoints use the same kind/version. This implementation intentionally does not read legacy `context-prune-*`, `openai-codex-native-compaction`, or older `segment-summary` entries. Start a new session after switching to this extension.
|
||||
|
||||
## Interfaces
|
||||
|
||||
- `context_tree_query`: recover original bounded tool evidence by source key or tool call ID.
|
||||
- `/compaction-status`: show raw/effective tokens, reclaimed tokens, confidence, segments, and pending semantic jobs.
|
||||
- `context_tree_query`: recover the original output of a tool result that pi-compaction cleared from context, by tool call ID (1–20 ids per call, bounded output). Use it when a `[pi-compaction] Earlier` placeholder lacks evidence needed for the current task.
|
||||
- `/compaction-status`: show raw/effective tokens, reclaimed tokens, confidence, segments, masked results, and generation.
|
||||
- Service `my-pi.pi-compaction.service.v1`: `getSnapshot`, `getMetrics`, and `query(sessionId, ids)` — `query` returns a placeholder record only for tool call IDs that are currently masked, so consumers such as the permission system's AutoReview see the same evidence the model does.
|
||||
|
||||
## Performance model
|
||||
|
||||
The first session hydration scans the branch once. Appended turns use delta projection and immutable cached snapshots. The `context` hook performs no model call and no session write. Semantic summaries run in a bounded background worker and become visible only at later safe event boundaries.
|
||||
The first session hydration scans the branch once. Appended turns use delta projection and immutable cached snapshots; the `context` hook performs no model call, no session write, and returns the message list unchanged except on the native-checkpoint path, where post-checkpoint `context_edit` entries are applied during projection. Masking drafts are produced in `turn_end` in one batch and only when both the trigger and the `minClear` hysteresis pass, so the hot path stays allocation-free for unprompted turns.
|
||||
|
||||
Reference in New Issue
Block a user