pi-openai-toolkit 0.20.7 → 0.21.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/LICENSE +21 -21
- package/NOTICE +83 -83
- package/README.md +8 -26
- package/README.zh.md +8 -26
- package/config.schema.json +278 -366
- package/docs/configuration.md +294 -310
- package/docs/internals.md +166 -175
- package/package.json +3 -13
- package/src/compact-client.ts +412 -389
- package/src/compaction-errors.ts +96 -0
- package/src/compaction-projection.ts +35 -35
- package/src/config/legacy.ts +519 -717
- package/src/config/migration.ts +103 -100
- package/src/config/notifications.ts +36 -28
- package/src/config/policy.ts +10 -18
- package/src/config/v2.ts +1167 -1380
- package/src/config.ts +310 -319
- package/src/context-management/codex-provider.ts +270 -270
- package/src/context-management/history-notes.ts +357 -357
- package/src/context-management/manual-compact.ts +0 -11
- package/src/context-management/tools.ts +371 -371
- package/src/context-management/types.ts +168 -168
- package/src/context-management/window-manager.ts +801 -801
- package/src/debug.ts +238 -237
- package/src/deferred-tool-carryover.ts +282 -282
- package/src/details-store.ts +151 -151
- package/src/extension-runtime.ts +1662 -1623
- package/src/image-generation/extension.ts +189 -189
- package/src/image-generation/protocol.ts +579 -579
- package/src/image-generation/types.ts +300 -300
- package/src/native-fallback.ts +4 -132
- package/src/payload-rewrite.ts +515 -518
- package/src/pi-context-hook.ts +117 -117
- package/src/remote-v2-client.ts +811 -814
- package/src/request-context-cache.ts +155 -155
- package/src/responses-headers.ts +180 -180
- package/src/runtime.ts +865 -832
- package/src/serializer.ts +882 -882
- package/src/supported-environment.ts +27 -27
- package/src/types.ts +565 -648
- package/src/web-search/alpha-client.ts +876 -876
- package/src/web-search/extension.ts +530 -530
- package/src/web-search/payload.ts +299 -299
- package/src/web-search/prompt.ts +60 -60
- package/src/web-search/types.ts +166 -166
- package/tsconfig.check.json +50 -54
- package/src/auto-mode/classifier.ts +0 -161
- package/src/auto-mode/extension.ts +0 -691
- package/src/auto-mode/model-selection-guard.ts +0 -52
- package/src/auto-mode/policy.ts +0 -146
- package/src/auto-mode/prompt.ts +0 -279
- package/src/auto-mode/reviewer.ts +0 -325
- package/src/auto-mode/tool-review-tui.ts +0 -211
- package/src/auto-mode/transcript.ts +0 -135
- package/src/auto-mode/types.ts +0 -137
package/docs/configuration.md
CHANGED
|
@@ -1,310 +1,294 @@
|
|
|
1
|
-
# Toolkit configuration
|
|
2
|
-
|
|
3
|
-
Toolkit reads only `~/.pi/agent/extensions/pi-openai-toolkit/config.json`. There are no project overrides, environment policy overlays, profiles, `extends`, or wildcard rules. Pi still owns extension loading, provider endpoints, model registration, and credentials. A project-local extension installation does not create project-local Toolkit policy.
|
|
4
|
-
|
|
5
|
-
This reference describes schema v2. Unversioned legacy configuration remains supported. Configuration schema v2 and Remote Compaction v2 are separate version numbers.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
### Start with a small document
|
|
10
|
-
|
|
11
|
-
Create the file and parent directory if absent. This example states the shipped feature defaults; it is not a conversion of an existing legacy file:
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
{
|
|
15
|
-
"schemaVersion": 2,
|
|
16
|
-
"defaults": {
|
|
17
|
-
"context": { "mode": "remote-compaction" },
|
|
18
|
-
"webSearch": { "route": "unmanaged" },
|
|
19
|
-
"imageGeneration": {
|
|
20
|
-
"enabled": false,
|
|
21
|
-
"defaultModel": "grok-imagine-image-2.0",
|
|
22
|
-
"allowedModels": ["grok-imagine-image-2.0"]
|
|
23
|
-
},
|
|
24
|
-
"responsesWebSocket": { "enabled": false }
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
| `
|
|
61
|
-
| `remoteCompaction.
|
|
62
|
-
| `remoteCompaction.
|
|
63
|
-
| `remoteCompaction.
|
|
64
|
-
| `
|
|
65
|
-
| `nativeFallback.
|
|
66
|
-
| `nativeFallback.
|
|
67
|
-
| `
|
|
68
|
-
| `remoteWindows.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
| `
|
|
101
|
-
|
|
|
102
|
-
| `
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
$env:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
export
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
|
191
|
-
|
|
|
192
|
-
| `
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
"
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
"
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
|
255
|
-
|
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
258
|
-
| `
|
|
259
|
-
| `
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
|
276
|
-
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
| `compaction.leaveManagedMode`, `contextReminderThresholdPercent` | `defaults.context.remoteWindows` fields |
|
|
296
|
-
| `compaction.gatewayContextModels` | Exact `models[key].compatibility.transport` |
|
|
297
|
-
| `webSearch.defaultRoute`, `routes`, `models` | Default/exact search route candidates, subject to review below |
|
|
298
|
-
| `imageGeneration.models` | `allowedModels` plus an explicit default taken from the legacy first entry |
|
|
299
|
-
| `autoMode.enabled` / `models` | Default/exact `autoMode.available` |
|
|
300
|
-
| Legacy auto reviewer/classifier/breaker controls | Corresponding `autoMode` controls |
|
|
301
|
-
| Legacy compaction debug/capture/path settings | `diagnostics` |
|
|
302
|
-
|
|
303
|
-
The preview cannot claim universal lossless conversion:
|
|
304
|
-
|
|
305
|
-
- A legacy hosted allowlist ignores unsupported APIs and malformed payloads; explicit v2 hosted selection fails closed. Moving a list entry to an exact hosted route changes those failure paths.
|
|
306
|
-
- Disabled legacy features can retain dormant model lists/routes. A simplified v2 policy cannot preserve enable-later intent without review.
|
|
307
|
-
- Gateway compatibility is now shared independently of context mode; review effects on compaction and image affinity.
|
|
308
|
-
- Unknown fields, invalid normalization, or candidate validation failures require review. `remoteV2ContextSource: "legacy"` remains `inputSource: "legacy"`; preview does not upgrade checkpoint provenance or opt any model into standalone search.
|
|
309
|
-
|
|
310
|
-
There is no automatic migration, writer, or `--write` option. Before a separately approved manual cutover, back up the original bytes and verify that every installed Toolkit copy supports v2. Older copies, including 0.14.13, do not support this format. Updating source in a checkout does not update an installed package. Keep the legacy file until that cutover is ready.
|
|
1
|
+
# Toolkit configuration
|
|
2
|
+
|
|
3
|
+
Toolkit reads only `~/.pi/agent/extensions/pi-openai-toolkit/config.json`. There are no project overrides, environment policy overlays, profiles, `extends`, or wildcard rules. Pi still owns extension loading, provider endpoints, model registration, and credentials. A project-local extension installation does not create project-local Toolkit policy.
|
|
4
|
+
|
|
5
|
+
This reference describes schema v2. Unversioned legacy configuration remains supported. Configuration schema v2 and Remote Compaction v2 are separate version numbers.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
### Start with a small document
|
|
10
|
+
|
|
11
|
+
Create the file and parent directory if absent. This example states the shipped feature defaults; it is not a conversion of an existing legacy file:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"schemaVersion": 2,
|
|
16
|
+
"defaults": {
|
|
17
|
+
"context": { "mode": "remote-compaction" },
|
|
18
|
+
"webSearch": { "route": "unmanaged" },
|
|
19
|
+
"imageGeneration": {
|
|
20
|
+
"enabled": false,
|
|
21
|
+
"defaultModel": "grok-imagine-image-2.0",
|
|
22
|
+
"allowedModels": ["grok-imagine-image-2.0"]
|
|
23
|
+
},
|
|
24
|
+
"responsesWebSocket": { "enabled": false }
|
|
25
|
+
},
|
|
26
|
+
"models": {},
|
|
27
|
+
"diagnostics": {
|
|
28
|
+
"level": "info",
|
|
29
|
+
"notifyOnLoad": false,
|
|
30
|
+
"captureRequests": false,
|
|
31
|
+
"captureResponses": false,
|
|
32
|
+
"redactSensitiveData": true
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`$schema` is optional editor metadata pointing to the shipped [config.schema.json](../config.schema.json). It does not change runtime schema selection. The editor schema describes canonical spelling; runtime also trims surrounding whitespace in supported strings and deduplicates lists. Runtime validation checks normalized key collisions and image-default membership that the editor schema cannot express.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### Resolution and errors
|
|
42
|
+
|
|
43
|
+
Precedence is built-ins, then `defaults`, then `models["provider/model-id"]`. Keys are exact and case-sensitive. Leading/trailing whitespace is trimmed; conflicting normalized keys are rejected. Model IDs may contain further slashes. No pattern matching or endpoint/capability guessing occurs.
|
|
44
|
+
|
|
45
|
+
Known nested objects merge by field. Missing fields inherit, arrays replace instead of append, and `false`/`0` retain their meanings. Only optional model references accept `null`: context producer and native-fallback model. Other active settings reject `null`. Defaults do not prohibit exact overrides; an exact model can select a different context mode or search route.
|
|
46
|
+
|
|
47
|
+
A missing file uses independent built-in defaults. Invalid JSON, an unreadable file, missing/unsupported `schemaVersion` on a v2-shaped document, or mixed legacy/v2 fields are reported distinctly. Unknown v2 policy keys are errors in their owning scope. Invalid selected settings block dependent operations; they never silently pick a more permissive route. Errors in other models remain visible without replacing a valid current model's policy. A valid exact leaf may shadow an invalid default leaf, but cannot hide a malformed containing object or unknown field in that feature scope.
|
|
48
|
+
|
|
49
|
+
Each public callback, tool execution, compaction, or config command uses an immutable snapshot across its awaited helpers. The next operation reads again. This does not make separate Pi headers, payload, and tool events one atomic transaction. Windows and results stay out of the config file.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### Context
|
|
54
|
+
|
|
55
|
+
Place `context` under `defaults` or an exact `models` entry.
|
|
56
|
+
|
|
57
|
+
| Relative field | Default | Contract |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| `mode` | `"remote-compaction"` | `"pi"` relinquishes Toolkit context management; `"remote-compaction"` uses the eligible Responses checkpoint path; `"remote-windows"` selects Codex windows where supported. |
|
|
60
|
+
| `remoteCompaction.model` | `null` | Exact producer reference; `null` uses the active model. In `remote-compaction`, it selects the synthetic checkpoint producer on the same effective base URL. In active `remote-windows`, manual `/compact` temporarily selects it for notes checkpoint duty on the same backend/account. |
|
|
61
|
+
| `remoteCompaction.inputSource` | `"legacy"` | `"legacy"` preserves session/raw-branch input; `"pi-context-hook"` opts into Pi's ordered context projection. Checkpoint provenance must match. |
|
|
62
|
+
| `remoteCompaction.allowContinuityBreak` | `false` | Allow restarting from Pi context after a foreign compaction entry. It does not make malformed opaque checkpoints replayable. |
|
|
63
|
+
| `remoteCompaction.apis` | `["openai-responses", "openai-codex-responses", "azure-openai-responses"]` | May narrow this set; `[]` permits no remote-compaction API. Azure uses Pi's resolved `AZURE_OPENAI_*` environment values for the `/openai/v1` Responses path, deployment mapping, and `api-version`; unsupported entries are errors. |
|
|
64
|
+
| `nativeFallback.enabled` | `true` | Enable the existing native-method fallback tier. |
|
|
65
|
+
| `nativeFallback.model` | `null` | Summary-model reference on the remote-ineligible path. Character-count estimates do not bypass it; resolution, auth or summary failure cancels compaction without retrying the active model. After a remote attempt fails, the existing producer-first selection is retained. Disabled/unset/same-model selections keep Pi's default path. |
|
|
66
|
+
| `nativeFallback.thinkingLevel` | `"off"` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`; actual model support still applies. |
|
|
67
|
+
| `remoteWindows.leaveManagedMode` | `"warn"` | Legacy compatibility field. Both values preserve the same behavior: non-window models receive only the current local window, and no bulk close-out compaction is started for retired Remote Context history. |
|
|
68
|
+
| `remoteWindows.reminderThresholdPercent` | `5` | Integer 0-100. `0` disables both the once-per-window reminder and exhausted-window fallback. |
|
|
69
|
+
|
|
70
|
+
Ordinary remote compaction tries V2 first. One automatic standalone `/v1/responses/compact` attempt is available only for the official HTTPS OpenAI endpoint, an `openai-responses` physical producer, public Pi auth metadata explicitly indicating configured non-OAuth auth, and an outgoing Bearer header matching Pi's resolved key. Missing/unknown auth metadata, an unrelated Authorization override, Codex affinity, OAuth, Azure, and third-party gateways do not opt in. A protocol-compatible rejection or invalid successful V2 checkpoint can qualify; auth/subscription, quota/rate-limit, network, abort, and unrelated server failures do not. No protocol selector, credential switch, or capability cache is added; a selected standalone attempt may add latency/cost.
|
|
71
|
+
|
|
72
|
+
Standalone success preserves the full canonical output window, including retained items, rather than treating retained assistant text as a summary. When actual remote attempts are exhausted, Toolkit warns that no encrypted checkpoint was produced and starts the existing native text-summary chain: the configured remote producer after a remote attempt, or `nativeFallback.model` when remote compaction is unavailable. `nativeFallback.enabled: false` disables only the configured-model tier; disabled/unset/same-model selections still permit Pi's default summary. Explicit summary-model failures and checkpoint-integrity failures cancel. OpenAI subscription-sharing OAuth can reject compaction; separately authenticating native Codex is a different route, not a way to reuse that grant. See the [wire contract](internals.md#remote-compaction-v2-wire-contract).
|
|
73
|
+
|
|
74
|
+
Native Codex eligibility derives from the actual Pi provider/API. Gateways additionally need the exact transport opt-in below. `remote-windows` keeps the Remote Window state persisted when a model without window capability is selected: that model receives only the current local window, while retired/managed Remote Context history is excluded from live requests and compaction producers. A no-summary boundary preserves the marker for later reuse. A configured window model whose activation fails does not silently receive a summary fallback. Normal `new_context` keeps its persisted-notes, duplicate and cooldown gates. Synthetic Remote V2 producer/consumer identity and checkpoint provenance are unchanged. See [Toolkit internals](internals.md).
|
|
75
|
+
|
|
76
|
+
In active `remote-windows`, `/compact [instructions]` starts checkpoint duty rather than producing a summary. The selected model must authenticate to the same native backend/account or gateway credential/affinity domain, fit the projected window plus its output reserve, and retain the required permitted context tools. Invalid or unsuitable explicit targets are refused without switching to a fallback model. The entire handoff uses the initiating context-policy snapshot; no config or global Pi defaults are rewritten.
|
|
77
|
+
|
|
78
|
+
Only a new persisted successful notes write/append after the handoff and the latest delivered user message authorizes its rollover. After the exact target marker is durable, Toolkit restores the original model/thinking before new-window inference and asks it to read the receipt first. Failure or cancellation restores an owned selection; a later user selection takes priority. Failed restoration blocks further handoff requests until selection/auth is repaired. Reload can recover selection, but does not automatically restart inference.
|
|
79
|
+
|
|
80
|
+
The SDK native compact call reports its intentional cancellation; the visible handoff is a separate agent operation. Pi's pre-hook “nothing to compact” and “already compacted” outcomes remain. Automatic threshold/overflow compaction and internal pending-trim maintenance do not initiate checkpoint duty. `nativeFallback.model` keeps its existing summary-model meaning.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### Compatibility transport
|
|
85
|
+
|
|
86
|
+
Only `models["provider/model-id"].compatibility.transport` is configurable: `"standard"` is the internal baseline and `"codex-gateway"` is an exact opt-in. There is no global `defaults.compatibility` and no built-in gateway model list.
|
|
87
|
+
|
|
88
|
+
This selects an existing Toolkit protocol profile, independently of context mode. It does not change Pi's provider, API, endpoint, or model. The same decoded document supplies compatibility for search, image generation, and a separately named compaction producer. A successful config resolution is not a backend capability test. When Pi selects a `pi-virtual` model, Toolkit uses Pi's runtime resolver (when available) to obtain the physical provider/model for capability, authentication, and endpoint checks; if that route cannot be verified, the feature fails closed instead of treating the virtual entry as an OpenAI model.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### Responses WebSocket transport
|
|
93
|
+
|
|
94
|
+
The Responses WebSocket extension is disabled by default. Enable it globally with `defaults.responsesWebSocket.enabled: true`; it is intentionally not a model-scoped override. Restart or reload Pi after changing this setting. An invalid or legacy configuration keeps the feature disabled.
|
|
95
|
+
|
|
96
|
+
The extension is an API-adapter override, not a provider registration. It applies to GPT model IDs whose Pi API is `openai-responses`, regardless of provider name. The active model's `baseUrl`, `apiKey`, configured headers, session id, and payload remain the source of truth.
|
|
97
|
+
|
|
98
|
+
The extension honors Pi's global `transport` setting:
|
|
99
|
+
|
|
100
|
+
| Pi `transport` | Behavior |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `auto` | Try `wss://.../responses?model=...` first; fall back to the original SSE adapter only before a stream starts. With a stable session id, reuse the WebSocket and send a continuation delta when possible. |
|
|
103
|
+
| `websocket` | Require the WebSocket path; do not fall back to SSE. This mode opens a request-scoped connection. |
|
|
104
|
+
| `websocket-cached` | Require the WebSocket path and keep a session-scoped connection for later turns. |
|
|
105
|
+
| `sse` | Bypass the extension and use the original HTTP/SSE adapter. |
|
|
106
|
+
|
|
107
|
+
The endpoint is derived from the model's base URL by appending `/responses` when needed and switching `https:`/`http:` to `wss:`/`ws:`. The first frame is a standard `response.create` object and incoming frames are passed through Pi's existing Responses event normalizer. For `auto` and `websocket-cached`, Toolkit caches an open socket by session/model/endpoint/auth identity for up to five minutes idle or 55 minutes of age. When the current transcript has the cached request and response as a prefix, the next frame uses `previous_response_id` and only the new input items; if it cannot prove that relationship, it sends the full payload instead. A missing session id or `cacheRetention: "none"` disables reuse. The upstream must support the standard Responses WebSocket contract, including continuation semantics for `previous_response_id`; this does not rewrite a server that only exposes Codex's `/codex/responses` path or Codex-only authentication.
|
|
108
|
+
|
|
109
|
+
This feature does not write Pi settings, model files, auth files, or global extensions. To keep the Toolkit adapter disabled, set `defaults.responsesWebSocket.enabled` to `false` or omit it. Once enabled, Pi's global `transport: "sse"` still bypasses the WebSocket path for a request.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### Provider-specific Responses endpoints
|
|
114
|
+
|
|
115
|
+
Toolkit consumes provider registration, endpoint, model, credential, and provider-scoped environment values from Pi. Keep those details in Pi's model and authentication stores; Toolkit configuration selects the feature policy and exact model overrides. Pi's complete `auth.env` object is preserved through Toolkit authentication and request setup, including compaction, replay, fallback, and hosted-tool boundaries.
|
|
116
|
+
|
|
117
|
+
#### Azure OpenAI Responses
|
|
118
|
+
|
|
119
|
+
Pi's `azure-openai-responses` API uses Azure's Responses endpoint. Toolkit uses Pi's resolved provider authentication and environment values for the base URL, deployment mapping, and `api-version`. Azure Responses requests use the `api-key` header and do not forward an inherited bearer `Authorization` header.
|
|
120
|
+
|
|
121
|
+
Set the API key and either a resource name or a full base URL before starting Pi. `AZURE_OPENAI_API_VERSION` defaults to `v1`, and `AZURE_OPENAI_DEPLOYMENT_NAME_MAP` maps the model ID selected in Pi to an Azure deployment name.
|
|
122
|
+
|
|
123
|
+
PowerShell:
|
|
124
|
+
|
|
125
|
+
```powershell
|
|
126
|
+
$env:AZURE_OPENAI_API_KEY = "replace-with-your-azure-key"
|
|
127
|
+
$env:AZURE_OPENAI_RESOURCE_NAME = "replace-with-your-resource"
|
|
128
|
+
$env:AZURE_OPENAI_API_VERSION = "2025-01-01"
|
|
129
|
+
$env:AZURE_OPENAI_DEPLOYMENT_NAME_MAP = "model-id=replace-with-deployment"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
POSIX shell:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
export AZURE_OPENAI_API_KEY="replace-with-your-azure-key"
|
|
136
|
+
export AZURE_OPENAI_RESOURCE_NAME="replace-with-your-resource"
|
|
137
|
+
export AZURE_OPENAI_API_VERSION="2025-01-01"
|
|
138
|
+
export AZURE_OPENAI_DEPLOYMENT_NAME_MAP="model-id=replace-with-deployment"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Use `AZURE_OPENAI_BASE_URL` instead of `AZURE_OPENAI_RESOURCE_NAME` when the full resource URL is already known, for example `https://your-resource.openai.azure.com`. Toolkit normalizes the resource root to `/openai/v1` and appends `api-version` to both the Responses and compact URLs.
|
|
142
|
+
|
|
143
|
+
Provider-scoped values can also be stored in Pi's `~/.pi/agent/auth.json`:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"azure-openai-responses": {
|
|
148
|
+
"type": "api_key",
|
|
149
|
+
"key": "$AZURE_OPENAI_API_KEY",
|
|
150
|
+
"env": {
|
|
151
|
+
"AZURE_OPENAI_RESOURCE_NAME": "replace-with-your-resource",
|
|
152
|
+
"AZURE_OPENAI_API_VERSION": "2025-01-01",
|
|
153
|
+
"AZURE_OPENAI_DEPLOYMENT_NAME_MAP": "model-id=replace-with-deployment"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Pi resolves the credential and complete `env` object for each request; provider-scoped values take priority over the process environment. Keep `auth.json` private. The selected Pi model ID may differ from the Azure deployment name when the mapping is configured.
|
|
160
|
+
|
|
161
|
+
Enable the Azure Responses API in the Toolkit policy and start Pi with the registered model ID:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"schemaVersion": 2,
|
|
166
|
+
"defaults": {
|
|
167
|
+
"context": {
|
|
168
|
+
"mode": "remote-compaction",
|
|
169
|
+
"remoteCompaction": {
|
|
170
|
+
"apis": ["azure-openai-responses"]
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"webSearch": { "route": "hosted" }
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
pi --model azure-openai-responses/<model-id>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The exact model must still be registered in Pi's model catalog and authenticated through Pi. Keep provider registration and credentials in Pi's own configuration.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### Web Search
|
|
187
|
+
|
|
188
|
+
`defaults.webSearch.route` and `models[exact].webSearch.route` accept:
|
|
189
|
+
|
|
190
|
+
| Route | Behavior |
|
|
191
|
+
| --- | --- |
|
|
192
|
+
| `unmanaged` | Default. Release Toolkit ownership and remove Toolkit-owned standalone exposure. Third-party search and unrelated network tools remain possible. |
|
|
193
|
+
| `local` | Restore the original local tool state and remove native/standalone search conflicts from provider payloads. Never activate a previously inactive local tool. |
|
|
194
|
+
| `hosted` | Use native Responses search with source annotations; suppress conflicting local and standalone tools. |
|
|
195
|
+
| `standalone-alpha` | Experimental, explicit opt-in. Expose sequential `web_run` and call the provider-relative `/alpha/search` endpoint once per execution. |
|
|
196
|
+
|
|
197
|
+
There is no v2 search master switch. `local` and `unmanaged` differ in payload cleanup and ownership. Missing auth, an unavailable route, a tool conflict, or invalid selected policy does not trigger another route. Hosted Responses search also accepts Pi's Azure Responses API; standalone-alpha remains restricted to the verified OpenAI/Codex `/alpha/search` routes. Standalone supports `search_query`, `image_query`, `open`, `click`, `find`, `screenshot`, `finance`, `weather`, `sports`, and `time`, with `response_length`. It sends a bounded command envelope rather than the full transcript; follow-up references depend on the provider's session/reference handling. The gateway must expose the endpoint and its standalone-search capability.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
### Images
|
|
202
|
+
|
|
203
|
+
Image settings are global-only under `defaults.imageGeneration`. `enabled` defaults to `false`. `defaultModel` defaults to `"grok-imagine-image-2.0"`; `allowedModels` defaults to `["grok-imagine-image-2.0"]`.
|
|
204
|
+
|
|
205
|
+
These are bare output-model IDs, not active-session model keys. Each normalized ID must contain 1-256 characters. The allowed list must remain nonempty after normalization and contain the explicit default. A caller's one-call `model` must be a member; policy and membership are checked before auth, local-reference preparation/upload, and paid dispatch. The active session remains the routing/auth model, while the selected image model is sent in a separate Images API request. Generation uses `/images/generations`; edits use `/images/edits` (Codex uses the corresponding `/codex/images/...` paths). The wrapper never injects a Responses `image_generation` tool. Responses are accepted only when they contain one validated PNG, JPEG, or WebP `data[].b64_json` image; the canonical artifact uses the detected format extension. A literal `quality: "auto"` is omitted from the wire request for compatibility gateways that reject it. `batchSize` is a tool argument from 1-10; each item is an independent `n: 1` request, partial success preserves saved artifacts, and batch calls cannot use a single-file `outputPath`. Config does not grant permission to upload arbitrary local files or imply that a provider supports a particular image model.
|
|
206
|
+
|
|
207
|
+
Image input limits are declared in Pi's model metadata, not in Toolkit policy. For example:
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"providers": {
|
|
212
|
+
"my-gateway": {
|
|
213
|
+
"baseUrl": "https://your-gateway.example/v1",
|
|
214
|
+
"api": "openai-responses",
|
|
215
|
+
"apiKey": "$MY_GATEWAY_KEY",
|
|
216
|
+
"models": [{
|
|
217
|
+
"id": "vision-model",
|
|
218
|
+
"name": "Vision Model",
|
|
219
|
+
"input": ["text", "image"],
|
|
220
|
+
"inputLimits": {
|
|
221
|
+
"images": {
|
|
222
|
+
"resize": {
|
|
223
|
+
"maxWidth": 1568,
|
|
224
|
+
"maxHeight": 1568,
|
|
225
|
+
"maxBytes": 524288,
|
|
226
|
+
"jpegQuality": 80
|
|
227
|
+
},
|
|
228
|
+
"maxPerMessage": 4,
|
|
229
|
+
"maxPerRequest": 8
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}]
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
At the compaction and replay boundary, Toolkit applies the declared resize profile before dispatch, counts images per message and request, and fails closed when a limit cannot be satisfied. It creates new input values without mutating the persisted session or original provider payload.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### Removed Auto Mode
|
|
243
|
+
|
|
244
|
+
Auto Mode, `/auto`, and `--auto` have been removed. Toolkit no longer performs this feature's tool-call review, background classification, or review confirmations. No replacement approval gate is installed.
|
|
245
|
+
|
|
246
|
+
Legacy root `autoMode`, v2 `defaults.autoMode`, and exact-model `autoMode` sections are ignored with an explicit removal warning, regardless of their contents. They do not invalidate other valid settings. The editor schema retains only deprecated compatibility entries, not the old controls. Remove these sections and any `--auto` launcher argument manually; Toolkit does not rewrite your configuration, session history, or saved review artifacts. Unrelated invalid settings and mixed legacy/v2 documents still fail validation.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
### Diagnostics and inspection
|
|
251
|
+
|
|
252
|
+
Diagnostics are plugin-wide, not model-scoped.
|
|
253
|
+
|
|
254
|
+
| Field | Default | Contract |
|
|
255
|
+
| --- | --- | --- |
|
|
256
|
+
| `level` | `"info"` | `error`, `warn`, `info`, or `debug`. Debug enables lifecycle/compaction debug artifacts. Configuration issues and operation-blocking failures remain visible at every level. |
|
|
257
|
+
| `notifyOnLoad` | `false` | Optional informational load notification. |
|
|
258
|
+
| `captureRequests` | `false` | Independently opt into provider request artifacts. |
|
|
259
|
+
| `captureResponses` | `false` | Independently capture compact responses; this is not an ordinary chat-response logger. |
|
|
260
|
+
| `redactSensitiveData` | `true` | Optional additional redaction. Critical credentials, account IDs, and opaque encrypted data are always redacted. |
|
|
261
|
+
| `artifactRoot` | `"~/.pi/agent/artifacts/pi-openai-toolkit/compaction"` | Relative paths resolve against the canonical config directory, not the current project. |
|
|
262
|
+
|
|
263
|
+
`/toolkit-config` (or `show`) displays effective values with built-in/default/exact/legacy origins. `/toolkit-config validate` reports document issues, including unrelated model entries. Reports are bounded and redacted; unknown field names are masked. Repeated issue notifications are deduplicated within a session and do not depend on compaction enablement or debug mode.
|
|
264
|
+
|
|
265
|
+
`/toolkit-config migration-preview` analyzes a legacy file without changing it. These are human commands using Pi's UI; no model tool, new headless stdout protocol, network probe, auth lookup, tool mutation, or persistent state write is added. Headless operation failures and typed resolution issues remain observable. A truncated candidate is not usable JSON.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
### Legacy compatibility and migration
|
|
270
|
+
|
|
271
|
+
Do not combine unversioned roots (`compaction`, `webSearch`, `imageGeneration`, `autoMode`) with `schemaVersion: 2`. Remaining legacy features are retained through a compatibility adapter, including nullable model clears, legacy image-list defaults, and source-dependent hosted-search failure handling. Invalid selected legacy route values are now blocked instead of disappearing into another selection.
|
|
272
|
+
|
|
273
|
+
The preview maps recognized fields into a candidate, supplies leaf origins, lists unmapped/dormant paths, and reports `ready`, `needs-review`, `already-v2`, or `unavailable`. `ready` means no known semantic difference was found in recognized active policy; it is not authorization to apply or proof of provider support. Unknown names are masked and their values are never copied into the report. The original source bytes remain the authoritative copy of unknown and dormant content.
|
|
274
|
+
|
|
275
|
+
| Legacy input | v2 destination |
|
|
276
|
+
| --- | --- |
|
|
277
|
+
| `compaction.enabled` / `contextManagement` | `defaults.context.mode` |
|
|
278
|
+
| `compaction.remoteCompactModel`, `remoteV2ContextSource`, `allowCompactionContinuityBreak`, `responsesApis` | `defaults.context.remoteCompaction` fields |
|
|
279
|
+
| `compaction.nativeFallback` | `defaults.context.nativeFallback` |
|
|
280
|
+
| `compaction.leaveManagedMode`, `contextReminderThresholdPercent` | `defaults.context.remoteWindows` fields |
|
|
281
|
+
| `compaction.gatewayContextModels` | Exact `models[key].compatibility.transport` |
|
|
282
|
+
| `webSearch.defaultRoute`, `routes`, `models` | Default/exact search route candidates, subject to review below |
|
|
283
|
+
| `imageGeneration.models` | `allowedModels` plus an explicit default taken from the legacy first entry |
|
|
284
|
+
| `autoMode` | Removed; omitted from the candidate with a warning and `needs-review` |
|
|
285
|
+
| Legacy compaction debug/capture/path settings | `diagnostics` |
|
|
286
|
+
|
|
287
|
+
The preview cannot claim universal lossless conversion:
|
|
288
|
+
|
|
289
|
+
- A legacy hosted allowlist ignores unsupported APIs and malformed payloads; explicit v2 hosted selection fails closed. Moving a list entry to an exact hosted route changes those failure paths.
|
|
290
|
+
- Disabled legacy features can retain dormant model lists/routes. A simplified v2 policy cannot preserve enable-later intent without review.
|
|
291
|
+
- Gateway compatibility is now shared independently of context mode; review effects on compaction and image affinity.
|
|
292
|
+
- Unknown fields, invalid normalization, or candidate validation failures require review. `remoteV2ContextSource: "legacy"` remains `inputSource: "legacy"`; preview does not upgrade checkpoint provenance or opt any model into standalone search.
|
|
293
|
+
|
|
294
|
+
There is no automatic migration, writer, or `--write` option. Before a separately approved manual cutover, back up the original bytes and verify that every installed Toolkit copy supports v2. Older copies, including 0.14.13, do not support this format. Updating source in a checkout does not update an installed package. Keep the legacy file until that cutover is ready.
|