pi-openai-toolkit 0.14.12 → 0.15.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/README.zh.md CHANGED
@@ -11,11 +11,11 @@
11
11
 
12
12
  | 功能 | 用途 |
13
13
  | --- | --- |
14
- | Codex 远程上下文 | 切换到新上下文窗口,并通过 `history` 按需检索较早窗口。 |
14
+ | Codex 远程上下文 | 使用适配的 Codex 窗口协议切换上下文窗口,并通过 `history` 检索较早窗口。 |
15
15
  | 远程压缩 v2 | 使用服务端返回的加密检查点继续符合条件的 Responses 会话。 |
16
- | 联网搜索路由 | 按精确模型路由选择本地 `pi-web-access`、Responses 托管 `web_search` 或 CPA standalone `web.run`。 |
17
- | 图像生成 | 生成图片,或根据明确传入的本地参考图片进行编辑。 |
18
- | 工具调用审查 | 在指定范围的工具调用执行前,由审查模型判断是否允许执行。 |
16
+ | 联网搜索路由 | 按精确模型选择本地 `pi-web-access`、Responses 托管 `web_search` 或实验性的 CPA 独立 `web_run`。 |
17
+ | 图像生成 | 调用 Responses 托管生图工具生成图片,或编辑明确传入的本地参考图片。 |
18
+ | 工具调用审查 | 使用 Toolkit 的审批门禁,由审查模型判断指定工具调用是否可以执行。 |
19
19
 
20
20
  本包沿用 Pi 已有的模型、认证和会话配置,不新增提供商或模型。
21
21
 
@@ -23,36 +23,33 @@
23
23
 
24
24
  需要 Pi 0.85.1 或更高版本,以及 Node.js 22.19.0 或更高版本。
25
25
 
26
- 安装扩展:
27
-
28
26
  ```bash
29
27
  pi install npm:pi-openai-toolkit
30
28
  ```
31
29
 
32
- 在当前项目中安装时,在命令后加上 `--local`。
30
+ 在当前项目中安装扩展时加上 `--local`。Toolkit 策略仍然只使用全局配置,不支持项目配置或环境变量策略覆盖。
33
31
 
34
- 只安装扩展不会自动启用所有功能。没有扩展配置时,压缩模块处于开启状态,但远程上下文关闭,联网搜索没有工具包选择的路由,图像生成关闭,自动模式也没有允许的模型和审查模型。
32
+ 没有配置文件时,符合条件的模型启用远程压缩 v2,远程上下文窗口关闭,搜索不由 Toolkit 管理,图像生成关闭,自动模式不可用。这些默认值不表示后端能力已经验证。
35
33
 
36
- 扩展配置文件位于:
34
+ Toolkit 唯一的配置文件是:
37
35
 
38
36
  `~/.pi/agent/extensions/pi-openai-toolkit/config.json`
39
37
 
40
- 下文除 `models.json` 示例外,其他 JSON 配置示例都写入此文件。文件不存在时,创建文件及所需目录;已有配置时,将字段合并到对应对象中,保留其他设置。
38
+ 下文除 Pi 模型注册示例外,其他 JSON 示例均使用**配置格式 v2**。文件不存在时,创建文件及所需目录;已有 v2 配置时,将示例合并到对应对象并保留其他设置。无版本号的旧格式仍受支持,请勿直接加入 v2 字段,也不要用示例覆盖原文件。先运行 `/toolkit-config migration-preview`;[配置参考](docs/configuration.md)说明了审查和已安装版本检查要求。读取配置和预览迁移都不会改写源文件。
41
39
 
42
40
  ## 快速开始:启用远程上下文
43
41
 
44
- 本节适用于想使用 Codex 风格上下文窗口的用户。如果只需要联网搜索、图像生成或工具调用审查,请直接跳到[常见用法](#常见用法)。
42
+ 本节适用于想使用 Codex 风格上下文窗口的用户。如果只需要搜索、生图或工具调用审查,请跳到[常见用法](#常见用法)。
45
43
 
46
44
  ### 使用 Pi 内置的 Codex 提供商
47
45
 
48
- 你需要先登录 Pi 内置的 `openai-codex` 提供商。
49
-
50
- 创建或合并扩展配置:
46
+ 你需要先登录 Pi 内置的 `openai-codex` 提供商。创建或合并以下 v2 Toolkit 配置:
51
47
 
52
48
  ```json
53
49
  {
54
- "compaction": {
55
- "contextManagement": "remote"
50
+ "schemaVersion": 2,
51
+ "defaults": {
52
+ "context": { "mode": "remote-windows" }
56
53
  }
57
54
  }
58
55
  ```
@@ -63,13 +60,13 @@ pi install npm:pi-openai-toolkit
63
60
  pi --model openai-codex/<model-id>
64
61
  ```
65
62
 
66
- 将 `<model-id>` 换成 Pi 配置中实际显示的模型 ID。会话中出现 `new_context`、`get_context_remaining`、`history` 和 `notes` 工具,说明扩展已经完成启用检查。
63
+ 将 `<model-id>` 换成 Pi 配置中实际显示的模型 ID。会话中出现 `new_context`、`get_context_remaining`、`history` 和 `notes`,说明已经激活;这不代表已完成后端往返验证。
67
64
 
68
65
  ### 使用兼容网关
69
66
 
70
- 本路线要求使用 `openai-responses` 接口,并且网关保留远程上下文所需的 Codex 协议字段。普通对话请求成功,不代表已经验证远程上下文兼容性。
67
+ 本路线要求使用 `openai-responses`,并且网关保留远程上下文所需的 Codex 协议字段。普通对话请求成功,不代表远程上下文兼容性已经验证。
71
68
 
72
- 如果 `~/.pi/agent/models.json` 中已有符合上述条件的网关模型,可以跳过模型配置,直接设置扩展白名单。否则,先添加或合并下面的提供商配置。请把 `my-gateway`、地址、环境变量名称和模型字段替换成实际值。示例中的数字只是示意值,不是项目默认值,必须改成符合实际模型与网关能力的上下文窗口和最大输出 token 数。
69
+ 如果 `~/.pi/agent/models.json` 中已有兼容模型,可以跳过注册,直接设置下方 Toolkit 精确模型覆盖。否则,添加或合并下面的 Pi 提供商配置。请替换提供商名称、地址、环境变量和模型字段。示例数字不是项目默认值。
73
70
 
74
71
  ```json
75
72
  {
@@ -91,7 +88,7 @@ pi --model openai-codex/<model-id>
91
88
  }
92
89
  ```
93
90
 
94
- 在启动 Pi 之前设置配置中引用的密钥。PowerShell 使用:
91
+ 启动 Pi 前设置配置中引用的密钥。PowerShell 使用:
95
92
 
96
93
  ```powershell
97
94
  $env:MY_GATEWAY_KEY = "replace-with-your-gateway-key"
@@ -103,136 +100,149 @@ POSIX shell 使用:
103
100
  export MY_GATEWAY_KEY="replace-with-your-gateway-key"
104
101
  ```
105
102
 
106
- 使用同一个终端启动 Pi。创建或合并扩展配置,并确保白名单条目与提供商名称和模型 ID 完全一致:
103
+ 使用同一个终端启动 Pi。在 Toolkit 配置中,确保键与已注册的提供商名称和模型 ID 完全一致:
107
104
 
108
105
  ```json
109
106
  {
110
- "compaction": {
111
- "contextManagement": "remote",
112
- "gatewayContextModels": ["my-gateway/gpt-5.6-luna"]
107
+ "schemaVersion": 2,
108
+ "models": {
109
+ "my-gateway/gpt-5.6-luna": {
110
+ "context": { "mode": "remote-windows" },
111
+ "compatibility": { "transport": "codex-gateway" }
112
+ }
113
113
  }
114
114
  }
115
115
  ```
116
116
 
117
- 使用相同的模型标识启动 Pi:
118
-
119
117
  ```bash
120
118
  pi --model my-gateway/gpt-5.6-luna
121
119
  ```
122
120
 
123
- 启用检查方式相同:会话中应该出现 `new_context`、`get_context_remaining`、`history` 和 `notes`。如果没有出现,先查看工具包通知,再检查提供商和模型字符串、接口、密钥、基础 URL 和白名单条目。
121
+ 检查是否出现 `new_context`、`get_context_remaining`、`history` 和 `notes`。如果没有,查看通知与 `/toolkit-config`,再检查精确模型键、Pi API、认证和基础 URL。传输设置只是显式选择协议适配,不会注册模型,也不能证明后端支持。
124
122
 
125
- 较早窗口的历史仍可通过 `history` 检索和读取,但不会全部自动加入当前上下文。
123
+ 较早窗口仍可通过 `history` 检索,但不会全部自动加入当前上下文。
126
124
 
127
125
  ## 常见用法
128
126
 
129
127
  ### 使用服务端压缩继续会话
130
128
 
131
- 如果希望使用 Responses 压缩路径,就保持远程上下文关闭。远程压缩 v2 会为符合条件的 Responses 模型保存并回放加密检查点。只有在压缩请求需要使用其他模型时,才设置 `compaction.remoteCompactModel`。
129
+ 使用 `context.mode: "remote-compaction"` 选择 Responses 压缩路径(默认值),或设为 `"pi"` 交回 Toolkit 的上下文管理权。只有需要独立模型生成检查点时才设置 `context.remoteCompaction.model`。这些字段放在 `defaults` 或精确的 `models` 覆盖下。
132
130
 
133
- 不配置 `compaction.remoteV2ContextSource` 时,Remote V2 保持原来的 `"legacy"` 输入链路:首次压缩使用 Pi 当前的 session context(最后才回退到事件提供的 preparation),递归压缩使用原始 branch tail。这会保留既有行为,但如果其他扩展改写消息,可能与 provider 实际看到的上下文不同。
131
+ `context.remoteCompaction.inputSource` 默认为 `"legacy"`:首次压缩使用 Pi 当前会话上下文,最后才回退到事件提供的数据;递归压缩使用原始分支尾部。这保留了既有行为,但当其他扩展改写消息时,可能与提供商实际看到的上下文不同。
134
132
 
135
- 将 `compaction.remoteV2ContextSource` 设为 `"pi-context-hook"` 可主动启用 Pi 0.85.1 runtime bridge,让 Remote V2 压缩使用与实时 provider 请求相同的有序 `context` hook 链。如果 Pi 无法提供这条公开 hook 路径,Remote V2 会取消压缩,而不会发送未投影的历史。只有检查点来源标记与当前设置一致时,才会继续回放。在两种模式之间切换后,必须重新创建 Remote V2 检查点;如果自定义状态必须保留在不透明检查点中,请关闭 Remote V2,或使用 Pi 原生压缩。
133
+ 主动选择 `"pi-context-hook"` 后,使用 Pi 有序上下文钩子投影。如果桥接不可用,压缩会取消,不会发送未投影的历史。检查点与来源绑定,切换来源后必须创建新检查点。详见[协议说明](docs/internals.md#remote-compaction-v2-wire-contract)。
136
134
 
137
135
  ### 选择联网搜索路由
138
136
 
139
- 联网搜索有三条互斥路由。可以设置一个全局默认路由,也可以按精确的 `provider/model-id` 覆盖:
137
+ 设置全局默认值和精确模型覆盖:
140
138
 
141
139
  ```json
142
140
  {
143
- "webSearch": {
144
- "enabled": true,
145
- "defaultRoute": "hosted",
146
- "routes": {
147
- "uwoacrimson/gpt-6-astra": "standalone-alpha",
148
- "my-gateway/gpt-5.6-luna": "local"
141
+ "schemaVersion": 2,
142
+ "defaults": {
143
+ "webSearch": { "route": "local" }
144
+ },
145
+ "models": {
146
+ "my-gateway/gpt-5.6-luna": {
147
+ "webSearch": { "route": "hosted" }
149
148
  }
150
149
  }
151
150
  }
152
151
  ```
153
152
 
154
- 路由选择是精确且确定的:`routes[provider/model-id]` 优先于 `defaultRoute`,`defaultRoute` 优先于旧版 `models` 列表。不支持通配符、模糊模型匹配、按模型名称猜能力、路由间 fallback 或重试。无效的路由值或模型键会告警后忽略,不会猜测路由;新旧字段重叠时会给出迁移告警。`enabled: false` 会释放工具包的工具所有权,并关闭工具包选择的全部三条路径。
153
+ - `unmanaged` 释放 Toolkit 的管理权,不会关闭第三方搜索或所有网络访问。
154
+ - `local` 保留本地 `pi-web-access` 工具原先的激活状态,并从提供商请求中移除冲突的托管或独立搜索工具。原先未激活的本地工具不会被自动激活。
155
+ - `hosted` 用原生 Responses 搜索工具和来源标注替换本地 `web_search` 函数。
156
+ - `standalone-alpha` 显式启用实验性的 CPA/Codex 网关搜索。它暴露顺序执行的 `web_run`,每次调用向提供商相对路径 `/alpha/search` 发送一次隔离请求,使用当前 Pi 模型及认证。网关必须实际支持该端点和能力,Toolkit 不会探测或替你开启。
155
157
 
156
- - **`local`** 保留已经安装的 `pi-web-access` `web_search` 工具。如果它原本没有激活,工具包不会替你激活;同时不会添加托管 provider 工具或 `web.run`。
157
- - **`hosted`** 移除名为 `web_search` 的本地 function,并注入原生 Responses `{ "type": "web_search" }` 工具和来源标注。旧版配置仍然有效:
158
-
159
- ```json
160
- {
161
- "webSearch": {
162
- "models": ["my-gateway/gpt-5.6-luna"]
163
- }
164
- }
165
- ```
166
-
167
- 没有配置新路由字段时,只有精确命中该列表、且 API 属于现有 Responses 系列(`openai-responses` 或 `openai-codex-responses`)的模型会使用托管搜索。
168
- - **`standalone-alpha`** 暴露一个 sequential 的 `web.run` 工具,并向 provider 相对的 `/alpha/search` 端点发送一次隔离的 `POST` 请求。例如基础地址是 `https://gateway.example/v1` 时,请求地址是 `https://gateway.example/v1/alpha/search`,不会变成 Responses 端点。支持的命令族包括 `search_query`、`image_query`、`open`、`click`、`find`、`screenshot`、`finance`、`weather`、`sports` 和 `time`;`response_length` 用于调整请求的结果长度。
169
-
170
- standalone 路由属于实验性的 CPA/Codex 网关协议,不是稳定的公开 OpenAI Responses 端点。网关/provider 必须提供 `/alpha/search`、启用 `alpha-search` 能力,并支持 standalone web search(Codex provider 通常以 `supports_standalone_web_search = true` 表示)。请求会复用 Pi 当前模型、认证、provider headers、会话标识及 Codex/gateway affinity,不会切换当前模型。MVP 发送受边界限制的命令 envelope,而不是完整会话 transcript;`ref_id` 后续操作依赖 provider 的会话/引用处理;每次工具调用最多发送一次请求;配置无效、路由不可用、取消、超时、非 2xx、响应畸形或超限时都会 fail closed。
158
+ 精确覆盖优先于默认值。不支持模式匹配、猜测能力或路由间回退。选中策略无效时,会阻止受影响操作,不会改选其他路由。旧版托管模型列表仍可读取,但其宽松失败处理与 v2 显式 `hosted` 不完全相同;迁移预览会标出差异。
171
159
 
172
160
  ### 生成图片
173
161
 
174
- 图像生成需要 Responses 会话,并且可能产生服务商费用。启用方式如下:
162
+ 图像生成需要 Responses 会话,并且可能产生服务商费用。全局启用方式如下:
175
163
 
176
164
  ```json
177
165
  {
178
- "imageGeneration": {
179
- "enabled": true,
180
- "models": ["gpt-image-2.5", "grok-imagine-image-2.0"]
166
+ "schemaVersion": 2,
167
+ "defaults": {
168
+ "imageGeneration": {
169
+ "enabled": true,
170
+ "defaultModel": "gpt-image-2.5",
171
+ "allowedModels": ["gpt-image-2.5", "grok-imagine-image-2.0"]
172
+ }
181
173
  }
182
174
  }
183
175
  ```
184
176
 
185
- `models` 填写嵌套 Responses `image_generation` 工具使用的裸模型 ID。列表第一项是默认模型;`openai_generate_image` 也支持通过可选的 `model` 参数在单次调用中切换,但该值必须与配置列表中的某一项完全一致。省略 `models` 时默认使用 `gpt-image-2.5`。列表为空或格式无效时会告警并回退到默认模型;如果要关闭工具,将 `enabled` 设置为 `false`。服务商或网关必须实际支持配置的生图模型。
177
+ 这里填写嵌套 Responses `image_generation` 工具使用的裸输出模型 ID。列表顺序不决定默认模型。`defaultModel` 必须属于非空的 `allowedModels` 列表,单次调用的可选 `model` 也必须在列表中。无效策略或不允许的选择会在认证、参考图上传及付费请求前被拒绝。提供商必须支持所选模型。
186
178
 
187
- `openai_generate_image` 支持文生图,也支持使用明确传入的本地参考图片进行编辑。
179
+ `openai_generate_image` 支持文生图和使用明确传入的本地参考图进行编辑。生图策略不能按当前会话模型覆盖。
188
180
 
189
181
  ### 启用工具调用自动审查
190
182
 
191
- 在 `autoMode` 中设置允许使用的模型和审查模型:
183
+ 为精确模型开放自动模式,并选择审查模型:
192
184
 
193
185
  ```json
194
186
  {
195
- "autoMode": {
196
- "models": ["my-gateway/gpt-5.6-luna"],
197
- "reviewerModel": "my-gateway/gpt-5.6-luna"
187
+ "schemaVersion": 2,
188
+ "models": {
189
+ "my-gateway/gpt-5.6-luna": {
190
+ "autoMode": {
191
+ "available": true,
192
+ "reviewerModel": "my-gateway/gpt-5.6-luna"
193
+ }
194
+ }
198
195
  }
199
196
  }
200
197
  ```
201
198
 
202
- 在会话中使用 `/auto on`,也可以用 `--auto` 启动 Pi。TUI 会显示自动模式已开启的提示;每次审查受控工具时,工作指示器会临时显示 `Auto mode: reviewing <tool>`,底部状态栏会保留当前审查范围。在支持兼容 tool renderer 的 Pi 版本中,自动模式下每个工具块底部都会显示一行状态:已审查的调用会显示 `allowed by reviewer · low risk · authorization medium` 或 `denied · <reason>`,不在当前审查范围内的调用会显示 `not reviewed · outside the configured gate`。如果当前 Pi 没有这个 renderer seam,扩展会告警一次并继续使用底部状态栏提示。默认的 `side-effect` 审查范围覆盖 `bash`、`write`、`edit` 和额外配置的工具。如果需要审查所有工具调用,将 `gate` 设置为 `"all"`。审查超时不会自动放行调用。
199
+ `available` 表示允许开启,使用 `/auto on` 或 `--auto` 才会实际开启;`/auto off` 明确关闭。默认 `side-effect` 范围覆盖 `bash`、`write`、`edit` 和额外配置的工具;`gate: "all"` 审查所有工具调用。审查超时不会自动放行。运行中配置变为无效时,已开启的门禁继续阻止调用,直到修正配置或明确关闭。
200
+
201
+ TUI 会显示开启提示、审查活动和底部状态。兼容的 Pi 工具渲染器还会显示每次调用的允许、拒绝、阻止或未审查状态。如果渲染接口不可用,Toolkit 告警一次并保留底部显示。审查器、分类器和熔断器的高级配置见[配置参考](docs/configuration.md)。
203
202
 
204
203
  ## 常用配置
205
204
 
206
- 配置文件为 `~/.pi/agent/extensions/pi-openai-toolkit/config.json`。未知键会告警后忽略。大多数模型列表必须使用精确的 `provider/model-id` 字符串,不支持通配符;`imageGeneration.models` 是例外,填写嵌套生图工具使用的裸模型 ID。
205
+ 全局文件按内置值、`defaults`、精确 `models["provider/model-id"]` 的顺序解析。缺失字段继承,数组整体替换,`false` 和 `0` 保持含义。支持的可选模型引用可以用 `null` 清除继承。默认值不是总开关:精确覆盖可以开启默认关闭的功能。
207
206
 
208
207
  | 配置项 | 默认值 | 用途 |
209
208
  | --- | --- | --- |
210
- | `compaction.enabled` | `true` | 压缩功能总开关。 |
211
- | `compaction.contextManagement` | `"off"` | 设置为 `"remote"` 后启用 Codex 远程上下文。 |
212
- | `compaction.gatewayContextModels` | `[]` | 允许使用远程上下文的网关模型。 |
213
- | `compaction.remoteCompactModel` | 未设置 | 仅用于 v2 压缩请求的可选模型。 |
214
- | `compaction.remoteV2ContextSource` | `"legacy"` | 保留原来的原始 session/branch 输入路径。设置为 `"pi-context-hook"` 后才启用 Pi 的有序 context hook projection。检查点与模式绑定。 |
215
- | `compaction.contextReminderThresholdPercent` | `5` | 每个窗口触发一次提醒的剩余预算百分比。设置为 `0` 会关闭提醒和窗口耗尽兜底。 |
216
- | `webSearch.enabled` | `true` | 工具包联网搜索路由的总开关。设为 `false` 时不选择任何工具包路由。 |
217
- | `webSearch.defaultRoute` | 未设置 | 默认路由:`local`、`hosted` 或 `standalone-alpha`。未设置时保留旧版行为。 |
218
- | `webSearch.routes` | 未设置 | 精确的 `provider/model-id` 路由覆盖。精确条目优先于 `defaultRoute`。 |
219
- | `webSearch.models` | `[]` | 旧版精确白名单;没有新路由字段时,列表中的 Responses 系列模型使用托管联网搜索。 |
220
- | `imageGeneration.enabled` | `false` | 启用 `openai_generate_image`。 |
221
- | `imageGeneration.models` | `["gpt-image-2.5"]` | 裸生图模型 ID;列表第一项是默认模型。 |
222
- | `autoMode.models` | `[]` | 允许使用自动模式的模型。 |
223
- | `autoMode.reviewerModel` | 未设置 | 审查自动模式调用的模型。 |
224
- | `autoMode.gate` | `"side-effect"` | 设置为 `"all"` 后审查所有工具调用。 |
225
- | `autoMode.timeoutMs` | `30000` | 审查超时时间,单位为毫秒。 |
209
+ | `defaults.context.mode` | `"remote-compaction"` | `"pi"`、`"remote-compaction"` 或 `"remote-windows"`。 |
210
+ | `models[exact].compatibility.transport` | `"standard"` | 用 `"codex-gateway"` 显式选择网关协议。 |
211
+ | `defaults.context.remoteCompaction.model` | `null` | 可选的检查点生成模型。 |
212
+ | `defaults.context.remoteCompaction.inputSource` | `"legacy"` | 与检查点来源绑定的输入策略。 |
213
+ | `defaults.context.remoteWindows.reminderThresholdPercent` | `5` | `0` 关闭提醒和窗口耗尽兜底。 |
214
+ | `defaults.webSearch.route` | `"unmanaged"` | Toolkit 搜索管理策略。 |
215
+ | `defaults.imageGeneration.enabled` | `false` | 全局生图开关。 |
216
+ | `defaults.imageGeneration.defaultModel` | `"gpt-image-2.5"` | 明确指定默认输出模型。 |
217
+ | `defaults.imageGeneration.allowedModels` | `["gpt-image-2.5"]` | 允许的输出模型,仅支持全局设置。 |
218
+ | `defaults.autoMode.available` | `false` | 是否允许开启工具审查。 |
219
+ | `defaults.autoMode.gate` | `"side-effect"` | 指定副作用工具,或 `"all"`。 |
220
+ | `defaults.autoMode.timeoutMs` | `30000` | 审查超时,单位为毫秒。 |
221
+ | `diagnostics.level` | `"info"` | `"debug"` 开启调试产物。 |
222
+ | `diagnostics.captureRequests` / `captureResponses` | `false` | 分别开启请求或压缩响应捕获。 |
223
+
224
+ 使用 `/toolkit-config` 查看有效值及来源,`/toolkit-config validate` 查看文档问题,`/toolkit-config migration-preview` 预览只读的旧格式迁移候选。这些命令需要 UI,不查询网络或认证,不激活工具,也不写文件。选中配置不表示后端支持已验证。
225
+
226
+ 未知 v2 策略键和畸形值会产生可见的分范围错误,不依赖调试模式。每个公开回调或工具执行及其等待的辅助操作使用同一份不可变快照,后续操作重新读取文件;独立 Pi 事件之间不保证原子事务。完整选项见[配置参考](docs/configuration.md)和[编辑器 schema](config.schema.json)。
226
227
 
227
228
  ## 开发
228
229
 
229
230
  在仓库根目录安装依赖后运行:
230
231
 
231
232
  ```bash
232
- npm run typecheck # 类型检查
233
- bun test # 运行测试
234
- npm run test:pi # 运行 Pi 冒烟测试
235
- npm pack --dry-run # 检查发布包内容
233
+ npm run typecheck
234
+ ```
235
+
236
+ ```bash
237
+ bun test
238
+ ```
239
+
240
+ ```bash
241
+ npm run test:pi
242
+ ```
243
+
244
+ ```bash
245
+ npm pack --dry-run
236
246
  ```
237
247
 
238
248
  ## 许可证
@@ -0,0 +1,352 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/awoaCrim/pi-openai-toolkit/blob/main/config.schema.json",
4
+ "title": "Pi OpenAI Toolkit global configuration v2",
5
+ "description": "Strict schema for the canonical global Toolkit configuration. Runtime validation additionally enforces normalized exact keys and image default membership.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "schemaVersion"
10
+ ],
11
+ "properties": {
12
+ "$schema": {
13
+ "type": "string",
14
+ "description": "Optional schema metadata URI. It does not select a runtime schema."
15
+ },
16
+ "schemaVersion": {
17
+ "const": 2
18
+ },
19
+ "defaults": {
20
+ "$ref": "#/$defs/defaults"
21
+ },
22
+ "models": {
23
+ "type": "object",
24
+ "propertyNames": {
25
+ "pattern": "^[^\\s*?\\[\\]{}\\u0000-\\u001f\\u007f]+/[^\\s*?\\[\\]{}\\u0000-\\u001f\\u007f]+$"
26
+ },
27
+ "additionalProperties": {
28
+ "$ref": "#/$defs/modelOverride"
29
+ }
30
+ },
31
+ "diagnostics": {
32
+ "$ref": "#/$defs/diagnostics"
33
+ }
34
+ },
35
+ "$defs": {
36
+ "modelRef": {
37
+ "description": "Exact provider/model reference; model ids may contain additional slashes.",
38
+ "anyOf": [
39
+ {
40
+ "type": "null"
41
+ },
42
+ {
43
+ "type": "string",
44
+ "minLength": 1,
45
+ "pattern": "^[^\\s*?\\[\\]{}\\u0000-\\u001f\\u007f]+/[^\\s*?\\[\\]{}\\u0000-\\u001f\\u007f]+$"
46
+ }
47
+ ]
48
+ },
49
+ "stringList": {
50
+ "type": "array",
51
+ "items": {
52
+ "type": "string"
53
+ }
54
+ },
55
+ "responsesApis": {
56
+ "type": "array",
57
+ "items": {
58
+ "enum": [
59
+ "openai-responses",
60
+ "openai-codex-responses"
61
+ ]
62
+ }
63
+ },
64
+ "context": {
65
+ "type": "object",
66
+ "additionalProperties": false,
67
+ "properties": {
68
+ "mode": {
69
+ "enum": [
70
+ "pi",
71
+ "remote-compaction",
72
+ "remote-windows"
73
+ ]
74
+ },
75
+ "remoteCompaction": {
76
+ "$ref": "#/$defs/remoteCompaction"
77
+ },
78
+ "nativeFallback": {
79
+ "$ref": "#/$defs/nativeFallback"
80
+ },
81
+ "remoteWindows": {
82
+ "$ref": "#/$defs/remoteWindows"
83
+ }
84
+ }
85
+ },
86
+ "remoteCompaction": {
87
+ "type": "object",
88
+ "additionalProperties": false,
89
+ "properties": {
90
+ "model": {
91
+ "$ref": "#/$defs/modelRef"
92
+ },
93
+ "inputSource": {
94
+ "enum": [
95
+ "legacy",
96
+ "pi-context-hook"
97
+ ]
98
+ },
99
+ "allowContinuityBreak": {
100
+ "type": "boolean"
101
+ },
102
+ "apis": {
103
+ "$ref": "#/$defs/responsesApis"
104
+ }
105
+ }
106
+ },
107
+ "nativeFallback": {
108
+ "type": "object",
109
+ "additionalProperties": false,
110
+ "properties": {
111
+ "enabled": {
112
+ "type": "boolean"
113
+ },
114
+ "model": {
115
+ "$ref": "#/$defs/modelRef"
116
+ },
117
+ "thinkingLevel": {
118
+ "enum": [
119
+ "off",
120
+ "minimal",
121
+ "low",
122
+ "medium",
123
+ "high",
124
+ "xhigh",
125
+ "max"
126
+ ]
127
+ }
128
+ }
129
+ },
130
+ "remoteWindows": {
131
+ "type": "object",
132
+ "additionalProperties": false,
133
+ "properties": {
134
+ "leaveManagedMode": {
135
+ "enum": [
136
+ "warn",
137
+ "compact"
138
+ ]
139
+ },
140
+ "reminderThresholdPercent": {
141
+ "type": "integer",
142
+ "minimum": 0,
143
+ "maximum": 100
144
+ }
145
+ }
146
+ },
147
+ "webSearch": {
148
+ "type": "object",
149
+ "additionalProperties": false,
150
+ "properties": {
151
+ "route": {
152
+ "enum": [
153
+ "unmanaged",
154
+ "local",
155
+ "hosted",
156
+ "standalone-alpha"
157
+ ]
158
+ }
159
+ }
160
+ },
161
+ "imageGeneration": {
162
+ "type": "object",
163
+ "additionalProperties": false,
164
+ "properties": {
165
+ "enabled": {
166
+ "type": "boolean"
167
+ },
168
+ "defaultModel": {
169
+ "type": "string",
170
+ "minLength": 1,
171
+ "maxLength": 256,
172
+ "pattern": "\\S"
173
+ },
174
+ "allowedModels": {
175
+ "type": "array",
176
+ "minItems": 1,
177
+ "items": {
178
+ "type": "string",
179
+ "minLength": 1,
180
+ "maxLength": 256,
181
+ "pattern": "\\S"
182
+ }
183
+ }
184
+ }
185
+ },
186
+ "autoMode": {
187
+ "type": "object",
188
+ "additionalProperties": false,
189
+ "properties": {
190
+ "available": {
191
+ "type": "boolean"
192
+ },
193
+ "reviewerModel": {
194
+ "$ref": "#/$defs/modelRef"
195
+ },
196
+ "gate": {
197
+ "enum": [
198
+ "side-effect",
199
+ "all"
200
+ ]
201
+ },
202
+ "extraTools": {
203
+ "$ref": "#/$defs/stringList"
204
+ },
205
+ "timeoutMs": {
206
+ "type": "integer",
207
+ "minimum": 1000,
208
+ "maximum": 120000
209
+ },
210
+ "transcript": {
211
+ "type": "boolean"
212
+ },
213
+ "evidenceTools": {
214
+ "type": "boolean"
215
+ },
216
+ "maxEvidenceRounds": {
217
+ "type": "integer",
218
+ "minimum": 0,
219
+ "maximum": 8
220
+ },
221
+ "classifier": {
222
+ "$ref": "#/$defs/classifier"
223
+ },
224
+ "circuitBreaker": {
225
+ "$ref": "#/$defs/circuitBreaker"
226
+ }
227
+ }
228
+ },
229
+ "classifier": {
230
+ "type": "object",
231
+ "additionalProperties": false,
232
+ "properties": {
233
+ "enabled": {
234
+ "type": "boolean"
235
+ },
236
+ "model": {
237
+ "$ref": "#/$defs/modelRef"
238
+ },
239
+ "timeoutMs": {
240
+ "type": "integer",
241
+ "minimum": 1000,
242
+ "maximum": 120000
243
+ },
244
+ "maxLag": {
245
+ "type": "integer",
246
+ "minimum": 0,
247
+ "maximum": 20
248
+ }
249
+ }
250
+ },
251
+ "circuitBreaker": {
252
+ "type": "object",
253
+ "additionalProperties": false,
254
+ "properties": {
255
+ "consecutiveDenials": {
256
+ "type": "integer",
257
+ "minimum": 0,
258
+ "maximum": 100
259
+ },
260
+ "recentDenials": {
261
+ "type": "integer",
262
+ "minimum": 0,
263
+ "maximum": 100
264
+ },
265
+ "windowSize": {
266
+ "type": "integer",
267
+ "minimum": 1,
268
+ "maximum": 200
269
+ }
270
+ }
271
+ },
272
+ "compatibility": {
273
+ "type": "object",
274
+ "additionalProperties": false,
275
+ "properties": {
276
+ "transport": {
277
+ "enum": [
278
+ "standard",
279
+ "codex-gateway"
280
+ ]
281
+ }
282
+ }
283
+ },
284
+ "defaults": {
285
+ "type": "object",
286
+ "additionalProperties": false,
287
+ "properties": {
288
+ "context": {
289
+ "$ref": "#/$defs/context"
290
+ },
291
+ "webSearch": {
292
+ "$ref": "#/$defs/webSearch"
293
+ },
294
+ "imageGeneration": {
295
+ "$ref": "#/$defs/imageGeneration"
296
+ },
297
+ "autoMode": {
298
+ "$ref": "#/$defs/autoMode"
299
+ }
300
+ }
301
+ },
302
+ "modelOverride": {
303
+ "type": "object",
304
+ "additionalProperties": false,
305
+ "properties": {
306
+ "context": {
307
+ "$ref": "#/$defs/context"
308
+ },
309
+ "webSearch": {
310
+ "$ref": "#/$defs/webSearch"
311
+ },
312
+ "autoMode": {
313
+ "$ref": "#/$defs/autoMode"
314
+ },
315
+ "compatibility": {
316
+ "$ref": "#/$defs/compatibility"
317
+ }
318
+ }
319
+ },
320
+ "diagnostics": {
321
+ "type": "object",
322
+ "additionalProperties": false,
323
+ "properties": {
324
+ "level": {
325
+ "enum": [
326
+ "error",
327
+ "warn",
328
+ "info",
329
+ "debug"
330
+ ]
331
+ },
332
+ "notifyOnLoad": {
333
+ "type": "boolean"
334
+ },
335
+ "captureRequests": {
336
+ "type": "boolean"
337
+ },
338
+ "captureResponses": {
339
+ "type": "boolean"
340
+ },
341
+ "redactSensitiveData": {
342
+ "type": "boolean"
343
+ },
344
+ "artifactRoot": {
345
+ "type": "string",
346
+ "minLength": 1,
347
+ "pattern": "\\S"
348
+ }
349
+ }
350
+ }
351
+ }
352
+ }