pi-openai-toolkit 0.14.12 → 0.15.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
@@ -11,11 +11,11 @@ Add Codex context windows, Responses compaction, hosted tools, and reviewed tool
11
11
 
12
12
  | Feature | Use it to |
13
13
  | --- | --- |
14
- | Codex Remote Context | Start a new context window and retrieve earlier windows with `history`. |
14
+ | Codex Remote Context | Use the adapted Codex window protocol to start a new context window and retrieve earlier windows with `history`. |
15
15
  | Remote Compaction v2 | Continue an eligible Responses session with an encrypted server checkpoint. |
16
- | Web Search routes | Choose local `pi-web-access`, hosted Responses `web_search`, or CPA standalone `web.run` per exact model route. |
17
- | Image generation | Generate images or edit explicitly supplied local reference images. |
18
- | Tool-call review | Ask a reviewer model whether selected tool calls may run. |
16
+ | Web Search routes | Choose local `pi-web-access`, hosted Responses `web_search`, or experimental CPA standalone `web_run` per exact model. |
17
+ | Image generation | Call the hosted Responses image tool to generate images or edit explicitly supplied local references. |
18
+ | Tool-call review | Use Toolkit's approval gate to ask a reviewer model whether selected tool calls may run. |
19
19
 
20
20
  The package uses Pi's existing model, authentication, and session configuration. It does not add a provider or model.
21
21
 
@@ -23,36 +23,33 @@ The package uses Pi's existing model, authentication, and session configuration.
23
23
 
24
24
  Requires Pi 0.85.1 or newer and Node.js 22.19.0 or newer.
25
25
 
26
- Install the extension:
27
-
28
26
  ```bash
29
27
  pi install npm:pi-openai-toolkit
30
28
  ```
31
29
 
32
- Use `--local` to install it in the current project.
30
+ Use `--local` to install the extension in the current project. Toolkit policy is still global; there are no project or environment policy overlays.
33
31
 
34
- Installing the package alone does not enable every feature. With no extension config, compaction is enabled but Remote Context is off, Web Search has no toolkit-selected route, image generation is disabled, and Auto Mode has no allowed models or reviewer.
32
+ Without a config file, Remote Compaction v2 is enabled for eligible models, Remote Context windows are off, search is unmanaged, image generation is disabled, and Auto Mode is unavailable. These defaults do not verify backend support.
35
33
 
36
- The extension config file is:
34
+ The only Toolkit config file is:
37
35
 
38
36
  `~/.pi/agent/extensions/pi-openai-toolkit/config.json`
39
37
 
40
- All JSON configuration examples below, except the `models.json` example, go in this file. If it does not exist, create the file and its parent directory. If it already exists, merge fields into the matching objects and keep the other settings.
38
+ All JSON examples below except the Pi model-registration example use **configuration schema v2**. Create the file and parent directory if absent. Merge examples into an existing v2 document, keeping its other settings. An unversioned legacy file remains supported: do not add v2 fields to it or overwrite it with an example. First use `/toolkit-config migration-preview`; the [configuration reference](docs/configuration.md) explains the review and installed-version checks. Loading config and previewing migration never rewrite the source file.
41
39
 
42
40
  ## Quick start: enable Remote Context
43
41
 
44
- This section is for users who want Codex-style context windows. If you only want Web Search, image generation, or tool-call review, skip to [Common tasks](#common-tasks).
42
+ This section is for Codex-style context windows. For search, images, or tool-call review only, skip to [Common tasks](#common-tasks).
45
43
 
46
44
  ### Use Pi's built-in Codex provider
47
45
 
48
- You must already be signed in to Pi's built-in `openai-codex` provider.
49
-
50
- Create or merge this extension config:
46
+ You must already be signed in to Pi's built-in `openai-codex` provider. Create or merge this v2 Toolkit config:
51
47
 
52
48
  ```json
53
49
  {
54
- "compaction": {
55
- "contextManagement": "remote"
50
+ "schemaVersion": 2,
51
+ "defaults": {
52
+ "context": { "mode": "remote-windows" }
56
53
  }
57
54
  }
58
55
  ```
@@ -63,13 +60,13 @@ Start Pi with a model from your existing Codex catalog:
63
60
  pi --model openai-codex/<model-id>
64
61
  ```
65
62
 
66
- Replace `<model-id>` with the model ID shown by your Pi setup. The session is activated when `new_context`, `get_context_remaining`, `history`, and `notes` appear as available tools.
63
+ Replace `<model-id>` with the ID shown by your Pi setup. The session is activated when `new_context`, `get_context_remaining`, `history`, and `notes` appear. This verifies activation, not a completed backend round trip.
67
64
 
68
65
  ### Use a compatible gateway
69
66
 
70
- This route requires the `openai-responses` API and a gateway that preserves the Codex protocol fields used by Remote Context. A successful ordinary chat request does not prove Remote Context compatibility.
67
+ This route requires `openai-responses` and a gateway that preserves Remote Context's Codex protocol fields. A successful ordinary chat request does not prove Remote Context compatibility.
71
68
 
72
- If `~/.pi/agent/models.json` already contains a gateway model that meets these conditions, skip model configuration and set the extension allowlist directly. Otherwise, add or merge the provider entry below. Replace `my-gateway`, the URL, the environment variable name, and the model values with values from your setup. The numeric values shown are examples, not project defaults; they must match the actual model and gateway.
69
+ If `~/.pi/agent/models.json` already registers a compatible model, skip registration and set Toolkit's exact model override below. Otherwise, add or merge this Pi provider entry. Replace the provider name, URL, environment variable, and model values with your setup. The numeric limits are examples, not project defaults.
73
70
 
74
71
  ```json
75
72
  {
@@ -103,136 +100,149 @@ In a POSIX shell:
103
100
  export MY_GATEWAY_KEY="replace-with-your-gateway-key"
104
101
  ```
105
102
 
106
- Use the same terminal session to start Pi. Create or merge the extension config, and make the allowlist entry exactly match the provider and model ID:
103
+ Use the same terminal to start Pi. In the Toolkit config, make the key exactly match the registered provider and model ID:
107
104
 
108
105
  ```json
109
106
  {
110
- "compaction": {
111
- "contextManagement": "remote",
112
- "gatewayContextModels": ["my-gateway/gpt-5.6-luna"]
107
+ "schemaVersion": 2,
108
+ "models": {
109
+ "my-gateway/gpt-5.6-luna": {
110
+ "context": { "mode": "remote-windows" },
111
+ "compatibility": { "transport": "codex-gateway" }
112
+ }
113
113
  }
114
114
  }
115
115
  ```
116
116
 
117
- Start Pi with the same model specification:
118
-
119
117
  ```bash
120
118
  pi --model my-gateway/gpt-5.6-luna
121
119
  ```
122
120
 
123
- The enablement check is the same: the session should expose `new_context`, `get_context_remaining`, `history`, and `notes`. If they do not appear, read the toolkit notification and check the exact provider/model string, API, key, base URL, and allowlist entry.
121
+ Check for `new_context`, `get_context_remaining`, `history`, and `notes`. If absent, read the notification and check `/toolkit-config`, the exact model key, Pi API, credentials, and base URL. The transport setting opts into a protocol profile; it does not register a model or prove the backend supports it.
124
122
 
125
- Earlier windows remain available through `history`, but they are not all automatically added to the current context.
123
+ Earlier windows remain retrievable through `history`, but are not all automatically inserted into the current context.
126
124
 
127
125
  ## Common tasks
128
126
 
129
127
  ### Continue a session with server-side compaction
130
128
 
131
- Leave Remote Context off when you want the Responses compaction path instead. Remote Compaction v2 stores and replays an encrypted checkpoint for eligible Responses models. Set `compaction.remoteCompactModel` only when the compaction request should use a separate model.
129
+ Use `context.mode: "remote-compaction"` for the Responses compaction path (the default), or `"pi"` to relinquish Toolkit context management. Set `context.remoteCompaction.model` only when a separate model should produce the checkpoint. These fields belong under `defaults` or an exact `models` override.
132
130
 
133
- When `compaction.remoteV2ContextSource` is omitted, Remote V2 keeps the original `"legacy"` input chain: first compaction uses Pi's current session context (or the supplied preparation as a last resort), and recursive compaction uses the raw branch tail. This preserves existing behavior, but can diverge from provider-visible context when other extensions rewrite messages.
131
+ `context.remoteCompaction.inputSource` defaults to `"legacy"`: first compaction uses Pi's current session context, with event preparation as a last resort; recursion uses the raw branch tail. This preserves existing behavior but can diverge from provider-visible context when other extensions rewrite messages.
134
132
 
135
- Set `compaction.remoteV2ContextSource` to `"pi-context-hook"` to opt into the Pi 0.85.1 runtime bridge. The toolkit then uses the same ordered `context` hook chain as the live provider request. If Pi cannot expose that public hook path, Remote V2 cancels instead of sending an unprojected history. Checkpoint replay is accepted only when its source marker matches the current setting. Switching between the two modes requires a new Remote V2 checkpoint; disable Remote V2 or use Pi's native compaction when custom-only state must survive inside the opaque checkpoint.
133
+ Opt into `"pi-context-hook"` to use the ordered Pi context-hook projection. If that bridge is unavailable, compaction cancels rather than sending unprojected history. Checkpoints are source-specific; switching input sources requires a new checkpoint. See [protocol details](docs/internals.md#remote-compaction-v2-wire-contract).
136
134
 
137
135
  ### Choose a Web Search route
138
136
 
139
- Web Search has three mutually exclusive routes. Configure one global default and, when needed, exact `provider/model-id` overrides:
137
+ Configure a global default and exact model overrides:
140
138
 
141
139
  ```json
142
140
  {
143
- "webSearch": {
144
- "enabled": true,
145
- "defaultRoute": "hosted",
146
- "routes": {
147
- "uwoacrimson/gpt-6-astra": "standalone-alpha",
148
- "my-gateway/gpt-5.6-luna": "local"
141
+ "schemaVersion": 2,
142
+ "defaults": {
143
+ "webSearch": { "route": "local" }
144
+ },
145
+ "models": {
146
+ "my-gateway/gpt-5.6-luna": {
147
+ "webSearch": { "route": "hosted" }
149
148
  }
150
149
  }
151
150
  }
152
151
  ```
153
152
 
154
- Route selection is exact and deterministic: `routes[provider/model-id]` wins over `defaultRoute`; `defaultRoute` wins over the legacy `models` list. There is no wildcard, fuzzy model matching, capability guessing, fallback, or retry between routes. Invalid route values/keys are ignored with warnings rather than guessed, and overlapping new/legacy fields produce migration warnings. `enabled: false` releases toolkit ownership and disables all three toolkit-selected paths.
153
+ - `unmanaged` releases Toolkit ownership. It does not disable third-party search or all Internet access.
154
+ - `local` preserves the original local `pi-web-access` tool state and removes conflicting hosted/standalone tools from provider payloads. It never activates a local tool that was inactive.
155
+ - `hosted` replaces the local `web_search` function with the native Responses search tool and source annotations.
156
+ - `standalone-alpha` deliberately opts into experimental CPA/Codex gateway search. It exposes sequential `web_run` and sends one isolated request per call to the provider-relative `/alpha/search`, using the current Pi model and credentials. The gateway must actually support that endpoint and capability; Toolkit does not probe or enable it.
155
157
 
156
- - **`local`** keeps the already-installed `pi-web-access` `web_search` tool. The toolkit does not activate it when it was not active, and it does not add a hosted provider tool or `web.run`.
157
- - **`hosted`** removes the local function named `web_search` and injects the native Responses `{ "type": "web_search" }` tool plus source annotations. The legacy configuration remains valid:
158
-
159
- ```json
160
- {
161
- "webSearch": {
162
- "models": ["my-gateway/gpt-5.6-luna"]
163
- }
164
- }
165
- ```
166
-
167
- With no new route fields, only models in this exact list and the existing Responses-family APIs (`openai-responses` or `openai-codex-responses`) use hosted search.
168
- - **`standalone-alpha`** exposes one sequential `web.run` tool and sends one isolated `POST` request to the provider-relative `/alpha/search` endpoint. A base URL such as `https://gateway.example/v1` therefore receives `https://gateway.example/v1/alpha/search`, not a Responses endpoint. Supported command families are `search_query`, `image_query`, `open`, `click`, `find`, `screenshot`, `finance`, `weather`, `sports`, and `time`; `response_length` controls the requested result size.
169
-
170
- The standalone route is an experimental CPA/Codex gateway protocol, not a stable public OpenAI Responses endpoint. The gateway/provider must expose `/alpha/search`, enable its `alpha-search` capability, and support standalone web search (Codex providers commonly expose this as `supports_standalone_web_search = true`). The request reuses Pi's current model, authentication, provider headers, session identity, and Codex/gateway affinity; it does not change the active model. The MVP sends the bounded command envelope rather than the full conversation transcript, relies on provider session/reference handling for `ref_id` follow-ups, makes at most one request per tool call, and fails closed on invalid configuration, unavailable routes, cancellation, timeout, non-2xx, malformed, or oversized responses.
158
+ Exact overrides win over defaults. There are no patterns, inferred capabilities, or fallback between routes. Invalid selected policy blocks the affected operation instead of choosing another route. The legacy hosted model list remains readable, but its permissive failure behavior is not identical to explicit v2 `hosted`; migration preview flags that difference.
171
159
 
172
160
  ### Generate an image
173
161
 
174
- Image generation requires a Responses session and may incur provider charges. Enable it with:
162
+ Image generation requires a Responses session and may incur provider charges. Enable it globally:
175
163
 
176
164
  ```json
177
165
  {
178
- "imageGeneration": {
179
- "enabled": true,
180
- "models": ["gpt-image-2.5", "grok-imagine-image-2.0"]
166
+ "schemaVersion": 2,
167
+ "defaults": {
168
+ "imageGeneration": {
169
+ "enabled": true,
170
+ "defaultModel": "gpt-image-2.5",
171
+ "allowedModels": ["gpt-image-2.5", "grok-imagine-image-2.0"]
172
+ }
181
173
  }
182
174
  }
183
175
  ```
184
176
 
185
- `models` contains the bare model IDs used by the nested Responses `image_generation` tool. The first entry is the default; `openai_generate_image` also accepts an optional `model` argument for a one-call override, but it must match a configured entry exactly. If `models` is omitted, the default is `gpt-image-2.5`. Empty or invalid lists are ignored with a warning and fall back to that default; set `enabled` to `false` to disable the tool. The provider or gateway must support the configured image model.
177
+ These are bare output-model IDs for the nested Responses `image_generation` tool. List order does not choose the default. `defaultModel` must belong to the nonempty `allowedModels` list; an optional one-call `model` must also be allowed. Invalid policy or a disallowed choice fails before authentication, reference upload, and paid dispatch. The provider must support the chosen model.
186
178
 
187
- The `openai_generate_image` tool supports text-to-image requests and edits using explicitly supplied local reference images.
179
+ `openai_generate_image` accepts text-to-image requests and edits using explicitly supplied local references. Image policy cannot be overridden per session model.
188
180
 
189
181
  ### Review tool calls automatically
190
182
 
191
- Allow a model and reviewer in `autoMode`:
183
+ Make Auto Mode available to an exact model and choose its reviewer:
192
184
 
193
185
  ```json
194
186
  {
195
- "autoMode": {
196
- "models": ["my-gateway/gpt-5.6-luna"],
197
- "reviewerModel": "my-gateway/gpt-5.6-luna"
187
+ "schemaVersion": 2,
188
+ "models": {
189
+ "my-gateway/gpt-5.6-luna": {
190
+ "autoMode": {
191
+ "available": true,
192
+ "reviewerModel": "my-gateway/gpt-5.6-luna"
193
+ }
194
+ }
198
195
  }
199
196
  }
200
197
  ```
201
198
 
202
- Use `/auto on` in the session, or start Pi with `--auto`. The TUI shows an activation notice and temporarily changes the working indicator to `Auto mode: reviewing <tool>` while a gated call is being reviewed; the footer keeps the active gate visible. On Pi versions that expose the compatible tool renderer, each tool block in Auto Mode also gets a bottom line: reviewed calls show states such as `allowed by reviewer · low risk · authorization medium` or `denied · <reason>`, while calls outside the configured gate show `not reviewed · outside the configured gate`. If that renderer seam is unavailable, the extension warns once and keeps the footer-only status. The default `side-effect` gate reviews `bash`, `write`, `edit`, and configured extra tools. Set `gate` to `"all"` when every tool call needs review. A reviewer timeout does not approve a call.
199
+ `available` permits engagement; use `/auto on` or `--auto` to engage. `/auto off` explicitly disengages it. The default `side-effect` gate covers `bash`, `write`, `edit`, and configured extra tools; `gate: "all"` reviews every tool call. A reviewer timeout does not approve a call. Invalid configuration while engaged keeps a blocking gate until corrected or explicitly turned off.
200
+
201
+ The TUI shows activation, review activity, and a footer status. Compatible Pi tool renderers also show per-call allowed, denied, blocked, or unreviewed states. If that renderer seam is unavailable, Toolkit warns once and retains the footer display. Reviewer, classifier, and circuit-breaker controls are in the [configuration reference](docs/configuration.md).
203
202
 
204
203
  ## Common configuration
205
204
 
206
- The config file is `~/.pi/agent/extensions/pi-openai-toolkit/config.json`. Unknown keys are ignored with a warning. Most model lists use exact `provider/model-id` strings, not globs; `imageGeneration.models` is an exception and contains bare nested image-generation model IDs.
205
+ The global file uses built-ins, then `defaults`, then exact `models["provider/model-id"]` overrides. Missing fields inherit; arrays replace; `false` and `0` are retained. Supported optional model references accept `null` to clear inheritance. Defaults are not master switches: an exact override can enable a feature whose default is disabled.
207
206
 
208
- | Key | Default | Use |
207
+ | Field | Default | Use |
209
208
  | --- | --- | --- |
210
- | `compaction.enabled` | `true` | Master switch for compaction. |
211
- | `compaction.contextManagement` | `"off"` | Enables Codex Remote Context when set to `"remote"`. |
212
- | `compaction.gatewayContextModels` | `[]` | Gateway models allowed to use Remote Context. |
213
- | `compaction.remoteCompactModel` | unset | Optional model used only for a v2 compaction request. |
214
- | `compaction.remoteV2ContextSource` | `"legacy"` | Preserve the original raw session/branch input path. Set `"pi-context-hook"` to opt into Pi's ordered context-hook projection. Checkpoints are mode-specific. |
215
- | `compaction.contextReminderThresholdPercent` | `5` | Remaining budget percentage for the once-per-window reminder. `0` disables the reminder and exhausted-window fallback. |
216
- | `webSearch.enabled` | `true` | Total switch for the toolkit's Web Search route selection. `false` selects no toolkit route. |
217
- | `webSearch.defaultRoute` | unset | Default route: `local`, `hosted`, or `standalone-alpha`. Unset preserves legacy behavior. |
218
- | `webSearch.routes` | unset | Exact `provider/model-id` to route overrides. Exact entries take precedence over `defaultRoute`. |
219
- | `webSearch.models` | `[]` | Legacy exact allowlist; without the new route fields, listed Responses-family models receive hosted Web Search. |
220
- | `imageGeneration.enabled` | `false` | Enables `openai_generate_image`. |
221
- | `imageGeneration.models` | `["gpt-image-2.5"]` | Bare image-generation model IDs; the first entry is the default. |
222
- | `autoMode.models` | `[]` | Models allowed to use Auto Mode. |
223
- | `autoMode.reviewerModel` | unset | Model that reviews Auto Mode calls. |
224
- | `autoMode.gate` | `"side-effect"` | Use `"all"` to review every tool call. |
225
- | `autoMode.timeoutMs` | `30000` | Review timeout in milliseconds. |
209
+ | `defaults.context.mode` | `"remote-compaction"` | `"pi"`, `"remote-compaction"`, or `"remote-windows"`. |
210
+ | `models[exact].compatibility.transport` | `"standard"` | Exact gateway opt-in with `"codex-gateway"`. |
211
+ | `defaults.context.remoteCompaction.model` | `null` | Optional checkpoint producer. |
212
+ | `defaults.context.remoteCompaction.inputSource` | `"legacy"` | Source-specific checkpoint input policy. |
213
+ | `defaults.context.remoteWindows.reminderThresholdPercent` | `5` | `0` disables reminders and exhausted-window fallback. |
214
+ | `defaults.webSearch.route` | `"unmanaged"` | Toolkit search ownership policy. |
215
+ | `defaults.imageGeneration.enabled` | `false` | Global image-generation switch. |
216
+ | `defaults.imageGeneration.defaultModel` | `"gpt-image-2.5"` | Explicit default output model. |
217
+ | `defaults.imageGeneration.allowedModels` | `["gpt-image-2.5"]` | Allowed output models, global only. |
218
+ | `defaults.autoMode.available` | `false` | Permission to engage tool review. |
219
+ | `defaults.autoMode.gate` | `"side-effect"` | Selected side-effect tools or `"all"`. |
220
+ | `defaults.autoMode.timeoutMs` | `30000` | Reviewer timeout in milliseconds. |
221
+ | `diagnostics.level` | `"info"` | `"debug"` enables debug artifacts. |
222
+ | `diagnostics.captureRequests` / `captureResponses` | `false` | Independent request/compact-response capture opt-ins. |
223
+
224
+ Use `/toolkit-config` for effective values and origins, `/toolkit-config validate` for document issues, and `/toolkit-config migration-preview` for a read-only legacy candidate. These commands require a UI and perform no network/auth lookup, tool activation, or file writes. Configuration selection does not verify backend support.
225
+
226
+ Unknown v2 policy keys and malformed values produce visible scoped errors, independent of debug mode. Each public callback or tool execution uses one immutable snapshot across its awaited helpers; later operations reread the file. Separate Pi events are not one atomic transaction. See the [complete configuration reference](docs/configuration.md) and [editor schema](config.schema.json).
226
227
 
227
228
  ## Development
228
229
 
229
230
  From the repository root, after dependencies are installed:
230
231
 
231
232
  ```bash
232
- npm run typecheck # Type-check
233
- bun test # Run tests
234
- npm run test:pi # Run the Pi smoke test
235
- npm pack --dry-run # Inspect the package contents
233
+ npm run typecheck
234
+ ```
235
+
236
+ ```bash
237
+ bun test
238
+ ```
239
+
240
+ ```bash
241
+ npm run test:pi
242
+ ```
243
+
244
+ ```bash
245
+ npm pack --dry-run
236
246
  ```
237
247
 
238
248
  ## License