pi-openai-toolkit 0.12.0 → 0.13.1

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_zh.md DELETED
@@ -1,337 +0,0 @@
1
- # pi-openai-toolkit
2
-
3
- <p align="center">
4
- <strong>专为 <a href="https://github.com/earendil-works/pi">Pi</a> 打造的 OpenAI 增强工具包:远端无损压缩 v2、原生托管联网搜索、图像生成与模型审批 Auto 模式</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.85.1)** 打造的 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
- 3. **原生图像生成** (`extensions/image-generation.ts`): 注册由 Responses 托管 `image_generation` 工具驱动的本地顺序工具,支持文生图和显式本地参考图编辑,同时避免把图像二进制写入会话历史。
18
- 4. **模型审批 Auto 模式** (`extensions/auto-mode.ts`): Pi 默认不会为工具调用弹出审批确认。Auto 模式为改变状态的工具调用加上一道审批门,由你指定的审批模型判定放行或拦截,让 Agent 不必停下来等你确认也能继续推进。
19
- 5. **Codex GPT-6 Astra 适配** (`extensions/codex-astra.ts`): 为实时请求补发 Codex 后端版本门禁头,并在 `gpt-6-astra` 上把思考档位变更改写为 `configuration_update` 会话项,换档位不再打断提示缓存。
20
-
21
- ## 安装使用
22
-
23
- 需要 **Pi >= 0.85.1** 与 **Node.js >= 22.19.0**;不再支持旧 Pi。GPT-6 Astra 的模型目录、OpenAI API Key 和 Codex 订阅登录由 Pi 提供,Toolkit 不重复实现登录流程。
24
-
25
- ### 全局安装已发布版本(推荐)
26
-
27
- ```bash
28
- pi install npm:pi-openai-toolkit
29
- ```
30
-
31
- 该命令会把工具包加入 Pi 的全局配置。可以使用以下命令确认安装成功:
32
-
33
- ```bash
34
- pi list
35
- ```
36
-
37
- 如果只想安装到当前项目,使用:
38
-
39
- ```bash
40
- pi install npm:pi-openai-toolkit --local
41
- ```
42
-
43
- ### Git 安装(替代 / 开发路径)
44
-
45
- ```bash
46
- pi install git:github.com/awoaCrim/pi-openai-toolkit
47
- ```
48
-
49
- ### 本地开发与调试加载
50
-
51
- 加载完整工具包:
52
-
53
- ```bash
54
- pi --no-extensions -e /本地绝对路径/pi-openai-toolkit
55
- ```
56
-
57
- 或单独加载某一子扩展:
58
-
59
- ```bash
60
- # 仅加载远端压缩
61
- pi --no-extensions -e /本地绝对路径/pi-openai-toolkit/extensions/compaction.ts
62
-
63
- # 仅加载原生联网搜索
64
- pi --no-extensions -e /本地绝对路径/pi-openai-toolkit/extensions/web-search.ts
65
-
66
- # 仅加载原生图像生成
67
- pi --no-extensions -e /本地绝对路径/pi-openai-toolkit/extensions/image-generation.ts
68
-
69
- # 仅加载 Auto 模式
70
- pi --no-extensions -e /本地绝对路径/pi-openai-toolkit/extensions/auto-mode.ts
71
-
72
- # 仅加载 Codex Astra 适配
73
- pi --no-extensions -e /本地绝对路径/pi-openai-toolkit/extensions/codex-astra.ts
74
- ```
75
-
76
- > ⚠️ **冲突提示**:请勿同时启用 `pi-remote-compact`、`@lll9p/pi-better-compaction` 或独立的 `pi-openai-web-search`。多重钩子会产生竞态或注入重复的 System Prompt。
77
-
78
- ---
79
-
80
- ## 配置文件说明
81
-
82
- 全局唯一配置路径:
83
-
84
- ```text
85
- ~/.pi/agent/extensions/pi-openai-toolkit/config.json
86
- ```
87
-
88
- Windows 下对应:
89
-
90
- ```text
91
- C:\Users\<user>\.pi\agent\extensions\pi-openai-toolkit\config.json
92
- ```
93
-
94
- ### 配置示例
95
-
96
- ```json
97
- {
98
- "compaction": {
99
- "enabled": true,
100
- "allowCompactionContinuityBreak": false,
101
- "remoteCompactModel": "uwoacrimson/gpt-5.6-luna",
102
- "nativeFallback": {
103
- "enabled": true,
104
- "model": null,
105
- "thinkingLevel": "off"
106
- },
107
- "responsesApis": [
108
- "openai-responses",
109
- "openai-codex-responses"
110
- ],
111
- "notifyOnLoad": false,
112
- "debug": false,
113
- "logProviderPayloads": false,
114
- "logCompactResponses": false,
115
- "redactSensitiveData": true,
116
- "artifactRoot": "~/.pi/agent/artifacts/pi-openai-toolkit/compaction"
117
- },
118
- "webSearch": {
119
- "enabled": true,
120
- "models": [
121
- "uwoacrimson/gpt-5.6-luna"
122
- ]
123
- },
124
- "imageGeneration": {
125
- "enabled": false
126
- },
127
- "autoMode": {
128
- "enabled": true,
129
- "models": [
130
- "uwoacrimson/gpt-5.6-luna"
131
- ],
132
- "reviewerModel": "uwoacrimson/gpt-5.6-sol",
133
- "gate": "side-effect",
134
- "extraTools": [
135
- "openai_generate_image"
136
- ],
137
- "timeoutMs": 30000,
138
- "transcript": true,
139
- "evidenceTools": true,
140
- "maxEvidenceRounds": 3,
141
- "classifier": {
142
- "enabled": false,
143
- "model": "uwoacrimson/gpt-5.6-luna",
144
- "timeoutMs": 15000,
145
- "maxLag": 2
146
- },
147
- "circuitBreaker": {
148
- "consecutiveDenials": 3,
149
- "recentDenials": 10,
150
- "windowSize": 50
151
- }
152
- },
153
- "codexAstra": {
154
- "enabled": true,
155
- "models": [
156
- "openai-codex/gpt-6-astra"
157
- ]
158
- }
159
- }
160
- ```
161
-
162
- ### 配置参数详解
163
-
164
- #### `compaction`(压缩配置)
165
-
166
- - `enabled` (*boolean*, 默认 `true`): 是否启用远端无损压缩。
167
- - `allowCompactionContinuityBreak` (*boolean*, 默认 `false`): 若最近一次历史压缩由其他方式(如文本摘要)生成,设为 `true` 允许直接从当前有效文本上下文重建密文压缩链。
168
- - `remoteCompactModel` (*string | null*, 默认 `null`): 仅用于 synthetic `remote_compaction_v2` 请求的模型,格式为 `"provider/model-id"`。Pi 不会切换当前会话模型,压缩完成后仍由原模型继续正常请求。覆盖模型必须与当前模型使用相同的实际生效 Base URL;Provider、Responses API 标识符和模型本身可以不同。为 `null` 时保持当前模型执行远端压缩的原有行为。
169
- - `nativeFallback.enabled` (*boolean*, 默认 `true`): Toolkit 用显式摘要模型跑原生压缩的总开关。它不影响远端链路:`remote_compaction_v2` 照常被尝试,成功时照常生效。设为 `false` 只跳过失败后的那一步原生压缩,因此所有降级都直接交给 Pi 默认的当前模型压缩。
170
- - `nativeFallback.model` (*string | null*, 默认 `null`): 摘要模型,格式为 `"provider/model-id"`(例如 `"openai/gpt-4o-mini"`),**仅**用于根本无法走远端 v2 的当前模型(非 Responses API,或 API 被 `responsesApis` 排除)。远端请求已经发出过的情境不会读这个字段;为 `null` 时由当前活动模型走 Pi 默认压缩路径。
171
- - `nativeFallback.thinkingLevel` (*string*, 默认 `"off"`): 由本扩展指定模型时,传给 Pi 原生 `compact()` 的思考级别。
172
- - `responsesApis` (*string[]*): 允许尝试远端压缩的 API 标识符子集(从 `["openai-responses", "openai-codex-responses"]` 中选定)。
173
- - `notifyOnLoad` (*boolean*, 默认 `false`): Pi 启动加载时是否弹出气泡提示。
174
- - `debug` (*boolean*, 默认 `false`): 是否开启调试模式并记录诊断日志。
175
- - `logProviderPayloads` / `logCompactResponses` (*boolean*, 默认 `false`): 是否在 Artifacts 中记录完整的 Provider 请求与 SSE 流事件体。
176
- - `redactSensitiveData` (*boolean*, 默认 `true`): 对调试日志应用完整的敏感值脱敏。即使设为 `false`,Authorization 凭据、API Key/Token 和 `encrypted_content` 密文也始终会被替换为 `[REDACTED]`。
177
- - `artifactRoot` (*string*): 诊断日志存储根目录,支持 `~/` 路径。
178
-
179
- #### `webSearch`(联网搜索配置)
180
-
181
- - `enabled` (*boolean*, 默认 `true`): 是否启用原生 OpenAI 联网搜索注入。
182
- - `models` (*string[]*): 精确的 `provider/model-id` 模型白名单。只有列表中的模型在 `openai-responses` 或 `openai-codex-responses` 端点上运行时,才会使用 Toolkit Web Search。空列表表示所有模型都不启用 Toolkit Web Search。
183
-
184
- #### `imageGeneration`(图像生成配置)
185
-
186
- - `enabled` (*boolean*, 默认 `false`): 本地工具 `openai_generate_image` 的唯一开关。默认关闭是因为每一次成功的 Provider 请求都可能产生费用。
187
-
188
- 这里没有模型白名单:托管 `image_generation` 是 Responses API 的能力,不属于某个厂商的特定模型。`enabled: true` 后,所有 API 为 `openai-responses` 或 `openai-codex-responses` 的当前模型都会拿到这个工具,其他 API 则完全看不到。联网搜索和压缩仍保留各自的模型白名单。
189
-
190
- 请求复用当前模型解析后的 Responses 端点、认证和请求头,托管图像工具固定使用 `gpt-image-2`;Pi 不会切换当前会话模型。不支持托管图像工具的网关仍会注册该工具,并在调用时返回有界错误;发送后不会自动重试。
191
-
192
- #### `autoMode`(Auto 模式配置)
193
-
194
- - `enabled` (*boolean*, 默认 `true`): 总开关。即使为 `true`,在未配置模型白名单和审批模型之前,Auto 模式仍然无法启用。
195
- - `models` (*string[]*, 默认 `[]`): 允许以 Auto 模式运行的**当前会话模型**精确 `provider/model-id` 白名单。空列表表示任何模型都无法使用 Auto 模式。
196
- - `reviewerModel` (*string | null*, 默认 `null`): 执行审批的模型,格式为 `"provider/model-id"`。它通过 Pi 的模型注册表解析且必须存在,仅用于一次性审批请求,不会成为当前会话模型。未设置时 Auto 模式无法启用。
197
- - `gate` (*`"side-effect" | "all"`*, 默认 `"side-effect"`): `side-effect` 只审批 `bash`、`write`、`edit`;`all` 审批包括只读工具在内的全部工具调用。
198
- - `extraTools` (*string[]*, 默认 `[]`): 在 `side-effect` 默认集之上额外审批的工具名,例如 `openai_generate_image` 或某个 MCP 工具名。
199
- - `timeoutMs` (*整数*, 默认 `30000`,范围 `1000`–`120000`): 审批模型所有轮次共用的总超时。超时永远不会被当作放行。
200
- - `transcript` (*boolean*, 默认 `true`): 给审批模型一份有界的会话上下文。关掉后它只能判断动作本身的风险,用户授权程度只能记为 `unknown`。
201
- - `evidenceTools` (*boolean*, 默认 `true`): 允许审批模型在结论之前调用只读工具(`read`、`grep`、`find`、`ls`)自己取证据。这些工具由本扩展执行;审批模型永远拿不到 `bash`、写入类工具或网络访问。
202
- - `maxEvidenceRounds` (*整数*, 默认 `3`,范围 `0`–`8`): 最多允许几轮取证,超过就必须给结论。设为 `0` 完全关闭工具,回到单次补全。
203
- - `classifier.enabled` (*boolean*, 默认 `false`): 是否启用非阻塞的轨迹预评分。开启后一个新鲜的 `low` 分数可以直接满足下一次受控调用,不必等完整审批。默认关闭是因为每个受控工具结果都会多一次模型调用。
204
- - `classifier.model` (*string | null*): 预评分模型,格式 `provider/model-id`,未设置时沿用 `reviewerModel`。预评分只能把调用退回阻塞审批;除了缓存的 `low` 快速通道之外它无权放行,也永不拒绝。
205
- - `classifier.timeoutMs` (*整数*, 默认 `15000`) 与 `classifier.maxLag` (*整数*, 默认 `2`,范围 `0`–`20`): 经过超过 `maxLag` 个工具调用、或用户又说了新话之后,分数作废并强制走阻塞审批。
206
- - `circuitBreaker.consecutiveDenials` (*整数*, 默认 `3`,`0` 关闭): 单轮内连续拒绝多少次就直接结束这一轮,而不是让主模型无限拉锯。
207
- - `circuitBreaker.recentDenials` (*整数*, 默认 `10`,`0` 关闭) 与 `circuitBreaker.windowSize` (*整数*, 默认 `50`,范围 `1`–`200`): 最近 N 次受审调用里拒绝多少次就结束这一轮。它抓的是没有连续出现但密度很高的拒绝。
208
-
209
- Auto 模式需要显式启用(`models` 默认为空),因为它相当于允许一个模型代你批准文件写入和命令执行。会话内可用 `pi --auto` 或 `/auto on` 开启,`/auto all` 一次审批全部工具。具体判定与降级规则见「核心工作原理解析」第 5 节。
210
-
211
- #### `codexAstra`(Codex GPT-6 Astra 适配配置)
212
-
213
- - `enabled` (*boolean*, 默认 `false`): Astra 适配层总开关:实时请求的版本门禁头,以及「核心工作原理解析」第 6 节描述的 stable-effort 改写。
214
- - `models` (*string[]*, 默认 `[]`): 接受 `configuration_update` 会话项的精确 `provider/model-id` 白名单。只有 Astra 世代模型能正确响应它(目前 `["openai-codex/gpt-6-astra"]`,或网关上对应的键如 `"uwoacrimson/gpt-6-astra"`);其他模型绝不会被改写。版本门禁头则对所有 `openai-codex-responses` 实时请求生效,不受这个列表限制。
215
-
216
- ---
217
-
218
- ## 核心工作原理解析
219
-
220
- ### 1. Remote Compaction v2(远端密文压缩)
221
-
222
- 摒弃了老旧且不稳定的 `POST /responses/compact` JSON 端点,采用最新 **`remote_compaction_v2`** 标准流式协议:
223
-
224
- ```http
225
- POST /responses
226
- Content-Type: application/json
227
-
228
- {
229
- "model": "...",
230
- "input": [
231
- ...当前会话输入上下文,
232
- { "type": "compaction_trigger" }
233
- ],
234
- "stream": true,
235
- "store": false
236
- }
237
- ```
238
-
239
- - **校验标准**:接收 SSE 流并验证 `response.completed` 事件(状态为 `completed`),且返回且仅返回一个包含非空 `encrypted_content` 密文的 `type: "compaction"` 数据块。
240
- - **远端压缩模型覆盖**:`compaction.remoteCompactModel` 可以让同一网关上的另一个 Responses 模型负责生成 checkpoint,而当前活动模型仍是 checkpoint 的消费者。synthetic 压缩请求会使用覆盖模型在注册表中的模型元数据、认证、请求头和实际 Base URL;旧 checkpoint、递归压缩 checkpoint 都仍由当前活动模型重放。
241
- - **无损重放机制**:密文数据完整存入 `CompactionEntry.details.compactedWindow`。在后续对话中,插件会自动将密文插入在最新的系统指令之后与最新几轮消息之前,实现完全服务端无损上下文还原。
242
- - **重放失败保护(Fail-Closed)**:重放以 Pi 生成的 compaction summary 哨兵为内容锚点,将其替换为密文压缩窗口;压缩后的其余上下文一律原样保留,因此其他扩展注入的临时消息不再阻断重放。若找不到哨兵锚点,插件会中止 provider 请求、弹出错误通知,并且即使 `logProviderPayloads` 关闭也会写入一份不含内容的安全失败记录 `*-replay-failure.json`。只含哨兵占位符的请求体永远不会发送给模型。
243
- - **三级优雅降级**:
244
- 1. 支持的 Responses 端点 &rarr; 触发 Remote v2 密文无损压缩;
245
- 2. 本可以远端压缩但网关报错或失败 &rarr; 用 `remoteCompactModel` 跑 Pi 原生 `compact()`,未配置覆盖模型则由当前活动模型执行;
246
- 3. 根本无法走远端的模型 &rarr; 用 `compaction.nativeFallback.model` 跑 Pi 原生 `compact()`,未配置则由当前活动模型执行;
247
-
248
- ### 2. Pi 原生自动压缩与续跑
249
-
250
- 自动压缩完全由 **Pi 0.85.1+** 管理。Pi 在工具结果写入后、下一次 assistant 请求前检查上下文阈值,符合条件时在同一次运行中压缩并继续。Toolkit 只通过公共 Hook 提供 Remote v2 结果和密文回放,不安装私有补丁、不额外触发压缩,也不发送隐藏续跑消息。
251
-
252
- - 在 Pi 的 `~/.pi/agent/settings.json` 或项目 `.pi/settings.json` 中配置 `compaction.enabled`、`compaction.reserveTokens` 和 `compaction.keepRecentTokens`。
253
- - Pi 关闭自动压缩或没有可压缩历史时,Toolkit 不另开一套驱动;手动 `/compact` 仍使用原有远端/原生降级链路。
254
- - Toolkit 配置中的旧 `compaction.autoCompaction` 已移除;旧键会按未知字段忽略,不会修改你的配置文件。
255
- - Remote v2 已包含完整压缩输入。公共 `context` Hook 在编码前移除能确认已被 checkpoint 覆盖的近期消息副本;会话存档不变,压缩后的新消息和临时注入内容保留。
256
- - 缓存参数遵循 Pi 的实际选择:适用的 GPT-5.6+ 长缓存保留 `prompt_cache_options.ttl: "30m"`,这些模型关闭缓存时保留 `mode: "explicit"`,不会对所有请求强制开启长缓存。不同压缩模型只接收其支持的参数。
257
-
258
- ### 3. 按模型启用的联网搜索
259
-
260
- 对于白名单中的 `openai-responses` 或 `openai-codex-responses` 模型,扩展直接拦截请求载荷:
261
-
262
- - 自动向 `tools` 注入 `{ "type": "web_search" }`;
263
- - 自动向 `include` 数组追加 `web_search_call.action.sources`;
264
- - 注入规范、去重的搜索引导 System Prompt;
265
- - **零额外网络延迟**:复用 Pi 当前活跃的 Provider 配置、认证凭据与 Base URL;
266
- - **Toolkit 接管搜索**:对于符合条件的模型,发给 Provider 的载荷会移除名为 `web_search` 的本地 Function Tool,只保留原生搜索;切换到不符合条件的模型后,会恢复该本地工具原先的 active 状态。
267
-
268
- ### 4. 原生图像生成与编辑
269
-
270
- 当 `imageGeneration.enabled` 为 `true` 且当前模型走 Responses API 时,Pi 会启用顺序工具 `openai_generate_image`:
271
-
272
- - **隔离请求**:仅发送一次非流式、`store: false` 的 Responses 请求,请求体只包含图像提示词和用户显式批准的参考图,不会附带最近会话历史;发送后不自动重试,避免重复计费。
273
- - **生成与编辑**:支持文生图,或使用 1–5 个显式指定的本地 PNG、JPEG、WebP 文件编辑。上传参考图前必须经过交互确认;Headless 会话拒绝上传参考图。
274
- - **复用当前路由,固定图像模型**:使用当前模型实际生效的 Base URL、认证和 Provider 请求头,但托管图像工具固定请求 `gpt-image-2`。不会走独立 Codex OAuth,也不会切换 Pi 当前模型。
275
- - **PNG Artifact**:校验返回的 PNG,并保存到 `<Pi agent dir>/generated-images/<session-id>/<image-call-id>.png`,绝不覆盖已有文件。
276
- - **安全的可选副本**:相对输出路径只允许写入可信项目;同时位于可信项目和 Pi Agent 目录之外的路径必须交互确认。仅支持 PNG,已有目标文件会被拒绝。
277
- - **紧凑会话数据**:工具结果只包含路径和有界元数据,不包含图像 Base64。终端支持图像显示时,Pi TUI 会从规范 Artifact 路径读取预览;删除 Artifact 后预览随即消失。显式参考路径字符串仍属于工具调用参数,但参考图字节不会写入会话。
278
- - **Headless 行为**:不带参考图并使用默认 Artifact 路径的文生图可在无 UI 环境运行;需要确认的参考图上传和外部输出路径会在 Headless 会话中被拒绝。
279
- - **计费与验证边界**:实际计费以配置的 Gateway/Provider 为准,工具不会自行构造 Pi usage/cost 元数据。确定性测试和冒烟检查不会发起生图请求;未经单独明确批准,也不会执行真实付费探针。
280
-
281
- ### 5. 模型审批的 Auto 模式
282
-
283
- Pi 本身在运行 `bash`、`write`、`edit` 前不会询问确认,内置的唯一 trust 提示只针对项目本地配置。本扩展补上这道审批门,并让审批模型来操作它,对应 Codex 的 `approval_policy` 加 `approvals_reviewer` 组合。
284
-
285
- - **开启动作不阻塞任务流**:`pi --auto`、`/auto on`、`/auto all` 只切换会话内状态并更新底部状态栏,开启时不会发起任何 Provider 请求。
286
- - **审批范围**:`side-effect` 审批 `bash`、`write`、`edit`;`extraTools` 追加工具名;`/auto all`(或 `gate: "all"`)审批全部工具调用。默认范围下只读工具直接放行。
287
- - **两个独立轴,一个推导结论**:审批模型分别给出动作本身的风险(`low`/`medium`/`high`/`critical`)和会话对它的授权程度(`unknown`/`low`/`medium`/`high`),再按固定表格推出 `allow`/`deny`:`low` 与 `medium` 风险放行,`high` 需要至少 `medium` 授权且范围窄,`critical` 一律拒绝。只问“这条命令危不危险”正是审批模型要么全部放行、要么全部拦截的原因。
288
- - **有界会话上下文**:审批模型收到的是从 Pi 会话条目重建的紧凑上下文。用户发言有自己独立的预算并优先保留,工具输出用另一份更小的预算,避免冗长命令输出挤掉真正能建立授权证据的人类发言。被省略的历史会标 `<truncated />` 而不是静默丢掉,且只有 `[user]` 条目能作为授权证据。
289
- - **审批模型可以自己取证**:`evidenceTools` 开启后,审批模型跑在一个有界的只读工具循环里(`read`、`grep`、`find`、`ls`)。它可以打开准备放行的脚本看它到底做什么、检查删除目标是否存在或为空、确认写入路径是否在项目内。这些调用由本扩展执行,审批模型永远拿不到 `bash` 与写入工具,也不会联网,这是“让裁判自己看一眼”能安全成立的前提。
290
- - **宽松结论契约**:只有结论字段是必需的。`{"outcome":"allow"}` 就是一个完整回答,风险、授权、理由由代码回填(拒绝但未说风险时按 `high` 记录,让审计往保守方向偏)。`outcome`/`rationale` 与旧的 `decision`/`reason` 两种写法都接受。解析失败是失败,不是猜测。
291
- - **不可信证据保持不可信**:工具参数、上下文文本、文件内容都标记为数据。其中出现的“用户已经同意过”、“很紧急”、或要求按某种方式回答的指令,按策略一律忽略。
292
- - **可选的非阻塞预评分**:`classifier.enabled` 后,每个受控工具结果之后会跑一次单 token 的轨迹分类(`high`/`low`)。新鲜的 `low` 可以直接满足下一次受控调用;`high`、过期分数、评分失败、以及本轮被拒绝过的同一工具重试,全部退回阻塞审批。预评分自己永不拒绝。
293
- - **拒绝带反规避条款**:拦截时会把风险等级、授权程度、理由一起返回给主模型,并附上明确禁止:不得通过变通、改名、拆分命令或间接执行达成同一结果。它只能换实质更安全的方案,或者来问你。
294
- - **没跑完的审批不是安全结论**:超时、取消、Provider 报错、输出不合法各自上报 cause,并告诉主模型不要因为这个失败就推断动作不安全。只有真正的 `deny` 才会被表述为拒绝。
295
- - **拒绝熔断器**:单轮内反复被拒会直接结束这一轮,而不是让主模型和审批模型无限拉锯;连续次数和滑动窗口内的拒绝密度两个条件都会触发。`turn_start` 会清空计数。
296
- - **降级人工确认**:交互会话中审批不可用时,扩展会带着失败原因直接问你;而 `-p` 与 JSON 模式无人可问,因此 fail-closed 直接拦截。
297
- - **实时重新校验资格**:切到 `autoMode.models` 之外的模型、清空 `reviewerModel` 或设 `enabled: false` 会立即退出 Auto 模式;切回白名单模型不会自动恢复,必须重新 `/auto on`。
298
- - **有界审计记录**:每次判定都以自定义会话条目(`pi-openai-toolkit.auto-mode-decision.v1`)落盘,包含工具名、调用 id、结论、有界理由、审批模型、风险等级、用户授权程度、取证轮数,以及判定来源(`reviewer`、`classifier`、`human`、`policy` 或 `circuit-breaker`)。自定义条目不进入 LLM 上下文,且不记录工具参数。
299
- - **费用边界**:每个受控调用至少产生一次审批补全;开启 `evidenceTools` 后,这一次审批最多可膨胀为 `maxEvidenceRounds` 轮额外补全。开启预评分时,每个受控工具结果多一次小补全。审批请求禁用提示缓存,除上述只读工具外不能执行任何操作。
300
-
301
- ### 6. Codex GPT-6 Astra 适配
302
-
303
- GPT-6 Astra 是 Codex 后端(ChatGPT OAuth)上的模型,有两个普通 OpenAI 客户端不会自动处理的线协议行为。本适配层全部覆盖,代码改写自 Oh My Pi 18.1.8(MIT)。
304
-
305
- - **后端版本门禁**:Codex 后端按 `version` 头决定放行或隐藏模型 SKU,`gpt-6-astra` 要求至少 `0.153.0`。扩展通过 `before_provider_headers` 给每条实时 `openai-codex-responses` 请求补发这个固定值(host 已设置时不覆盖);本包自己的合成请求(远端 v2、原生 v1、托管图像)由共享头构造器携带同一固定值。这个常量跟随上游 `CODEX_CLIENT_VERSION`:OpenAI 提高门禁时,改的就是它。
306
- - **stable effort + `configuration_update`**:OpenAI 提示缓存从请求第一个字节开始比对,而请求级 `reasoning.effort` 就在头部——中途换思考档位通常会打爆整个缓存前缀。Astra 接受一种 `configuration_update` 输入项,从该项位置起改档位而不动请求级字段。本扩展把这套机制接到当前会话:首个请求钉住基线档位,之后的每次变更插入到它应生效的会话位置(作效于哪条用户消息就插在哪条之前,工具循环中途变更插在最近一条工具结果之后),后续请求在同一位置重放该项,请求体开头始终字节不变,缓存前缀存活。
307
- - **历史重写安全**:每个插入项都锚定在它所在位置前一条内容的指纹上。后续请求的历史对不上(压缩、切分支、`/clear`,任何历史重写),基线直接作废,下一次请求用自己的档位重新钉基线,而不是把更新插到过期位置。
308
- - **压缩隔离**:compact 端点拒绝含 `configuration_update` 的历史。两层防御:payload 改写器对带 `compaction_trigger` 的请求绝不插入;两个压缩客户端对回放输入里的该类项一律防御性剥离——所以 Astra 会话照常被本包压缩。
309
- - **适用范围**:改写只作用于两种 Responses 线协议家族内 `codexAstra.models` 白名单中的模型(目前已知只有 astra 接受该 item,其他模型碰它就 400——网关代理同一模型时,白名单就是声明这件事的地方),且只改真正携带线上级 effort 的请求,`off`/`none` 不动。网关透传已实测:插在生效用户消息之前的 `configuration_update` 返回 HTTP 200 且响应完整。整个钩子在 try/catch 里,任何意外形状或规划失败都原样放行请求。若 host 自身已实现同样行为(例如 Oh My Pi),两边只开一个,避免双重插入。
310
-
311
- 目录说明:Pi 内置的 `openai-codex` 模型列表还没有 `gpt-6-astra`,需要在 `~/.pi/agent/models.json` 内置 provider 下注册(自定义 models 会与内置列表合并):`api: "openai-codex-responses"`、`baseUrl: "https://chatgpt.com/backend-api"`、`contextWindow: 272000`、`maxTokens: 128000`,并用 `thinkingLevelMap` 声明 `low` 到 `max`。登录用 Pi 的 Codex OAuth 流程;本包通过 Pi 的 `ModelRegistry` 读凭据,不碰存储文件。
312
-
313
- ---
314
-
315
- ## 测试与验证
316
-
317
- ```bash
318
- # 类型检查
319
- npm run typecheck
320
-
321
- # 单元与集成测试 (Bun)
322
- bun test
323
-
324
- # Pi 冒烟测试
325
- npm run test:pi
326
-
327
- # 检查 npm 发布包内容
328
- npm pack --dry-run
329
- ```
330
-
331
- ---
332
-
333
- ## 开源协议与致谢
334
-
335
- - 本项目基于 **MIT 许可证** 开源,详情见 [LICENSE](./LICENSE)。
336
- - 原生联网搜索特性逻辑参考并演进自 [`code-yeongyu/pi-openai-web-search`](https://github.com/code-yeongyu/pi-openai-web-search)(Commit `39643380682f02f306b0de2673ff136c45ccc2a2`)。详细版权声明与 MIT 许可授权请参阅 [NOTICE](./NOTICE)。
337
- - [LINUX DO](https://linux.do/) community.