@lll9p/pi-better-compaction 0.2.1 → 0.5.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 +103 -132
- package/README.zh-CN.md +162 -0
- package/package.json +7 -2
- package/src/compact-client-v2.ts +428 -0
- package/src/compact-client.ts +1 -63
- package/src/config.ts +38 -0
- package/src/extension-runtime.ts +247 -17
- package/src/midrun.ts +229 -0
- package/src/native-fallback.ts +21 -3
- package/src/retained-messages.ts +98 -0
- package/src/runtime.ts +41 -2
- package/src/shared-headers.ts +103 -0
- package/src/types.ts +30 -4
package/README.md
CHANGED
|
@@ -1,116 +1,61 @@
|
|
|
1
1
|
# pi-better-compaction
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English | [中文](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
native `/responses/compact` endpoint, then replay the opaque compacted window on later
|
|
7
|
-
requests without patching Pi core.
|
|
8
|
-
2. **Every other API** (Anthropic, Gemini, etc.) runs Pi's own native compaction method,
|
|
9
|
-
optionally driven by a **dedicated compaction model** so you can summarize with a cheaper/faster
|
|
10
|
-
model than the one you are chatting with.
|
|
5
|
+
A [pi](https://github.com/nicepkg/pi) extension that upgrades context compaction with three coordinated strategies:
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
1. An optional **mid-run guard** aborts an oversized tool loop, waits for `agent_settled`, compacts once, then resumes with a hidden custom message.
|
|
8
|
+
2. **OpenAI Responses APIs** use the provider's native compaction endpoint, preserving opaque context that plain text summaries lose.
|
|
9
|
+
3. **All other APIs** (Anthropic, Gemini, etc.) can run pi's built-in compaction with a **dedicated cheaper/faster model**, so summarization doesn't consume quota on your primary model.
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- **Minimum Pi version:** `@earendil-works/pi-coding-agent >= 0.80.0`
|
|
18
|
-
|
|
19
|
-
This extension relies on `modelRegistry.getApiKeyAndHeaders(model)` and the exported native
|
|
20
|
-
`compact()` function.
|
|
21
|
-
|
|
22
|
-
## Behavior
|
|
23
|
-
|
|
24
|
-
The `session_before_compact` decision tree:
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
session_before_compact
|
|
28
|
-
│
|
|
29
|
-
├─ config.enabled == false ───────────────────────► Pi default compaction
|
|
30
|
-
│
|
|
31
|
-
├─ current model API is a Responses API
|
|
32
|
-
│ │ (openai-responses / openai-codex-responses, narrowable via config)
|
|
33
|
-
│ ├─ POST /responses/compact
|
|
34
|
-
│ │ ├─ success ─────────────────────────────────► store opaque window + real summary
|
|
35
|
-
│ │ ├─ user aborted ─────────────────────────────► cancel
|
|
36
|
-
│ │ └─ failure (404 / network / malformed) ──────► fall through ▼
|
|
37
|
-
│ └─ (missing base URL / API key) ─────────────────► fall through ▼
|
|
38
|
-
│
|
|
39
|
-
├─ config.compactionModel is set and resolvable and ≠ current model
|
|
40
|
-
│ └─ run Pi's native compact() with that model ────► use its result
|
|
41
|
-
│
|
|
42
|
-
└─ otherwise ─────────────────────────────────────► Pi default compaction
|
|
43
|
-
(no model configured, or it equals the current model — Pi runs the
|
|
44
|
-
same native method itself, keeping its streaming progress UI)
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
On the next supported Responses request after a native `/responses/compact`, the
|
|
48
|
-
`before_provider_request` hook rewrites Pi's summary-oriented replay into:
|
|
49
|
-
|
|
50
|
-
- fresh current prompt envelope
|
|
51
|
-
- stored opaque compacted window
|
|
52
|
-
- live post-compaction tail
|
|
53
|
-
|
|
54
|
-
Requests produced by the native-method fallback carry Pi's standard `{readFiles, modifiedFiles}`
|
|
55
|
-
details, so they replay through Pi's default path — no rewrite, no special handling.
|
|
56
|
-
|
|
57
|
-
By default, a session whose latest compaction is not a stored native opaque window does not attempt
|
|
58
|
-
`/responses/compact`, preserving strict replay continuity. Set `allowCompactionContinuityBreak` to
|
|
59
|
-
`true` to restart native compaction from Pi's current effective context instead. Any information
|
|
60
|
-
already omitted by Pi's text summary cannot be recovered, but the successful compact response
|
|
61
|
-
becomes the new opaque replay checkpoint for later turns.
|
|
62
|
-
|
|
63
|
-
### Selection is by API, not provider
|
|
64
|
-
|
|
65
|
-
Any provider speaking a Responses API gets a native compact attempt, including OpenAI-compatible
|
|
66
|
-
proxies with a custom `baseUrl`. If such an endpoint does not implement `/responses/compact`, the
|
|
67
|
-
request 404s and the extension fails through to the configured fallback model (or Pi default). To
|
|
68
|
-
avoid the probe entirely for one API, narrow `responsesCompactApis`.
|
|
11
|
+
Everything fails open — if any step cannot proceed, pi's default compaction takes over.
|
|
69
12
|
|
|
70
13
|
## Install
|
|
71
14
|
|
|
72
|
-
From npm (recommended):
|
|
73
|
-
|
|
74
15
|
```bash
|
|
16
|
+
# From npm (recommended)
|
|
75
17
|
pi install npm:@lll9p/pi-better-compaction
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Try it for a single run without installing:
|
|
79
18
|
|
|
80
|
-
|
|
19
|
+
# Try without installing
|
|
81
20
|
pi -e npm:@lll9p/pi-better-compaction
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
From a checkout (development):
|
|
85
21
|
|
|
86
|
-
|
|
22
|
+
# From source
|
|
87
23
|
git clone https://github.com/lll9p/pi-better-compaction.git
|
|
88
|
-
cd pi-better-compaction
|
|
89
|
-
pi install .
|
|
24
|
+
cd pi-better-compaction && pi install .
|
|
90
25
|
```
|
|
91
26
|
|
|
92
27
|
After installation, run `/reload`.
|
|
93
28
|
|
|
29
|
+
## Requirements
|
|
30
|
+
|
|
31
|
+
- **pi** ≥ 0.84.3 (`@earendil-works/pi-coding-agent >= 0.84.3`)
|
|
32
|
+
|
|
94
33
|
## Configuration
|
|
95
34
|
|
|
96
|
-
|
|
35
|
+
Config file location:
|
|
97
36
|
|
|
98
37
|
```
|
|
99
38
|
~/.pi/agent/extensions/pi-better-compaction/config.json
|
|
100
39
|
```
|
|
101
40
|
|
|
102
|
-
|
|
41
|
+
If the file doesn't exist, all defaults apply. The extension never creates this file.
|
|
103
42
|
|
|
104
|
-
|
|
43
|
+
### Defaults
|
|
44
|
+
|
|
45
|
+
```jsonc
|
|
105
46
|
{
|
|
106
47
|
"enabled": true,
|
|
107
|
-
"
|
|
108
|
-
|
|
109
|
-
|
|
48
|
+
"midRun": {
|
|
49
|
+
"enabled": false,
|
|
50
|
+
"thresholdPercent": 80
|
|
51
|
+
},
|
|
52
|
+
"compactionVersion": "v2",
|
|
53
|
+
"compactionModel": null,
|
|
110
54
|
"compactionThinkingLevel": "off",
|
|
111
|
-
|
|
112
55
|
"responsesCompactApis": ["openai-responses", "openai-codex-responses"],
|
|
56
|
+
"allowCompactionContinuityBreak": false,
|
|
113
57
|
|
|
58
|
+
// Debug & logging
|
|
114
59
|
"notifyOnLoad": false,
|
|
115
60
|
"debug": false,
|
|
116
61
|
"logProviderPayloads": false,
|
|
@@ -120,31 +65,82 @@ A missing file silently uses the defaults below. The extension never writes this
|
|
|
120
65
|
}
|
|
121
66
|
```
|
|
122
67
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
|
126
|
-
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
68
|
+
### Options reference
|
|
69
|
+
|
|
70
|
+
| Option | Type | Default | Description |
|
|
71
|
+
|--------|------|---------|-------------|
|
|
72
|
+
| `enabled` | `boolean` | `true` | Master switch. Set `false` to disable the extension entirely. |
|
|
73
|
+
| `midRun.enabled` | `boolean` | `false` | Enable the mid-run guard. It may abort a long tool loop once context reaches the configured threshold. |
|
|
74
|
+
| `midRun.thresholdPercent` | `number` | `80` | Context usage percentage that triggers the mid-run guard after a tool-bearing turn. Must be greater than 0 and at most 100. |
|
|
75
|
+
| `compactionVersion` | `"v1" \| "v2"` | `"v2"` | Protocol for Responses-family APIs. **V2** (streaming, encrypted blob) is the current OpenAI default. **V1** uses the legacy `/responses/compact` endpoint. |
|
|
76
|
+
| `compactionModel` | `string \| null` | `null` | Model for fallback compaction (non-Responses APIs, or when native compact fails). Format: `"provider/model-id"`, e.g. `"openai/gpt-5.1-mini"`. `null` = let pi use the current chat model. |
|
|
77
|
+
| `compactionThinkingLevel` | `string` | `"off"` | Thinking level for the fallback compaction model. One of: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`. |
|
|
78
|
+
| `responsesCompactApis` | `string[]` | `["openai-responses", "openai-codex-responses"]` | Which Responses APIs use native compaction. Can only narrow the built-in set; unknown entries are ignored with a warning. |
|
|
79
|
+
| `allowCompactionContinuityBreak` | `boolean` | `false` | Allow restarting native compaction when the latest session compaction was created by pi's default path (not this extension). Sacrifices opaque-window continuity at that boundary. |
|
|
80
|
+
| `notifyOnLoad` | `boolean` | `false` | Show a notification in the TUI when the extension loads. |
|
|
81
|
+
| `debug` | `boolean` | `false` | Write lifecycle and compaction-event debug artifacts. |
|
|
82
|
+
| `logProviderPayloads` | `boolean` | `false` | Write `before_provider_request` payload artifacts. |
|
|
83
|
+
| `logCompactResponses` | `boolean` | `false` | Write compact endpoint request/response artifacts. |
|
|
84
|
+
| `redactSensitiveData` | `boolean` | `true` | Redact secrets in debug artifacts. |
|
|
85
|
+
| `artifactRoot` | `string` | `"~/.pi/agent/artifacts/pi-better-compaction"` | Root directory for debug artifacts. Supports `~/` and relative paths (resolved against config dir). |
|
|
86
|
+
|
|
87
|
+
### Example: enable mid-run compaction
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"midRun": {
|
|
92
|
+
"enabled": true,
|
|
93
|
+
"thresholdPercent": 80
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Example: use a cheap model for fallback compaction
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"compactionModel": "openai/gpt-5.1-mini",
|
|
103
|
+
"compactionThinkingLevel": "off"
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Example: force V1 compaction protocol
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"compactionVersion": "v1"
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## How it works
|
|
116
|
+
|
|
117
|
+
With `midRun.enabled`, a completed tool-bearing `turn_end` above the threshold only calls `ctx.abort()`. After Pi emits `agent_settled`, the guard reuses any compaction Pi already completed during abort handling; otherwise it calls `ctx.compact()` exactly once. A successful or coalesced compaction triggers the next turn with a hidden custom message. Failed compaction does not resume, preventing a compact-fail-resume loop.
|
|
136
118
|
|
|
137
|
-
|
|
119
|
+
When pi triggers compaction (`session_before_compact`):
|
|
138
120
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
back to the minimal `model` / `input` / `instructions` body.
|
|
121
|
+
1. **Responses API detected** → run native compaction (V2 or V1 per config):
|
|
122
|
+
- **V2**: streams a request with `compaction_trigger` to `/responses`; the API returns an encrypted compaction blob. Retained user/developer messages + blob form the compacted context.
|
|
123
|
+
- **V1**: POSTs to `/responses/compact`; receives an opaque compacted window.
|
|
124
|
+
- On success, the compacted window is stored and replayed on subsequent requests via `before_provider_request`.
|
|
144
125
|
|
|
145
|
-
|
|
126
|
+
2. **Not a Responses API, or native compact failed** → if `compactionModel` is configured and differs from the current model, run pi's built-in `compact()` with that model.
|
|
146
127
|
|
|
147
|
-
|
|
128
|
+
3. **No fallback configured** → pi's default compaction runs as if the extension weren't installed.
|
|
129
|
+
|
|
130
|
+
Selection is by API type, not provider — any OpenAI-compatible proxy speaking a Responses API gets a native compact attempt. If the endpoint doesn't support it, the request fails and falls through to the configured fallback.
|
|
131
|
+
|
|
132
|
+
## Debugging
|
|
133
|
+
|
|
134
|
+
Enable debug artifacts:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"debug": true,
|
|
139
|
+
"logCompactResponses": true
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Then `/reload`, run `/compact`, send a follow-up message, and inspect:
|
|
148
144
|
|
|
149
145
|
```
|
|
150
146
|
<artifactRoot>/sessions/<session-id>/
|
|
@@ -154,38 +150,13 @@ Written per session under:
|
|
|
154
150
|
└── lifecycle/
|
|
155
151
|
```
|
|
156
152
|
|
|
157
|
-
Troubleshooting flow:
|
|
158
|
-
|
|
159
|
-
1. set `debug: true` and `logCompactResponses: true` (keep `redactSensitiveData: true`)
|
|
160
|
-
2. `/reload`
|
|
161
|
-
3. run `/compact`, then send a follow-up message
|
|
162
|
-
4. inspect the newest artifact in the session directory
|
|
163
|
-
|
|
164
|
-
## Package structure
|
|
165
|
-
|
|
166
|
-
```
|
|
167
|
-
package-root/
|
|
168
|
-
├── index.ts # entrypoint declared in package.json
|
|
169
|
-
├── src/
|
|
170
|
-
│ ├── extension-runtime.ts # hook registration + compaction decision tree
|
|
171
|
-
│ ├── config.ts # config.json loader (single source + defaults)
|
|
172
|
-
│ ├── runtime.ts # API-based environment resolution + auth
|
|
173
|
-
│ ├── compact-client.ts # /responses/compact client + summary extraction
|
|
174
|
-
│ ├── native-fallback.ts # configured-model native compact() driver
|
|
175
|
-
│ ├── request-context-cache.ts # captures codex-aligned fields from live requests
|
|
176
|
-
│ ├── serializer.ts # Responses input serialization
|
|
177
|
-
│ ├── payload-rewrite.ts # native opaque-window replay rewrite
|
|
178
|
-
│ ├── details-store.ts # latest-valid native compaction lookup
|
|
179
|
-
│ ├── debug.ts # artifact writing + redaction
|
|
180
|
-
│ ├── supported-environment.ts # re-exports
|
|
181
|
-
│ └── types.ts # config + persisted native-compaction types
|
|
182
|
-
└── test/
|
|
183
|
-
```
|
|
184
|
-
|
|
185
153
|
## Tests
|
|
186
154
|
|
|
187
155
|
```bash
|
|
188
156
|
bun test
|
|
189
157
|
bun test --coverage --coverage-reporter=text --coverage-reporter=lcov
|
|
190
|
-
bun test ./test/pi-smoke.test.ts
|
|
191
158
|
```
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# pi-better-compaction
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
一个 [pi](https://github.com/nicepkg/pi) 扩展,通过三条协同策略提升上下文压缩效果:
|
|
6
|
+
|
|
7
|
+
1. 可选的 **mid-run guard** 在工具循环占满上下文时先中止运行,等待 `agent_settled` 后只压缩一次,再通过隐藏消息继续任务。
|
|
8
|
+
2. **OpenAI Responses 系列 API** 使用提供商原生压缩端点,保留纯文本摘要无法留存的不透明上下文。
|
|
9
|
+
3. **其他所有 API**(Anthropic、Gemini 等)可用一个**独立的低成本模型**执行 pi 内置压缩,避免在主模型上消耗额度。
|
|
10
|
+
|
|
11
|
+
所有环节都安全降级——任何步骤无法执行时,pi 的默认压缩自动接管。
|
|
12
|
+
|
|
13
|
+
## 安装
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# 从 npm 安装(推荐)
|
|
17
|
+
pi install npm:@lll9p/pi-better-compaction
|
|
18
|
+
|
|
19
|
+
# 临时试用,不安装
|
|
20
|
+
pi -e npm:@lll9p/pi-better-compaction
|
|
21
|
+
|
|
22
|
+
# 从源码安装
|
|
23
|
+
git clone https://github.com/lll9p/pi-better-compaction.git
|
|
24
|
+
cd pi-better-compaction && pi install .
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
安装后执行 `/reload` 生效。
|
|
28
|
+
|
|
29
|
+
## 要求
|
|
30
|
+
|
|
31
|
+
- **pi** ≥ 0.84.3(`@earendil-works/pi-coding-agent >= 0.84.3`)
|
|
32
|
+
|
|
33
|
+
## 配置
|
|
34
|
+
|
|
35
|
+
配置文件路径:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
~/.pi/agent/extensions/pi-better-compaction/config.json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
文件不存在时使用默认值。扩展不会自动创建此文件。
|
|
42
|
+
|
|
43
|
+
### 默认配置
|
|
44
|
+
|
|
45
|
+
```jsonc
|
|
46
|
+
{
|
|
47
|
+
"enabled": true,
|
|
48
|
+
"midRun": {
|
|
49
|
+
"enabled": false,
|
|
50
|
+
"thresholdPercent": 80
|
|
51
|
+
},
|
|
52
|
+
"compactionVersion": "v2",
|
|
53
|
+
"compactionModel": null,
|
|
54
|
+
"compactionThinkingLevel": "off",
|
|
55
|
+
"responsesCompactApis": ["openai-responses", "openai-codex-responses"],
|
|
56
|
+
"allowCompactionContinuityBreak": false,
|
|
57
|
+
|
|
58
|
+
// 调试与日志
|
|
59
|
+
"notifyOnLoad": false,
|
|
60
|
+
"debug": false,
|
|
61
|
+
"logProviderPayloads": false,
|
|
62
|
+
"logCompactResponses": false,
|
|
63
|
+
"redactSensitiveData": true,
|
|
64
|
+
"artifactRoot": "~/.pi/agent/artifacts/pi-better-compaction"
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 配置项说明
|
|
69
|
+
|
|
70
|
+
| 选项 | 类型 | 默认值 | 说明 |
|
|
71
|
+
|------|------|--------|------|
|
|
72
|
+
| `enabled` | `boolean` | `true` | 总开关。设为 `false` 完全禁用扩展。 |
|
|
73
|
+
| `midRun.enabled` | `boolean` | `false` | 启用 mid-run guard。上下文达到阈值后,它可能主动中止长工具循环。 |
|
|
74
|
+
| `midRun.thresholdPercent` | `number` | `80` | 工具型 turn 完成后触发 mid-run guard 的上下文占用百分比。必须大于 0 且不超过 100。 |
|
|
75
|
+
| `compactionVersion` | `"v1" \| "v2"` | `"v2"` | Responses 系列 API 的压缩协议。**V2**(流式,加密 blob)是 OpenAI 当前默认协议;**V1** 使用旧版 `/responses/compact` 端点。 |
|
|
76
|
+
| `compactionModel` | `string \| null` | `null` | 回退压缩使用的模型(用于非 Responses API,或原生压缩失败时)。格式:`"provider/model-id"`,如 `"openai/gpt-5.1-mini"`。`null` = 由 pi 使用当前对话模型。 |
|
|
77
|
+
| `compactionThinkingLevel` | `string` | `"off"` | 回退压缩模型的思考级别。可选:`off`、`minimal`、`low`、`medium`、`high`、`xhigh`、`max`。 |
|
|
78
|
+
| `responsesCompactApis` | `string[]` | `["openai-responses", "openai-codex-responses"]` | 启用原生压缩的 Responses API 列表。只能缩小内置集合,不能添加新值。 |
|
|
79
|
+
| `allowCompactionContinuityBreak` | `boolean` | `false` | 当会话最近一次压缩不是本扩展创建的时,是否允许重新开始原生压缩。会在该边界处牺牲不透明窗口的连续性。 |
|
|
80
|
+
| `notifyOnLoad` | `boolean` | `false` | 扩展加载时在 TUI 中显示通知。 |
|
|
81
|
+
| `debug` | `boolean` | `false` | 写入生命周期和压缩事件的调试文件。 |
|
|
82
|
+
| `logProviderPayloads` | `boolean` | `false` | 写入 `before_provider_request` 请求体调试文件。 |
|
|
83
|
+
| `logCompactResponses` | `boolean` | `false` | 写入压缩端点的请求/响应调试文件。 |
|
|
84
|
+
| `redactSensitiveData` | `boolean` | `true` | 在调试文件中脱敏。 |
|
|
85
|
+
| `artifactRoot` | `string` | `"~/.pi/agent/artifacts/pi-better-compaction"` | 调试文件根目录。支持 `~/` 和相对路径(相对于配置文件目录解析)。 |
|
|
86
|
+
|
|
87
|
+
### 示例:启用 mid-run 压缩
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"midRun": {
|
|
92
|
+
"enabled": true,
|
|
93
|
+
"thresholdPercent": 80
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 示例:使用低成本模型做回退压缩
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"compactionModel": "openai/gpt-5.1-mini",
|
|
103
|
+
"compactionThinkingLevel": "off"
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 示例:强制使用 V1 压缩协议
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"compactionVersion": "v1"
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 工作原理
|
|
116
|
+
|
|
117
|
+
启用 `midRun.enabled` 后,超过阈值的工具型 `turn_end` 只调用 `ctx.abort()`。Pi 发出 `agent_settled` 后,guard 会复用 abort 收尾阶段已经完成的压缩;如果没有,则只调用一次 `ctx.compact()`。压缩成功或竞争合并后,通过隐藏 custom message 触发下一轮。压缩失败时不会自动继续,避免进入“压缩失败—继续—再次失败”的循环。
|
|
118
|
+
|
|
119
|
+
pi 触发压缩时(`session_before_compact`):
|
|
120
|
+
|
|
121
|
+
1. **检测到 Responses API** → 执行原生压缩(根据配置选择 V2 或 V1):
|
|
122
|
+
- **V2**:向 `/responses` 端点发送携带 `compaction_trigger` 的流式请求,API 返回加密压缩 blob。保留的用户/开发者消息 + blob 组成压缩后的上下文。
|
|
123
|
+
- **V1**:POST 到 `/responses/compact`,接收不透明的压缩窗口。
|
|
124
|
+
- 成功后,压缩窗口被存储,后续请求通过 `before_provider_request` 钩子回放。
|
|
125
|
+
|
|
126
|
+
2. **非 Responses API,或原生压缩失败** → 若配置了 `compactionModel` 且与当前模型不同,使用该模型执行 pi 内置的 `compact()` 方法。
|
|
127
|
+
|
|
128
|
+
3. **未配置回退模型** → pi 的默认压缩照常执行,如同扩展未安装。
|
|
129
|
+
|
|
130
|
+
判断依据是 API 类型而非提供商——任何使用 Responses API 协议的 OpenAI 兼容代理都会触发原生压缩尝试。如果端点不支持,请求失败后自动回退。
|
|
131
|
+
|
|
132
|
+
## 调试
|
|
133
|
+
|
|
134
|
+
启用调试文件输出:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"debug": true,
|
|
139
|
+
"logCompactResponses": true
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
然后 `/reload`,执行 `/compact`,发送一条后续消息,检查:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
<artifactRoot>/sessions/<session-id>/
|
|
147
|
+
├── provider-requests/
|
|
148
|
+
├── compact-responses/
|
|
149
|
+
├── compaction-events/
|
|
150
|
+
└── lifecycle/
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## 测试
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
bun test
|
|
157
|
+
bun test --coverage --coverage-reporter=text --coverage-reporter=lcov
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 许可证
|
|
161
|
+
|
|
162
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lll9p/pi-better-compaction",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Better compaction for pi: native /responses/compact replay for OpenAI Responses APIs, plus a configurable compaction model driving pi's native summarization everywhere else.",
|
|
6
6
|
"author": "Lilin Lao",
|
|
@@ -33,18 +33,23 @@
|
|
|
33
33
|
"files": [
|
|
34
34
|
"index.ts",
|
|
35
35
|
"src/compact-client.ts",
|
|
36
|
+
"src/compact-client-v2.ts",
|
|
36
37
|
"src/config.ts",
|
|
37
38
|
"src/debug.ts",
|
|
38
39
|
"src/details-store.ts",
|
|
39
40
|
"src/extension-runtime.ts",
|
|
41
|
+
"src/midrun.ts",
|
|
40
42
|
"src/native-fallback.ts",
|
|
41
43
|
"src/payload-rewrite.ts",
|
|
42
44
|
"src/request-context-cache.ts",
|
|
45
|
+
"src/retained-messages.ts",
|
|
43
46
|
"src/runtime.ts",
|
|
44
47
|
"src/serializer.ts",
|
|
48
|
+
"src/shared-headers.ts",
|
|
45
49
|
"src/supported-environment.ts",
|
|
46
50
|
"src/types.ts",
|
|
47
51
|
"README.md",
|
|
52
|
+
"README.zh-CN.md",
|
|
48
53
|
"LICENSE"
|
|
49
54
|
],
|
|
50
55
|
"scripts": {
|
|
@@ -55,6 +60,6 @@
|
|
|
55
60
|
"peerDependencies": {
|
|
56
61
|
"@earendil-works/pi-agent-core": "*",
|
|
57
62
|
"@earendil-works/pi-ai": "*",
|
|
58
|
-
"@earendil-works/pi-coding-agent": ">=0.
|
|
63
|
+
"@earendil-works/pi-coding-agent": ">=0.84.3"
|
|
59
64
|
}
|
|
60
65
|
}
|