pi-openai-toolkit 0.14.3 → 0.14.5
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 +135 -175
- package/README.zh.md +135 -175
- package/docs/internals.md +73 -0
- package/extensions/auto-mode.ts +1 -1
- package/extensions/codex-astra.ts +1 -1
- package/extensions/compaction.ts +1 -1
- package/extensions/image-generation.ts +1 -1
- package/extensions/web-search.ts +1 -1
- package/package.json +127 -126
- package/src/config.ts +621 -582
- package/src/context-management/codex-provider.ts +260 -262
- package/src/context-management/history-notes.ts +325 -319
- package/src/context-management/tools.ts +5 -3
- package/src/context-management/types.ts +161 -160
- package/src/extension-runtime.ts +9 -5
- package/src/image-generation/extension.ts +19 -2
- package/src/image-generation/protocol.ts +473 -405
- package/src/image-generation/service.ts +249 -243
- package/src/image-generation/types.ts +189 -184
- package/src/responses-headers.ts +108 -108
- package/src/runtime.ts +477 -477
- package/src/types.ts +18 -0
- package/src/web-search/prompt.ts +1 -1
package/README.zh.md
CHANGED
|
@@ -1,251 +1,211 @@
|
|
|
1
1
|
# pi-openai-toolkit
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](./LICENSE)
|
|
3
|
+
为 Pi 添加 Codex 上下文窗口、Responses 压缩、托管工具和工具调用审查。
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/pi-openai-toolkit)
|
|
6
|
+
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
[
|
|
8
|
+
[英文版](README.md)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## 功能
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
| 功能 | 用途 |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| Codex 远程上下文 | 切换到新上下文窗口,并通过 `history` 按需检索较早窗口。 |
|
|
15
|
+
| 远程压缩 v2 | 使用服务端返回的加密检查点继续符合条件的 Responses 会话。 |
|
|
16
|
+
| 托管联网搜索 | 为指定模型启用 OpenAI 托管的搜索工具。 |
|
|
17
|
+
| 图像生成 | 生成图片,或根据明确传入的本地参考图片进行编辑。 |
|
|
18
|
+
| 工具调用审查 | 在指定范围的工具调用执行前,由审查模型判断是否允许执行。 |
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
本包沿用 Pi 已有的模型、认证和会话配置,不新增提供商或模型。
|
|
19
21
|
|
|
20
|
-
##
|
|
21
|
-
- [安全](#安全)
|
|
22
|
-
- [背景](#背景)
|
|
23
|
-
- [安装](#安装)
|
|
24
|
-
- [使用](#使用)
|
|
25
|
-
- [配置](#配置)
|
|
26
|
-
- [功能指南](#功能指南)
|
|
27
|
-
- [开发](#开发)
|
|
28
|
-
- [API](#api)
|
|
29
|
-
- [Remote Context 工具](#remote-context-工具)
|
|
30
|
-
- [HTTP 协议参考](#http-协议参考)
|
|
31
|
-
- [维护者](#维护者)
|
|
32
|
-
- [贡献](#贡献)
|
|
33
|
-
- [许可证](#许可证)
|
|
34
|
-
- [致谢](#致谢)
|
|
35
|
-
|
|
36
|
-
## 安全
|
|
37
|
-
|
|
38
|
-
- **覆盖模型不会有静默的有损摘要。** `contextManagement: "remote"` 覆盖某模型期间,Pi 原生压缩在阈值、手动 `/compact`、溢出全部路径上被取消,v2 也不发送。若想再加宿主级保险,在 Pi `settings.json` 设 `"compaction": { "enabled": false }`;覆盖范围外的模型照常走 Pi 自己的策略。
|
|
39
|
-
- **网关隔离。** 网关模式只转发配置的数据面 key;OAuth 令牌、account cookie、account ID 一律剥离;artifact 中凭据与不透明密文永远脱敏。
|
|
40
|
-
- **Checkpoint 门禁。** `new_context` 无法在没有本窗口成功 notes 写入、也没有用户显式 `force` 授权时丢弃未保存工作状态——Codex 官方实验特性上出现过的"后端故障 + 换窗丢状态"在此被硬拦。
|
|
41
|
-
- **计费与审批边界。** 图像生成显式开启且可能产生费用;审批请求禁用提示缓存、只授予只读工具,无 UI 会话 fail-closed。
|
|
42
|
-
|
|
43
|
-
## 背景
|
|
44
|
-
|
|
45
|
-
Pi 内置压缩会把旧轮次摘要成文本,细节随之丢失;OpenAI Codex 后端其实提供两种无损机制,普通客户端拿不到:**`remote_compaction_v2` SSE 协议**(用加密密文项替换被摘要的前缀)与实验性**上下文窗口体系**(`new_context` / `history` / `notes`,完全不做摘要地换窗)。本工具包对着真实后端实现了两者,并已在 Codex OAuth 与 Codex 兼容网关中继(NEWapi + CLIProxyAPI)上端到端验证。
|
|
46
|
-
|
|
47
|
-
来源说明:Remote Context 协议逆向自 `@howaboua/pi-codex-conversion@3.0.29`(source commit `7021ae48e8efe36a3becc5830d529696ff798e5e`);Astra 适配层移植自 Oh My Pi 18.1.8(MIT);联网搜索行为改编自 [`pi-openai-web-search`](https://github.com/code-yeongyu/pi-openai-web-search)(commit `3964338`)。完整归属见 [NOTICE](./NOTICE)。alpha 的 `history`/`notes` 端点可能随时变更,本仓库的端点与 header fixture 必须同步更新。
|
|
22
|
+
## 安装
|
|
48
23
|
|
|
49
|
-
|
|
24
|
+
需要 Pi 0.85.1 或更高版本,以及 Node.js 22.19.0 或更高版本。
|
|
50
25
|
|
|
51
|
-
|
|
26
|
+
安装扩展:
|
|
52
27
|
|
|
53
28
|
```bash
|
|
54
29
|
pi install npm:pi-openai-toolkit
|
|
55
30
|
```
|
|
56
31
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
pi install npm:pi-openai-toolkit --local
|
|
61
|
-
```
|
|
32
|
+
在当前项目中安装时,在命令后加上 `--local`。
|
|
62
33
|
|
|
63
|
-
|
|
34
|
+
只安装扩展不会自动启用所有功能。没有扩展配置时,压缩模块处于开启状态,但远程上下文关闭,联网搜索没有目标模型,图像生成关闭,自动模式也没有允许的模型和审查模型。
|
|
64
35
|
|
|
65
|
-
|
|
66
|
-
pi install git:github.com/awoaCrim/pi-openai-toolkit
|
|
67
|
-
```
|
|
36
|
+
扩展配置文件位于:
|
|
68
37
|
|
|
69
|
-
|
|
38
|
+
`~/.pi/agent/extensions/pi-openai-toolkit/config.json`
|
|
70
39
|
|
|
71
|
-
|
|
40
|
+
下文除 `models.json` 示例外,其他 JSON 配置示例都写入此文件。文件不存在时,创建文件及所需目录;已有配置时,将字段合并到对应对象中,保留其他设置。
|
|
72
41
|
|
|
73
|
-
|
|
42
|
+
## 快速开始:启用远程上下文
|
|
74
43
|
|
|
75
|
-
|
|
44
|
+
本节适用于想使用 Codex 风格上下文窗口的用户。如果只需要联网搜索、图像生成或工具调用审查,请直接跳到[常见用法](#常见用法)。
|
|
76
45
|
|
|
77
|
-
|
|
46
|
+
### 使用 Pi 内置的 Codex 提供商
|
|
78
47
|
|
|
79
|
-
|
|
48
|
+
你需要先登录 Pi 内置的 `openai-codex` 提供商。
|
|
80
49
|
|
|
81
|
-
|
|
50
|
+
创建或合并扩展配置:
|
|
82
51
|
|
|
83
52
|
```json
|
|
84
53
|
{
|
|
85
54
|
"compaction": {
|
|
86
|
-
"
|
|
87
|
-
"contextManagement": "remote",
|
|
88
|
-
"contextReminderThresholdPercent": 10,
|
|
89
|
-
"allowCompactionContinuityBreak": false,
|
|
90
|
-
"remoteCompactModel": "uwoacrimson/gpt-5.6-luna",
|
|
91
|
-
"nativeFallback": { "enabled": true, "model": null, "thinkingLevel": "off" },
|
|
92
|
-
"responsesApis": ["openai-responses", "openai-codex-responses"],
|
|
93
|
-
"notifyOnLoad": false,
|
|
94
|
-
"debug": false,
|
|
95
|
-
"logProviderPayloads": false,
|
|
96
|
-
"logCompactResponses": false,
|
|
97
|
-
"redactSensitiveData": true,
|
|
98
|
-
"artifactRoot": "~/.pi/agent/artifacts/pi-openai-toolkit/compaction"
|
|
99
|
-
},
|
|
100
|
-
"webSearch": { "enabled": true, "models": ["uwoacrimson/gpt-5.6-luna"] },
|
|
101
|
-
"imageGeneration": { "enabled": false },
|
|
102
|
-
"autoMode": {
|
|
103
|
-
"enabled": true,
|
|
104
|
-
"models": ["uwoacrimson/gpt-5.6-luna"],
|
|
105
|
-
"reviewerModel": "uwoacrimson/gpt-5.6-luna",
|
|
106
|
-
"gate": "side-effect"
|
|
55
|
+
"contextManagement": "remote"
|
|
107
56
|
}
|
|
108
57
|
}
|
|
109
58
|
```
|
|
110
59
|
|
|
111
|
-
|
|
60
|
+
使用已有 Codex 模型目录中的模型启动 Pi:
|
|
112
61
|
|
|
113
62
|
```bash
|
|
114
|
-
pi --model
|
|
63
|
+
pi --model openai-codex/<model-id>
|
|
115
64
|
```
|
|
116
65
|
|
|
117
|
-
|
|
66
|
+
将 `<model-id>` 换成 Pi 配置中实际显示的模型 ID。会话中出现 `new_context`、`get_context_remaining`、`history` 和 `notes` 工具,说明扩展已经完成启用检查。
|
|
118
67
|
|
|
119
|
-
|
|
68
|
+
### 使用兼容网关
|
|
120
69
|
|
|
121
|
-
|
|
70
|
+
本路线要求使用 `openai-responses` 接口,并且网关保留远程上下文所需的 Codex 协议字段。普通对话请求成功,不代表已经验证远程上下文兼容性。
|
|
122
71
|
|
|
123
|
-
|
|
124
|
-
| --- | --- | --- |
|
|
125
|
-
| `enabled` | *boolean*, `true` | 压缩扩展 hook 总开关。 |
|
|
126
|
-
| `contextManagement` | `"off"` \| `"remote"`, `"off"` | 启用 Codex 远端上下文管理。覆盖模型为原生 Codex 模型,加上在 Codex 兼容网关(`openai-responses`)上的 `gpt-6-astra`;匹配规则内置,无白名单。覆盖模型由其独占:不发送 `remote_compaction_v2`,且取消 Pi 原生压缩(见[安全](#安全))。设回 `"off"` 即回滚。 |
|
|
127
|
-
| `contextReminderThresholdPercent` | *integer* `0`-`100`, `5` | 仅 Remote Context:当前窗口剩余 token 低于窗口该百分比时,每窗口注入一次 checkpoint 提醒;`0` 关闭提醒(窗口耗尽兜底仍生效)。建议明显高于 Pi 原生 reserve 余量(默认 16384 token,约为 272k 窗口的 6%),让模型在撞阈值前有机会主动换窗。 |
|
|
128
|
-
| `allowCompactionContinuityBreak` | *boolean*, `false` | v2 路径:最近一次压缩由其他方式(如文本摘要)生成时,允许从当前文本上下文重建密文链。 |
|
|
129
|
-
| `remoteCompactModel` | *string \| null*, `null` | v2 路径:仅用于 synthetic `remote_compaction_v2` 请求的模型,会话模型不切换;必须与当前模型解析出相同生效 Base URL。 |
|
|
130
|
-
| `nativeFallback.enabled` | *boolean*, `true` | 远端请求已尝试但失败时,用显式摘要模型跑 Pi 原生压缩;成功远端链路不受影响。 |
|
|
131
|
-
| `nativeFallback.model` | *string \| null*, `null` | 仅用于完全无法走 v2 的模型(非 Responses API 或被 `responsesApis` 排除);`null` 用当前模型。 |
|
|
132
|
-
| `nativeFallback.thinkingLevel` | *string*, `"off"` | 本扩展指定模型时传给 Pi `compact()` 的思考级别。 |
|
|
133
|
-
| `responsesApis` | *string[]*, 两个 API | 限定可尝试远端压缩的 API 标识符子集;仅 `contextManagement` 为 `"off"` 时生效。 |
|
|
134
|
-
| `notifyOnLoad` | *boolean*, `false` | 启动横幅通知。 |
|
|
135
|
-
| `debug` | *boolean*, `false` | 在 `artifactRoot` 下写 lifecycle 与压缩 artifact,含每次 `session_start` 的 Remote Context 激活结果与原因。 |
|
|
136
|
-
| `logProviderPayloads` / `logCompactResponses` | *boolean*, `false` | 额外把原始 provider 请求体与压缩 SSE 事件写入 artifact。除非排查特定请求,保持关闭。 |
|
|
137
|
-
| `redactSensitiveData` | *boolean*, `true` | artifact 全量脱敏;即使设为 `false`,Authorization 凭据、API Key/Token、Codex account ID 与 `encrypted_content` / `encrypted_output` 也始终脱敏。 |
|
|
138
|
-
| `artifactRoot` | *string*, `~/.pi/agent/artifacts/pi-openai-toolkit/compaction` | artifact 根目录;相对路径基于配置目录解析。 |
|
|
139
|
-
|
|
140
|
-
#### `webSearch`
|
|
141
|
-
|
|
142
|
-
| 键 | 类型 / 默认 | 说明 |
|
|
143
|
-
| --- | --- | --- |
|
|
144
|
-
| `enabled` | *boolean*, `true` | 总开关。 |
|
|
145
|
-
| `models` | *string[]*, `[]` | 接收托管 `web_search` 注入的精确白名单(限 Responses 系 API)。名单内模型的上行载荷会移除本地 `web_search` 函数工具,原生搜索成为唯一路径;切到名单外模型即恢复。 |
|
|
146
|
-
|
|
147
|
-
#### `imageGeneration`
|
|
148
|
-
|
|
149
|
-
| 键 | 类型 / 默认 | 说明 |
|
|
150
|
-
| --- | --- | --- |
|
|
151
|
-
| `enabled` | *boolean*, `false` | `openai_generate_image` 的唯一开关。默认关闭,因为每次成功请求都可能产生费用。无模型白名单:托管图像工具是 Responses API 能力,对所有 Responses 系模型暴露、其余隐藏。 |
|
|
72
|
+
如果 `~/.pi/agent/models.json` 中已有符合上述条件的网关模型,可以跳过模型配置,直接设置扩展白名单。否则,先添加或合并下面的提供商配置。请把 `my-gateway`、地址、环境变量名称和模型字段替换成实际值。示例中的数字只是示意值,不是项目默认值,必须改成符合实际模型与网关能力的上下文窗口和最大输出 token 数。
|
|
152
73
|
|
|
153
|
-
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"providers": {
|
|
77
|
+
"my-gateway": {
|
|
78
|
+
"baseUrl": "https://your-gateway.example/v1",
|
|
79
|
+
"api": "openai-responses",
|
|
80
|
+
"apiKey": "$MY_GATEWAY_KEY",
|
|
81
|
+
"models": [{
|
|
82
|
+
"id": "gpt-5.6-luna",
|
|
83
|
+
"name": "GPT-5.6 Luna",
|
|
84
|
+
"reasoning": true,
|
|
85
|
+
"input": ["text"],
|
|
86
|
+
"contextWindow": 272000,
|
|
87
|
+
"maxTokens": 128000
|
|
88
|
+
}]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
154
93
|
|
|
155
|
-
|
|
156
|
-
| --- | --- | --- |
|
|
157
|
-
| `enabled` | *boolean*, `true` | 总开关;未列入白名单或未设 `reviewerModel` 前依然无法启用。 |
|
|
158
|
-
| `models` | *string[]*, `[]` | 允许进入 auto 模式的当前会话模型白名单。 |
|
|
159
|
-
| `reviewerModel` | *string \| null*, `null` | 审批模型(`provider/model-id`,经 Pi 注册表解析)。只用于单次审批请求,绝不成为会话模型。 |
|
|
160
|
-
| `gate` | `"side-effect"` \| `"all"`, `"side-effect"` | 审批范围;`/auto all` 把当次会话扩到全部工具。 |
|
|
161
|
-
| `extraTools` | *string[]*, `[]` | 在副作用集(`bash`、`write`、`edit`)之外追加审批的工具名。 |
|
|
162
|
-
| `timeoutMs` | *integer* 1000-120000, `30000` | 审批模型全部轮次的总时限;超时绝不视为通过。 |
|
|
163
|
-
| `transcript` | *boolean*, `true` | 给审批模型有界的会话视图,使其能判断"用户是否授权"而非只看命令危险度。 |
|
|
164
|
-
| `evidenceTools` | *boolean*, `true` | 允许审批模型先用 Pi 只读工具(`read`/`grep`/`find`/`ls`)查证;它永远拿不到 `bash`、写工具或网络。 |
|
|
165
|
-
| `maxEvidenceRounds` | *integer* 0-8, `3` | 调查轮数上限;`0` 为单次补全。 |
|
|
166
|
-
| `classifier.*` | 见码内说明 | 可选非阻塞低风险预打分(`enabled` `false`、`model`、`timeoutMs` `15000`、`maxLag` `2`),只能给普通调用开快车道,绝不否决。 |
|
|
167
|
-
| `circuitBreaker.*` | — | 否决熔断(连续 `consecutiveDenials` `3` 或窗口 `windowSize` `50` 内 `recentDenials` `10` 结束回合;`0` 关闭)。 |
|
|
94
|
+
在启动 Pi 之前设置配置中引用的密钥。PowerShell 使用:
|
|
168
95
|
|
|
169
|
-
|
|
96
|
+
```powershell
|
|
97
|
+
$env:MY_GATEWAY_KEY = "replace-with-your-gateway-key"
|
|
98
|
+
```
|
|
170
99
|
|
|
171
|
-
|
|
100
|
+
POSIX shell 使用:
|
|
172
101
|
|
|
173
|
-
|
|
102
|
+
```bash
|
|
103
|
+
export MY_GATEWAY_KEY="replace-with-your-gateway-key"
|
|
104
|
+
```
|
|
174
105
|
|
|
175
|
-
|
|
106
|
+
使用同一个终端启动 Pi。创建或合并扩展配置,并确保白名单条目与提供商名称和模型 ID 完全一致:
|
|
176
107
|
|
|
177
|
-
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"compaction": {
|
|
111
|
+
"contextManagement": "remote",
|
|
112
|
+
"gatewayContextModels": ["my-gateway/gpt-5.6-luna"]
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
178
116
|
|
|
179
|
-
|
|
117
|
+
使用相同的模型标识启动 Pi:
|
|
180
118
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- **预算。** `get_context_remaining` 报告实时窗口预算;`contextReminderThresholdPercent` 控制每窗口一次的 checkpoint 提醒。
|
|
185
|
-
- **压缩独占。** 覆盖模型的全部压缩事件由本包接管:不发送 v2;即使 Remote 运行时暂时未激活也取消 Pi 原生压缩(阈值、手动 `/compact`、溢出三条路径全拦),不会有有损摘要背地里插入。未激活原因以通知呈现(`debug` 开启时同时写入 `session_start` lifecycle artifact 的 `activation` 字段),请修复该原因而非期待压缩。
|
|
119
|
+
```bash
|
|
120
|
+
pi --model my-gateway/gpt-5.6-luna
|
|
121
|
+
```
|
|
186
122
|
|
|
187
|
-
|
|
123
|
+
启用检查方式相同:会话中应该出现 `new_context`、`get_context_remaining`、`history` 和 `notes`。如果没有出现,先查看工具包通知,再检查提供商和模型字符串、接口、密钥、基础 URL 和白名单条目。
|
|
188
124
|
|
|
189
|
-
|
|
125
|
+
较早窗口的历史仍可通过 `history` 检索和读取,但不会全部自动加入当前上下文。
|
|
190
126
|
|
|
191
|
-
|
|
127
|
+
## 常见用法
|
|
192
128
|
|
|
193
|
-
|
|
129
|
+
### 使用服务端压缩继续会话
|
|
194
130
|
|
|
195
|
-
|
|
131
|
+
如果希望使用 Responses 压缩路径,就保持远程上下文关闭。远程压缩 v2 会为符合条件的 Responses 模型保存并回放加密检查点。只有在压缩请求需要使用其他模型时,才设置 `compaction.remoteCompactModel`。
|
|
196
132
|
|
|
197
|
-
|
|
133
|
+
### 启用托管联网搜索
|
|
198
134
|
|
|
199
|
-
|
|
135
|
+
在 `webSearch.models` 中填写精确的模型标识:
|
|
200
136
|
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"webSearch": {
|
|
140
|
+
"models": ["my-gateway/gpt-5.6-luna"]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
206
143
|
```
|
|
207
144
|
|
|
208
|
-
|
|
145
|
+
对于这些模型,扩展会用 OpenAI 托管的 Responses 搜索工具替代 Pi 本地的 `web_search` 工具。
|
|
209
146
|
|
|
210
|
-
|
|
147
|
+
### 生成图片
|
|
211
148
|
|
|
212
|
-
|
|
149
|
+
图像生成需要 Responses 会话,并且可能产生服务商费用。启用方式如下:
|
|
213
150
|
|
|
214
|
-
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"imageGeneration": {
|
|
154
|
+
"enabled": true,
|
|
155
|
+
"models": ["gpt-image-2.5", "grok-imagine-image-2.0"]
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
215
159
|
|
|
216
|
-
|
|
217
|
-
| --- | --- | --- |
|
|
218
|
-
| `new_context` | `{ force?: boolean }` | 换到下一窗口,不摘要。当前窗口没有成功的 notes checkpoint 时拒绝(`force` 可越过);已有换窗排队时报告 "already scheduled"。 |
|
|
219
|
-
| `get_context_remaining` | 无 | 当前窗口剩余 token 与窗口身份;尚无任何用量来源时返回 unknown。 |
|
|
220
|
-
| `history` | `{ action: "list_windows" \| "list_items" \| "read_item" \| "search_contents", ... }` | 读取既往窗口。返回的 `item_id`/窗口 ID 必须原样传递;搜索词按加密参数策略发送。 |
|
|
221
|
-
| `notes` | `{ action: "list_files_by_prefix" \| "read_file" \| "search_contents" \| "append_to_file" \| "write_file", path, text, ... }` | 跨窗口工作记忆。路径解析到会话 agent 目录下(如 `/root/notes/<file>` 或相对路径);非法路径由后端拒绝。成功的 append/write 就是满足 `new_context` 门禁的凭证。 |
|
|
160
|
+
`models` 填写嵌套 Responses `image_generation` 工具使用的裸模型 ID。列表第一项是默认模型;`openai_generate_image` 也支持通过可选的 `model` 参数在单次调用中切换,但该值必须与配置列表中的某一项完全一致。省略 `models` 时默认使用 `gpt-image-2.5`。列表为空或格式无效时会告警并回退到默认模型;如果要关闭工具,将 `enabled` 设置为 `false`。服务商或网关必须实际支持配置的生图模型。
|
|
222
161
|
|
|
223
|
-
|
|
162
|
+
`openai_generate_image` 支持文生图,也支持使用明确传入的本地参考图片进行编辑。
|
|
224
163
|
|
|
225
|
-
###
|
|
164
|
+
### 启用工具调用自动审查
|
|
226
165
|
|
|
227
|
-
|
|
166
|
+
在 `autoMode` 中设置允许使用的模型和审查模型:
|
|
228
167
|
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"autoMode": {
|
|
171
|
+
"models": ["my-gateway/gpt-5.6-luna"],
|
|
172
|
+
"reviewerModel": "my-gateway/gpt-5.6-luna"
|
|
173
|
+
}
|
|
174
|
+
}
|
|
233
175
|
```
|
|
234
176
|
|
|
235
|
-
|
|
177
|
+
在会话中使用 `/auto on`。默认的 `side-effect` 审查范围覆盖 `bash`、`write`、`edit` 和额外配置的工具。如果需要审查所有工具调用,将 `gate` 设置为 `"all"`。审查超时不会自动放行调用。
|
|
236
178
|
|
|
237
|
-
##
|
|
179
|
+
## 常用配置
|
|
238
180
|
|
|
239
|
-
|
|
181
|
+
配置文件为 `~/.pi/agent/extensions/pi-openai-toolkit/config.json`。未知键会告警后忽略。大多数模型列表必须使用精确的 `provider/model-id` 字符串,不支持通配符;`imageGeneration.models` 是例外,填写嵌套生图工具使用的裸模型 ID。
|
|
240
182
|
|
|
241
|
-
|
|
183
|
+
| 配置项 | 默认值 | 用途 |
|
|
184
|
+
| --- | --- | --- |
|
|
185
|
+
| `compaction.enabled` | `true` | 压缩功能总开关。 |
|
|
186
|
+
| `compaction.contextManagement` | `"off"` | 设置为 `"remote"` 后启用 Codex 远程上下文。 |
|
|
187
|
+
| `compaction.gatewayContextModels` | `[]` | 允许使用远程上下文的网关模型。 |
|
|
188
|
+
| `compaction.remoteCompactModel` | 未设置 | 仅用于 v2 压缩请求的可选模型。 |
|
|
189
|
+
| `compaction.contextReminderThresholdPercent` | `5` | 每个窗口触发一次提醒的剩余预算百分比。设置为 `0` 会关闭提醒和窗口耗尽兜底。 |
|
|
190
|
+
| `webSearch.models` | `[]` | 使用托管联网搜索的模型。 |
|
|
191
|
+
| `imageGeneration.enabled` | `false` | 启用 `openai_generate_image`。 |
|
|
192
|
+
| `imageGeneration.models` | `["gpt-image-2.5"]` | 裸生图模型 ID;列表第一项是默认模型。 |
|
|
193
|
+
| `autoMode.models` | `[]` | 允许使用自动模式的模型。 |
|
|
194
|
+
| `autoMode.reviewerModel` | 未设置 | 审查自动模式调用的模型。 |
|
|
195
|
+
| `autoMode.gate` | `"side-effect"` | 设置为 `"all"` 后审查所有工具调用。 |
|
|
196
|
+
| `autoMode.timeoutMs` | `30000` | 审查超时时间,单位为毫秒。 |
|
|
242
197
|
|
|
243
|
-
|
|
198
|
+
## 开发
|
|
244
199
|
|
|
245
|
-
|
|
200
|
+
在仓库根目录安装依赖后运行:
|
|
246
201
|
|
|
247
|
-
|
|
202
|
+
```bash
|
|
203
|
+
npm run typecheck # 类型检查
|
|
204
|
+
bun test # 运行测试
|
|
205
|
+
npm run test:pi # 运行 Pi 冒烟测试
|
|
206
|
+
npm pack --dry-run # 检查发布包内容
|
|
207
|
+
```
|
|
248
208
|
|
|
249
|
-
##
|
|
209
|
+
## 许可证
|
|
250
210
|
|
|
251
|
-
|
|
211
|
+
MIT © awoaCrim 与贡献者。见 [LICENSE](LICENSE) 和 [NOTICE](NOTICE)。
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Toolkit Internals
|
|
2
|
+
|
|
3
|
+
Developer-facing reference for [pi-openai-toolkit](../README.md). This is the protocol and implementation detail that the README deliberately keeps out of the user's way. If you are only installing the toolkit, you never need this page; if you are changing wire behavior, fixtures, or the compaction strategy code, start here.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Remote Context protocol](#remote-context-protocol)
|
|
8
|
+
- [Rollover lifecycle](#rollover-lifecycle)
|
|
9
|
+
- [Remote Compaction v2 wire contract](#remote-compaction-v2-wire-contract)
|
|
10
|
+
- [Artifacts and debugging](#artifacts-and-debugging)
|
|
11
|
+
- [Provenance](#provenance)
|
|
12
|
+
|
|
13
|
+
## Remote Context protocol
|
|
14
|
+
|
|
15
|
+
Internal alpha endpoints, adapted from `@howaboua/pi-codex-conversion`:
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
POST {base}/alpha/history/v2/list_windows | list_items | read_item | search_contents
|
|
19
|
+
POST {base}/alpha/notes/v2/list_files_by_prefix | read_file | search_contents | append_to_file | write_file
|
|
20
|
+
GET {base}/alpha/notes/v2/thread_hint
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Native route uses `{base} = <backend-api>/codex` with `Authorization: Bearer <oauth token>`, `ChatGPT-Account-ID`, and Codex CLI headers. Gateway route uses the configured `/v1` base with the data-plane API key, `originator: codex_cli_rs`, `X-Codex-Affinity-Scope`, and `X-Codex-Model` carrying the bare model id, never local credentials. Both set `Session-Id` / `X-Client-Request-Id` to the bounded Pi session id, `x-openai-tool-output-truncation-policy`, and `x-openai-encrypted-tool-arguments` for endpoints with encrypted parameters; encrypted results come back as `encrypted_output` and are re-encoded into later requests. These are alpha contracts: the upstream backend may change them at any time.
|
|
24
|
+
|
|
25
|
+
Search text and note bodies are sent under the encrypted-argument policy. Live model requests carry `x-codex-window-id` and `x-codex-turn-metadata` request headers derived from the active window identity.
|
|
26
|
+
|
|
27
|
+
Coverage is never inferred from model names. A native session is `provider: "openai-codex"` on api `openai-codex-responses` (any model id). A gateway session must be on api `openai-responses` and carry an exact `provider/model` key listed in `compaction.gatewayContextModels`; the list ships empty and there is no built-in gateway SKU ([src/context-management/codex-provider.ts](../src/context-management/codex-provider.ts)). Unlisted gateway models, listed or not, keep running remote compaction v2 when Remote Context declines them. The toolkit registers no provider or model with Pi; it resolves credentials and base URLs through Pi's `ModelRegistry`.
|
|
28
|
+
|
|
29
|
+
## Rollover lifecycle
|
|
30
|
+
|
|
31
|
+
The `new_context` happy path, end to end:
|
|
32
|
+
|
|
33
|
+
```mermaid
|
|
34
|
+
sequenceDiagram
|
|
35
|
+
participant Model
|
|
36
|
+
participant Toolkit
|
|
37
|
+
participant Pi
|
|
38
|
+
participant Backend
|
|
39
|
+
Model->>Toolkit: notes append_to_file (checkpoint)
|
|
40
|
+
Toolkit->>Backend: alpha notes request (encrypted args)
|
|
41
|
+
Backend-->>Toolkit: encrypted_output
|
|
42
|
+
Model->>Toolkit: new_context
|
|
43
|
+
Toolkit->>Toolkit: verify successful notes write in this window
|
|
44
|
+
Toolkit-->>Pi: window marker appended, previous window trim scheduled
|
|
45
|
+
Model->>Backend: next request with the new x-codex-window-id
|
|
46
|
+
Pi->>Toolkit: session_before_compact
|
|
47
|
+
Toolkit-->>Pi: no-summary boundary consuming the scheduled trim
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
State invariants the lifecycle code must keep honest:
|
|
51
|
+
|
|
52
|
+
- The checkpoint gate verifies a *successful* `notes` `append_to_file` / `write_file` against the persisted session branch after the latest window boundary, so it survives restarts and forks.
|
|
53
|
+
- Budget checks are skipped until the current window has produced its own assistant usage; acting on the previous window's usage anchor burns the once-per-window reminder on a false alarm.
|
|
54
|
+
- The scheduled trim is consumed exactly once, synchronously, by the first compaction attempt whose boundary window id matches. Every other compaction path (threshold without a scheduled rollover, manual `/compact`, overflow) is cancelled.
|
|
55
|
+
- A window boundary is persisted as a `codex-context-window` custom message; `session_start` replays boundaries from the branch and rebuilds identity after forks.
|
|
56
|
+
|
|
57
|
+
## Remote Compaction v2 wire contract
|
|
58
|
+
|
|
59
|
+
A `compaction_trigger` item appended to the live streaming request yields one output item of `type: "compaction"` with non-empty `encrypted_content`, stored in `CompactionEntry.details.compactedWindow`. On later requests the opaque checkpoint is replayed ahead of live turns: zero-loss, no text summary. Replay fails closed: if the summary anchor cannot be located, the request is aborted with a notification and a content-free failure artifact; the sentinel-only payload is never sent. A v2 response with a missing or empty checkpoint is never stored, and the `nativeFallback` tier is skipped: Pi's own threshold drives the next attempt, which may use `remoteCompactModel` when configured. `remoteCompactModel` must resolve to the same effective base URL as the active model.
|
|
60
|
+
|
|
61
|
+
## Artifacts and debugging
|
|
62
|
+
|
|
63
|
+
With `debug: true` the toolkit writes lifecycle and compaction artifacts under `artifactRoot` (default `~/.pi/agent/artifacts/pi-openai-toolkit/compaction`):
|
|
64
|
+
|
|
65
|
+
- each `session_start` writes a lifecycle artifact whose `activation` field records `active`, or the exact inactive reason (`tool-name-conflict`, `missing-api-key`, `auth-resolution-failed`, `model-not-covered`, ...);
|
|
66
|
+
- `logProviderPayloads` additionally writes raw provider request payloads, `logCompactResponses` the compact SSE bodies; keep both off unless inspecting a specific request;
|
|
67
|
+
- artifacts always redact Authorization credentials, API keys/tokens, Codex account ids, and opaque `encrypted_content` / `encrypted_output`, even with `redactSensitiveData: false`.
|
|
68
|
+
|
|
69
|
+
## Provenance
|
|
70
|
+
|
|
71
|
+
The Remote Context protocol was reverse-engineered from `@howaboua/pi-codex-conversion@3.0.29` (source commit `7021ae48e8efe36a3becc5830d529696ff798e5e`). The Astra compatibility layer is adapted from Oh My Pi 18.1.8 (MIT). Web Search behavior was adapted from [`pi-openai-web-search`](https://github.com/code-yeongyu/pi-openai-web-search) (commit `3964338`). Attribution details are in [NOTICE](../NOTICE).
|
|
72
|
+
|
|
73
|
+
Protocol fixtures live in [src/context-management/](../src/context-management/) and must be updated together with any upstream alpha endpoint change; fixture-based tests are required for new wire behavior.
|
package/extensions/auto-mode.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "../src/auto-mode/extension.ts";
|
|
1
|
+
export { default } from "../src/auto-mode/extension.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "../src/codex-astra/extension.ts";
|
|
1
|
+
export { default } from "../src/codex-astra/extension.ts";
|
package/extensions/compaction.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "../src/extension-runtime.ts";
|
|
1
|
+
export { default } from "../src/extension-runtime.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "../src/image-generation/extension.ts";
|
|
1
|
+
export { default } from "../src/image-generation/extension.ts";
|
package/extensions/web-search.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "../src/web-search/extension.ts";
|
|
1
|
+
export { default } from "../src/web-search/extension.ts";
|