@narumitw/pi-codex-compact 0.51.3 → 0.53.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 +90 -90
- package/dist/chunks/chunk-7H7JJ7ZV.js +37 -0
- package/dist/chunks/chunk-7H7JJ7ZV.js.map +7 -0
- package/dist/chunks/{settings-menu-PEDLURUH.js → settings-menu-TVWWDPBF.js} +52 -35
- package/dist/chunks/settings-menu-TVWWDPBF.js.map +7 -0
- package/dist/index.ts +541 -101
- package/dist/index.ts.map +4 -4
- package/package.json +53 -57
- package/src/checkpoint.ts +265 -218
- package/src/codex-compact.ts +252 -229
- package/src/model-api.ts +56 -5
- package/src/protocol.ts +318 -179
- package/src/remote-compact.ts +276 -0
- package/src/remote-shared.ts +16 -0
- package/src/remote-types.ts +46 -0
- package/src/remote-v2.ts +66 -0
- package/src/remote.ts +14 -116
- package/src/settings-menu.ts +213 -201
- package/src/settings.ts +228 -176
- package/src/terminal.ts +6 -0
- package/dist/chunks/chunk-6TZ2L2BM.js +0 -13
- package/dist/chunks/chunk-6TZ2L2BM.js.map +0 -7
- package/dist/chunks/settings-menu-PEDLURUH.js.map +0 -7
package/README.md
CHANGED
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@narumitw/pi-codex-compact) [](https://pi.dev) [](./LICENSE)
|
|
4
4
|
|
|
5
|
-
Use
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Pi still decides when compaction runs and retains its normal `/compact`, threshold, overflow, and session-publication behavior.
|
|
5
|
+
Use Responses compaction in Pi through Remote Compaction V2 or the unary `responses/compact` API.
|
|
6
|
+
The extension stores an opaque server-generated checkpoint and replays it in later compatible requests instead of generating a local plaintext summary.
|
|
7
|
+
Pi still decides when compaction runs and keeps its normal `/compact`, threshold, overflow, and session-publication behavior.
|
|
10
8
|
|
|
11
9
|
## ✨ Features
|
|
12
10
|
|
|
13
|
-
-
|
|
11
|
+
- Supports `openai-codex-responses`, `openai-responses`, and `azure-openai-responses`, plus explicitly profiled custom APIs.
|
|
12
|
+
- Uses Remote V2 or same-origin unary `responses/compact` through the active provider and credentials.
|
|
14
13
|
- Handles manual, threshold, and overflow compaction through Pi's existing lifecycle.
|
|
15
14
|
- Validates and persists one bounded opaque checkpoint that survives compatible reloads, resumes, and forks.
|
|
16
15
|
- Replays the latest checkpoint while preserving newer conversation and extension context.
|
|
17
|
-
- Supports repeated compaction by carrying the previous checkpoint
|
|
16
|
+
- Supports repeated and cross-protocol compaction by carrying the previous checkpoint forward.
|
|
18
17
|
- Falls back to Pi's native plaintext compaction on non-cancellation failures.
|
|
19
|
-
- Provides `/codex-compact` for route status, settings, and manual compaction.
|
|
18
|
+
- Provides `/codex-compact` for effective-route status, settings, and manual compaction.
|
|
20
19
|
|
|
21
20
|
## 📦 Install
|
|
22
21
|
|
|
@@ -39,42 +38,35 @@ npm --workspace @narumitw/pi-codex-compact run build
|
|
|
39
38
|
pi -e ./packages/pi-codex-compact
|
|
40
39
|
```
|
|
41
40
|
|
|
42
|
-
The package declares `dist/index.ts`, so
|
|
43
|
-
Loading the package enables
|
|
44
|
-
|
|
41
|
+
The package declares `dist/index.ts`, so build a local checkout before loading its package directory.
|
|
42
|
+
Loading the package enables automatic Responses compaction routing with the documented defaults.
|
|
43
|
+
Do not load a global npm installation and the local workspace at the same time.
|
|
44
|
+
|
|
45
|
+
Pi extensions run with your user permissions.
|
|
46
|
+
Review third-party extension source before installing it.
|
|
45
47
|
|
|
46
48
|
## 🚀 Quick start
|
|
47
49
|
|
|
48
|
-
1. Sign in through Pi's built-in OpenAI Codex
|
|
49
|
-
2. Select a model
|
|
50
|
-
3. Work normally.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
1. Sign in through Pi's built-in OpenAI, OpenAI Codex, or Azure OpenAI provider, or configure a compatible custom provider.
|
|
51
|
+
2. Select a model using `openai-codex-responses`, `openai-responses`, or `azure-openai-responses`.
|
|
52
|
+
3. Work normally; Pi's automatic compaction and built-in `/compact` continue to operate.
|
|
53
|
+
|
|
54
|
+
Run `/codex-compact` when you want to inspect the effective route or choose **Compact now**.
|
|
55
|
+
After compaction, compatible requests replay the opaque checkpoint automatically.
|
|
54
56
|
|
|
57
|
+
With the default `auto` protocol, Codex Responses uses Remote V2 while OpenAI and Azure OpenAI Responses use unary `responses/compact`.
|
|
55
58
|
When the active model uses another API, compaction remains entirely Pi-native.
|
|
59
|
+
To opt in a compatible custom API, add it to `apiProfiles` as described below.
|
|
56
60
|
|
|
57
61
|
## 💬 Commands
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
In TUI mode, the root menu shows whether Remote V2 is enabled, the active model, and whether a manual compact will use **Codex Remote V2** or **Pi native**.
|
|
64
|
-
It contains:
|
|
63
|
+
Run `/codex-compact` to inspect the effective compaction path, change settings, or request manual compaction in TUI mode.
|
|
64
|
+
It accepts no arguments.
|
|
65
|
+
RPC reports the manual settings path without compacting; print and JSON modes reject the command.
|
|
66
|
+
Closing the menu with Escape or Ctrl+C does not compact the session.
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Settings
|
|
69
|
-
Close
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**Compact now** closes the menu before asking Pi to compact the active session.
|
|
73
|
-
Escape or Ctrl+C closes without compacting, and an obsolete menu cannot trigger work after session replacement or shutdown.
|
|
74
|
-
**Settings** opens the bounded settings editor.
|
|
75
|
-
In non-TUI modes, the command reports the manual settings path instead of opening custom UI or compacting.
|
|
76
|
-
|
|
77
|
-
Pi's built-in `/compact` remains available and follows the same extension hook when the active model uses `openai-codex-responses`.
|
|
68
|
+
Manual compaction uses **Responses Remote V2**, **Responses Compact API**, or **Pi native**, as described in [Settings](#-settings).
|
|
69
|
+
Pi's built-in `/compact` remains available and follows the same extension hook.
|
|
78
70
|
|
|
79
71
|
## ⚙️ Settings
|
|
80
72
|
|
|
@@ -90,6 +82,10 @@ There is no environment-variable or project-level override.
|
|
|
90
82
|
```json
|
|
91
83
|
{
|
|
92
84
|
"enabled": true,
|
|
85
|
+
"protocol": "auto",
|
|
86
|
+
"apiProfiles": {
|
|
87
|
+
"custom-responses": "codex-responses-v1"
|
|
88
|
+
},
|
|
93
89
|
"requestTimeoutMs": 300000,
|
|
94
90
|
"maxRetries": 2,
|
|
95
91
|
"replacementTokenBudget": 64000,
|
|
@@ -99,19 +95,21 @@ There is no environment-variable or project-level override.
|
|
|
99
95
|
|
|
100
96
|
| Setting | Default | Accepted values | Behavior | Recommendation |
|
|
101
97
|
| --- | ---: | --- | --- | --- |
|
|
102
|
-
| `enabled` | `true` | Boolean | Attempt
|
|
98
|
+
| `enabled` | `true` | Boolean | Attempt a supported remote compaction route. | Keep enabled unless diagnosing provider behavior. |
|
|
99
|
+
| `protocol` | `"auto"` | `"auto"`, `"remote-v2"`, or `"responses-compact"` | Select by API or force one remote protocol. | Keep `auto`; force a route only when diagnosing a compatible backend. |
|
|
100
|
+
| `apiProfiles` | `{}` | Object mapping a custom API id to `"codex-responses-v1"` | Explicitly opts a non-built-in API into Codex-compatible request fields and replay. | Leave empty unless the provider documents Codex Responses compatibility. |
|
|
103
101
|
| `requestTimeoutMs` | `300000` | Integer from 30,000 to 600,000 ms | Bound one extension-owned remote request. | Keep five minutes; increase only for a consistently slow connection. |
|
|
104
102
|
| `maxRetries` | `2` | Integer from 0 to 2 | Retry transient provider transport failures before Pi fallback. | Keep two; use zero when diagnosing the first failure. |
|
|
105
103
|
| `replacementTokenBudget` | `64000` | Integer from 8,000 to 128,000 tokens | Bound approximate retained user-message text beside the opaque item. | Keep 64K; lower it to reduce session size or raise it only when recent user context is being lost. |
|
|
106
|
-
| `notifyOnFallback` | `true` | Boolean | Warn when
|
|
104
|
+
| `notifyOnFallback` | `true` | Boolean | Warn when remote compaction fails and Pi-native compaction takes over. | Keep enabled so silent fallback does not hide protocol or entitlement problems. |
|
|
107
105
|
|
|
108
106
|
Missing fields use defaults.
|
|
109
107
|
Settings reload on every `session_start`, including `/reload`, resume, and fork.
|
|
110
108
|
Menu writes apply immediately, preserve unknown JSON fields, serialize within the current Pi process, and use a final conflict check plus same-directory atomic rename.
|
|
111
109
|
On Unix, temporary files use mode `0600`.
|
|
112
110
|
|
|
113
|
-
Malformed, invalid, oversized, or symlinked settings files
|
|
114
|
-
|
|
111
|
+
Malformed, invalid, oversized, or symlinked settings files remain unchanged.
|
|
112
|
+
Defaults stay active, and the menu remains read-only until the file is fixed and Pi is reloaded.
|
|
115
113
|
Separate Pi processes do not share a mutation lock; a detected concurrent edit is rejected so the user can reopen Settings and retry.
|
|
116
114
|
|
|
117
115
|
### Relationship to Codex configuration
|
|
@@ -120,49 +118,59 @@ This extension does **not** read `~/.codex/config.toml`.
|
|
|
120
118
|
|
|
121
119
|
| Codex setting | Extension behavior |
|
|
122
120
|
| --- | --- |
|
|
123
|
-
| `features.remote_compaction_v2` | Conceptually corresponds to
|
|
121
|
+
| `features.remote_compaction_v2` | Conceptually corresponds to `protocol: "remote-v2"`; it is not imported. |
|
|
124
122
|
| `model_auto_compact_token_limit` | Not duplicated. Pi's own compaction threshold remains authoritative. |
|
|
125
123
|
| `model_auto_compact_token_limit_scope` | Not supported; Pi extensions do not own Codex's compact-window lineage. |
|
|
126
|
-
| `compact_prompt` / `experimental_compact_prompt_file` | Not used by
|
|
124
|
+
| `compact_prompt` / `experimental_compact_prompt_file` | Not used by either remote protocol, whose opaque checkpoint is generated by the server. |
|
|
127
125
|
| `features.token_budget` | Not supported; token-budget context reset is a different experimental strategy. |
|
|
128
126
|
|
|
129
127
|
## ✅ Requirements and compatibility
|
|
130
128
|
|
|
131
129
|
- Pi APIs compatible with the package's declared peer dependencies.
|
|
132
|
-
-
|
|
133
|
-
- A
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
130
|
+
- One of `openai-codex-responses`, `openai-responses`, or `azure-openai-responses` on the active model, or an explicit `apiProfiles` entry for a custom Codex-compatible API.
|
|
131
|
+
- A provider whose HTTP Responses adapter honors Pi's public `onPayload` and injected `fetch` options.
|
|
132
|
+
- A backend supporting the selected protocol and opaque `compaction` replay.
|
|
133
|
+
- Working credentials and any required compaction entitlement.
|
|
134
|
+
|
|
135
|
+
| Model API | `auto` route | Other selectable route |
|
|
136
|
+
| --- | --- | --- |
|
|
137
|
+
| `openai-codex-responses` | Responses Remote V2 | Responses Compact API |
|
|
138
|
+
| `openai-responses` | Responses Compact API | Responses Remote V2 |
|
|
139
|
+
| `azure-openai-responses` | Responses Compact API | Responses Remote V2 |
|
|
140
|
+
|
|
141
|
+
The installed built-in adapters are covered by deterministic transport tests.
|
|
142
|
+
A custom provider or proxy is eligible when its model explicitly uses one of these APIs, but its backend still owns compatible routing, authentication, request transforms, and opaque replay.
|
|
143
|
+
For a custom API label, eligibility is opt-in: `apiProfiles` must map that exact non-built-in label to `"codex-responses-v1"`. The default is empty, and an unconfigured custom API remains Pi-native.
|
|
144
|
+
`codex-responses-v1` uses Remote V2 in `auto` mode. With `responses-compact` explicitly selected, it retains the Codex Compact request fields, including tools and reasoning. The provider must honor Pi's public `transport: "sse"`, `onPayload`, and injected `fetch` options, and its backend must support the selected compaction protocol and opaque item replay. The profile declares compatibility; it does not probe the backend.
|
|
145
|
+
The extension does not send a separate capability probe or automatically retry a failed billable request through the other protocol.
|
|
146
|
+
A failed remote attempt falls back to Pi native, but an ordinary request cannot transparently recover after an incompatible provider has already received an existing opaque checkpoint.
|
|
140
147
|
Provider provenance is stored for diagnosis but is not a replay gate.
|
|
141
|
-
Switching providers can replay a checkpoint only when the API and exact model ID still match;
|
|
148
|
+
Switching providers can replay a checkpoint only when the API label, compatibility profile, and exact model ID still match. Custom API checkpoints also require a current matching `apiProfiles` entry; removing or changing it leaves Pi's visible fallback marker plus retained recent messages in context.
|
|
142
149
|
|
|
143
150
|
## 🔄 How it works
|
|
144
151
|
|
|
145
152
|
1. Pi prepares compaction and selects the recent message suffix it will retain.
|
|
146
153
|
2. If an earlier compatible checkpoint is present, the extension identifies its boundary from the summary persisted on the active `CompactionEntry` and validates the retained suffix fingerprints.
|
|
147
|
-
3.
|
|
148
|
-
4.
|
|
149
|
-
5. It
|
|
150
|
-
6. It
|
|
154
|
+
3. Remote V2 projects that checkpoint into a normal Responses SSE request and appends exactly one final `compaction_trigger`.
|
|
155
|
+
4. Unary compact captures the provider-built payload and authentication, rewrites only the same-origin `/responses` path to `/responses/compact`, and requests JSON without making a normal inference call.
|
|
156
|
+
5. It requires one bounded non-empty opaque `compaction` item; unary output may precede it only with user-role retained messages.
|
|
157
|
+
6. It constructs bounded replacement history and stores it with Pi suffix fingerprints, the real API label, and the resolved compatibility profile in versioned `CompactionEntry.details`.
|
|
151
158
|
7. On later compatible requests, it replaces an exactly validated marker with the persisted replacement history immediately before provider dispatch.
|
|
152
159
|
|
|
153
160
|
The persisted entry remains the summary identity source, so replay does not depend on the wording generated by the currently installed extension version.
|
|
154
161
|
If persisted summary identity, fingerprints, model identity, payload shape, or marker count do not match exactly, the extension leaves Pi's visible fallback context unchanged instead of guessing.
|
|
162
|
+
Older v1 and v2 checkpoints are normalized to the current checkpoint format when read; their built-in API label determines the profile. They still replay only when the current route authorizes that API/profile/model combination.
|
|
155
163
|
|
|
156
164
|
## 🔒 Security and privacy
|
|
157
165
|
|
|
158
|
-
Remote compaction sends the active conversation context
|
|
166
|
+
Remote compaction sends the active conversation context and system prompt to the configured Responses backend; Remote V2 also sends active tool schemas.
|
|
159
167
|
The Pi session stores the producing provider ID, encrypted compaction item, and bounded recent user-role Responses items.
|
|
160
168
|
It does not store credentials, authorization headers, or request headers in checkpoint details.
|
|
161
169
|
|
|
162
170
|
| Boundary | Limit |
|
|
163
171
|
| --- | ---: |
|
|
164
|
-
| Observed SSE stream | 8 MiB |
|
|
165
|
-
| Serialized opaque compaction item | 2 MiB |
|
|
172
|
+
| Observed SSE stream or unary JSON response | 8 MiB |
|
|
173
|
+
| Serialized opaque compaction item or retained output item | 2 MiB |
|
|
166
174
|
| Persisted replacement history | 8 MiB |
|
|
167
175
|
| Retained user text | 64K approximate tokens by default; configurable from 8K to 128K |
|
|
168
176
|
| Settings file | 64 KiB |
|
|
@@ -175,52 +183,29 @@ These hard byte ceilings are intentionally not configurable.
|
|
|
175
183
|
|
|
176
184
|
## 🚧 Limitations
|
|
177
185
|
|
|
178
|
-
-
|
|
179
|
-
|
|
180
|
-
- Full older history depends on this extension, the `openai-codex-responses` API, the exact checkpoint model ID, and a provider route whose backend accepts the opaque item.
|
|
186
|
+
- Codex Remote V2 remains an undocumented hosted contract and can change independently of Pi or this package; keep backups of important sessions.
|
|
187
|
+
- Full older history depends on this extension, the checkpoint API label and compatibility profile, the exact checkpoint model ID, and a provider route whose backend accepts the opaque item.
|
|
181
188
|
Removing the extension exposes only the portability fallback marker and Pi-retained recent messages.
|
|
182
189
|
- The package does not reproduce Codex core's context-window UUID/number lineage, previous-model compatibility fallback, exact pre-turn ordering, or exact mid-turn model-session ownership.
|
|
190
|
+
- Pi's public `getAllTools()` metadata does not expose `constrainedSampling`; Remote V2 preserves active tool order, names, descriptions, and parameter schemas but cannot reproduce that optional field.
|
|
183
191
|
- Remote failure falls back to Pi's plaintext summary, so a session can contain both remote opaque and native compaction entries over time.
|
|
184
192
|
- Settings concurrency is coordinated only within one Pi process; separate processes rely on the final conflict check.
|
|
185
193
|
|
|
186
|
-
## 🗂️ Package layout
|
|
187
|
-
|
|
188
|
-
```text
|
|
189
|
-
src/index.ts Thin Pi entrypoint
|
|
190
|
-
src/codex-compact.ts Pi lifecycle, command, provider projection, and fallback
|
|
191
|
-
src/remote.ts Provider stream invocation, auth payload, timeout, and retry controls
|
|
192
|
-
src/protocol.ts Bounded SSE parsing and Remote V2 payload/output validation
|
|
193
|
-
src/checkpoint.ts Replacement history, fingerprints, persistence, and replay projection
|
|
194
|
-
src/model-api.ts Codex Responses API detection for Remote V2 eligibility
|
|
195
|
-
src/settings.ts Global settings validation and atomic persistence
|
|
196
|
-
src/settings-menu.ts First-use manual compaction and settings TUI
|
|
197
|
-
|
|
198
|
-
dist/ Generated source-mapped Jiti runtime and lazy menu chunk
|
|
199
|
-
scripts/ Runtime builder
|
|
200
|
-
benchmark/ Three-arm compaction benchmark, self-test, and methodology
|
|
201
|
-
test/ Protocol, checkpoint, lifecycle, remote, settings, menu, and builder coverage
|
|
202
|
-
```
|
|
203
|
-
|
|
204
194
|
## 📊 Benchmark
|
|
205
195
|
|
|
206
|
-
The repository includes a seeded
|
|
207
|
-
|
|
208
|
-
It holds history length nearly fixed while varying information density across five state categories and ten history epochs.
|
|
209
|
-
|
|
196
|
+
The repository includes a seeded benchmark that compares uncompressed full context, Pi-native plaintext compaction, and this extension's Remote V2 path.
|
|
197
|
+
It keeps history length nearly fixed while varying information density across five state categories and ten history epochs.
|
|
210
198
|
Benchmark v3 uses repeated artifacts, isolated evaluator probes, seed-level paired statistics, one Pi SDK estimator for dry and live fixtures, and committed protocol manifests for confirmatory candidates.
|
|
211
|
-
|
|
212
199
|
It never treats nominal Pi 20K and Codex 20K settings as equal information capacity or automatically claims that protocol-conformant evidence was genuinely held out.
|
|
213
200
|
|
|
214
201
|
Preview its exploratory diagnostic without making a provider request:
|
|
215
202
|
|
|
216
203
|
```bash
|
|
217
|
-
|
|
204
|
+
npm run benchmark:codex-compact
|
|
218
205
|
```
|
|
219
206
|
|
|
220
|
-
A live run requires
|
|
221
|
-
|
|
207
|
+
A live run requires `--live`, review of the request and cost exposure, OpenAI Codex OAuth, and Remote V2 entitlement.
|
|
222
208
|
The repository preserves the explicitly labeled v2 matched-tail diagnostic and the v3 calibration evidence, while seeds 301–304 remain consumed and unavailable for future confirmatory protocols.
|
|
223
|
-
|
|
224
209
|
See the [benchmark guide](https://github.com/narumiruna/pi-extensions/tree/main/packages/pi-codex-compact/benchmark) for manifests, repetitions, commands, privacy, cost semantics, and interpretation limits.
|
|
225
210
|
|
|
226
211
|
## 🧪 Development
|
|
@@ -230,14 +215,29 @@ From the repository root:
|
|
|
230
215
|
```bash
|
|
231
216
|
npm --workspace @narumitw/pi-codex-compact run check
|
|
232
217
|
npm test
|
|
233
|
-
|
|
218
|
+
npm run package:pack -- codex-compact
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
See the [Codex compaction mechanism notes](https://github.com/narumiruna/pi-extensions/blob/main/docs/implementation-notes/codex-compaction-mechanism.md) for the underlying Codex mechanism research and the extension boundary.
|
|
222
|
+
|
|
223
|
+
## 🗂️ Package layout
|
|
224
|
+
|
|
225
|
+
```text
|
|
226
|
+
packages/pi-codex-compact/
|
|
227
|
+
├── src/ # Authoritative implementation and helpers
|
|
228
|
+
│ ├── index.ts # Thin Pi entrypoint
|
|
229
|
+
│ └── codex-compact.ts # Compaction routing, replay, and fallback
|
|
230
|
+
├── dist/ # Generated Jiti runtime
|
|
231
|
+
├── scripts/build-runtime.mjs # Runtime builder
|
|
232
|
+
├── benchmark/ # Repository-only benchmark and methodology
|
|
233
|
+
└── test/ # Behavior and lifecycle coverage
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
-
|
|
236
|
+
The generated runtime is built from `src/index.ts` and does not import back into `src`.
|
|
237
237
|
|
|
238
238
|
## 🔎 Keywords
|
|
239
239
|
|
|
240
|
-
Pi extension, Pi coding agent, OpenAI Codex, custom provider, proxy, Remote Compaction V2, opaque checkpoint, Responses API, context compaction.
|
|
240
|
+
Pi extension, Pi coding agent, OpenAI Codex, Azure OpenAI, custom provider, proxy, Remote Compaction V2, Responses Compact API, opaque checkpoint, Responses API, context compaction.
|
|
241
241
|
|
|
242
242
|
## 📄 License
|
|
243
243
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- the generated entry uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
|
|
4
|
+
// src/model-api.ts
|
|
5
|
+
function resolveResponsesCompactionProfile(api, apiProfiles = {}) {
|
|
6
|
+
if (api === "openai-codex-responses") return "codex-responses-v1";
|
|
7
|
+
if (api === "openai-responses" || api === "azure-openai-responses") return "openai-responses-v1";
|
|
8
|
+
return api && Object.hasOwn(apiProfiles, api) && apiProfiles[api] === "codex-responses-v1" ? "codex-responses-v1" : void 0;
|
|
9
|
+
}
|
|
10
|
+
function resolveCompactionRouteForApi(api, options) {
|
|
11
|
+
if (!options.enabled) return { kind: "native", reason: "remote compaction is disabled" };
|
|
12
|
+
if (!api) return { kind: "native", reason: "no active model" };
|
|
13
|
+
const profile = resolveResponsesCompactionProfile(api, options.apiProfiles);
|
|
14
|
+
if (!profile) {
|
|
15
|
+
return { kind: "native", reason: `API ${api} does not support Responses compaction` };
|
|
16
|
+
}
|
|
17
|
+
const protocol = options.protocol === "auto" ? profile === "codex-responses-v1" ? "remote-v2" : "responses-compact" : options.protocol;
|
|
18
|
+
return { kind: "remote", protocol, api, profile };
|
|
19
|
+
}
|
|
20
|
+
function resolveCompactionRoute(model, options) {
|
|
21
|
+
return resolveCompactionRouteForApi(model?.api, options);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/terminal.ts
|
|
25
|
+
function terminalText(value) {
|
|
26
|
+
return Array.from(value, (character) => {
|
|
27
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
28
|
+
return codePoint < 32 || codePoint >= 127 && codePoint <= 159 ? " " : character;
|
|
29
|
+
}).join("");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
resolveCompactionRouteForApi,
|
|
34
|
+
resolveCompactionRoute,
|
|
35
|
+
terminalText
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=chunk-7H7JJ7ZV.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/model-api.ts", "../../src/terminal.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport type { CodexCompactSettings } from \"./settings.js\";\n\nexport const RESPONSES_COMPACTION_APIS = [\n \"openai-codex-responses\",\n \"openai-responses\",\n \"azure-openai-responses\",\n] as const;\n\nexport type BuiltInResponsesCompactionApi = (typeof RESPONSES_COMPACTION_APIS)[number];\nexport type ResponsesCompactionApi = BuiltInResponsesCompactionApi;\nexport type ResponsesCompactionProfile = \"codex-responses-v1\" | \"openai-responses-v1\";\nexport type RemoteCompactionProtocol = \"remote-v2\" | \"responses-compact\";\nexport type RemoteCompactionProtocolSetting = \"auto\" | RemoteCompactionProtocol;\n\nexport type CompactionRoute =\n | { kind: \"remote\"; protocol: RemoteCompactionProtocol; api: Api; profile: ResponsesCompactionProfile }\n | { kind: \"native\"; reason: string };\n\nfunction resolveResponsesCompactionProfile(\n api: Api | undefined,\n apiProfiles: Readonly<Record<string, \"codex-responses-v1\">> = {},\n): ResponsesCompactionProfile | undefined {\n if (api === \"openai-codex-responses\") return \"codex-responses-v1\";\n if (api === \"openai-responses\" || api === \"azure-openai-responses\") return \"openai-responses-v1\";\n return api && Object.hasOwn(apiProfiles, api) && apiProfiles[api] === \"codex-responses-v1\"\n ? \"codex-responses-v1\"\n : undefined;\n}\n\nexport function resolveCompactionRouteForApi(\n api: Api | undefined,\n options: Pick<CodexCompactSettings, \"enabled\" | \"protocol\"> & {\n apiProfiles?: Readonly<Record<string, \"codex-responses-v1\">>;\n },\n): CompactionRoute {\n if (!options.enabled) return { kind: \"native\", reason: \"remote compaction is disabled\" };\n if (!api) return { kind: \"native\", reason: \"no active model\" };\n const profile = resolveResponsesCompactionProfile(api, options.apiProfiles);\n if (!profile) {\n return { kind: \"native\", reason: `API ${api} does not support Responses compaction` };\n }\n const protocol =\n options.protocol === \"auto\"\n ? profile === \"codex-responses-v1\"\n ? \"remote-v2\"\n : \"responses-compact\"\n : options.protocol;\n return { kind: \"remote\", protocol, api, profile };\n}\n\nexport function resolveCompactionRoute(\n model: Model<Api> | undefined,\n options: Pick<CodexCompactSettings, \"enabled\" | \"protocol\"> & {\n apiProfiles?: Readonly<Record<string, \"codex-responses-v1\">>;\n },\n): CompactionRoute {\n return resolveCompactionRouteForApi(model?.api, options);\n}\n", "export function terminalText(value: string): string {\n return Array.from(value, (character) => {\n const codePoint = character.codePointAt(0) ?? 0;\n return codePoint < 32 || (codePoint >= 127 && codePoint <= 159) ? \" \" : character;\n }).join(\"\");\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAmBA,SAAS,kCACP,KACA,cAA8D,CAAC,GACvB;AACxC,MAAI,QAAQ,yBAA0B,QAAO;AAC7C,MAAI,QAAQ,sBAAsB,QAAQ,yBAA0B,QAAO;AAC3E,SAAO,OAAO,OAAO,OAAO,aAAa,GAAG,KAAK,YAAY,GAAG,MAAM,uBAClE,uBACA;AACN;AAEO,SAAS,6BACd,KACA,SAGiB;AACjB,MAAI,CAAC,QAAQ,QAAS,QAAO,EAAE,MAAM,UAAU,QAAQ,gCAAgC;AACvF,MAAI,CAAC,IAAK,QAAO,EAAE,MAAM,UAAU,QAAQ,kBAAkB;AAC7D,QAAM,UAAU,kCAAkC,KAAK,QAAQ,WAAW;AAC1E,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,MAAM,UAAU,QAAQ,OAAO,GAAG,yCAAyC;AAAA,EACtF;AACA,QAAM,WACJ,QAAQ,aAAa,SACjB,YAAY,uBACV,cACA,sBACF,QAAQ;AACd,SAAO,EAAE,MAAM,UAAU,UAAU,KAAK,QAAQ;AAClD;AAEO,SAAS,uBACd,OACA,SAGiB;AACjB,SAAO,6BAA6B,OAAO,KAAK,OAAO;AACzD;;;AC1DO,SAAS,aAAa,OAAuB;AAClD,SAAO,MAAM,KAAK,OAAO,CAAC,cAAc;AACtC,UAAM,YAAY,UAAU,YAAY,CAAC,KAAK;AAC9C,WAAO,YAAY,MAAO,aAAa,OAAO,aAAa,MAAO,MAAM;AAAA,EAC1E,CAAC,EAAE,KAAK,EAAE;AACZ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,31 +1,37 @@
|
|
|
1
1
|
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
2
|
// @ts-nocheck -- the generated entry uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
resolveCompactionRouteForApi,
|
|
5
|
+
terminalText
|
|
6
|
+
} from "./chunk-7H7JJ7ZV.js";
|
|
6
7
|
|
|
7
8
|
// src/settings-menu.ts
|
|
8
|
-
function safeText(value) {
|
|
9
|
-
return Array.from(value, (character) => {
|
|
10
|
-
const codePoint = character.codePointAt(0) ?? 0;
|
|
11
|
-
return codePoint < 32 || codePoint >= 127 && codePoint <= 159 ? " " : character;
|
|
12
|
-
}).join("");
|
|
13
|
-
}
|
|
14
9
|
function timeoutLabel(milliseconds) {
|
|
15
10
|
return `${milliseconds / 6e4} min`;
|
|
16
11
|
}
|
|
17
12
|
function retentionLabel(tokens) {
|
|
18
13
|
return `${tokens / 1e3}K tokens`;
|
|
19
14
|
}
|
|
15
|
+
function protocolLabel(protocol) {
|
|
16
|
+
switch (protocol) {
|
|
17
|
+
case "auto":
|
|
18
|
+
return "Auto";
|
|
19
|
+
case "remote-v2":
|
|
20
|
+
return "Remote V2";
|
|
21
|
+
case "responses-compact":
|
|
22
|
+
return "Responses Compact";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
20
25
|
async function update(runtime, ctx, patch, signal) {
|
|
21
26
|
try {
|
|
22
27
|
await runtime.update(patch, signal);
|
|
23
|
-
|
|
28
|
+
if (signal.aborted) return { kind: "rejected" };
|
|
29
|
+
ctx.ui.notify("Responses compaction settings saved.", "info");
|
|
24
30
|
return { kind: "stay" };
|
|
25
31
|
} catch (error) {
|
|
26
32
|
if (signal.aborted) return { kind: "rejected" };
|
|
27
33
|
ctx.ui.notify(
|
|
28
|
-
`Could not save pi-codex-compact.json: ${
|
|
34
|
+
`Could not save pi-codex-compact.json: ${terminalText(error instanceof Error ? error.message : String(error))}`,
|
|
29
35
|
"error"
|
|
30
36
|
);
|
|
31
37
|
return { kind: "rejected" };
|
|
@@ -37,11 +43,12 @@ function createCodexCompactMenu(runtime, options = {}) {
|
|
|
37
43
|
screens: {
|
|
38
44
|
main: ({ state }) => ({
|
|
39
45
|
kind: "actions",
|
|
40
|
-
title: "
|
|
46
|
+
title: "Responses Compaction",
|
|
41
47
|
lines: [
|
|
42
|
-
`Remote
|
|
43
|
-
`
|
|
44
|
-
`
|
|
48
|
+
`Remote compaction: ${state.settings.enabled ? "On" : "Off"}`,
|
|
49
|
+
`Protocol setting: ${protocolLabel(state.settings.protocol)}`,
|
|
50
|
+
`Active model: ${terminalText(options.status?.model ?? "none")}`,
|
|
51
|
+
`Compact route: ${terminalText(compactRoute(state, options.status))}`
|
|
45
52
|
],
|
|
46
53
|
items: [
|
|
47
54
|
{
|
|
@@ -62,17 +69,25 @@ function createCodexCompactMenu(runtime, options = {}) {
|
|
|
62
69
|
}),
|
|
63
70
|
settings: ({ state }) => ({
|
|
64
71
|
kind: "settings",
|
|
65
|
-
title: "
|
|
66
|
-
lines: [`User settings \xB7 ${
|
|
72
|
+
title: "Responses Compaction Settings",
|
|
73
|
+
lines: [`User settings \xB7 ${terminalText(state.path)}`],
|
|
67
74
|
items: [
|
|
68
75
|
{
|
|
69
76
|
id: "enabled",
|
|
70
77
|
label: "Remote compaction",
|
|
71
|
-
description: "Use
|
|
78
|
+
description: "Use a supported Responses compaction protocol.",
|
|
72
79
|
currentValue: state.settings.enabled ? "On" : "Off",
|
|
73
80
|
values: ["On", "Off"],
|
|
74
81
|
action: "set-enabled"
|
|
75
82
|
},
|
|
83
|
+
{
|
|
84
|
+
id: "protocol",
|
|
85
|
+
label: "Protocol",
|
|
86
|
+
description: "Choose automatically or force one supported remote protocol.",
|
|
87
|
+
currentValue: protocolLabel(state.settings.protocol),
|
|
88
|
+
values: ["Auto", "Remote V2", "Responses Compact"],
|
|
89
|
+
action: "set-protocol"
|
|
90
|
+
},
|
|
76
91
|
{
|
|
77
92
|
id: "requestTimeoutMs",
|
|
78
93
|
label: "Request timeout",
|
|
@@ -100,7 +115,7 @@ function createCodexCompactMenu(runtime, options = {}) {
|
|
|
100
115
|
{
|
|
101
116
|
id: "notifyOnFallback",
|
|
102
117
|
label: "Fallback notifications",
|
|
103
|
-
description: "Warn when
|
|
118
|
+
description: "Warn when remote compaction fails and Pi native takes over.",
|
|
104
119
|
currentValue: state.settings.notifyOnFallback ? "On" : "Off",
|
|
105
120
|
values: ["On", "Off"],
|
|
106
121
|
action: "set-notify"
|
|
@@ -111,8 +126,8 @@ function createCodexCompactMenu(runtime, options = {}) {
|
|
|
111
126
|
kind: "detail",
|
|
112
127
|
title: "Codex Compact Settings \xB7 Read only",
|
|
113
128
|
lines: [
|
|
114
|
-
`Invalid settings file: ${
|
|
115
|
-
`Issue: ${
|
|
129
|
+
`Invalid settings file: ${terminalText(state.path)}`,
|
|
130
|
+
`Issue: ${terminalText(state.issue ?? "unknown validation error")}`,
|
|
116
131
|
"Built-in defaults are active. Repair the file and run /reload; it will not be overwritten."
|
|
117
132
|
],
|
|
118
133
|
hint: "back"
|
|
@@ -124,28 +139,29 @@ function createCodexCompactMenu(runtime, options = {}) {
|
|
|
124
139
|
return { kind: "close" };
|
|
125
140
|
},
|
|
126
141
|
"set-enabled": ({ ctx, value, signal }) => update(runtime, ctx, { enabled: value === "On" }, signal),
|
|
127
|
-
"set-
|
|
142
|
+
"set-protocol": ({ ctx, value, signal }) => update(
|
|
128
143
|
runtime,
|
|
129
144
|
ctx,
|
|
130
|
-
{
|
|
145
|
+
{
|
|
146
|
+
protocol: value === "Remote V2" ? "remote-v2" : value === "Responses Compact" ? "responses-compact" : "auto"
|
|
147
|
+
},
|
|
131
148
|
signal
|
|
132
149
|
),
|
|
150
|
+
"set-timeout": ({ ctx, value, signal }) => update(runtime, ctx, { requestTimeoutMs: Number.parseInt(value ?? "5", 10) * 6e4 }, signal),
|
|
133
151
|
"set-retries": ({ ctx, value, signal }) => update(runtime, ctx, { maxRetries: Number.parseInt(value ?? "2", 10) }, signal),
|
|
134
|
-
"set-retention": ({ ctx, value, signal }) => update(
|
|
135
|
-
runtime,
|
|
136
|
-
ctx,
|
|
137
|
-
{ replacementTokenBudget: Number.parseInt(value ?? "64", 10) * 1e3 },
|
|
138
|
-
signal
|
|
139
|
-
),
|
|
152
|
+
"set-retention": ({ ctx, value, signal }) => update(runtime, ctx, { replacementTokenBudget: Number.parseInt(value ?? "64", 10) * 1e3 }, signal),
|
|
140
153
|
"set-notify": ({ ctx, value, signal }) => update(runtime, ctx, { notifyOnFallback: value === "On" }, signal)
|
|
141
154
|
}
|
|
142
155
|
};
|
|
143
156
|
}
|
|
144
157
|
async function showCodexCompactMenu(runtime, ctx, owner) {
|
|
145
|
-
if (ctx.mode
|
|
146
|
-
ctx.ui.notify(`Edit
|
|
158
|
+
if (ctx.mode === "rpc" && ctx.hasUI) {
|
|
159
|
+
ctx.ui.notify(`Edit Responses compaction settings at ${terminalText(runtime.get().path)}.`, "info");
|
|
147
160
|
return;
|
|
148
161
|
}
|
|
162
|
+
if (ctx.mode !== "tui") {
|
|
163
|
+
throw new Error("/codex-compact requires TUI or RPC UI support");
|
|
164
|
+
}
|
|
149
165
|
const { runMenu } = await import("@narumitw/pi-tui-kit");
|
|
150
166
|
if (owner.signal.aborted || !owner.isCurrent()) return;
|
|
151
167
|
let compactRequested = false;
|
|
@@ -167,7 +183,7 @@ async function showCodexCompactMenu(runtime, ctx, owner) {
|
|
|
167
183
|
ctx.compact({
|
|
168
184
|
onError: (error) => {
|
|
169
185
|
if (!owner.signal.aborted && owner.isCurrent()) {
|
|
170
|
-
ctx.ui.notify(`Compaction failed: ${
|
|
186
|
+
ctx.ui.notify(`Compaction failed: ${terminalText(error.message)}`, "error");
|
|
171
187
|
}
|
|
172
188
|
}
|
|
173
189
|
});
|
|
@@ -176,16 +192,17 @@ function compactMenuStatus(ctx) {
|
|
|
176
192
|
const model = ctx.model;
|
|
177
193
|
return {
|
|
178
194
|
model: model ? `${model.provider}/${model.id}` : "none",
|
|
179
|
-
|
|
195
|
+
api: model?.api
|
|
180
196
|
};
|
|
181
197
|
}
|
|
182
198
|
function compactRoute(state, status) {
|
|
183
|
-
|
|
184
|
-
|
|
199
|
+
const route = resolveCompactionRouteForApi(status?.api, state.settings);
|
|
200
|
+
if (route.kind === "native") return `Pi native (${route.reason})`;
|
|
201
|
+
return route.protocol === "remote-v2" ? "Responses Remote V2" : "Responses Compact API";
|
|
185
202
|
}
|
|
186
203
|
export {
|
|
187
204
|
compactMenuStatus,
|
|
188
205
|
createCodexCompactMenu,
|
|
189
206
|
showCodexCompactMenu
|
|
190
207
|
};
|
|
191
|
-
//# sourceMappingURL=settings-menu-
|
|
208
|
+
//# sourceMappingURL=settings-menu-TVWWDPBF.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/settings-menu.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Api } from \"@earendil-works/pi-ai\";\nimport type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { MenuDefinition } from \"@narumitw/pi-tui-kit\";\nimport { resolveCompactionRouteForApi } from \"./model-api.js\";\nimport type { CodexCompactSettings, CodexCompactSettingsRuntime, CodexCompactSettingsState } from \"./settings.js\";\nimport { terminalText as safeText } from \"./terminal.js\";\n\ntype Screen = \"main\" | \"settings\" | \"invalid\";\ntype Action =\n | \"compact-now\"\n | \"set-enabled\"\n | \"set-protocol\"\n | \"set-timeout\"\n | \"set-retries\"\n | \"set-retention\"\n | \"set-notify\";\n\nexport interface SettingsMenuOwner {\n signal: AbortSignal;\n isCurrent(): boolean;\n}\n\ninterface CompactMenuStatus {\n model: string;\n api?: Api;\n}\n\nfunction timeoutLabel(milliseconds: number): string {\n return `${milliseconds / 60_000} min`;\n}\n\nfunction retentionLabel(tokens: number): string {\n return `${tokens / 1000}K tokens`;\n}\n\nfunction protocolLabel(protocol: CodexCompactSettings[\"protocol\"]): string {\n switch (protocol) {\n case \"auto\":\n return \"Auto\";\n case \"remote-v2\":\n return \"Remote V2\";\n case \"responses-compact\":\n return \"Responses Compact\";\n }\n}\n\nasync function update(\n runtime: CodexCompactSettingsRuntime,\n ctx: ExtensionCommandContext,\n patch: Partial<CodexCompactSettings>,\n signal: AbortSignal,\n) {\n try {\n await runtime.update(patch, signal);\n if (signal.aborted) return { kind: \"rejected\" as const };\n ctx.ui.notify(\"Responses compaction settings saved.\", \"info\");\n return { kind: \"stay\" as const };\n } catch (error) {\n if (signal.aborted) return { kind: \"rejected\" as const };\n ctx.ui.notify(\n `Could not save pi-codex-compact.json: ${safeText(error instanceof Error ? error.message : String(error))}`,\n \"error\",\n );\n return { kind: \"rejected\" as const };\n }\n}\n\nexport function createCodexCompactMenu(\n runtime: CodexCompactSettingsRuntime,\n options: { onCompactRequested?: () => void; status?: CompactMenuStatus } = {},\n): MenuDefinition<CodexCompactSettingsState, Screen, Action, ExtensionCommandContext> {\n return {\n start: \"main\",\n screens: {\n main: ({ state }) => ({\n kind: \"actions\",\n title: \"Responses Compaction\",\n lines: [\n `Remote compaction: ${state.settings.enabled ? \"On\" : \"Off\"}`,\n `Protocol setting: ${protocolLabel(state.settings.protocol)}`,\n `Active model: ${safeText(options.status?.model ?? \"none\")}`,\n `Compact route: ${safeText(compactRoute(state, options.status))}`,\n ],\n items: [\n {\n id: \"compact-now\",\n label: \"Compact now\",\n description: \"Close this menu and compact the active session immediately.\",\n action: \"compact-now\",\n },\n state.kind === \"invalid\"\n ? {\n id: \"settings\",\n label: \"Settings\",\n description: \"Read-only until the invalid settings file is repaired.\",\n to: \"invalid\" as const,\n }\n : { id: \"settings\", label: \"Settings\", to: \"settings\" as const },\n { id: \"close\", label: \"Close\", close: true },\n ],\n hint: \"close\",\n }),\n settings: ({ state }) => ({\n kind: \"settings\",\n title: \"Responses Compaction Settings\",\n lines: [`User settings \u00B7 ${safeText(state.path)}`],\n items: [\n {\n id: \"enabled\",\n label: \"Remote compaction\",\n description: \"Use a supported Responses compaction protocol.\",\n currentValue: state.settings.enabled ? \"On\" : \"Off\",\n values: [\"On\", \"Off\"],\n action: \"set-enabled\",\n },\n {\n id: \"protocol\",\n label: \"Protocol\",\n description: \"Choose automatically or force one supported remote protocol.\",\n currentValue: protocolLabel(state.settings.protocol),\n values: [\"Auto\", \"Remote V2\", \"Responses Compact\"],\n action: \"set-protocol\",\n },\n {\n id: \"requestTimeoutMs\",\n label: \"Request timeout\",\n description: \"Maximum time for the extension-owned remote compaction request.\",\n currentValue: timeoutLabel(state.settings.requestTimeoutMs),\n values: [\"2 min\", \"5 min\", \"10 min\"],\n action: \"set-timeout\",\n },\n {\n id: \"maxRetries\",\n label: \"Transport retries\",\n description: \"Retry transient provider failures before falling back to Pi.\",\n currentValue: String(state.settings.maxRetries),\n values: [\"0\", \"1\", \"2\"],\n action: \"set-retries\",\n },\n {\n id: \"replacementTokenBudget\",\n label: \"Retained user history\",\n description: \"Approximate user-message budget kept beside the opaque checkpoint.\",\n currentValue: retentionLabel(state.settings.replacementTokenBudget),\n values: [\"32K tokens\", \"64K tokens\", \"96K tokens\", \"128K tokens\"],\n action: \"set-retention\",\n },\n {\n id: \"notifyOnFallback\",\n label: \"Fallback notifications\",\n description: \"Warn when remote compaction fails and Pi native takes over.\",\n currentValue: state.settings.notifyOnFallback ? \"On\" : \"Off\",\n values: [\"On\", \"Off\"],\n action: \"set-notify\",\n },\n ],\n }),\n invalid: ({ state }) => ({\n kind: \"detail\",\n title: \"Codex Compact Settings \u00B7 Read only\",\n lines: [\n `Invalid settings file: ${safeText(state.path)}`,\n `Issue: ${safeText(state.issue ?? \"unknown validation error\")}`,\n \"Built-in defaults are active. Repair the file and run /reload; it will not be overwritten.\",\n ],\n hint: \"back\",\n }),\n },\n actions: {\n \"compact-now\": async () => {\n options.onCompactRequested?.();\n return { kind: \"close\" };\n },\n \"set-enabled\": ({ ctx, value, signal }) => update(runtime, ctx, { enabled: value === \"On\" }, signal),\n \"set-protocol\": ({ ctx, value, signal }) =>\n update(\n runtime,\n ctx,\n {\n protocol:\n value === \"Remote V2\" ? \"remote-v2\" : value === \"Responses Compact\" ? \"responses-compact\" : \"auto\",\n },\n signal,\n ),\n \"set-timeout\": ({ ctx, value, signal }) =>\n update(runtime, ctx, { requestTimeoutMs: Number.parseInt(value ?? \"5\", 10) * 60_000 }, signal),\n \"set-retries\": ({ ctx, value, signal }) =>\n update(runtime, ctx, { maxRetries: Number.parseInt(value ?? \"2\", 10) }, signal),\n \"set-retention\": ({ ctx, value, signal }) =>\n update(runtime, ctx, { replacementTokenBudget: Number.parseInt(value ?? \"64\", 10) * 1000 }, signal),\n \"set-notify\": ({ ctx, value, signal }) => update(runtime, ctx, { notifyOnFallback: value === \"On\" }, signal),\n },\n };\n}\n\nexport async function showCodexCompactMenu(\n runtime: CodexCompactSettingsRuntime,\n ctx: ExtensionCommandContext,\n owner: SettingsMenuOwner,\n): Promise<void> {\n if (ctx.mode === \"rpc\" && ctx.hasUI) {\n ctx.ui.notify(`Edit Responses compaction settings at ${safeText(runtime.get().path)}.`, \"info\");\n return;\n }\n if (ctx.mode !== \"tui\") {\n throw new Error(\"/codex-compact requires TUI or RPC UI support\");\n }\n const { runMenu } = await import(\"@narumitw/pi-tui-kit\");\n if (owner.signal.aborted || !owner.isCurrent()) return;\n let compactRequested = false;\n await runMenu(\n ctx,\n createCodexCompactMenu(runtime, {\n onCompactRequested: () => {\n compactRequested = true;\n },\n status: compactMenuStatus(ctx),\n }),\n {\n getState: () => runtime.get(),\n signal: owner.signal,\n isCurrent: owner.isCurrent,\n },\n );\n if (!compactRequested || owner.signal.aborted || !owner.isCurrent()) return;\n ctx.compact({\n onError: (error) => {\n if (!owner.signal.aborted && owner.isCurrent()) {\n ctx.ui.notify(`Compaction failed: ${safeText(error.message)}`, \"error\");\n }\n },\n });\n}\n\nexport function compactMenuStatus(ctx: ExtensionCommandContext): CompactMenuStatus {\n const model = ctx.model;\n return {\n model: model ? `${model.provider}/${model.id}` : \"none\",\n api: model?.api,\n };\n}\n\nfunction compactRoute(state: Readonly<CodexCompactSettingsState>, status: CompactMenuStatus | undefined): string {\n const route = resolveCompactionRouteForApi(status?.api, state.settings);\n if (route.kind === \"native\") return `Pi native (${route.reason})`;\n return route.protocol === \"remote-v2\" ? \"Responses Remote V2\" : \"Responses Compact API\";\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|