pi-midcompact 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,14 +1,104 @@
1
1
  # pi-midcompact
2
2
 
3
- **Compress stale parts of a long Pi session without deleting the original history.**
3
+ [简体中文](./README.zh-CN.md)
4
4
 
5
- Long-running work accumulates exploration, command output, rejected approaches, and completed phases. `pi-midcompact` lets you and the Agent replace only the parts you have reviewed with concise summaries, leaving the current task and important decisions in full context.
5
+ **Attention-aware mid-context compression: compress the noise, keep the signal.**
6
+
7
+ “Attention-aware” borrows the core idea of neural attention: keep in working context what future work still needs to attend to, rather than deciding from message age alone. A long session does not become stale uniformly. Exploratory reads, failed attempts, routine tool output, and implementation work that is already complete can occupy most of the context window after their value has largely expired. A user requirement, hard-won decision, or unresolved failure from much earlier may still need to remain verbatim.
8
+
9
+ Pi's built-in `/compact` behaves like **prefix compaction**: it turns an older contiguous prefix into one summary and retains a recent tail. That is appropriate automatic maintenance, but the cut itself does not distinguish a dispensable old exploration from an older decision worth keeping raw.
10
+
11
+ The name `pi-midcompact` points to the other option: **mid-context compression**. It compresses selected spans inside the active context while leaving valuable raw context on either side in place, and preserves the original session history for recall.
6
12
 
7
13
  - Choose exactly which conversation ranges to compress.
8
14
  - Review the proposed boundaries and summaries before anything changes.
9
15
  - Keep the original Pi session entries available for later recall.
10
16
  - Keep compression local to the current session-tree branch.
11
17
 
18
+ ## What it does
19
+
20
+ At a natural checkpoint, `pi-midcompact` freezes the active session leaf as an anchor and opens a separate transaction. The Agent proposes ranges for completed low-value phases, preserves load-bearing messages verbatim, and prepares a draft for review. Nothing changes until you explicitly commit the plan.
21
+
22
+ ### User-directed depth, Agent-designed plan
23
+
24
+ The workflow is **Agent-driven but user-directed**. You describe the desired retention depth and what must remain visible; the Agent examines the frozen anchor, discusses trade-offs with you, and drafts selective ranges and summaries. You do not need to select atom IDs yourself.
25
+
26
+ > “I only want to reclaim roughly 30% of the stale context. Do not compress aggressively; keep the reasoning behind earlier decisions verbatim.”
27
+
28
+ That is planning guidance, not an enforced token target: semantic importance wins over an exact percentage. The Agent turns it into a reviewable proposal—selected ranges, explicit `KEEP` holes, and summaries—then you approve, revise, or reject it before committing.
29
+
30
+ ### A selective projection, prepared on a temporary branch
31
+
32
+ `/midcompact start` freezes the current session leaf as an **anchor**. Planning happens on a disposable child branch, so the discussion used to create and edit the draft never becomes part of the committed working context.
33
+
34
+ ```text
35
+ Frozen anchor: raw session history
36
+
37
+ [early exploration]──[decision to KEEP]──[routine tool output]──[latest work] ◀ anchor
38
+ ╰──── d1 ────╯ ╰──── d2 ────╯
39
+
40
+ Planning is isolated on a temporary branch:
41
+
42
+ ... [latest work] ──┬── [transaction] ── [draft v1] ── [draft v2] ◀ review / edit
43
+ │ (abandoned at commit)
44
+ └── [midcompact-state] ◀ committed leaf
45
+ (reviewed selection metadata, not a model message; written only by /midcompact commit)
46
+
47
+ Later model requests see a selective projection:
48
+
49
+ [summary d1]──[decision to KEEP]──[summary d2]──[latest work]
50
+
51
+ The raw session JSONL still contains:
52
+
53
+ [original d1]──[decision to KEEP]──[original d2]──[latest work]
54
+ ```
55
+
56
+ ### A reviewed draft can reclaim meaningful context
57
+
58
+ The browser review captured below selects **42 of 73 atoms** in **2 ranges**: approximately **31.0k → 488 tokens**, for an estimated **30.6k-token reduction**. The other 31 atoms remain unselected and visible as raw context. Click either image to open it at full resolution.
59
+
60
+ <p align="center">
61
+ <a href="./figures/review-webui.png">
62
+ <img src="./figures/review-webui.png" alt="Browser review UI showing 42 of 73 atoms selected across two compression ranges" width="49%">
63
+ </a>
64
+ <a href="./figures/review-tui.png">
65
+ <img src="./figures/review-tui.png" alt="Native TUI review showing a selected compression range and its retained atoms" width="49%">
66
+ </a>
67
+ </p>
68
+
69
+ <p align="center"><sub>Editable browser review UI · Native Pi TUI review</sub></p>
70
+
71
+ ### Prefix compaction versus mid-context compression
72
+
73
+ Both mechanisms preserve the stored JSONL history, but they decide what later model requests see in different ways:
74
+
75
+ ```text
76
+ Pi built-in /compact — automatic threshold or one manual command
77
+
78
+ [older contiguous history────────────────────][recent tail]
79
+
80
+
81
+ [one compaction summary──────────────────────][recent tail]
82
+
83
+ pi-midcompact — mid-context compression, review, then human commit
84
+
85
+ [stale phase]──[load-bearing decision]──[routine output]──[recent work]
86
+ d1 KEEP d2
87
+ │ │
88
+ ▼ ▼
89
+ [summary d1]──[load-bearing decision]──[summary d2]──[recent work]
90
+ ```
91
+
92
+ | | Pi `/compact` | `pi-midcompact` |
93
+ | --- | --- | --- |
94
+ | Starts | Automatically near the context limit, or with `/compact` | At an explicit natural checkpoint with `/midcompact start` |
95
+ | Selects | One older contiguous prefix; keeps a recent token-budgeted tail | One or more reviewed ranges, including non-contiguous ranges and `KEEP` holes |
96
+ | Planning | Optional one-shot instruction to focus the generated summary | User states scope and retention depth; the Agent discusses trade-offs and drafts selective ranges and summaries |
97
+ | Decision gate | Generates a compaction checkpoint directly | Draft → TUI or browser review → explicit human `/midcompact commit` |
98
+ | Best fit | Automatic context maintenance and overflow recovery | Deliberate cleanup of completed phases while retaining specific decisions verbatim |
99
+
100
+ `pi-midcompact` does not disable or replace Pi's automatic compaction; it gives you a separate, human-reviewed way to make selective reductions. See [Pi's compaction documentation](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/docs/compaction.md) for the built-in mechanism.
101
+
12
102
  ## Install
13
103
 
14
104
  From npm:
@@ -34,10 +124,14 @@ Start a transaction at a natural breakpoint: the current work is complete enough
34
124
  Run:
35
125
 
36
126
  ```text
37
- /midcompact
127
+ /midcompact start
38
128
  ```
39
129
 
40
- Pi creates a temporary transaction after the anchor and tells the Agent how to plan the compression. No conversation is changed yet.
130
+ Pi asks for confirmation, then creates a temporary transaction after the anchor and tells the Agent how to plan the compression. No conversation is changed yet. You can include the initial scope in the same command:
131
+
132
+ ```text
133
+ /midcompact start Compress the early repository exploration, but keep user requirements verbatim.
134
+ ```
41
135
 
42
136
  ### 2. Discuss what to compress with the Agent
43
137
 
@@ -46,7 +140,7 @@ Describe the goal in normal language. For example:
46
140
  ```text
47
141
  Compress the early repository exploration and routine command output.
48
142
  Keep the user's requirements, the rejected database decision, and the final validation errors verbatim.
49
- Aim for a moderate reduction, not the smallest possible context.
143
+ Reclaim roughly 30% of the stale context, but preserve semantic distinctions rather than chasing an exact token number.
50
144
  ```
51
145
 
52
146
  The Agent locates relevant parts of the frozen conversation, proposes one or more ranges, and writes a summary for each range. You can ask it to preserve a specific message, split a range, or revise a summary.
@@ -59,9 +153,15 @@ Run:
59
153
  /midcompact review
60
154
  ```
61
155
 
62
- The native TUI displays the frozen conversation as a linear timeline. Each item is marked either `KEEP` or as belonging to a proposed range. Review the range boundaries and the summary that will replace each range.
156
+ In interactive mode, the native TUI displays the frozen conversation as a linear timeline. Each item is marked either `KEEP` or as belonging to a proposed range. Review the range boundaries and the summary that will replace each range.
157
+
158
+ For RPC, print, or other no-TUI modes, use the editable local browser interface instead:
159
+
160
+ ```text
161
+ /midcompact review-webui
162
+ ```
63
163
 
64
- You can edit a selected summary or topic in the TUI. To change range boundaries or leave an important hole uncompressed, tell the Agent what to keep and ask it to revise the plan, then review it again.
164
+ You can edit a selected summary or topic, remove a range, and switch between compression ranges in either review surface. To change range boundaries or leave an important hole uncompressed, tell the Agent what to keep and ask it to revise the plan, then review it again.
65
165
 
66
166
  ### 4. Commit the reviewed compression
67
167
 
@@ -75,8 +175,6 @@ This is deliberately a human command. The Agent cannot commit compression itself
75
175
 
76
176
  Pi returns to the anchor, discards the temporary planning branch, stores the reviewed compression state, and resumes work from the committed branch. Future model requests receive the selected old ranges as summaries instead of raw messages.
77
177
 
78
- ![A compression transaction keeps planning separate from the working branch.](./figures/transaction-lifecycle.svg)
79
-
80
178
  ### 5. Continue working or abort
81
179
 
82
180
  Keep working normally after committing. If you decide not to compress, run:
@@ -87,37 +185,7 @@ Keep working normally after committing. If you decide not to compress, run:
87
185
 
88
186
  This returns to the anchor and discards the transaction without changing the active context.
89
187
 
90
- ## What the Agent Does
91
-
92
- During an active transaction, the Agent uses the `midcompact` tool against the frozen anchor snapshot:
93
-
94
- ![How the Agent turns semantic judgment into a reviewed compression plan.](./figures/agent-planning.svg)
95
-
96
- | Action | Purpose |
97
- | --- | --- |
98
- | `locate` | Finds likely conversation landmarks and shows readable previews. |
99
- | `plan` | Adds, revises, removes, or displays proposed compression ranges and summaries. |
100
- | `recall` | Searches committed summaries or temporarily retrieves original content from a compressed block. |
101
-
102
- The Agent makes semantic decisions: which exploration is stale, which user requirements and decisions must stay visible, and what a useful summary needs to retain. The extension enforces the mechanical rules: ranges cannot overlap, incomplete tool exchanges cannot be compressed, and the Agent cannot bypass the human commit gate.
103
-
104
- Temporary references such as `a0007` exist only during planning. They are not inserted into normal prompts or retained as permanent message identifiers.
105
-
106
- ## What Happens Behind the Scenes
107
-
108
- A committed compression does not rewrite or delete the Pi session.
109
-
110
- ![Compression replaces a reviewed range only in later model requests.](./figures/context-projection.svg)
111
-
112
- 1. `/midcompact` freezes the current session-tree leaf as the anchor and starts a temporary maintenance branch.
113
- 2. The Agent and you discuss a draft on that branch. This planning chatter is abandoned at commit.
114
- 3. `/midcompact commit` returns to the anchor and saves a branch-local `midcompact-state` entry containing the reviewed ranges and summaries.
115
- 4. Before later model requests, the extension finds the exact selected raw message sequences and projects them into summary messages.
116
- 5. The underlying session entries remain unchanged. If an exact match cannot be found, the extension keeps the raw messages rather than removing uncertain content.
117
-
118
- This is why the process is both selective and reversible at the information-access level: a summary saves context, while the source history remains available through recall or the Pi session tree.
119
-
120
- ## Review Controls
188
+ ## Native TUI Controls
121
189
 
122
190
  Inside `/midcompact review`:
123
191
 
@@ -136,8 +204,9 @@ Enter/Esc/q close
136
204
 
137
205
  | Command | Result |
138
206
  | --- | --- |
139
- | `/midcompact` | Starts a transaction at the current session-tree leaf. |
140
- | `/midcompact review` | Opens the draft review timeline. |
207
+ | `/midcompact start [instructions]` | Confirms and starts a transaction at the current session-tree leaf, optionally with an initial compression focus. |
208
+ | `/midcompact review` | Opens the draft review timeline in the native TUI; in non-TUI modes, points to `review-webui`. |
209
+ | `/midcompact review-webui` | Starts an editable local browser review page; works without a TUI. |
141
210
  | `/midcompact commit` | Commits the reviewed draft. Human only. |
142
211
  | `/midcompact abort` | Abandons the transaction and returns to the anchor. |
143
212
  | `/midcompact status` | Displays the current draft, or the committed compression state on this branch. |
@@ -147,9 +216,12 @@ The extension shows planning status in Pi's footer only while a transaction is a
147
216
  ## Guarantees and Limits
148
217
 
149
218
  - **Original history is retained.** Compression changes what later model requests see, not the stored Pi messages.
219
+ - **Fail-open projection.** If an exact reviewed sequence no longer resolves, the extension sends the raw history unchanged rather than removing uncertain content.
150
220
  - **State is branch-local.** Navigating with `/tree` to a point before a committed state restores raw history; returning to its descendant restores the projection.
151
221
  - **Human review is required.** The Agent can propose a plan but cannot execute `/midcompact commit`.
152
222
  - **Tool protocol is protected.** Unknown, incomplete, or orphaned tool exchanges are not compressible.
153
223
  - **Repeated transactions work.** Later transactions can compress newly accumulated raw context; existing summaries remain protected.
154
224
  - **Native Pi `/compact` interaction needs more real-session validation.** Avoid relying on mixed automatic/native compaction behavior for critical work until it has been exercised in your environment.
155
- - **Review is TUI-only.** There is no browser review interface in this version.
225
+ - **Provider and extension interoperability needs more real-session validation.** Unusual message shapes, third-party context-transform ordering, and long-lived exact message fingerprints have not been broadly exercised.
226
+ - **Very long sessions are not stress-tested.** Large review snapshots and repeated block accumulation may eventually require consolidation.
227
+ - **Browser review is local.** `review-webui` binds to loopback, opens an editable review page, and keeps the draft mutations in the same branch-local transaction as the native TUI.
@@ -0,0 +1,227 @@
1
+ # pi-midcompact
2
+
3
+ [English](./README.md)
4
+
5
+ **Attention-aware 的上下文中段压缩:压缩噪声,保留关键信息。**
6
+
7
+ 这里的 Attention-aware 借用注意力机制的核心想法:保留与压缩的判断,要看后续工作仍需关注什么,不能只按消息新旧划分。长会话里的内容不会同时失去价值。早期探索、失败尝试、常规工具输出,以及已经完成的实现过程,在对应工作结束后往往只有很少的后续价值,却可能占据大部分上下文。相比之下,较早的用户需求、关键决策或尚未解决的错误,仍可能需要保留原文。
8
+
9
+ Pi 内置的 `/compact` 可理解为**前缀压缩**(prefix compaction):它把一段较早的连续历史汇总为一份摘要,并保留近期上下文。这适合自动维护会话;不过,切分边界本身不会区分可舍弃的早期探索和应保留原文的较早决策。
10
+
11
+ `pi-midcompact` 名称中的 mid 指向另一种做法:**上下文中段压缩**(mid-context compression)。它在活跃上下文内部选择区段压缩,让两侧仍有价值的内容保留原文,并保留原始会话历史,供需要时召回。
12
+
13
+ - 可选择多个对话区段进行压缩。
14
+ - 区段边界和摘要均须审查后才会生效。
15
+ - 原始 Pi 会话条目可在需要时由 Agent 召回。
16
+ - 压缩状态只在当前会话树分支生效。
17
+
18
+ ## 它解决什么问题
19
+
20
+ 在合适的工作节点,`pi-midcompact` 会把当前会话叶节点冻结为锚点,并开启独立事务。Agent 负责为已经完成、后续价值较低的阶段拟定压缩区段,关键消息保留原文;草案必须经过审查,只有显式提交后才会生效。
21
+
22
+ ### 用户确定方向,Agent 设计方案
23
+
24
+ 这套流程由 Agent 推动,方向由用户确定。用户只需说明希望保留什么、准备压缩到什么程度;Agent 会查看冻结后的锚点,与用户讨论取舍,拟定待压缩区段和摘要。用户不必自己定位对话原子编号。
25
+
26
+ > “我只想回收大约 30% 的陈旧上下文,不要压得太狠;早期决策背后的推理请保留原文。”
27
+
28
+ 这里的比例只作规划参考,语义上的重要性高于精确比例。Agent 会把要求转成一份可审查的方案:列出拟压缩区段、明确 `KEEP` 保留区,并为每个区段撰写摘要。用户可以批准、修改或否决,再决定是否提交。
29
+
30
+ ### 在临时分支中规划,提交后选择性投影
31
+
32
+ `/midcompact start` 会把当前会话叶节点冻结为**锚点**。规划工作发生在临时子分支上,因此用于制定和修改草案的对话不会进入提交后的工作上下文。
33
+
34
+ ```text
35
+ 冻结锚点:原始会话历史
36
+
37
+ [早期探索]────[保留的决策]────[常规工具输出]────[最近工作] ◀ 锚点
38
+ ╰── d1 ──╯ ╰── d2 ──╯
39
+
40
+ 规划工作在临时分支上进行:
41
+
42
+ ... [最近工作] ──┬── [事务] ── [草案 v1] ── [草案 v2] ◀ 审查 / 修改
43
+ │ (提交时舍弃)
44
+ └── [midcompact-state] ◀ 提交后的叶节点
45
+ (记录已审查的选择;不是模型消息;仅由 /midcompact commit 写入)
46
+
47
+ 后续模型请求看到的是选择性投影后的上下文:
48
+
49
+ [d1 摘要]────[保留的决策]────[d2 摘要]────[最近工作]
50
+
51
+ 原始会话 JSONL 仍保留:
52
+
53
+ [d1 原文]────[保留的决策]────[d2 原文]────[最近工作]
54
+ ```
55
+
56
+ ### 实际压缩效果
57
+
58
+ 下方浏览器审查界面中的草案包含 **2 个区段**,覆盖 **73 个对话原子(atom,最小可压缩单元)中的 42 个**:约从 **31.0k token 降至 488 token**,预计减少 **30.6k token**。其余 31 个原子未被选中,仍以原文留在上下文中。点击图片可查看原图。
59
+
60
+ <p align="center">
61
+ <a href="./figures/review-webui.png">
62
+ <img src="./figures/review-webui.png" alt="浏览器审查界面:73 个对话原子中有 42 个分布在两个压缩区段内" width="49%">
63
+ </a>
64
+ <a href="./figures/review-tui.png">
65
+ <img src="./figures/review-tui.png" alt="原生 TUI 审查界面:展示选中的压缩区段及其中的对话原子" width="49%">
66
+ </a>
67
+ </p>
68
+
69
+ <p align="center"><sub>可编辑的浏览器审查界面 · Pi 原生 TUI 审查界面</sub></p>
70
+
71
+ ### 前缀压缩与上下文中段压缩
72
+
73
+ 两种机制都保留 JSONL 中存储的原始历史,但它们决定后续模型请求内容的方式不同:
74
+
75
+ ```text
76
+ Pi 内置 /compact —— 达到阈值时自动执行,或手动执行一次命令
77
+
78
+ [较早的一段连续历史────────────────────][保留的近期上下文]
79
+
80
+
81
+ [一份压缩摘要──────────────────────────][保留的近期上下文]
82
+
83
+ pi-midcompact —— 上下文中段压缩,审查后由用户提交
84
+
85
+ [陈旧阶段]────[关键决策]────[常规输出]────[近期工作]
86
+ d1 KEEP d2
87
+ │ │
88
+ ▼ ▼
89
+ [d1 摘要]────[关键决策]────[d2 摘要]────[近期工作]
90
+ ```
91
+
92
+ | 项目 | Pi `/compact` | `pi-midcompact` |
93
+ | --- | --- | --- |
94
+ | 开始条件 | 接近上下文上限时自动触发,或运行 `/compact` | 在合适的工作节点运行 `/midcompact start` |
95
+ | 选择范围 | 一段较早的连续前缀,并按 token 预算保留近期内容 | 一个或多个经过审查的区段;支持不连续区段和 `KEEP` 保留区 |
96
+ | 规划方式 | 支持一次性指令,用于限定生成摘要的重点 | 用户说明范围和保留深度;Agent 讨论取舍并拟定区段与摘要 |
97
+ | 提交约束 | 直接生成压缩检查点 | 先形成草案,再用 TUI 或浏览器审查,最后由用户运行 `/midcompact commit` |
98
+ | 适用场景 | 自动维护上下文、从上下文溢出中恢复 | 清理已经完成的工作阶段,同时保留特定决策原文 |
99
+
100
+ `pi-midcompact` 不会关闭或替代 Pi 的自动压缩;它提供另一条经过人工审查的选择性压缩路径。Pi 内置机制可参阅 [Pi 的 compaction 文档](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/docs/compaction.md)。
101
+
102
+ ## 安装
103
+
104
+ 从 npm 安装:
105
+
106
+ ```bash
107
+ pi install npm:pi-midcompact
108
+ ```
109
+
110
+ 从 GitHub 安装:
111
+
112
+ ```bash
113
+ pi install git:github.com/frostime/pi-midcompact
114
+ ```
115
+
116
+ 安装后重启 Pi,或运行 `/reload`。此扩展适用于 Pi `0.84.x`。
117
+
118
+ ## 使用方法
119
+
120
+ 应在合适的工作节点启动事务:当前阶段已完成到足以概括的程度,且 Pi 处于空闲状态。当前节点会成为冻结的**锚点**。Agent 只针对这个快照拟定方案,之后的规划对话不会意外进入被压缩的工作上下文。
121
+
122
+ ### 1. 设置压缩检查点
123
+
124
+ 运行:
125
+
126
+ ```text
127
+ /midcompact start
128
+ ```
129
+
130
+ Pi 会要求确认,随后在锚点之后创建临时事务,并提示 Agent 开始规划。此时尚未改动任何会话内容。也可以在命令中直接写明初始范围:
131
+
132
+ ```text
133
+ /midcompact start 压缩前期仓库探索过程,但保留用户需求原文。
134
+ ```
135
+
136
+ ### 2. 与 Agent 讨论压缩方案
137
+
138
+ 直接用自然语言说明目标,例如:
139
+
140
+ ```text
141
+ 压缩前期仓库探索和常规命令输出。
142
+ 保留用户需求、被否决的数据库方案,以及最终验证错误的原文。
143
+ 希望回收约 30% 的陈旧上下文,但不要为了凑精确数字而丢失语义差别。
144
+ ```
145
+
146
+ Agent 会在冻结的会话快照中定位相关内容,提出一个或多个区段,并为每个区段撰写摘要。可以要求它保留某条消息、拆分区段,或重写摘要。
147
+
148
+ ### 3. 审查草案
149
+
150
+ 运行:
151
+
152
+ ```text
153
+ /midcompact review
154
+ ```
155
+
156
+ 在交互模式下,原生 TUI 会把冻结的对话显示为线性时间线。每个条目都会标为 `KEEP`,或标明其所属的拟压缩区段。请检查区段边界,以及将用来替换原文的摘要。
157
+
158
+ 在 RPC、print 或其他没有 TUI 的模式下,请改用可编辑的本地浏览器界面:
159
+
160
+ ```text
161
+ /midcompact review-webui
162
+ ```
163
+
164
+ 两种审查界面都可以修改所选区段的摘要或主题、移除区段、切换不同区段。若需调整边界,或保留一个重要的未压缩部分,请告诉 Agent 保留什么,并要求它修订方案后再次审查。
165
+
166
+ ### 4. 提交已审查的压缩
167
+
168
+ 方案确认后,运行:
169
+
170
+ ```text
171
+ /midcompact commit
172
+ ```
173
+
174
+ 这个命令只能由用户执行,Agent 无法自行提交压缩。
175
+
176
+ Pi 会回到锚点,放弃临时规划分支,保存已审查的压缩状态,然后从提交后的分支继续工作。后续模型请求会收到所选旧区段的摘要,而不是原始消息。
177
+
178
+ ### 5. 继续工作或放弃事务
179
+
180
+ 提交后可以继续正常工作。若决定不压缩,运行:
181
+
182
+ ```text
183
+ /midcompact abort
184
+ ```
185
+
186
+ 该命令会回到锚点,丢弃事务,不改变当前生效的上下文。
187
+
188
+ ## 原生 TUI 快捷键
189
+
190
+ 在 `/midcompact review` 中:
191
+
192
+ ```text
193
+ n/p 或 Left/Right 选择拟压缩区段
194
+ Up/Down、j/k 滚动
195
+ PgUp/PgDn 翻页
196
+ x 展开所选区段中的对话原子
197
+ e 编辑所选摘要
198
+ t 编辑所选主题
199
+ d 移除所选区段
200
+ Enter/Esc/q 关闭
201
+ ```
202
+
203
+ ## 命令
204
+
205
+ | 命令 | 作用 |
206
+ | --- | --- |
207
+ | `/midcompact start [instructions]` | 确认后在当前会话树叶节点启动事务;可选地提供初始压缩重点。 |
208
+ | `/midcompact review` | 在原生 TUI 中打开草案审查;非 TUI 模式下会提示使用 `review-webui`。 |
209
+ | `/midcompact review-webui` | 启动可编辑的本地浏览器审查页面;无需 TUI。 |
210
+ | `/midcompact commit` | 提交已审查的草案;只能由用户执行。 |
211
+ | `/midcompact abort` | 放弃事务并回到锚点。 |
212
+ | `/midcompact status` | 显示当前草案,或本分支已提交的压缩状态。 |
213
+
214
+ 扩展只在事务进行期间在 Pi 页脚显示规划状态;提交或放弃后会自动清除。
215
+
216
+ ## 保证与限制
217
+
218
+ - **保留原始历史。** 压缩只改变后续模型请求看到的内容,不改写存储的 Pi 消息。
219
+ - **匹配失败时保留原文。** 若无法精确定位已审查的消息序列,扩展会原样发送历史,而不会删除不确定的内容。
220
+ - **状态只在分支内生效。** 用 `/tree` 回到压缩状态之前的节点会恢复原始历史;回到其后代节点则恢复投影。
221
+ - **必须人工审查。** Agent 可以提出方案,不能执行 `/midcompact commit`。
222
+ - **保护工具调用协议。** 未知、不完整或孤立的工具调用交互不能压缩。
223
+ - **支持重复事务。** 后续事务可以继续压缩新积累的原始上下文;已有摘要保持受保护状态。
224
+ - **与 Pi 原生 `/compact` 的组合仍需更多真实会话验证。** 在完成充分验证前,不应在关键工作中依赖两者混用。
225
+ - **Provider 与扩展互操作性仍需更多真实会话验证。** 非常规消息形态、第三方上下文转换顺序,以及长时间运行的精确消息指纹尚未得到广泛验证。
226
+ - **超长会话尚未完成压力测试。** 审查快照很大、压缩块反复累积时,最终可能需要进一步整合。
227
+ - **浏览器审查仅在本机开放。** `review-webui` 绑定到 loopback 地址,提供可编辑的审查页面;其草案修改与原生 TUI 使用同一条分支事务。
Binary file
Binary file
@@ -52,7 +52,7 @@
52
52
  <circle cx="245" cy="505" r="23" class="anchor"/>
53
53
  <polygon points="245,489 249,499 260,499 251,506 255,517 245,511 235,517 239,506 230,499 241,499" fill="#2563eb"/>
54
54
  <text x="290" y="512" class="label blue">T50 · anchor</text>
55
- <text x="290" y="537" class="small blue">/midcompact freezes the snapshot here</text>
55
+ <text x="290" y="537" class="small blue">/midcompact start freezes here</text>
56
56
 
57
57
  <!-- maintenance branch -->
58
58
  <path d="M268 505 H 575" class="dash"/>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-midcompact",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "Branch-aware mid-context compression for the Pi coding agent",
5
5
  "author": "frostime",
6
6
  "repository": {
@@ -27,6 +27,7 @@
27
27
  "src",
28
28
  "skills",
29
29
  "README.md",
30
+ "README.zh-CN.md",
30
31
  "figures"
31
32
  ],
32
33
  "scripts": {
@@ -1,57 +1,117 @@
1
1
  ---
2
2
  name: midcompact
3
- description: Use during an active /midcompact transaction to selectively compress stale middle sections of a long Pi conversation, or later to recall exact details from compressed blocks.
3
+ description: Use during an active /midcompact transaction to plan and draft selective compression of stale middle sections of a long Pi conversation, or independently to retrieve details from previously compressed blocks. Covers how to choose compression ranges, how to negotiate compression depth with the user, and the midcompact tool interface.
4
4
  ---
5
5
 
6
6
  # Midcompact
7
7
 
8
- Use this skill only when a `/midcompact` transaction is active, or when exact information must be recovered from a previously compressed block.
8
+ Use this skill when a `/midcompact start` transaction is active, or when information must be retrieved from a previously compressed block.
9
9
 
10
- ## Mental model
10
+ ## What compression does
11
11
 
12
- The transaction is based on a frozen anchor snapshot. Maintenance discussion, locator calls, draft revisions, and review happen on a temporary branch. A successful commit returns to the anchor without summarizing that maintenance branch, then stores only the reviewed compression projection.
12
+ Mid-context compaction is **selective replacement** inside one linear conversation, not a restart:
13
13
 
14
- The extension handles session-tree mechanics and protocol safety. You decide semantic value.
14
+ ```
15
+ A → B → C → ... → NOW
16
+ └─ selected slices become summaries; everything else stays verbatim
17
+ ```
15
18
 
16
- Do not infer importance from a tool name. A user constraint, approval, correction, decision, or other critical fact may appear inside any message or tool exchange. Inspect actual content.
19
+ Three mechanical facts shape how you work:
17
20
 
18
- ## Context awareness
21
+ - **KEEP by omission.** Anything outside a draft range stays verbatim. You declare only what to compress, never what to preserve.
22
+ - **Originals survive.** Session entries stay on disk, and `action="recall"` brings an active committed block back into view. Compression is reversible at the information-access level, not a deletion — but recall returns a readable rendering, not a byte-exact replay, so it is no substitute for keeping something verbatim.
23
+ - **Projection is layered.** Compression applies to what future models see, not to stored history.
19
24
 
20
- The tool reports approximate context telemetry while planning:
25
+ ## Who decides what
21
26
 
22
- - anchor usage captured when `/midcompact` started;
23
- - approximate raw tokens selected by the current draft;
24
- - approximate summary tokens;
25
- - approximate whole-context usage if the draft were committed now.
27
+ | Actor | Owns |
28
+ |-------|------|
29
+ | Extension | Session-tree mechanics, projection, protocol safety |
30
+ | You | Semantic judgment: which content may yield to a summary, and what each summary must carry |
31
+ | User | Compression scope and depth; the only actor that can commit |
26
32
 
27
- Treat these numbers as **awareness, not a target**. Do not maximize token reduction or keep adding ranges merely because more compression is possible. Use the scale information together with semantic value and the user's conversational guidance. If the user says they only want a modest reduction, preserve more context; if they want more headroom, look for additional stale regions.
33
+ You cannot commit. `/midcompact commit` is the user's gate. Your output is a proposal.
28
34
 
29
- Projected values are estimates. Prefer semantic correctness over apparent numeric precision.
35
+ ## What may be compressed
30
36
 
31
- ## Compression workflow
37
+ One conservation law decides every case:
32
38
 
33
- 1. Decide which completed or stale regions are candidates for compression.
34
- 2. Use `midcompact(action="locate", ...)` to resolve semantic landmarks to atom refs. Locator results include readable previews; request `detail="full"` when a boundary is ambiguous.
35
- 3. Build a draft with `midcompact(action="plan", op="add", start=..., end=..., summary=...)`.
36
- - Use multiple ranges for non-contiguous compression.
37
- - To preserve an important atom verbatim inside a broader phase, split the compression into ranges around that atom.
38
- - Prefer KEEP-by-omission when uncertain.
39
- - After each meaningful draft change, use the returned context telemetry to understand its scale; do not treat it as a quota.
40
- 4. Use `midcompact(action="plan", op="show")` and present the complete proposed plan to the user. Include what each range begins/ends with, not only atom IDs.
41
- 5. Recommend `/midcompact review` when the user wants to inspect the linear anchor timeline, proposed ranges, summaries, and KEEP holes. Incorporate requested changes with `op="update"`, `op="remove"`, additional ranges, or the review UI.
42
- 6. After the user is satisfied, ask them to run `/midcompact commit`. The Agent cannot commit itself. The explicit user command is the commit gate and returns the session tree to the anchor before persisting the projection.
39
+ > Compression must conserve every fact that can still affect the work **in the projected context**. After a range is replaced, each such fact must remain available with sufficient fidelity, either in text left verbatim outside the ranges or in the replacement summary.
43
40
 
44
- A good summary preserves what the next working Agent needs: user intent and constraints, decisions and rationale, relevant file paths/signatures/errors, validation state, rejected approaches when the reason matters, unresolved issues, and the next useful state. Remove repetitive exploration and process noise rather than merely shortening prose.
41
+ Not age. Not token count. Not whether it is a tool call or prose. Two consequences follow:
42
+
43
+ - **The summary is load-bearing.** When a fact lives only inside a compressed range, omitting it from the summary removes it from the projected context. Recall is a recovery path, not a default carrier.
44
+ - **Some information must not be entrusted to paraphrase.** Exact requirement wording, literal error text, decision-critical evidence, protocol structure. When exact form or provenance matters, keep the source verbatim unless the replacement preserves it with equivalent fidelity.
45
+
46
+ Illustrative cases, derived from the law:
47
+
48
+ - Work that reached a conclusion or resolved result, with nothing downstream depending on how it got there → the summary states the outcome, or the concluding atom stays outside the range → compressible.
49
+ - Tool output fully absorbed into the answer that follows it → the answer sits outside the range → a thin summary suffices.
50
+ - A constraint, correction, or approval the user stated once → if the wording itself carries the constraint, keep it verbatim; otherwise the summary must state it explicitly.
51
+ - A rejected approach whose rejection reason still constrains current work → the summary must carry the reason; the exploration around it can go.
52
+
53
+ **Reverse failure.** Some content looks stale but is the only record of an environment quirk, a version-specific behavior, or a failure mode that will resurface. If you cannot state faithfully what a segment established, you cannot summarize it conservingly — keep it verbatim.
54
+
55
+ **Your summary becomes the successor.** The next working Agent — likely you, after commit — sees only your summary. Write what it needs to avoid redoing or breaking work: user intent and constraints, decisions and their rationale, file paths and signatures, validation state, unresolved issues, and the next useful state. Cutting repetitive exploration is the goal; shortening prose is not.
56
+
57
+ ## Phase 1 — read, segment, propose, align
58
+
59
+ **Do not call `plan` until you have presented the semantic candidates and the user has confirmed or adjusted the direction**, unless the user explicitly instructs you to skip the proposal.
60
+
61
+ 1. Read back over the conversation in your current context and segment it semantically — by phase of work, not by message count.
62
+ 2. Judge each segment against the conservation law. For each candidate, be able to say where its load-bearing facts would end up.
63
+ 3. Present candidates: where each begins and ends, roughly how large it is, and what its summary would carry. Name segments you deliberately excluded when the exclusion is non-obvious.
64
+ 4. If scope or depth is still unresolved, ask how deep to go and which regions matter. Depth is the user's decision, not a number you optimize.
65
+
66
+ `locate` is read-only and may be used sparingly here to confirm a boundary you are about to propose, but not to scan exploratorily. A session that has reached compression is already near its limit: speculative calls, and a plan rebuilt after review, both consume what you are trying to reclaim.
67
+
68
+ If `/midcompact start` carried an instruction (it arrives as `User focus: ...`), treat it as guidance for whichever of scope and depth it specifies. Still propose, but briefly; ask only what the instruction leaves open.
69
+
70
+ ## Phase 2 — locate, draft, review
71
+
72
+ 1. `action="locate"` to resolve the landmarks you agreed on into atom refs. Results include previews; request `detail="full"` when a boundary is ambiguous.
73
+ 2. `action="plan", op="add"` per range — several ranges for non-contiguous compression. To keep one important atom verbatim inside a broader phase, add ranges around it; that is KEEP by omission in practice.
74
+ 3. `action="plan", op="show"`, then present the complete plan described by content rather than atom IDs.
75
+ 4. Recommend `/midcompact review` when the user wants to inspect the anchor timeline, ranges, summaries, and KEEP holes visually. In non-interactive modes (no TUI, RPC, print), `/midcompact review` only warns and points to `/midcompact review-webui`, which starts a local web page that works without a TUI. Apply changes with `op="update"`, `op="remove"`, or new ranges.
76
+ 5. Ask the user to run `/midcompact commit` when satisfied.
77
+
78
+ ## Tool interface
79
+
80
+ **Atoms are not messages.** An atom is the smallest compressible unit. One assistant message containing one or more tool calls, plus its immediately following matching results, forms a single `tool_exchange` atom; you cannot compress half of one.
81
+
82
+ **Two ref namespaces.** `a0001` is an atom ref, valid only within the current transaction's anchor snapshot — indices shift after every commit, so never reuse one across transactions; re-run `locate`. `c0001` is a compressed block id, stable while that block stays active on the current branch, used by `recall`.
83
+
84
+ `action="locate"` — pass either `ref` for a direct lookup, or at least one real filter: `pattern`, `tool_name`, or a `source` other than `any`. With none it returns nothing rather than an error. Optional: `direction` (`oldest`/`newest`), `limit` (default 5, max 20), `detail` (`brief`/`full`).
85
+
86
+ `action="plan"` — `op` defaults to `show`.
87
+
88
+ | op | Requires |
89
+ |----|----------|
90
+ | `show` | — |
91
+ | `add` | `start`, `end`, `summary`; `topic` optional |
92
+ | `update` | `draft_id` and at least one of `summary`, `topic` |
93
+ | `remove` | `draft_id` |
94
+
95
+ `op="add"` rejects a range when any of the following holds. These are mechanical constraints, independent of semantic value — a range must satisfy both.
96
+
97
+ | Condition | Meaning |
98
+ |-----------|---------|
99
+ | Range crosses a protected atom | Split the plan around it. An atom is protected when its tool-call protocol is still open (an incomplete `tool_exchange`, or an orphaned tool result), when it is an existing compressed block, when its message kind is not one the extension can compress, or when its messages have no persistent session entry to anchor to. |
100
+ | Range overlaps an existing draft range | Remove or update that range instead. |
101
+ | `start` occurs after `end` | Refs are positional; order them. |
102
+ | Unknown atom ref | Usually a typo or a ref carried over from an earlier transaction. Re-run `locate` against the current snapshot. |
103
+
104
+ **Telemetry** accompanies every `plan` result: anchor usage at start, approximate raw and summary tokens for the draft, and projected whole-context usage if committed now. Use it to check the draft against the depth agreed in Phase 1. It is awareness, not a target, and the projections are estimates.
45
105
 
46
106
  ## Repeated compression
47
107
 
48
- A session may be midcompacted multiple times. Existing compressed blocks remain active and protected; a later transaction can compress newly accumulated raw history around them. Do not attempt to recursively compress an already compressed block in the current version.
108
+ A session may be compacted multiple times. Committed blocks stay active and appear as protected atoms in later snapshots, so they cannot be recompressed. A later transaction compresses raw history accumulated around them.
49
109
 
50
110
  ## Recall
51
111
 
52
- Compression is reversible at the information-access level. Original session entries remain stored.
112
+ `action="recall"` works whether or not a transaction is active, does not change the projection, and reads blocks active on the current branch.
53
113
 
54
- - `midcompact(action="recall", pattern="...")` searches active compressed block summaries/topics.
55
- - `midcompact(action="recall", ref="c0001")` temporarily returns the original content for that block.
114
+ - `pattern="..."` searches topics and summaries of active blocks (`limit` default 8, max 20).
115
+ - `ref="c0001"` returns a readable, structure-flattened rendering of that block's messages, truncated if long. On a truncation marker, retry the same ref with `detail="full"`; if that still truncates, inspect the session tree. There is no paging.
56
116
 
57
- Recall does not change the compression projection. Use it when a summary lacks a detail needed for current work.
117
+ Every summary in context states its own block id and the exact recall call for it. Use recall when a summary lacks a detail the current work needs.