@narumitw/pi-codex-compact 0.51.3 → 0.52.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
@@ -2,21 +2,20 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@narumitw/pi-codex-compact)](https://www.npmjs.com/package/@narumitw/pi-codex-compact) [![Pi extension](https://img.shields.io/badge/Pi-extension-blue)](https://pi.dev) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
4
4
 
5
- Use Codex Remote Compaction V2 in Pi instead of generating a local plaintext summary for models that use the `openai-codex-responses` API.
6
-
7
- The extension requests and stores an opaque server-generated checkpoint, then safely replays it in later Codex Responses requests.
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
- - Uses the active Codex Responses provider and credentials without persisting secrets or request headers.
11
+ - Supports `openai-codex-responses`, `openai-responses`, and `azure-openai-responses`.
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 into the next request.
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,19 +38,23 @@ 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 an unbuilt local checkout must be built before Pi loads the package directory.
43
- Loading the package enables Remote V2 with safe defaults.
44
- Avoid loading a global npm installation and the local workspace at the same time.
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 provider, or configure a custom provider that routes to a compatible Codex backend.
49
- 2. Select a model whose API is `openai-codex-responses`.
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`.
50
52
  3. Work normally.
51
53
  Pi's automatic compaction and built-in `/compact` continue to operate.
52
54
  4. Run `/codex-compact` to inspect the effective route or choose **Compact now**.
53
55
  5. After compaction, continue the session normally; compatible requests replay the opaque checkpoint.
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.
56
59
 
57
60
  ## 💬 Commands
@@ -60,7 +63,7 @@ When the active model uses another API, compaction remains entirely Pi-native.
60
63
  /codex-compact
61
64
  ```
62
65
 
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**.
66
+ In TUI mode, the menu shows whether remote compaction is enabled, the protocol setting, the active model, and whether manual compaction will use **Responses Remote V2**, **Responses Compact API**, or **Pi native**.
64
67
  It contains:
65
68
 
66
69
  ```text
@@ -72,9 +75,10 @@ Close
72
75
  **Compact now** closes the menu before asking Pi to compact the active session.
73
76
  Escape or Ctrl+C closes without compacting, and an obsolete menu cannot trigger work after session replacement or shutdown.
74
77
  **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.
78
+ In RPC mode, the command reports the manual settings path instead of opening custom UI or compacting.
79
+ Print and JSON modes reject the command explicitly because they cannot open the menu or safely replace their normal output with an interactive result.
76
80
 
77
- Pi's built-in `/compact` remains available and follows the same extension hook when the active model uses `openai-codex-responses`.
81
+ Pi's built-in `/compact` remains available and follows the same extension hook for all three supported Responses APIs.
78
82
 
79
83
  ## ⚙️ Settings
80
84
 
@@ -90,6 +94,7 @@ There is no environment-variable or project-level override.
90
94
  ```json
91
95
  {
92
96
  "enabled": true,
97
+ "protocol": "auto",
93
98
  "requestTimeoutMs": 300000,
94
99
  "maxRetries": 2,
95
100
  "replacementTokenBudget": 64000,
@@ -99,19 +104,20 @@ There is no environment-variable or project-level override.
99
104
 
100
105
  | Setting | Default | Accepted values | Behavior | Recommendation |
101
106
  | --- | ---: | --- | --- | --- |
102
- | `enabled` | `true` | Boolean | Attempt Remote V2 when the active model uses `openai-codex-responses`. | Keep enabled unless diagnosing provider behavior. |
107
+ | `enabled` | `true` | Boolean | Attempt a supported remote compaction route. | Keep enabled unless diagnosing provider behavior. |
108
+ | `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. |
103
109
  | `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
110
  | `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
111
  | `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 Remote V2 fails and Pi-native compaction takes over. | Keep enabled so silent fallback does not hide protocol or entitlement problems. |
112
+ | `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
113
 
108
114
  Missing fields use defaults.
109
115
  Settings reload on every `session_start`, including `/reload`, resume, and fork.
110
116
  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
117
  On Unix, temporary files use mode `0600`.
112
118
 
113
- Malformed, invalid, oversized, or symlinked settings files are never overwritten.
114
- Safe defaults stay active, and the menu provides read-only repair guidance until the file is fixed and Pi is reloaded.
119
+ Malformed, invalid, oversized, or symlinked settings files remain unchanged.
120
+ Defaults stay active, and the menu remains read-only until the file is fixed and Pi is reloaded.
115
121
  Separate Pi processes do not share a mutation lock; a detected concurrent edit is rejected so the user can reopen Settings and retry.
116
122
 
117
123
  ### Relationship to Codex configuration
@@ -120,34 +126,41 @@ This extension does **not** read `~/.codex/config.toml`.
120
126
 
121
127
  | Codex setting | Extension behavior |
122
128
  | --- | --- |
123
- | `features.remote_compaction_v2` | Conceptually corresponds to this extension's `enabled`; it is not imported. |
129
+ | `features.remote_compaction_v2` | Conceptually corresponds to `protocol: "remote-v2"`; it is not imported. |
124
130
  | `model_auto_compact_token_limit` | Not duplicated. Pi's own compaction threshold remains authoritative. |
125
131
  | `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 Remote V2, whose opaque checkpoint is generated by the server. |
132
+ | `compact_prompt` / `experimental_compact_prompt_file` | Not used by either remote protocol, whose opaque checkpoint is generated by the server. |
127
133
  | `features.token_budget` | Not supported; token-budget context reset is a different experimental strategy. |
128
134
 
129
135
  ## ✅ Requirements and compatibility
130
136
 
131
137
  - Pi APIs compatible with the package's declared peer dependencies.
132
- - API `openai-codex-responses` on the active model.
133
- - A built-in or custom provider that routes that API to a backend supporting `compaction_trigger` and opaque `compaction` replay.
134
- - Working credentials and Remote V2 entitlement for that backend.
135
-
136
- The built-in `openai-codex` provider is supported, and a custom provider or proxy is eligible when its model explicitly uses `openai-codex-responses`.
137
- Generic `openai-responses`, `azure-openai-responses`, GitHub Copilot, and other merely Responses-compatible API labels are not eligible.
138
- The extension does not probe provider capabilities before compaction; a provider that declares `openai-codex-responses` owns compatible routing, authentication, request transforms, SSE transport, and opaque replay.
139
- A failed Remote V2 compaction attempt falls back to Pi native, but an ordinary request cannot transparently recover after an incompatible provider has already received an existing opaque checkpoint.
138
+ - One of `openai-codex-responses`, `openai-responses`, or `azure-openai-responses` on the active model.
139
+ - A provider whose HTTP Responses adapter honors Pi's public `onPayload` and injected `fetch` options.
140
+ - A backend supporting the selected protocol and opaque `compaction` replay.
141
+ - Working credentials and any required compaction entitlement.
142
+
143
+ | Model API | `auto` route | Other selectable route |
144
+ | --- | --- | --- |
145
+ | `openai-codex-responses` | Responses Remote V2 | Responses Compact API |
146
+ | `openai-responses` | Responses Compact API | Responses Remote V2 |
147
+ | `azure-openai-responses` | Responses Compact API | Responses Remote V2 |
148
+
149
+ The installed built-in adapters are covered by deterministic transport tests.
150
+ 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.
151
+ The extension does not send a separate capability probe or automatically retry a failed billable request through the other protocol.
152
+ 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
153
  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; switching model IDs leaves Pi's visible fallback marker plus retained recent messages in context.
154
+ Switching providers can replay a checkpoint only when the API label and exact model ID still match; switching APIs or model IDs leaves Pi's visible fallback marker plus retained recent messages in context.
142
155
 
143
156
  ## 🔄 How it works
144
157
 
145
158
  1. Pi prepares compaction and selects the recent message suffix it will retain.
146
159
  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. It projects that checkpoint into the current Responses input, appends exactly one final `compaction_trigger`, and sends a normal authenticated Codex Responses SSE request with cache retention disabled.
148
- 4. It requires a completed response containing exactly one non-empty opaque `compaction` item.
149
- 5. It constructs bounded replacement history from recent raw user-role Responses items followed by the opaque item.
150
- 6. It stores that history and fingerprints of Pi's retained suffix in versioned `CompactionEntry.details`.
160
+ 3. Remote V2 projects that checkpoint into a normal Responses SSE request and appends exactly one final `compaction_trigger`.
161
+ 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.
162
+ 5. It requires one bounded non-empty opaque `compaction` item; unary output may precede it only with user-role retained messages.
163
+ 6. It constructs bounded replacement history and stores it with Pi suffix fingerprints in versioned `CompactionEntry.details`.
151
164
  7. On later compatible requests, it replaces an exactly validated marker with the persisted replacement history immediately before provider dispatch.
152
165
 
153
166
  The persisted entry remains the summary identity source, so replay does not depend on the wording generated by the currently installed extension version.
@@ -155,14 +168,14 @@ If persisted summary identity, fingerprints, model identity, payload shape, or m
155
168
 
156
169
  ## 🔒 Security and privacy
157
170
 
158
- Remote compaction sends the active conversation context, system prompt, and active tool schemas to the configured backend used by the selected Codex Responses provider.
171
+ Remote compaction sends the active conversation context and system prompt to the configured Responses backend; Remote V2 also sends active tool schemas.
159
172
  The Pi session stores the producing provider ID, encrypted compaction item, and bounded recent user-role Responses items.
160
173
  It does not store credentials, authorization headers, or request headers in checkpoint details.
161
174
 
162
175
  | Boundary | Limit |
163
176
  | --- | ---: |
164
- | Observed SSE stream | 8 MiB |
165
- | Serialized opaque compaction item | 2 MiB |
177
+ | Observed SSE stream or unary JSON response | 8 MiB |
178
+ | Serialized opaque compaction item or retained output item | 2 MiB |
166
179
  | Persisted replacement history | 8 MiB |
167
180
  | Retained user text | 64K approximate tokens by default; configurable from 8K to 128K |
168
181
  | Settings file | 64 KiB |
@@ -175,52 +188,29 @@ These hard byte ceilings are intentionally not configurable.
175
188
 
176
189
  ## 🚧 Limitations
177
190
 
178
- - The wire contract is undocumented and can change independently of Pi or this package.
179
- Keep backups of important sessions.
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.
191
+ - Codex Remote V2 remains an undocumented hosted contract and can change independently of Pi or this package; keep backups of important sessions.
192
+ - Full older history depends on this extension, the checkpoint API label, the exact checkpoint model ID, and a provider route whose backend accepts the opaque item.
181
193
  Removing the extension exposes only the portability fallback marker and Pi-retained recent messages.
182
194
  - 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.
195
+ - 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
196
  - Remote failure falls back to Pi's plaintext summary, so a session can contain both remote opaque and native compaction entries over time.
184
197
  - Settings concurrency is coordinated only within one Pi process; separate processes rely on the final conflict check.
185
198
 
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
199
  ## 📊 Benchmark
205
200
 
206
- The repository includes a seeded three-arm benchmark for uncompressed full context, Pi-native plaintext compaction, and this extension's Codex Remote Compaction V2 path.
207
-
208
- It holds history length nearly fixed while varying information density across five state categories and ten history epochs.
209
-
201
+ The repository includes a seeded benchmark that compares uncompressed full context, Pi-native plaintext compaction, and this extension's Remote V2 path.
202
+ It keeps history length nearly fixed while varying information density across five state categories and ten history epochs.
210
203
  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
204
  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
205
 
214
206
  Preview its exploratory diagnostic without making a provider request:
215
207
 
216
208
  ```bash
217
- just benchmark-codex-compact
209
+ npm run benchmark:codex-compact
218
210
  ```
219
211
 
220
- A live run requires an explicit `--live` flag, reviewed request and cost exposure, OpenAI Codex OAuth, and Remote V2 entitlement.
221
-
212
+ A live run requires `--live`, review of the request and cost exposure, OpenAI Codex OAuth, and Remote V2 entitlement.
222
213
  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
214
  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
215
 
226
216
  ## 🧪 Development
@@ -230,14 +220,36 @@ From the repository root:
230
220
  ```bash
231
221
  npm --workspace @narumitw/pi-codex-compact run check
232
222
  npm test
233
- just pack codex-compact
223
+ npm run package:pack -- codex-compact
234
224
  ```
235
225
 
236
226
  See [`docs/implementation-notes/codex-compaction-mechanism.md`](../../docs/implementation-notes/codex-compaction-mechanism.md) for the underlying Codex mechanism research and the extension boundary.
237
227
 
228
+ ## 🗂️ Package layout
229
+
230
+ ```text
231
+ src/index.ts Thin Pi entrypoint
232
+ src/codex-compact.ts Pi lifecycle, command, provider projection, and fallback
233
+ src/remote.ts Protocol dispatch
234
+ src/remote-v2.ts Remote V2 provider stream and SSE inspection
235
+ src/remote-compact.ts Unary Compact API bridge and usage normalization
236
+ src/remote-shared.ts Shared provider completion handling
237
+ src/remote-types.ts Protocol-neutral request and response types
238
+ src/protocol.ts Bounded SSE/JSON parsing and payload/output validation
239
+ src/checkpoint.ts Replacement history, fingerprints, persistence, and replay projection
240
+ src/model-api.ts Responses API and protocol route selection
241
+ src/settings.ts Global settings validation and atomic persistence
242
+ src/settings-menu.ts First-use manual compaction and settings TUI
243
+
244
+ dist/ Generated source-mapped Jiti runtime and lazy menu chunk
245
+ scripts/ Runtime builder
246
+ benchmark/ Three-arm compaction benchmark, self-test, and methodology
247
+ test/ Protocol, checkpoint, lifecycle, remote, settings, menu, and builder coverage
248
+ ```
249
+
238
250
  ## 🔎 Keywords
239
251
 
240
- Pi extension, Pi coding agent, OpenAI Codex, custom provider, proxy, Remote Compaction V2, opaque checkpoint, Responses API, context compaction.
252
+ 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
253
 
242
254
  ## 📄 License
243
255
 
@@ -0,0 +1,43 @@
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
+ import { hasApi } from "@earendil-works/pi-ai";
6
+ var RESPONSES_COMPACTION_APIS = [
7
+ "openai-codex-responses",
8
+ "openai-responses",
9
+ "azure-openai-responses"
10
+ ];
11
+ function usesResponsesCompactionApi(model) {
12
+ return model !== void 0 && RESPONSES_COMPACTION_APIS.some((api) => hasApi(model, api));
13
+ }
14
+ function resolveCompactionRouteForApi(api, options) {
15
+ if (!options.enabled) return { kind: "native", reason: "remote compaction is disabled" };
16
+ if (!api) return { kind: "native", reason: "no active model" };
17
+ if (!RESPONSES_COMPACTION_APIS.includes(api)) {
18
+ return { kind: "native", reason: `API ${api} does not support Responses compaction` };
19
+ }
20
+ const supportedApi = api;
21
+ const protocol = options.protocol === "auto" ? supportedApi === "openai-codex-responses" ? "remote-v2" : "responses-compact" : options.protocol;
22
+ return { kind: "remote", protocol, api: supportedApi };
23
+ }
24
+ function resolveCompactionRoute(model, options) {
25
+ return resolveCompactionRouteForApi(model?.api, options);
26
+ }
27
+
28
+ // src/terminal.ts
29
+ function terminalText(value) {
30
+ return Array.from(value, (character) => {
31
+ const codePoint = character.codePointAt(0) ?? 0;
32
+ return codePoint < 32 || codePoint >= 127 && codePoint <= 159 ? " " : character;
33
+ }).join("");
34
+ }
35
+
36
+ export {
37
+ RESPONSES_COMPACTION_APIS,
38
+ usesResponsesCompactionApi,
39
+ resolveCompactionRouteForApi,
40
+ resolveCompactionRoute,
41
+ terminalText
42
+ };
43
+ //# sourceMappingURL=chunk-JYXZMCXD.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 { hasApi } from \"@earendil-works/pi-ai\";\n\nexport const RESPONSES_COMPACTION_APIS = [\n\t\"openai-codex-responses\",\n\t\"openai-responses\",\n\t\"azure-openai-responses\",\n] as const;\n\nexport type ResponsesCompactionApi = (typeof RESPONSES_COMPACTION_APIS)[number];\nexport type RemoteCompactionProtocol = \"remote-v2\" | \"responses-compact\";\nexport type RemoteCompactionProtocolSetting = \"auto\" | RemoteCompactionProtocol;\n\nexport type CompactionRoute =\n\t| { kind: \"remote\"; protocol: RemoteCompactionProtocol; api: ResponsesCompactionApi }\n\t| { kind: \"native\"; reason: string };\n\nexport function usesResponsesCompactionApi(\n\tmodel: Model<Api> | undefined,\n): model is Model<ResponsesCompactionApi> {\n\treturn model !== undefined && RESPONSES_COMPACTION_APIS.some((api) => hasApi(model, api));\n}\n\nexport function resolveCompactionRouteForApi(\n\tapi: Api | undefined,\n\toptions: { enabled: boolean; protocol: RemoteCompactionProtocolSetting },\n): CompactionRoute {\n\tif (!options.enabled) return { kind: \"native\", reason: \"remote compaction is disabled\" };\n\tif (!api) return { kind: \"native\", reason: \"no active model\" };\n\tif (!RESPONSES_COMPACTION_APIS.includes(api as ResponsesCompactionApi)) {\n\t\treturn { kind: \"native\", reason: `API ${api} does not support Responses compaction` };\n\t}\n\tconst supportedApi = api as ResponsesCompactionApi;\n\tconst protocol =\n\t\toptions.protocol === \"auto\"\n\t\t\t? supportedApi === \"openai-codex-responses\"\n\t\t\t\t? \"remote-v2\"\n\t\t\t\t: \"responses-compact\"\n\t\t\t: options.protocol;\n\treturn { kind: \"remote\", protocol, api: supportedApi };\n}\n\nexport function resolveCompactionRoute(\n\tmodel: Model<Api> | undefined,\n\toptions: { enabled: boolean; protocol: RemoteCompactionProtocolSetting },\n): CompactionRoute {\n\treturn resolveCompactionRouteForApi(model?.api, options);\n}\n", "export function terminalText(value: string): string {\n\treturn Array.from(value, (character) => {\n\t\tconst codePoint = character.codePointAt(0) ?? 0;\n\t\treturn codePoint < 32 || (codePoint >= 127 && codePoint <= 159) ? \" \" : character;\n\t}).join(\"\");\n}\n"],
5
+ "mappings": ";;;;AACA,SAAS,cAAc;AAEhB,IAAM,4BAA4B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AACD;AAUO,SAAS,2BACf,OACyC;AACzC,SAAO,UAAU,UAAa,0BAA0B,KAAK,CAAC,QAAQ,OAAO,OAAO,GAAG,CAAC;AACzF;AAEO,SAAS,6BACf,KACA,SACkB;AAClB,MAAI,CAAC,QAAQ,QAAS,QAAO,EAAE,MAAM,UAAU,QAAQ,gCAAgC;AACvF,MAAI,CAAC,IAAK,QAAO,EAAE,MAAM,UAAU,QAAQ,kBAAkB;AAC7D,MAAI,CAAC,0BAA0B,SAAS,GAA6B,GAAG;AACvE,WAAO,EAAE,MAAM,UAAU,QAAQ,OAAO,GAAG,yCAAyC;AAAA,EACrF;AACA,QAAM,eAAe;AACrB,QAAM,WACL,QAAQ,aAAa,SAClB,iBAAiB,2BAChB,cACA,sBACD,QAAQ;AACZ,SAAO,EAAE,MAAM,UAAU,UAAU,KAAK,aAAa;AACtD;AAEO,SAAS,uBACf,OACA,SACkB;AAClB,SAAO,6BAA6B,OAAO,KAAK,OAAO;AACxD;;;AC/CO,SAAS,aAAa,OAAuB;AACnD,SAAO,MAAM,KAAK,OAAO,CAAC,cAAc;AACvC,UAAM,YAAY,UAAU,YAAY,CAAC,KAAK;AAC9C,WAAO,YAAY,MAAO,aAAa,OAAO,aAAa,MAAO,MAAM;AAAA,EACzE,CAAC,EAAE,KAAK,EAAE;AACX;",
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
- usesCodexResponsesApi
5
- } from "./chunk-6TZ2L2BM.js";
4
+ resolveCompactionRouteForApi,
5
+ terminalText
6
+ } from "./chunk-JYXZMCXD.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
- ctx.ui.notify("Codex compaction settings saved.", "info");
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: ${safeText(error instanceof Error ? error.message : String(error))}`,
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: "Codex Remote Compaction",
46
+ title: "Responses Compaction",
41
47
  lines: [
42
- `Remote V2: ${state.settings.enabled ? "On" : "Off"}`,
43
- `Active model: ${safeText(options.status?.model ?? "none")}`,
44
- `Compact route: ${safeText(compactRoute(state, options.status))}`
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: "Codex Remote Compaction Settings",
66
- lines: [`User settings \xB7 ${safeText(state.path)}`],
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 Codex Remote V2 when the model uses openai-codex-responses.",
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 Remote V2 fails and native Pi compaction takes over.",
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: ${safeText(state.path)}`,
115
- `Issue: ${safeText(state.issue ?? "unknown validation error")}`,
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,6 +139,14 @@ 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),
142
+ "set-protocol": ({ ctx, value, signal }) => update(
143
+ runtime,
144
+ ctx,
145
+ {
146
+ protocol: value === "Remote V2" ? "remote-v2" : value === "Responses Compact" ? "responses-compact" : "auto"
147
+ },
148
+ signal
149
+ ),
127
150
  "set-timeout": ({ ctx, value, signal }) => update(
128
151
  runtime,
129
152
  ctx,
@@ -142,10 +165,13 @@ function createCodexCompactMenu(runtime, options = {}) {
142
165
  };
143
166
  }
144
167
  async function showCodexCompactMenu(runtime, ctx, owner) {
145
- if (ctx.mode !== "tui") {
146
- ctx.ui.notify(`Edit Codex compaction settings at ${safeText(runtime.get().path)}.`, "info");
168
+ if (ctx.mode === "rpc" && ctx.hasUI) {
169
+ ctx.ui.notify(`Edit Responses compaction settings at ${terminalText(runtime.get().path)}.`, "info");
147
170
  return;
148
171
  }
172
+ if (ctx.mode !== "tui") {
173
+ throw new Error("/codex-compact requires TUI or RPC UI support");
174
+ }
149
175
  const { runMenu } = await import("@narumitw/pi-tui-kit");
150
176
  if (owner.signal.aborted || !owner.isCurrent()) return;
151
177
  let compactRequested = false;
@@ -167,7 +193,7 @@ async function showCodexCompactMenu(runtime, ctx, owner) {
167
193
  ctx.compact({
168
194
  onError: (error) => {
169
195
  if (!owner.signal.aborted && owner.isCurrent()) {
170
- ctx.ui.notify(`Compaction failed: ${safeText(error.message)}`, "error");
196
+ ctx.ui.notify(`Compaction failed: ${terminalText(error.message)}`, "error");
171
197
  }
172
198
  }
173
199
  });
@@ -176,16 +202,17 @@ function compactMenuStatus(ctx) {
176
202
  const model = ctx.model;
177
203
  return {
178
204
  model: model ? `${model.provider}/${model.id}` : "none",
179
- remoteEligible: usesCodexResponsesApi(model)
205
+ api: model?.api
180
206
  };
181
207
  }
182
208
  function compactRoute(state, status) {
183
- if (!state.settings.enabled) return "Pi native (Remote V2 off)";
184
- return status?.remoteEligible ? "Codex Remote V2" : "Pi native (requires openai-codex-responses)";
209
+ const route = resolveCompactionRouteForApi(status?.api, state.settings);
210
+ if (route.kind === "native") return `Pi native (${route.reason})`;
211
+ return route.protocol === "remote-v2" ? "Responses Remote V2" : "Responses Compact API";
185
212
  }
186
213
  export {
187
214
  compactMenuStatus,
188
215
  createCodexCompactMenu,
189
216
  showCodexCompactMenu
190
217
  };
191
- //# sourceMappingURL=settings-menu-PEDLURUH.js.map
218
+ //# sourceMappingURL=settings-menu-VYQ6ABCP.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 {\n\tCodexCompactSettings,\n\tCodexCompactSettingsRuntime,\n\tCodexCompactSettingsState,\n} from \"./settings.js\";\nimport { terminalText as safeText } from \"./terminal.js\";\n\ntype Screen = \"main\" | \"settings\" | \"invalid\";\ntype Action =\n\t| \"compact-now\"\n\t| \"set-enabled\"\n\t| \"set-protocol\"\n\t| \"set-timeout\"\n\t| \"set-retries\"\n\t| \"set-retention\"\n\t| \"set-notify\";\n\nexport interface SettingsMenuOwner {\n\tsignal: AbortSignal;\n\tisCurrent(): boolean;\n}\n\ninterface CompactMenuStatus {\n\tmodel: string;\n\tapi?: Api;\n}\n\nfunction timeoutLabel(milliseconds: number): string {\n\treturn `${milliseconds / 60_000} min`;\n}\n\nfunction retentionLabel(tokens: number): string {\n\treturn `${tokens / 1000}K tokens`;\n}\n\nfunction protocolLabel(protocol: CodexCompactSettings[\"protocol\"]): string {\n\tswitch (protocol) {\n\t\tcase \"auto\":\n\t\t\treturn \"Auto\";\n\t\tcase \"remote-v2\":\n\t\t\treturn \"Remote V2\";\n\t\tcase \"responses-compact\":\n\t\t\treturn \"Responses Compact\";\n\t}\n}\n\nasync function update(\n\truntime: CodexCompactSettingsRuntime,\n\tctx: ExtensionCommandContext,\n\tpatch: Partial<CodexCompactSettings>,\n\tsignal: AbortSignal,\n) {\n\ttry {\n\t\tawait runtime.update(patch, signal);\n\t\tif (signal.aborted) return { kind: \"rejected\" as const };\n\t\tctx.ui.notify(\"Responses compaction settings saved.\", \"info\");\n\t\treturn { kind: \"stay\" as const };\n\t} catch (error) {\n\t\tif (signal.aborted) return { kind: \"rejected\" as const };\n\t\tctx.ui.notify(\n\t\t\t`Could not save pi-codex-compact.json: ${safeText(error instanceof Error ? error.message : String(error))}`,\n\t\t\t\"error\",\n\t\t);\n\t\treturn { kind: \"rejected\" as const };\n\t}\n}\n\nexport function createCodexCompactMenu(\n\truntime: CodexCompactSettingsRuntime,\n\toptions: { onCompactRequested?: () => void; status?: CompactMenuStatus } = {},\n): MenuDefinition<CodexCompactSettingsState, Screen, Action, ExtensionCommandContext> {\n\treturn {\n\t\tstart: \"main\",\n\t\tscreens: {\n\t\t\tmain: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Responses Compaction\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Remote compaction: ${state.settings.enabled ? \"On\" : \"Off\"}`,\n\t\t\t\t\t`Protocol setting: ${protocolLabel(state.settings.protocol)}`,\n\t\t\t\t\t`Active model: ${safeText(options.status?.model ?? \"none\")}`,\n\t\t\t\t\t`Compact route: ${safeText(compactRoute(state, options.status))}`,\n\t\t\t\t],\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"compact-now\",\n\t\t\t\t\t\tlabel: \"Compact now\",\n\t\t\t\t\t\tdescription: \"Close this menu and compact the active session immediately.\",\n\t\t\t\t\t\taction: \"compact-now\",\n\t\t\t\t\t},\n\t\t\t\t\tstate.kind === \"invalid\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: \"settings\",\n\t\t\t\t\t\t\t\tlabel: \"Settings\",\n\t\t\t\t\t\t\t\tdescription: \"Read-only until the invalid settings file is repaired.\",\n\t\t\t\t\t\t\t\tto: \"invalid\" as const,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: { id: \"settings\", label: \"Settings\", to: \"settings\" as const },\n\t\t\t\t\t{ id: \"close\", label: \"Close\", close: true },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t\tsettings: ({ state }) => ({\n\t\t\t\tkind: \"settings\",\n\t\t\t\ttitle: \"Responses Compaction Settings\",\n\t\t\t\tlines: [`User settings \u00B7 ${safeText(state.path)}`],\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"enabled\",\n\t\t\t\t\t\tlabel: \"Remote compaction\",\n\t\t\t\t\t\tdescription: \"Use a supported Responses compaction protocol.\",\n\t\t\t\t\t\tcurrentValue: state.settings.enabled ? \"On\" : \"Off\",\n\t\t\t\t\t\tvalues: [\"On\", \"Off\"],\n\t\t\t\t\t\taction: \"set-enabled\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"protocol\",\n\t\t\t\t\t\tlabel: \"Protocol\",\n\t\t\t\t\t\tdescription: \"Choose automatically or force one supported remote protocol.\",\n\t\t\t\t\t\tcurrentValue: protocolLabel(state.settings.protocol),\n\t\t\t\t\t\tvalues: [\"Auto\", \"Remote V2\", \"Responses Compact\"],\n\t\t\t\t\t\taction: \"set-protocol\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"requestTimeoutMs\",\n\t\t\t\t\t\tlabel: \"Request timeout\",\n\t\t\t\t\t\tdescription: \"Maximum time for the extension-owned remote compaction request.\",\n\t\t\t\t\t\tcurrentValue: timeoutLabel(state.settings.requestTimeoutMs),\n\t\t\t\t\t\tvalues: [\"2 min\", \"5 min\", \"10 min\"],\n\t\t\t\t\t\taction: \"set-timeout\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"maxRetries\",\n\t\t\t\t\t\tlabel: \"Transport retries\",\n\t\t\t\t\t\tdescription: \"Retry transient provider failures before falling back to Pi.\",\n\t\t\t\t\t\tcurrentValue: String(state.settings.maxRetries),\n\t\t\t\t\t\tvalues: [\"0\", \"1\", \"2\"],\n\t\t\t\t\t\taction: \"set-retries\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"replacementTokenBudget\",\n\t\t\t\t\t\tlabel: \"Retained user history\",\n\t\t\t\t\t\tdescription: \"Approximate user-message budget kept beside the opaque checkpoint.\",\n\t\t\t\t\t\tcurrentValue: retentionLabel(state.settings.replacementTokenBudget),\n\t\t\t\t\t\tvalues: [\"32K tokens\", \"64K tokens\", \"96K tokens\", \"128K tokens\"],\n\t\t\t\t\t\taction: \"set-retention\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"notifyOnFallback\",\n\t\t\t\t\t\tlabel: \"Fallback notifications\",\n\t\t\t\t\t\tdescription: \"Warn when remote compaction fails and Pi native takes over.\",\n\t\t\t\t\t\tcurrentValue: state.settings.notifyOnFallback ? \"On\" : \"Off\",\n\t\t\t\t\t\tvalues: [\"On\", \"Off\"],\n\t\t\t\t\t\taction: \"set-notify\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}),\n\t\t\tinvalid: ({ state }) => ({\n\t\t\t\tkind: \"detail\",\n\t\t\t\ttitle: \"Codex Compact Settings \u00B7 Read only\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Invalid settings file: ${safeText(state.path)}`,\n\t\t\t\t\t`Issue: ${safeText(state.issue ?? \"unknown validation error\")}`,\n\t\t\t\t\t\"Built-in defaults are active. Repair the file and run /reload; it will not be overwritten.\",\n\t\t\t\t],\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\t\"compact-now\": async () => {\n\t\t\t\toptions.onCompactRequested?.();\n\t\t\t\treturn { kind: \"close\" };\n\t\t\t},\n\t\t\t\"set-enabled\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { enabled: value === \"On\" }, signal),\n\t\t\t\"set-protocol\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(\n\t\t\t\t\truntime,\n\t\t\t\t\tctx,\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocol:\n\t\t\t\t\t\t\tvalue === \"Remote V2\"\n\t\t\t\t\t\t\t\t? \"remote-v2\"\n\t\t\t\t\t\t\t\t: value === \"Responses Compact\"\n\t\t\t\t\t\t\t\t\t? \"responses-compact\"\n\t\t\t\t\t\t\t\t\t: \"auto\",\n\t\t\t\t\t},\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\"set-timeout\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(\n\t\t\t\t\truntime,\n\t\t\t\t\tctx,\n\t\t\t\t\t{ requestTimeoutMs: Number.parseInt(value ?? \"5\", 10) * 60_000 },\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\"set-retries\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { maxRetries: Number.parseInt(value ?? \"2\", 10) }, signal),\n\t\t\t\"set-retention\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(\n\t\t\t\t\truntime,\n\t\t\t\t\tctx,\n\t\t\t\t\t{ replacementTokenBudget: Number.parseInt(value ?? \"64\", 10) * 1000 },\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\"set-notify\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { notifyOnFallback: value === \"On\" }, signal),\n\t\t},\n\t};\n}\n\nexport async function showCodexCompactMenu(\n\truntime: CodexCompactSettingsRuntime,\n\tctx: ExtensionCommandContext,\n\towner: SettingsMenuOwner,\n): Promise<void> {\n\tif (ctx.mode === \"rpc\" && ctx.hasUI) {\n\t\tctx.ui.notify(`Edit Responses compaction settings at ${safeText(runtime.get().path)}.`, \"info\");\n\t\treturn;\n\t}\n\tif (ctx.mode !== \"tui\") {\n\t\tthrow new Error(\"/codex-compact requires TUI or RPC UI support\");\n\t}\n\tconst { runMenu } = await import(\"@narumitw/pi-tui-kit\");\n\tif (owner.signal.aborted || !owner.isCurrent()) return;\n\tlet compactRequested = false;\n\tawait runMenu(\n\t\tctx,\n\t\tcreateCodexCompactMenu(runtime, {\n\t\t\tonCompactRequested: () => {\n\t\t\t\tcompactRequested = true;\n\t\t\t},\n\t\t\tstatus: compactMenuStatus(ctx),\n\t\t}),\n\t\t{\n\t\t\tgetState: () => runtime.get(),\n\t\t\tsignal: owner.signal,\n\t\t\tisCurrent: owner.isCurrent,\n\t\t},\n\t);\n\tif (!compactRequested || owner.signal.aborted || !owner.isCurrent()) return;\n\tctx.compact({\n\t\tonError: (error) => {\n\t\t\tif (!owner.signal.aborted && owner.isCurrent()) {\n\t\t\t\tctx.ui.notify(`Compaction failed: ${safeText(error.message)}`, \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport function compactMenuStatus(ctx: ExtensionCommandContext): CompactMenuStatus {\n\tconst model = ctx.model;\n\treturn {\n\t\tmodel: model ? `${model.provider}/${model.id}` : \"none\",\n\t\tapi: model?.api,\n\t};\n}\n\nfunction compactRoute(\n\tstate: Readonly<CodexCompactSettingsState>,\n\tstatus: CompactMenuStatus | undefined,\n): string {\n\tconst route = resolveCompactionRouteForApi(status?.api, state.settings);\n\tif (route.kind === \"native\") return `Pi native (${route.reason})`;\n\treturn route.protocol === \"remote-v2\" ? \"Responses Remote V2\" : \"Responses Compact API\";\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }