pi-openai-toolkit 0.24.0 → 0.24.2

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
@@ -57,7 +57,7 @@ Set `context.remoteCompaction.model` to use a separate producer on the same effe
57
57
 
58
58
  ## Codex Fast
59
59
 
60
- Fast is OFF by default. Run `/fast` in Pi's terminal or a UI-backed RPC client such as pi-web to turn it ON, then run it again to turn it OFF. Notifications confirm changes; the status is `Fast ON`, `Fast OFF`, or `Fast N/A` for an ineligible route, with display placement controlled by the client. Print/JSON and headless commands cannot toggle Fast. No Fast configuration is needed.
60
+ Fast is OFF by default. Run `/fast` in Pi's terminal or a UI-backed RPC client such as pi-web to turn it ON, then run it again to turn it OFF. Notifications confirm changes. Eligible routes show `Fast ON` or `Fast OFF`; other routes hide the indicator while retaining the session preference. Display placement is controlled by the client. Print/JSON and headless commands cannot toggle Fast. No Fast configuration is needed.
61
61
 
62
62
  Supports native Codex and recognizable GPT/Codex models on compatible Responses gateways. The selection is saved only in the current session: reload/resume retain it; new or forked sessions start OFF. ON requests Fast, while OFF requests Standard, overriding an existing service-tier preference on eligible conversation requests without changing reasoning effort or configuration files.
63
63
 
package/README.zh.md CHANGED
@@ -57,7 +57,7 @@ Toolkit 只读取一个全局配置文件,即使扩展安装在项目内也一
57
57
 
58
58
  ## Codex Fast
59
59
 
60
- Fast 默认关闭。在 Pi 终端或 pi-web 等支持 UI 的 RPC 客户端中输入 `/fast` 开启,再输入一次关闭。切换结果通过通知确认;状态为 `Fast ON`、`Fast OFF`,不适用的路由为 `Fast N/A`,显示位置由客户端决定。print/JSON 和无 UI 模式不能切换 Fast。无需添加 Fast 配置。
60
+ Fast 默认关闭。在 Pi 终端或 pi-web 等支持 UI 的 RPC 客户端中输入 `/fast` 开启,再输入一次关闭。切换结果通过通知确认。适用的路由显示 `Fast ON` 或 `Fast OFF`;不适用时隐藏状态项,并保留会话偏好。显示位置由客户端决定。print/JSON 和无 UI 模式不能切换 Fast。无需添加 Fast 配置。
61
61
 
62
62
  支持原生 Codex,以及兼容 Responses 网关中可识别的 GPT/Codex 模型。开关只保存在当前会话:reload 和续聊保留状态,新建或 fork 的会话默认关闭。开启时请求 Fast,关闭时请求标准档,会覆盖符合条件的对话请求中原有的服务档位,但不改变 reasoning effort 或配置文件。
63
63
 
package/docs/internals.md CHANGED
@@ -31,7 +31,7 @@ Selected invalid policy blocks dependent operations; unrelated model errors rema
31
31
 
32
32
  Native openai-codex-responses routes qualify. Non-official HTTP(S) openai-responses gateways qualify for recognizable GPT/Codex IDs or an exact Codex gateway identity, including a resolved virtual route. Unknown opaque aliases without that identity, Azure, other APIs and ordinary api.openai.com API-key routes remain untouched. Capability does not establish entitlement.
33
33
 
34
- Version-1 pi-openai-toolkit:codex-fast entries contain only the owning Pi sessionId and enabled boolean and stay outside model context. Reload/resume and active-branch navigation restore the latest valid owned preference; malformed latest metadata defaults OFF. New/forked sessions ignore foreign preferences and start OFF. Model switches show N/A without discarding the saved preference. Missing identity or a failed append cannot report success.
34
+ Version-1 pi-openai-toolkit:codex-fast entries contain only the owning Pi sessionId and enabled boolean and stay outside model context. Reload/resume and active-branch navigation restore the latest valid owned preference; malformed latest metadata defaults OFF. New/forked sessions ignore foreign preferences and start OFF. Ineligible routes have no Fast status item; switching back to an eligible model restores Fast ON/OFF from the saved preference. Pending status refreshes cannot overwrite newer model/session state or restore the status after shutdown. Missing identity or a failed append cannot report success.
35
35
 
36
36
  The payload hook snapshots selection and returns a new object only when an eligible ordinary request needs a tier change. Explicit OFF overrides existing Fast/Flex preferences to Standard. Compaction shapes and malformed/foreign payloads stay unchanged. Fast loads after Web Search/images and before Astra; it cannot change pre-search extras cached for separate clients. Native and Toolkit gateway WebSocket adapters compare non-input body fields, so a tier change invalidates an incompatible previous_response_id delta. Offline actual-encoder fixtures live in [test/pi-codex-fast.test.ts](../test/pi-codex-fast.test.ts), not live Fast availability evidence.
37
37
 
@@ -57,6 +57,8 @@ The selected model is the checkpoint **consumer**. An optional configured model
57
57
 
58
58
  A compaction_trigger item appended to a separate synthetic streaming Responses request yields one output item of type compaction with nonempty encrypted_content, stored in CompactionEntry.details.compactedWindow. The request retains the current conversation identity; the selected model/thinking never changes and no new session or synthetic continuation is created. On later requests the opaque checkpoint replaces Pi's verified summary anchor ahead of live turns. Missing anchors abort with a notification and content-free failure artifact; sentinel-only payloads are never sent.
59
59
 
60
+ Historical tool calls are serialized as function_call items. Only compatible fc_* item IDs are retained; other optional IDs, including ctc_* custom-tool IDs, are omitted without changing call_id, tool arguments, result pairing or persisted history.
61
+
60
62
  The incremental SSE consumer validates the first terminal event and reconciles its checkpoint with prior item evidence. A valid completed frame ends the operation even if the body stays open; best-effort reader cancellation is not awaited. Incomplete EOF, conflicting evidence and terminal errors cannot become successful checkpoints. Astra-only configuration_update items and injected native Web Search are excluded from synthetic compaction.
61
63
 
62
64
  Missing/invalid checkpoints are not stored. Ordinary compaction may try the gated standalone protocol below; exhausted remote attempts warn once before native text summary. A failed remote attempt selects remoteCompactModel for the configured native tier; remote-ineligible resolution selects nativeFallback.model. Disabled/unset/same-model native selections keep Pi's default, including when nativeFallback.enabled is false. Explicit summary failures, aborts and projection/provenance/context-edit failures cancel; an invalid producer does not silently retry Remote V2 using the consumer.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-openai-toolkit",
3
- "version": "0.24.0",
3
+ "version": "0.24.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -59,7 +59,7 @@ export function registerCodexFastExtension(
59
59
  const id = currentSessionId;
60
60
  const eligible = id && await eligibleModel(ctx, model);
61
61
  if (epoch !== statusEpoch || sessionId(ctx) !== id) return;
62
- if (ctx.hasUI) ctx.ui.setStatus(CODEX_FAST_STATUS_KEY, eligible ? "Fast " + (enabled ? "ON" : "OFF") : "Fast N/A");
62
+ if (ctx.hasUI) ctx.ui.setStatus(CODEX_FAST_STATUS_KEY, eligible ? "Fast " + (enabled ? "ON" : "OFF") : undefined);
63
63
  }
64
64
 
65
65
  pi.on("session_start", async (_event, ctx) => { restore(ctx); await refreshStatus(ctx); });
@@ -7,6 +7,7 @@ import {
7
7
  type ConfigIssue,
8
8
  } from "./policy";
9
9
  import { redactValue } from "../debug";
10
+ import { detectRetiredRemoteWindows } from "../retired-remote-windows";
10
11
 
11
12
  const lastNotice = new WeakMap<object, string>();
12
13
 
@@ -28,15 +29,18 @@ export function formatConfigIssues(issues: readonly ConfigIssue[], limit = 12):
28
29
  /** Per-session bounded notice, independent of feature enablement/debug. Never logs raw config. */
29
30
  export function notifyConfigIssues(ctx: ExtensionContext, resolved: ResolvedToolkitConfig): void {
30
31
  const owner = ctx.sessionManager ?? ctx;
31
- if (resolved.issues.length === 0) {
32
+ if (!ctx.hasUI || typeof ctx.ui?.notify !== "function") return;
33
+ const hasRetiredWindows = resolved.issues.some((issue) => issue.code === RETIRED_REMOTE_WINDOWS_ISSUE)
34
+ && detectRetiredRemoteWindows(ctx.sessionManager.getBranch()) !== undefined;
35
+ const issues = resolved.issues.filter((issue) => issue.code !== RETIRED_REMOTE_WINDOWS_ISSUE || hasRetiredWindows);
36
+ if (issues.length === 0) {
32
37
  lastNotice.delete(owner);
33
38
  return;
34
39
  }
35
- if (!ctx.hasUI || typeof ctx.ui?.notify !== "function") return;
36
- const message = formatConfigIssues(resolved.issues, 4);
40
+ const message = formatConfigIssues(issues, 4);
37
41
  const fingerprint = `${resolved.source ?? "defaults"}\n${resolved.modelKey ?? ""}\n${message}`;
38
42
  if (lastNotice.get(owner) === fingerprint) return;
39
43
  lastNotice.set(owner, fingerprint);
40
44
  ctx.ui.notify(`Toolkit configuration:\n${message}\nUse /toolkit-config validate for details.`,
41
- resolved.issues.some((issue) => issue.severity === "error") ? "error" : "warning");
45
+ issues.some((issue) => issue.severity === "error") ? "error" : "warning");
42
46
  }
package/src/serializer.ts CHANGED
@@ -661,7 +661,8 @@ function serializeAssistantMessage(message: AssistantMessage, messageIndex: numb
661
661
  const [callId, rawItemId] = block.id.split("|");
662
662
  items.push({
663
663
  type: "function_call",
664
- id: rawItemId,
664
+ // Custom-tool item IDs are invalid on function_call; call_id retains pairing.
665
+ id: rawItemId?.startsWith("fc_") ? rawItemId : undefined,
665
666
  call_id: callId,
666
667
  name: block.name,
667
668
  arguments: JSON.stringify(block.arguments),