pi-openai-toolkit 0.3.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 -0
- package/NOTICE +33 -0
- package/README.md +175 -0
- package/README_zh.md +172 -0
- package/extensions/compaction.ts +1 -0
- package/extensions/web-search.ts +1 -0
- package/package.json +79 -0
- package/src/compact-client.ts +426 -0
- package/src/config.ts +273 -0
- package/src/debug.ts +168 -0
- package/src/details-store.ts +151 -0
- package/src/extension-runtime.ts +537 -0
- package/src/native-fallback.ts +151 -0
- package/src/payload-rewrite.ts +556 -0
- package/src/provider-headers.ts +23 -0
- package/src/remote-v2-client.ts +526 -0
- package/src/request-context-cache.ts +106 -0
- package/src/runtime.ts +283 -0
- package/src/serializer.ts +554 -0
- package/src/supported-environment.ts +17 -0
- package/src/types.ts +333 -0
- package/src/web-search/extension.ts +80 -0
- package/src/web-search/payload.ts +96 -0
- package/src/web-search/prompt.ts +20 -0
- package/src/web-search/types.ts +47 -0
- package/tsconfig.check.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 lll9p
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
pi-openai-toolkit
|
|
2
|
+
Copyright (c) 2026 awoaCrim and contributors
|
|
3
|
+
|
|
4
|
+
The native OpenAI Web Search behavior in this package was adapted from
|
|
5
|
+
code-yeongyu/pi-openai-web-search at commit
|
|
6
|
+
39643380682f02f306b0de2673ff136c45ccc2a2.
|
|
7
|
+
|
|
8
|
+
Upstream copyright and license notice:
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2026 Yeongyu Kim
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
|
|
30
|
+
The adapted implementation targets the @earendil-works Pi interfaces and is
|
|
31
|
+
integrated with pi-openai-toolkit's independent compaction and Web Search
|
|
32
|
+
extension entry points. The upstream NOTICE also identifies the behavior as a
|
|
33
|
+
standalone port of the senpi-mono built-in openai-web-search extension.
|
package/README.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# pi-openai-toolkit
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>OpenAI-focused toolkit for <a href="https://github.com/badlogic/pi">Pi</a>: Native Remote Compaction v2 & Hosted Web Search</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="./README.md">English</a> | <a href="./README_zh.md">简体中文</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
`pi-openai-toolkit` is an all-in-one OpenAI enhancement package for **Pi (>= 0.84.x)**. It bundles two high-performance extensions designed for OpenAI Responses endpoints:
|
|
14
|
+
|
|
15
|
+
1. **Remote Responses Compaction v2** (`extensions/compaction.ts`): Server-side opaque context compaction using the `remote_compaction_v2` SSE streaming protocol. Preserves context fidelity without lossy text re-summarization.
|
|
16
|
+
2. **Model-Scoped Web Search** (`extensions/web-search.ts`): Toolkit-owned hosted Web Search for an exact `provider/model-id` allowlist configured with `webSearch.models`, across the supported `openai-responses` and `openai-codex-responses` APIs.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
### Install via Pi Package Manager (recommended)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pi install npm:pi-openai-toolkit
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Git installation (alternative / development)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pi install git:github.com/awoaCrim/pi-openai-toolkit
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Local Development / Testing
|
|
33
|
+
|
|
34
|
+
Load the complete toolkit:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pi --no-extensions -e /absolute/path/to/pi-openai-toolkit
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or load a single extension independently:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Compaction only
|
|
44
|
+
pi --no-extensions -e /absolute/path/to/pi-openai-toolkit/extensions/compaction.ts
|
|
45
|
+
|
|
46
|
+
# Web Search only
|
|
47
|
+
pi --no-extensions -e /absolute/path/to/pi-openai-toolkit/extensions/web-search.ts
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> ⚠️ **Conflict Warning**: Do not run `pi-remote-compact`, `@lll9p/pi-better-compaction`, or standalone `pi-openai-web-search` alongside `pi-openai-toolkit`. Duplicate hooks cause race conditions and duplicated system prompts.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Configuration
|
|
55
|
+
|
|
56
|
+
Configuration file location:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
~/.pi/agent/extensions/pi-openai-toolkit/config.json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Example `config.json`
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"compaction": {
|
|
67
|
+
"enabled": true,
|
|
68
|
+
"allowCompactionContinuityBreak": false,
|
|
69
|
+
"model": null,
|
|
70
|
+
"thinkingLevel": "off",
|
|
71
|
+
"responsesApis": [
|
|
72
|
+
"openai-responses",
|
|
73
|
+
"openai-codex-responses"
|
|
74
|
+
],
|
|
75
|
+
"notifyOnLoad": false,
|
|
76
|
+
"debug": false,
|
|
77
|
+
"logProviderPayloads": false,
|
|
78
|
+
"logCompactResponses": false,
|
|
79
|
+
"redactSensitiveData": true,
|
|
80
|
+
"artifactRoot": "~/.pi/agent/artifacts/pi-openai-toolkit/compaction"
|
|
81
|
+
},
|
|
82
|
+
"webSearch": {
|
|
83
|
+
"enabled": true,
|
|
84
|
+
"models": [
|
|
85
|
+
"uwoacrimson/gpt-5.6-luna"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Configuration Options
|
|
92
|
+
|
|
93
|
+
#### `compaction`
|
|
94
|
+
|
|
95
|
+
- `enabled` (*boolean*, default: `true`): Enable or disable Remote Compaction.
|
|
96
|
+
- `allowCompactionContinuityBreak` (*boolean*, default: `false`): When `true`, allows restarting a fresh native opaque compaction chain from Pi's current session text if the latest compaction was made by another strategy (e.g. text summary).
|
|
97
|
+
- `model` (*string | null*, default: `null`): Fallback model formatted as `provider/model-id` (e.g. `"openai/gpt-4o-mini"`) used if the remote compact gateway fails or when switching to non-Responses APIs. If `null`, uses the session's active model.
|
|
98
|
+
- `thinkingLevel` (*string*, default: `"off"`): Reasoning / thinking level passed to Pi native compaction fallback (`"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`, `"max"`).
|
|
99
|
+
- `responsesApis` (*string[]*): Narrow the supported remote compaction API identifiers (subset of `["openai-responses", "openai-codex-responses"]`).
|
|
100
|
+
- `notifyOnLoad` (*boolean*, default: `false`): Show a notification banner on Pi startup.
|
|
101
|
+
- `debug` (*boolean*, default: `false`): Output diagnostics and write execution artifacts to disk.
|
|
102
|
+
- `logProviderPayloads` / `logCompactResponses` (*boolean*, default: `false`): Write raw provider request payloads and compact SSE event bodies to artifacts.
|
|
103
|
+
- `redactSensitiveData` (*boolean*, default: `true`): Automatically redact Authorization headers, API keys, sensitive URL query tokens, and opaque `encrypted_content` ciphertext from debug artifacts.
|
|
104
|
+
- `artifactRoot` (*string*): Directory root for diagnostic artifacts. Relative paths resolve against the config directory.
|
|
105
|
+
|
|
106
|
+
#### `webSearch`
|
|
107
|
+
|
|
108
|
+
- `enabled` (*boolean*, default: `true`): Enable or disable native OpenAI Web Search injection.
|
|
109
|
+
- `models` (*string[]*): Exact `provider/model-id` allowlist. Toolkit Web Search is used only for listed models running on `openai-responses` or `openai-codex-responses`. An empty list disables toolkit Web Search for all models.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Core Mechanics
|
|
114
|
+
|
|
115
|
+
### 1. Remote Compaction v2 Protocol
|
|
116
|
+
|
|
117
|
+
Instead of legacy JSON endpoints (`POST /responses/compact`), this toolkit implements the **`remote_compaction_v2`** protocol over standard streaming Responses:
|
|
118
|
+
|
|
119
|
+
```http
|
|
120
|
+
POST /responses
|
|
121
|
+
Content-Type: application/json
|
|
122
|
+
|
|
123
|
+
{
|
|
124
|
+
"model": "...",
|
|
125
|
+
"input": [
|
|
126
|
+
...currentResponsesInput,
|
|
127
|
+
{ "type": "compaction_trigger" }
|
|
128
|
+
],
|
|
129
|
+
"stream": true,
|
|
130
|
+
"store": false
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
- **Validation Criteria**: Must return a valid SSE stream with `response.completed` (status `completed`) containing exactly one output item of `type: "compaction"` with non-empty `encrypted_content`.
|
|
135
|
+
- **Zero Loss Replay**: The opaque encrypted item is stored in `CompactionEntry.details.compactedWindow`. On subsequent requests, it is transparently prepended after fresh preamble instructions alongside live turns, eliminating lossy text re-summaries.
|
|
136
|
+
- **Graceful Multi-Tier Fallback**:
|
|
137
|
+
1. Compatible Responses endpoints → Remote v2 Opaque Compaction.
|
|
138
|
+
2. Gateway failure or non-Responses model → Configured `compaction.model` fallback.
|
|
139
|
+
3. Otherwise → Pi default native text compaction.
|
|
140
|
+
|
|
141
|
+
### 2. Model-Scoped Web Search
|
|
142
|
+
|
|
143
|
+
For allowlisted models using `openai-responses` or `openai-codex-responses`, the extension hooks into `before_provider_request` and `before_agent_start`:
|
|
144
|
+
|
|
145
|
+
- Injects `{ "type": "web_search" }` tool definition into the payload.
|
|
146
|
+
- Appends `web_search_call.action.sources` to the Responses `include` array.
|
|
147
|
+
- Appends concise search prompting to the system instructions.
|
|
148
|
+
- **Zero-Latency**: Uses Pi's existing connection, auth headers, and base URL without standalone HTTP overhead.
|
|
149
|
+
- **Toolkit Ownership**: For an eligible model, the outgoing payload removes the local function tool named `web_search` so native search is the only search path. Switching to an ineligible model restores that local tool's previous active state.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Development & Testing
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Typecheck TypeScript definitions
|
|
157
|
+
npm run typecheck
|
|
158
|
+
|
|
159
|
+
# Run full test suite with Bun
|
|
160
|
+
bun test
|
|
161
|
+
|
|
162
|
+
# Run Pi integration smoke tests
|
|
163
|
+
npm run test:pi
|
|
164
|
+
|
|
165
|
+
# Dry-run package archive
|
|
166
|
+
npm pack --dry-run
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## License & Acknowledgments
|
|
172
|
+
|
|
173
|
+
- Licensed under the **MIT License**. See [LICENSE](./LICENSE) for details.
|
|
174
|
+
- Native Web Search behavior was adapted from [`code-yeongyu/pi-openai-web-search`](https://github.com/code-yeongyu/pi-openai-web-search) (commit `39643380682f02f306b0de2673ff136c45ccc2a2`). See [NOTICE](./NOTICE).
|
|
175
|
+
- [LINUX DO](https://linux.do/) community.
|
package/README_zh.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# pi-openai-toolkit
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>专为 <a href="https://github.com/badlogic/pi">Pi</a> 打造的 OpenAI 全功能增强工具包:远端无损压缩 v2 & 原生托管联网搜索</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="./README.md">English</a> | <a href="./README_zh.md">简体中文</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
`pi-openai-toolkit` 是专为 **Pi (>= 0.84.x)** 打造的 OpenAI 全功能增强工具包,集成了两项针对 OpenAI Responses 协议的核心扩展:
|
|
14
|
+
|
|
15
|
+
1. **远端无损压缩 (Remote Compaction v2)** (`extensions/compaction.ts`): 基于 `remote_compaction_v2` SSE 流式协议实现的服务端密文无损会话压缩,彻底告别会话变长后丢失细节的文本二次摘要。
|
|
16
|
+
2. **按模型启用的联网搜索** (`extensions/web-search.ts`): 通过 `webSearch.models` 精确匹配 `provider/model-id`,由 Toolkit 为符合条件的 `openai-responses` 与 `openai-codex-responses` 会话提供并拥有原生联网搜索。
|
|
17
|
+
|
|
18
|
+
## 安装使用
|
|
19
|
+
|
|
20
|
+
### 通过 Pi 安装 (推荐)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pi install npm:pi-openai-toolkit
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Git 安装(替代 / 开发路径)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pi install git:github.com/awoaCrim/pi-openai-toolkit
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 本地开发与调试加载
|
|
33
|
+
|
|
34
|
+
加载完整工具包:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pi --no-extensions -e /本地绝对路径/pi-openai-toolkit
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
或单独加载某一子扩展:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# 仅加载远端压缩
|
|
44
|
+
pi --no-extensions -e /本地绝对路径/pi-openai-toolkit/extensions/compaction.ts
|
|
45
|
+
|
|
46
|
+
# 仅加载原生联网搜索
|
|
47
|
+
pi --no-extensions -e /本地绝对路径/pi-openai-toolkit/extensions/web-search.ts
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> ⚠️ **冲突提示**:请勿同时启用 `pi-remote-compact`、`@lll9p/pi-better-compaction` 或独立的 `pi-openai-web-search`。多重钩子会产生竞态或注入重复的 System Prompt。
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 配置文件说明
|
|
55
|
+
|
|
56
|
+
全局唯一配置路径:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
~/.pi/agent/extensions/pi-openai-toolkit/config.json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 配置示例
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"compaction": {
|
|
67
|
+
"enabled": true,
|
|
68
|
+
"allowCompactionContinuityBreak": false,
|
|
69
|
+
"model": null,
|
|
70
|
+
"thinkingLevel": "off",
|
|
71
|
+
"responsesApis": [
|
|
72
|
+
"openai-responses",
|
|
73
|
+
"openai-codex-responses"
|
|
74
|
+
],
|
|
75
|
+
"notifyOnLoad": false,
|
|
76
|
+
"debug": false,
|
|
77
|
+
"logProviderPayloads": false,
|
|
78
|
+
"logCompactResponses": false,
|
|
79
|
+
"redactSensitiveData": true,
|
|
80
|
+
"artifactRoot": "~/.pi/agent/artifacts/pi-openai-toolkit/compaction"
|
|
81
|
+
},
|
|
82
|
+
"webSearch": {
|
|
83
|
+
"enabled": true,
|
|
84
|
+
"models": [
|
|
85
|
+
"uwoacrimson/gpt-5.6-luna"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 配置参数详解
|
|
92
|
+
|
|
93
|
+
#### `compaction`(压缩配置)
|
|
94
|
+
|
|
95
|
+
- `enabled` (*boolean*, 默认 `true`): 是否启用远端无损压缩。
|
|
96
|
+
- `allowCompactionContinuityBreak` (*boolean*, 默认 `false`): 若最近一次历史压缩由其他方式(如文本摘要)生成,设为 `true` 允许直接从当前有效文本上下文重建密文压缩链。
|
|
97
|
+
- `model` (*string | null*, 默认 `null`): 降级模型,格式为 `"provider/model-id"`(例如 `"openai/gpt-4o-mini"`)。当网关不支持远端压缩或切换到非 Responses 协议模型时使用。为 `null` 时使用当前会话模型。
|
|
98
|
+
- `thinkingLevel` (*string*, 默认 `"off"`): 降级模型调用 Pi 原生压缩时的思考级别(`"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`, `"max"`)。
|
|
99
|
+
- `responsesApis` (*string[]*): 允许尝试远端压缩的 API 标识符子集(从 `["openai-responses", "openai-codex-responses"]` 中选定)。
|
|
100
|
+
- `notifyOnLoad` (*boolean*, 默认 `false`): Pi 启动加载时是否弹出气泡提示。
|
|
101
|
+
- `debug` (*boolean*, 默认 `false`): 是否开启调试模式并记录诊断日志。
|
|
102
|
+
- `logProviderPayloads` / `logCompactResponses` (*boolean*, 默认 `false`): 是否在 Artifacts 中记录完整的 Provider 请求与 SSE 流事件体。
|
|
103
|
+
- `redactSensitiveData` (*boolean*, 默认 `true`): 自动对日志中的 Authorization 请求头、API Key、URL 敏感参数及 `encrypted_content` 密文进行脱敏处理(替换为 `[REDACTED]`)。
|
|
104
|
+
- `artifactRoot` (*string*): 诊断日志存储根目录,支持 `~/` 路径。
|
|
105
|
+
|
|
106
|
+
#### `webSearch`(联网搜索配置)
|
|
107
|
+
|
|
108
|
+
- `enabled` (*boolean*, 默认 `true`): 是否启用原生 OpenAI 联网搜索注入。
|
|
109
|
+
- `models` (*string[]*): 精确的 `provider/model-id` 模型白名单。只有列表中的模型在 `openai-responses` 或 `openai-codex-responses` 端点上运行时,才会使用 Toolkit Web Search。空列表表示所有模型都不启用 Toolkit Web Search。
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 核心工作原理解析
|
|
114
|
+
|
|
115
|
+
### 1. Remote Compaction v2(远端密文压缩)
|
|
116
|
+
|
|
117
|
+
摒弃了老旧且不稳定的 `POST /responses/compact` JSON 端点,采用最新 **`remote_compaction_v2`** 标准流式协议:
|
|
118
|
+
|
|
119
|
+
```http
|
|
120
|
+
POST /responses
|
|
121
|
+
Content-Type: application/json
|
|
122
|
+
|
|
123
|
+
{
|
|
124
|
+
"model": "...",
|
|
125
|
+
"input": [
|
|
126
|
+
...当前会话输入上下文,
|
|
127
|
+
{ "type": "compaction_trigger" }
|
|
128
|
+
],
|
|
129
|
+
"stream": true,
|
|
130
|
+
"store": false
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
- **校验标准**:接收 SSE 流并验证 `response.completed` 事件(状态为 `completed`),且返回且仅返回一个包含非空 `encrypted_content` 密文的 `type: "compaction"` 数据块。
|
|
135
|
+
- **无损重放机制**:密文数据完整存入 `CompactionEntry.details.compactedWindow`。在后续对话中,插件会自动将密文插入在最新的系统指令之后与最新几轮消息之前,实现完全服务端无损上下文还原。
|
|
136
|
+
- **三级优雅降级**:
|
|
137
|
+
1. 支持的 Responses 端点 → 触发 Remote v2 密文无损压缩;
|
|
138
|
+
2. 网关不支持或报错 → 降级调用用户指定的 `compaction.model`;
|
|
139
|
+
3. 未配置降级模型 → 回退至 Pi 默认的当前模型摘要压缩。
|
|
140
|
+
|
|
141
|
+
### 2. 按模型启用的联网搜索
|
|
142
|
+
|
|
143
|
+
对于白名单中的 `openai-responses` 或 `openai-codex-responses` 模型,扩展直接拦截请求载荷:
|
|
144
|
+
|
|
145
|
+
- 自动向 `tools` 注入 `{ "type": "web_search" }`;
|
|
146
|
+
- 自动向 `include` 数组追加 `web_search_call.action.sources`;
|
|
147
|
+
- 注入规范、去重的搜索引导 System Prompt;
|
|
148
|
+
- **零额外网络延迟**:复用 Pi 当前活跃的 Provider 配置、认证凭据与 Base URL;
|
|
149
|
+
- **Toolkit 接管搜索**:对于符合条件的模型,发给 Provider 的载荷会移除名为 `web_search` 的本地 Function Tool,只保留原生搜索;切换到不符合条件的模型后,会恢复该本地工具原先的 active 状态。
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 测试与验证
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# 类型检查
|
|
157
|
+
npm run typecheck
|
|
158
|
+
|
|
159
|
+
# 单元与集成测试 (Bun)
|
|
160
|
+
bun test
|
|
161
|
+
|
|
162
|
+
# Pi 冒烟测试
|
|
163
|
+
npm run test:pi
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 开源协议与致谢
|
|
169
|
+
|
|
170
|
+
- 本项目基于 **MIT 许可证** 开源,详情见 [LICENSE](./LICENSE)。
|
|
171
|
+
- 原生联网搜索特性逻辑参考并演进自 [`code-yeongyu/pi-openai-web-search`](https://github.com/code-yeongyu/pi-openai-web-search)(Commit `39643380682f02f306b0de2673ff136c45ccc2a2`)。详细版权声明与 MIT 许可授权请参阅 [NOTICE](./NOTICE)。
|
|
172
|
+
- [LINUX DO](https://linux.do/) community.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "../src/extension-runtime.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "../src/web-search/extension.ts";
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-openai-toolkit",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "OpenAI-focused Pi toolkit providing remote Responses compaction and native Web Search.",
|
|
7
|
+
"author": "awoaCrim and contributors",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/awoaCrim/pi-openai-toolkit.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/awoaCrim/pi-openai-toolkit/issues"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/awoaCrim/pi-openai-toolkit#readme",
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public",
|
|
19
|
+
"registry": "https://registry.npmjs.org/"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"pi-package",
|
|
23
|
+
"pi-extension",
|
|
24
|
+
"openai",
|
|
25
|
+
"compaction",
|
|
26
|
+
"web-search",
|
|
27
|
+
"codex",
|
|
28
|
+
"responses"
|
|
29
|
+
],
|
|
30
|
+
"pi": {
|
|
31
|
+
"extensions": [
|
|
32
|
+
"./extensions/compaction.ts",
|
|
33
|
+
"./extensions/web-search.ts"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"extensions/compaction.ts",
|
|
38
|
+
"extensions/web-search.ts",
|
|
39
|
+
"src/compact-client.ts",
|
|
40
|
+
"src/config.ts",
|
|
41
|
+
"src/debug.ts",
|
|
42
|
+
"src/details-store.ts",
|
|
43
|
+
"src/extension-runtime.ts",
|
|
44
|
+
"src/native-fallback.ts",
|
|
45
|
+
"src/payload-rewrite.ts",
|
|
46
|
+
"src/provider-headers.ts",
|
|
47
|
+
"src/remote-v2-client.ts",
|
|
48
|
+
"src/request-context-cache.ts",
|
|
49
|
+
"src/runtime.ts",
|
|
50
|
+
"src/serializer.ts",
|
|
51
|
+
"src/supported-environment.ts",
|
|
52
|
+
"src/types.ts",
|
|
53
|
+
"src/web-search/extension.ts",
|
|
54
|
+
"src/web-search/payload.ts",
|
|
55
|
+
"src/web-search/prompt.ts",
|
|
56
|
+
"src/web-search/types.ts",
|
|
57
|
+
"README.md",
|
|
58
|
+
"README_zh.md",
|
|
59
|
+
"LICENSE",
|
|
60
|
+
"NOTICE",
|
|
61
|
+
"tsconfig.check.json"
|
|
62
|
+
],
|
|
63
|
+
"scripts": {
|
|
64
|
+
"test": "bun test",
|
|
65
|
+
"test:coverage": "bun test --coverage --coverage-reporter=text --coverage-reporter=lcov && node ./scripts/check-lcov.mjs ./coverage/lcov.info",
|
|
66
|
+
"test:pi": "bun test ./test/pi-smoke.test.ts",
|
|
67
|
+
"typecheck": "tsc -p tsconfig.check.json"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"@earendil-works/pi-agent-core": "*",
|
|
71
|
+
"@earendil-works/pi-ai": "*",
|
|
72
|
+
"@earendil-works/pi-coding-agent": ">=0.80.0"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@types/node": "24.12.4",
|
|
76
|
+
"bun": "1.2.23",
|
|
77
|
+
"typescript": "5.9.3"
|
|
78
|
+
}
|
|
79
|
+
}
|