pi-openai-toolkit 0.11.0 → 0.11.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.md CHANGED
@@ -220,7 +220,7 @@ Auto mode is opt-in through the empty-by-default `models` allowlist because it a
220
220
  #### `codexAstra`
221
221
 
222
222
  - `enabled` (*boolean*, default: `false`): Master switch for the GPT-6 Astra compatibility layer: the Codex backend version-gate header on live requests, and the stable-effort `configuration_update` rewrite described in section 6 of Core Mechanics.
223
- - `models` (*string[]*, default: `[]`): Exact `provider/model-id` allowlist of models that accept the `configuration_update` input item. Today that is only `["openai-codex/gpt-6-astra"]`; the rewrite is never applied to any other model, and the version header applies to all `openai-codex-responses` requests regardless of this list.
223
+ - `models` (*string[]*, default: `[]`): Exact `provider/model-id` allowlist of models that accept the `configuration_update` input item. Only Astra-era models answer it correctly (today `["openai-codex/gpt-6-astra"]`, or your gateway's equivalent key such as `"uwoacrimson/gpt-6-astra"`); the rewrite is never applied to any other model, and the version header applies to all `openai-codex-responses` requests regardless of this list.
224
224
 
225
225
  ---
226
226
 
@@ -314,7 +314,7 @@ GPT-6 Astra is a Codex-backend (ChatGPT OAuth) model with two wire behaviors tha
314
314
  - **Stable effort with `configuration_update`**: OpenAI prompt caching compares the request from the first byte, and the request-level `reasoning.effort` sits at the top - changing thinking level mid-conversation normally busts the whole cached prefix. Astra instead accepts a `configuration_update` input item that changes effort from that point onward while the request-level field stays put. This extension implements that for the active conversation: the first request pins the baseline effort, every later change is spliced into the transcript at the position it should take effect (before the user message it applies to, or after the latest tool result inside a tool loop), and the same item is replayed at that position on every following request. The request body keeps the baseline byte-stable, so the cache prefix survives level changes.
315
315
  - **History-rewrite safety**: Each spliced item is anchored to a fingerprint of the transcript position it was inserted at. If a later request's history no longer matches - compaction, branch switch, `/clear`, anything rewrote the transcript - the baseline is discarded and the next request re-pins its own effort, rather than placing an update at a stale position.
316
316
  - **Compaction isolation**: The compact endpoints reject histories containing `configuration_update` items. This is enforced in two places: the payload rewriter never splices items into a `compaction_trigger`-shaped request, and both compaction clients strip any such item defensively from replayed input, so an Astra session can still be compacted by this package.
317
- - **Scope**: The rewrite applies only to models listed in `codexAstra.models` (Astra is the only SKU that accepts the item; anything else answers HTTP 400 on it), only when the request actually carries a wire-level effort, and never to `off`/`none`. Everything runs inside a try/catch: any unexpected payload shape or planner failure leaves the request untouched. To avoid double-splicing when both this toolkit and a host that implements the same behavior (Oh My Pi itself) are active, enable this layer on only one side.
317
+ - **Scope**: The rewrite applies only to models listed in `codexAstra.models` on either Responses wire family (Astra is the only SKU known to accept the item; anything else answers HTTP 400 on it - the allowlist is what encodes that knowledge for gateways that proxy it), only when the request actually carries a wire-level effort, and never to `off`/`none`. Everything runs inside a try/catch: any unexpected payload shape or planner failure leaves the request untouched. To avoid double-splicing when both this toolkit and a host that implements the same behavior (Oh My Pi itself) are active, enable this layer on only one side.
318
318
 
319
319
  Catalog note: Pi's bundled `openai-codex` model list does not include `gpt-6-astra` yet. Register it in `~/.pi/agent/models.json` under the built-in provider (custom models merge into the built-in list): `api: "openai-codex-responses"`, `baseUrl: "https://chatgpt.com/backend-api"`, `contextWindow: 272000`, `maxTokens: 128000`, and a `thinkingLevelMap` exposing `low` through `max`. Pi's Codex OAuth login supplies the token; this package reads it through Pi's `ModelRegistry` and never touches the credential store directly.
320
320
 
package/README_zh.md CHANGED
@@ -218,7 +218,7 @@ Auto 模式需要显式启用(`models` 默认为空),因为它相当于允
218
218
  #### `codexAstra`(Codex GPT-6 Astra 适配配置)
219
219
 
220
220
  - `enabled` (*boolean*, 默认 `false`): Astra 适配层总开关:实时请求的版本门禁头,以及「核心工作原理解析」第 6 节描述的 stable-effort 改写。
221
- - `models` (*string[]*, 默认 `[]`): 接受 `configuration_update` 会话项的精确 `provider/model-id` 白名单。目前只有 `["openai-codex/gpt-6-astra"]`;其他模型绝不会被改写。版本门禁头则对所有 `openai-codex-responses` 实时请求生效,不受这个列表限制。
221
+ - `models` (*string[]*, 默认 `[]`): 接受 `configuration_update` 会话项的精确 `provider/model-id` 白名单。只有 Astra 世代模型能正确响应它(目前 `["openai-codex/gpt-6-astra"]`,或网关上对应的键如 `"uwoacrimson/gpt-6-astra"`);其他模型绝不会被改写。版本门禁头则对所有 `openai-codex-responses` 实时请求生效,不受这个列表限制。
222
222
 
223
223
  ---
224
224
 
@@ -312,7 +312,7 @@ GPT-6 Astra 是 Codex 后端(ChatGPT OAuth)上的模型,有两个普通 Op
312
312
  - **stable effort + `configuration_update`**:OpenAI 提示缓存从请求第一个字节开始比对,而请求级 `reasoning.effort` 就在头部——中途换思考档位通常会打爆整个缓存前缀。Astra 接受一种 `configuration_update` 输入项,从该项位置起改档位而不动请求级字段。本扩展把这套机制接到当前会话:首个请求钉住基线档位,之后的每次变更插入到它应生效的会话位置(作效于哪条用户消息就插在哪条之前,工具循环中途变更插在最近一条工具结果之后),后续请求在同一位置重放该项,请求体开头始终字节不变,缓存前缀存活。
313
313
  - **历史重写安全**:每个插入项都锚定在它所在位置前一条内容的指纹上。后续请求的历史对不上(压缩、切分支、`/clear`,任何历史重写),基线直接作废,下一次请求用自己的档位重新钉基线,而不是把更新插到过期位置。
314
314
  - **压缩隔离**:compact 端点拒绝含 `configuration_update` 的历史。两层防御:payload 改写器对带 `compaction_trigger` 的请求绝不插入;两个压缩客户端对回放输入里的该类项一律防御性剥离——所以 Astra 会话照常被本包压缩。
315
- - **适用范围**:改写只作用于 `codexAstra.models` 白名单内的模型(目前只有 astra 接受该 item,其他模型碰它就 400),且只改真正携带线上级 effort 的请求,`off`/`none` 不动。整个钩子在 try/catch 里,任何意外形状或规划失败都原样放行请求。若 host 自身已实现同样行为(例如 Oh My Pi),两边只开一个,避免双重插入。
315
+ - **适用范围**:改写只作用于两种 Responses 线协议家族内 `codexAstra.models` 白名单中的模型(目前已知只有 astra 接受该 item,其他模型碰它就 400——网关代理同一模型时,白名单就是声明这件事的地方),且只改真正携带线上级 effort 的请求,`off`/`none` 不动。整个钩子在 try/catch 里,任何意外形状或规划失败都原样放行请求。若 host 自身已实现同样行为(例如 Oh My Pi),两边只开一个,避免双重插入。
316
316
 
317
317
  目录说明: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` 读凭据,不碰存储文件。
318
318
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-openai-toolkit",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "OpenAI-focused Pi toolkit providing remote Responses compaction, native Web Search, native image generation, and model-reviewed auto mode.",
@@ -72,7 +72,12 @@ export function registerCodexAstraExtension(
72
72
  if (!astra.enabled || astra.models.length === 0) return undefined;
73
73
 
74
74
  const model = ctx.model;
75
- if (!model || model.api !== "openai-codex-responses") return undefined;
75
+ // Both Responses wire families carry the same reasoning.effort prefix
76
+ // problem, and upstream OMP plans on both providers; which models
77
+ // accept the item is decided by the allowlist, not by API family.
78
+ if (!model || (model.api !== "openai-codex-responses" && model.api !== "openai-responses")) {
79
+ return undefined;
80
+ }
76
81
  if (!isExactModelAllowed(model, astra.models)) return undefined;
77
82
 
78
83
  const payload = parseAstraPayload(event.payload);