pi-openai-toolkit 0.20.0 → 0.20.2

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
@@ -105,7 +105,7 @@ The Toolkit WebSocket adapter is disabled by default. Enable it globally for GPT
105
105
  }
106
106
  ```
107
107
 
108
- It reuses the selected model's provider, base URL, credentials, headers, and model ID without registering another provider. Pi's `transport: "auto"` tries WebSocket first and falls back to SSE before streaming starts; `transport: "sse"` keeps the original HTTP/SSE path. Restart or reload Pi after changing the Toolkit setting. See [WebSocket configuration](docs/configuration.md#responses-websocket-transport).
108
+ It reuses the selected model's provider, base URL, credentials, headers, and model ID without registering another provider. Pi's `transport: "auto"` tries WebSocket first and falls back to SSE before streaming starts; with a stable session it also reuses the socket and sends only the new continuation input when the transcript matches. Use `transport: "websocket-cached"` to require that cached path, or `transport: "sse"` to keep the original HTTP/SSE path. Restart or reload Pi after changing the Toolkit setting. See [WebSocket configuration](docs/configuration.md#responses-websocket-transport).
109
109
 
110
110
  ### Auto Mode
111
111
 
package/README.zh.md CHANGED
@@ -105,7 +105,7 @@ Toolkit 的 WebSocket adapter 默认关闭。对使用 Pi `openai-responses` API
105
105
  }
106
106
  ```
107
107
 
108
- 它沿用当前模型的 provider、base URL、凭据、headers 和 model ID,不注册新的 provider。Pi 的 `transport: "auto"` 会先尝试 WebSocket,并在开始流式输出前回退到 SSE;`transport: "sse"` 保持原有 HTTP/SSE 路径。修改 Toolkit 配置后请重启或 reload Pi。详见[WebSocket 配置](docs/configuration.md#responses-websocket-transport)。
108
+ 它沿用当前模型的 provider、base URL、凭据、headers 和 model ID,不注册新的 provider。Pi 的 `transport: "auto"` 会先尝试 WebSocket,并在开始流式输出前回退到 SSE;会话 ID 稳定时还会复用连接,并在历史匹配时只发送新的 continuation 输入。使用 `transport: "websocket-cached"` 可强制要求缓存连接路径,使用 `transport: "sse"` 则保持原有 HTTP/SSE 路径。修改 Toolkit 配置后请重启或 reload Pi。详见[WebSocket 配置](docs/configuration.md#responses-websocket-transport)。
109
109
 
110
110
  ### Auto Mode
111
111
 
@@ -96,12 +96,12 @@ The extension honors Pi's global `transport` setting:
96
96
 
97
97
  | Pi `transport` | Behavior |
98
98
  | --- | --- |
99
- | `auto` | Try `wss://.../responses?model=...` first; fall back to the original SSE adapter only before a stream starts. |
100
- | `websocket` | Require the WebSocket path; do not fall back to SSE. |
101
- | `websocket-cached` | Use the WebSocket path with the same strict behavior. |
99
+ | `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. |
100
+ | `websocket` | Require the WebSocket path; do not fall back to SSE. This mode opens a request-scoped connection. |
101
+ | `websocket-cached` | Require the WebSocket path and keep a session-scoped connection for later turns. |
102
102
  | `sse` | Bypass the extension and use the original HTTP/SSE adapter. |
103
103
 
104
- 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. The upstream must support the standard Responses WebSocket contract; this does not rewrite a server that only exposes Codex's `/codex/responses` path or Codex-only authentication.
104
+ 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.
105
105
 
106
106
  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.
107
107
 
package/package.json CHANGED
@@ -1,140 +1,140 @@
1
- {
2
- "name": "pi-openai-toolkit",
3
- "version": "0.20.0",
4
- "private": false,
5
- "type": "module",
6
- "engines": {
7
- "node": ">=22.19.0"
8
- },
9
- "description": "OpenAI toolkit for Pi: Codex Remote Context windows, remote compaction v2, routed Web Search, image gen, auto mode.",
10
- "author": "awoaCrim and contributors",
11
- "license": "MIT",
12
- "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/awoaCrim/pi-openai-toolkit.git"
15
- },
16
- "bugs": {
17
- "url": "https://github.com/awoaCrim/pi-openai-toolkit/issues"
18
- },
19
- "homepage": "https://github.com/awoaCrim/pi-openai-toolkit#readme",
20
- "publishConfig": {
21
- "access": "public",
22
- "registry": "https://registry.npmjs.org/"
23
- },
24
- "keywords": [
25
- "pi-package",
26
- "pi-extension",
27
- "openai",
28
- "compaction",
29
- "web-search",
30
- "image-generation",
31
- "auto-mode",
32
- "codex",
33
- "responses"
34
- ],
35
- "pi": {
36
- "extensions": [
37
- "./src/extension-runtime.ts",
38
- "./src/web-search/extension.ts",
39
- "./src/image-generation/extension.ts",
40
- "./src/auto-mode/extension.ts",
41
- "./src/codex-astra/extension.ts",
42
- "./src/responses-websocket/extension.ts"
43
- ]
44
- },
45
- "files": [
46
- "src/compact-client.ts",
47
- "src/compaction-projection.ts",
48
- "src/pi-context-hook.ts",
49
- "src/config.ts",
50
- "src/config-command.ts",
51
- "src/config/policy.ts",
52
- "src/config/legacy.ts",
53
- "src/config/v2.ts",
54
- "src/config/migration.ts",
55
- "src/config/notifications.ts",
56
- "config.schema.json",
57
- "src/debug.ts",
58
- "src/details-store.ts",
59
- "src/deferred-tool-carryover.ts",
60
- "src/extension-runtime.ts",
61
- "src/context-management/types.ts",
62
- "src/context-management/messages.ts",
63
- "src/context-management/window-budget.ts",
64
- "src/context-management/window-request.ts",
65
- "src/context-management/window-bulk.ts",
66
- "src/context-management/window-manager.ts",
67
- "src/context-management/manual-compact.ts",
68
- "src/context-management/codex-provider.ts",
69
- "src/context-management/history-notes.ts",
70
- "src/context-management/tools.ts",
71
- "src/context-management/namespace-tools.ts",
72
- "src/context-management/tool-contract.ts",
73
- "src/image-generation/artifacts.ts",
74
- "src/image-generation/client.ts",
75
- "src/image-generation/eligibility.ts",
76
- "src/image-generation/extension.ts",
77
- "src/image-generation/protocol.ts",
78
- "src/image-generation/references.ts",
79
- "src/image-generation/render.ts",
80
- "src/image-generation/service.ts",
81
- "src/image-generation/types.ts",
82
- "src/auto-mode/extension.ts",
83
- "src/auto-mode/tool-review-tui.ts",
84
- "src/auto-mode/policy.ts",
85
- "src/auto-mode/model-selection-guard.ts",
86
- "src/auto-mode/prompt.ts",
87
- "src/auto-mode/transcript.ts",
88
- "src/auto-mode/reviewer.ts",
89
- "src/auto-mode/classifier.ts",
90
- "src/auto-mode/types.ts",
91
- "src/codex-astra/effort-planner.ts",
92
- "src/codex-astra/extension.ts",
93
- "src/responses-websocket/extension.ts",
94
- "src/responses-websocket/transport.ts",
95
- "src/model-scope.ts",
96
- "src/native-fallback.ts",
97
- "src/payload-rewrite.ts",
98
- "src/provider-headers.ts",
99
- "src/responses-headers.ts",
100
- "src/remote-v2-client.ts",
101
- "src/request-context-cache.ts",
102
- "src/runtime.ts",
103
- "src/serializer.ts",
104
- "src/supported-environment.ts",
105
- "src/types.ts",
106
- "src/web-search/alpha-client.ts",
107
- "src/web-search/extension.ts",
108
- "src/web-search/payload.ts",
109
- "src/web-search/prompt.ts",
110
- "src/web-search/types.ts",
111
- "docs/internals.md",
112
- "docs/configuration.md",
113
- "README.md",
114
- "README.zh.md",
115
- "LICENSE",
116
- "NOTICE",
117
- "tsconfig.check.json"
118
- ],
119
- "scripts": {
120
- "test": "bun test",
121
- "test:coverage": "bun test --coverage --coverage-reporter=text --coverage-reporter=lcov && node ./scripts/check-lcov.mjs ./coverage/lcov.info",
122
- "test:pi": "bun test ./test/pi-smoke.test.ts",
123
- "typecheck": "tsc -p tsconfig.check.json"
124
- },
125
- "peerDependencies": {
126
- "@earendil-works/pi-agent-core": ">=0.87.0",
127
- "@earendil-works/pi-ai": ">=0.87.0",
128
- "@earendil-works/pi-coding-agent": ">=0.87.0",
129
- "@earendil-works/pi-tui": ">=0.87.0"
130
- },
131
- "devDependencies": {
132
- "@earendil-works/pi-agent-core": "0.99.1",
133
- "@earendil-works/pi-ai": "0.99.1",
134
- "@earendil-works/pi-coding-agent": "0.99.1",
135
- "@earendil-works/pi-tui": "0.99.1",
136
- "@types/node": "24.12.4",
137
- "bun": "1.2.23",
138
- "typescript": "5.9.3"
139
- }
140
- }
1
+ {
2
+ "name": "pi-openai-toolkit",
3
+ "version": "0.20.2",
4
+ "private": false,
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=22.19.0"
8
+ },
9
+ "description": "OpenAI toolkit for Pi: Codex Remote Context windows, remote compaction v2, routed Web Search, image gen, auto mode.",
10
+ "author": "awoaCrim and contributors",
11
+ "license": "MIT",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/awoaCrim/pi-openai-toolkit.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/awoaCrim/pi-openai-toolkit/issues"
18
+ },
19
+ "homepage": "https://github.com/awoaCrim/pi-openai-toolkit#readme",
20
+ "publishConfig": {
21
+ "access": "public",
22
+ "registry": "https://registry.npmjs.org/"
23
+ },
24
+ "keywords": [
25
+ "pi-package",
26
+ "pi-extension",
27
+ "openai",
28
+ "compaction",
29
+ "web-search",
30
+ "image-generation",
31
+ "auto-mode",
32
+ "codex",
33
+ "responses"
34
+ ],
35
+ "pi": {
36
+ "extensions": [
37
+ "./src/extension-runtime.ts",
38
+ "./src/web-search/extension.ts",
39
+ "./src/image-generation/extension.ts",
40
+ "./src/auto-mode/extension.ts",
41
+ "./src/codex-astra/extension.ts",
42
+ "./src/responses-websocket/extension.ts"
43
+ ]
44
+ },
45
+ "files": [
46
+ "src/compact-client.ts",
47
+ "src/compaction-projection.ts",
48
+ "src/pi-context-hook.ts",
49
+ "src/config.ts",
50
+ "src/config-command.ts",
51
+ "src/config/policy.ts",
52
+ "src/config/legacy.ts",
53
+ "src/config/v2.ts",
54
+ "src/config/migration.ts",
55
+ "src/config/notifications.ts",
56
+ "config.schema.json",
57
+ "src/debug.ts",
58
+ "src/details-store.ts",
59
+ "src/deferred-tool-carryover.ts",
60
+ "src/extension-runtime.ts",
61
+ "src/context-management/types.ts",
62
+ "src/context-management/messages.ts",
63
+ "src/context-management/window-budget.ts",
64
+ "src/context-management/window-request.ts",
65
+ "src/context-management/window-bulk.ts",
66
+ "src/context-management/window-manager.ts",
67
+ "src/context-management/manual-compact.ts",
68
+ "src/context-management/codex-provider.ts",
69
+ "src/context-management/history-notes.ts",
70
+ "src/context-management/tools.ts",
71
+ "src/context-management/namespace-tools.ts",
72
+ "src/context-management/tool-contract.ts",
73
+ "src/image-generation/artifacts.ts",
74
+ "src/image-generation/client.ts",
75
+ "src/image-generation/eligibility.ts",
76
+ "src/image-generation/extension.ts",
77
+ "src/image-generation/protocol.ts",
78
+ "src/image-generation/references.ts",
79
+ "src/image-generation/render.ts",
80
+ "src/image-generation/service.ts",
81
+ "src/image-generation/types.ts",
82
+ "src/auto-mode/extension.ts",
83
+ "src/auto-mode/tool-review-tui.ts",
84
+ "src/auto-mode/policy.ts",
85
+ "src/auto-mode/model-selection-guard.ts",
86
+ "src/auto-mode/prompt.ts",
87
+ "src/auto-mode/transcript.ts",
88
+ "src/auto-mode/reviewer.ts",
89
+ "src/auto-mode/classifier.ts",
90
+ "src/auto-mode/types.ts",
91
+ "src/codex-astra/effort-planner.ts",
92
+ "src/codex-astra/extension.ts",
93
+ "src/responses-websocket/extension.ts",
94
+ "src/responses-websocket/transport.ts",
95
+ "src/model-scope.ts",
96
+ "src/native-fallback.ts",
97
+ "src/payload-rewrite.ts",
98
+ "src/provider-headers.ts",
99
+ "src/responses-headers.ts",
100
+ "src/remote-v2-client.ts",
101
+ "src/request-context-cache.ts",
102
+ "src/runtime.ts",
103
+ "src/serializer.ts",
104
+ "src/supported-environment.ts",
105
+ "src/types.ts",
106
+ "src/web-search/alpha-client.ts",
107
+ "src/web-search/extension.ts",
108
+ "src/web-search/payload.ts",
109
+ "src/web-search/prompt.ts",
110
+ "src/web-search/types.ts",
111
+ "docs/internals.md",
112
+ "docs/configuration.md",
113
+ "README.md",
114
+ "README.zh.md",
115
+ "LICENSE",
116
+ "NOTICE",
117
+ "tsconfig.check.json"
118
+ ],
119
+ "scripts": {
120
+ "test": "bun test",
121
+ "test:coverage": "bun test --coverage --coverage-reporter=text --coverage-reporter=lcov && node ./scripts/check-lcov.mjs ./coverage/lcov.info",
122
+ "test:pi": "bun test ./test/pi-smoke.test.ts",
123
+ "typecheck": "tsc -p tsconfig.check.json"
124
+ },
125
+ "peerDependencies": {
126
+ "@earendil-works/pi-agent-core": ">=0.87.0",
127
+ "@earendil-works/pi-ai": ">=0.87.0",
128
+ "@earendil-works/pi-coding-agent": ">=0.87.0",
129
+ "@earendil-works/pi-tui": ">=0.87.0"
130
+ },
131
+ "devDependencies": {
132
+ "@earendil-works/pi-agent-core": "0.99.1",
133
+ "@earendil-works/pi-ai": "0.99.1",
134
+ "@earendil-works/pi-coding-agent": "0.99.1",
135
+ "@earendil-works/pi-tui": "0.99.1",
136
+ "@types/node": "24.12.4",
137
+ "bun": "1.2.23",
138
+ "typescript": "5.9.3"
139
+ }
140
+ }
@@ -119,6 +119,7 @@ export function createContextManagementTools(
119
119
  label: "new_context",
120
120
  description: "Start a new remote Codex context window without generating a conversation summary. Requires a persisted successful notes checkpoint in the current window.",
121
121
  parameters: NEW_CONTEXT_PARAMETERS,
122
+ exposure: "direct",
122
123
  promptSnippet: "Start a new remote Codex context window without summarizing history.",
123
124
  promptGuidelines: [
124
125
  "Before this new_context call, checkpoint active work in notes; only a persisted successful notes append/write in the current window unlocks this rollover, and no conversation summary carries over.",
@@ -169,6 +170,7 @@ export function createContextManagementTools(
169
170
  label: "get_context_remaining",
170
171
  description: "Get the remaining tokens in the current remote Codex context window.",
171
172
  parameters: EMPTY_PARAMETERS,
173
+ exposure: "direct",
172
174
  async execute(_id, _params, _signal, _update, ctx) {
173
175
  await assertActive(ctx);
174
176
  const remaining = manager.remaining(ctx);
@@ -183,6 +185,7 @@ export function createContextManagementTools(
183
185
  label: "history",
184
186
  description: "Search or read prior remote Codex context-window history. Pass IDs unchanged.",
185
187
  parameters: HISTORY_PARAMETERS,
188
+ exposure: "direct",
186
189
  promptSnippet: "Search or read prior remote Codex context-window history.",
187
190
  promptGuidelines: [
188
191
  "When the user asks about decisions, code, or details from earlier in the conversation that are no longer in the current context window, use history first instead of relying on fragments that survived compaction.",
@@ -201,6 +204,7 @@ export function createContextManagementTools(
201
204
  label: "notes",
202
205
  description: "Read and checkpoint remote Codex notes across context windows.",
203
206
  parameters: NOTES_PARAMETERS,
207
+ exposure: "direct",
204
208
  promptSnippet: "Read and checkpoint remote Codex notes across context windows.",
205
209
  promptGuidelines: [
206
210
  "Before calling new_context, checkpoint the current turn's active work (unfinished tasks, decisions, open questions, references) into notes with append_to_file or write_file so it survives the window change; wait for that result to be persisted before calling new_context.",
@@ -4,6 +4,7 @@ import { loadToolkitConfig, resolveToolkitConfig } from "../config";
4
4
  import { createResponsesWebSocketProvider } from "./transport";
5
5
 
6
6
  const SOURCE_ID = "pi-openai-toolkit:openai-responses-websocket";
7
+ let baseProvider: ReturnType<typeof getApiProvider>;
7
8
 
8
9
  /**
9
10
  * Add the transport branch at the API-adapter boundary instead of registering
@@ -21,9 +22,9 @@ export function installResponsesWebSocketTransport(
21
22
  if (!resolved.policy.responsesWebSocket.enabled || resolved.invalidFeatures.includes("responsesWebSocket")) {
22
23
  return false;
23
24
  }
24
- const original = getApiProvider("openai-responses");
25
- if (!original) return false;
26
- registerApiProvider(createResponsesWebSocketProvider(original, true), SOURCE_ID);
25
+ baseProvider ??= getApiProvider("openai-responses");
26
+ if (!baseProvider) return false;
27
+ registerApiProvider(createResponsesWebSocketProvider(baseProvider, true), SOURCE_ID);
27
28
  return true;
28
29
  }
29
30