pi-openai-toolkit 0.23.2 → 0.24.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.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # pi-openai-toolkit
2
2
 
3
- Remote context windows, Responses compaction, web search, and image generation for Pi. Uses Pi's existing models, endpoints, authentication, and sessions without registering another provider or model.
3
+ Responses compaction, web search, and image generation for Pi. Uses Pi's existing models, endpoints, authentication, and sessions without registering another provider or model.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/pi-openai-toolkit.svg)](https://www.npmjs.com/package/pi-openai-toolkit)
6
6
  [![MIT](https://img.shields.io/npm/l/pi-openai-toolkit.svg)](LICENSE)
@@ -47,30 +47,19 @@ Settings resolve in this order: built-in defaults → `defaults` → `models["pr
47
47
  Set `defaults.context.mode` or an individual model's `context.mode`:
48
48
 
49
49
  - `remote-compaction`: the default; continue with encrypted checkpoints returned by the server
50
- - `remote-windows`: use Codex remote context windows, retrieve earlier work with `history`, and save handoff notes with `notes`
51
50
  - `pi`: leave context management to Pi
52
51
 
53
52
  **Remote compaction** accepts `openai-responses`, `openai-codex-responses`, and `azure-openai-responses`. It tries V2 first. On the official OpenAI API-key route, a qualifying protocol failure can trigger one standalone `/v1/responses/compact` request; its complete encrypted replacement window is preserved for replay. OpenAI OAuth, native Codex, Azure, and gateways keep their existing V2 route. OpenAI subscription-sharing OAuth and native Codex login are separate grants, not interchangeable credentials. Backend/model access is still required.
54
53
 
55
- Set `context.remoteCompaction.model` to use a separate producer on the same effective base URL without changing the active model. For ordinary remote compaction, exhausted remote attempts warn before continuing with a native text summary. `nativeFallback.enabled: false` disables only Toolkit's configured-model tier, not Pi's default summary. Aborts, incompatible provenance, and edits to sealed history still cancel rather than bypassing checkpoint safety. See [context settings](docs/configuration.md#context) and [checkpoint rules](docs/internals.md#remote-compaction-v2-wire-contract).
54
+ Set `context.remoteCompaction.model` to use a separate producer on the same effective base URL without changing the active model. When its full `provider/model-id` matches the current model, Toolkit directly reuses the current runtime, authentication snapshot, and session; it does not select the model again or switch to native summarization merely because the models match. For ordinary remote compaction, exhausted remote attempts warn before continuing with a native text summary. `nativeFallback.enabled: false` disables only Toolkit's configured-model tier, not Pi's default summary. Aborts, incompatible provenance, and edits to sealed history still cancel rather than bypassing checkpoint safety. See [context settings](docs/configuration.md#context) and [checkpoint rules](docs/internals.md#remote-compaction-v2-wire-contract).
56
55
 
57
- **Remote windows** require the native `openai-codex` provider with `openai-codex-responses`, or an `openai-responses` gateway implementing the protocol. Gateways require `compatibility.transport: "codex-gateway"` on the exact model entry. This setting does not add the capability to an ordinary compatible endpoint.
58
-
59
- Change `mode` in the example above to `remote-windows`. Eligible sessions expose `new_context`, `get_context_remaining`, `history`, and `notes`. Manual `/compact [instructions]` uses Pi's native text compression of **only the current window**. It does not use the Toolkit remote producer or configured fallback, switch the active model, open another window, or send an automatic continuation. `remote-compaction` is the mode that selects Toolkit's remote/fallback compression chain.
60
-
61
- An existing effective window boundary survives model changes and switches to `remote-compaction` or `pi`: retired history stays outside live requests and every compaction tier. Historical boundaries constrain input; they cannot replace a requested compression with no-summary cleanup. Window identity is preserved for switching back. An unsafe current-window view cancels rather than reopening archived windows. The legacy `leaveManagedMode` setting remains compatible but does not trigger bulk close-out compaction.
62
-
63
- Native text compression cannot read an existing encrypted checkpoint. If that checkpoint owns the current context, native compression/fallback cancels and preserves it instead of summarizing its placeholder and losing information. Compatible remote compression can still reuse it.
64
-
65
- Raw history remains in the local Pi session JSONL; remote `history`/`notes` are separate backend APIs. Window markers alone are not native Pi cutoffs, so request-time isolation requires the extension to be loaded. An old session already ending in a no-summary cleanup may report `Already compacted` before any extension hook; continue with a genuine user message before retrying. Toolkit does not rewrite those logs or bypass Pi's eligibility checks.
66
-
67
- Remote windows use alpha endpoints that may change upstream. When switching models, the remote window remains persisted and reusable; see the [window lifecycle](docs/internals.md#rollover-lifecycle).
56
+ **Remote Windows has been removed**, including its four tools and model-selection recovery. Old window sessions are not continuable: Toolkit refuses branches containing their markers instead of resending retired history. Start a new session; existing files are not rewritten or deleted. Dormant window settings are ignored with a warning, but a selected `remote-windows` mode must be changed explicitly. See [retirement guidance](docs/configuration.md#removed-remote-windows). Shared Codex gateway transport remains available to compaction and images.
68
57
 
69
58
  ## Codex Fast
70
59
 
71
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.
72
61
 
73
- Supports native Codex and recognizable GPT/Codex models on compatible Responses gateways. The selection is saved only in the current session: reload/resume and `new_context` 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.
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.
74
63
 
75
64
  Fast may increase usage/cost. The indicator shows the requested mode, not confirmed backend acceleration; a gateway may reject, ignore, or downgrade it. Opaque gateway model aliases need an existing Codex gateway identity. See the [Fast contract](docs/internals.md#codex-fast-session-control) for scope and lifecycle details.
76
65
 
package/README.zh.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # pi-openai-toolkit
2
2
 
3
- 为 Pi 添加远程上下文窗口、Responses 压缩、联网搜索和图像生成。沿用 Pi 的模型、端点、认证和会话配置,不另行注册提供商或模型。
3
+ 为 Pi 添加 Responses 压缩、联网搜索和图像生成。沿用 Pi 的模型、端点、认证和会话配置,不另行注册提供商或模型。
4
4
 
5
5
  [![npm 版本](https://img.shields.io/npm/v/pi-openai-toolkit.svg)](https://www.npmjs.com/package/pi-openai-toolkit)
6
6
  [![MIT](https://img.shields.io/npm/l/pi-openai-toolkit.svg)](LICENSE)
@@ -47,30 +47,19 @@ Toolkit 只读取一个全局配置文件,即使扩展安装在项目内也一
47
47
  通过 `defaults.context.mode` 或单个模型的 `context.mode` 选择:
48
48
 
49
49
  - `remote-compaction`:默认模式,使用服务端返回的加密检查点继续会话
50
- - `remote-windows`:使用 Codex 远程上下文窗口,通过 `history` 检索较早内容、`notes` 保存交接信息
51
50
  - `pi`:交给 Pi 管理上下文
52
51
 
53
52
  **远程压缩**支持 `openai-responses`、`openai-codex-responses` 和 `azure-openai-responses`,先尝试 V2。官方 OpenAI API-key 路由遇到符合条件的协议失败时,可再尝试一次独立的 `/v1/responses/compact`,并完整保存返回的加密替换窗口用于重放。OpenAI OAuth、原生 Codex、Azure 和网关保持原有 V2 路由。OpenAI subscription-sharing OAuth 与原生 Codex 登录是两种独立授权,凭据不能互换;模型和后端仍须具备相应权限。
54
53
 
55
- 可用 `context.remoteCompaction.model` 指定同一有效 base URL 下的独立压缩模型,不改变当前模型。普通远程压缩的远程尝试全部失败后,会明确提示并继续文本摘要。`nativeFallback.enabled: false` 只关闭 Toolkit 的指定模型回退层,不关闭 Pi 默认摘要。取消操作、来源不匹配或已封存历史被修改时,仍会取消,不能绕过检查点安全检查。详见[上下文配置](docs/configuration.md#context)和[检查点规则](docs/internals.md#remote-compaction-v2-wire-contract)。
54
+ 可用 `context.remoteCompaction.model` 指定同一有效 base URL 下的独立压缩模型,不改变当前模型。指定模型的完整 `provider/model-id` 与当前模型相同时,直接复用当前运行信息、鉴权快照和 session,不重复选择模型,也不会仅因模型相同就改用原生文本摘要。普通远程压缩的远程尝试全部失败后,会明确提示并继续文本摘要。`nativeFallback.enabled: false` 只关闭 Toolkit 的指定模型回退层,不关闭 Pi 默认摘要。取消操作、来源不匹配或已封存历史被修改时,仍会取消,不能绕过检查点安全检查。详见[上下文配置](docs/configuration.md#context)和[检查点规则](docs/internals.md#remote-compaction-v2-wire-contract)。
56
55
 
57
- **远程窗口**需要原生 `openai-codex` 提供商的 `openai-codex-responses` API,或支持相应协议的 `openai-responses` 网关。网关必须在精确模型下设置 `compatibility.transport: "codex-gateway"`;这一设置不会让普通兼容端点自动获得该能力。
58
-
59
- 将上例的 `mode` 改为 `remote-windows` 后,符合条件的会话会提供 `new_context`、`get_context_remaining`、`history` 和 `notes`。手动 `/compact [instructions]` 使用 Pi 原生文本压缩,**只处理当前窗口**。它不调用 Toolkit 的远程 producer 或指定回退模型,不切换当前模型、打开新窗口,也不自动发送续跑提示。只有 `remote-compaction` 模式选择 Toolkit 的远程压缩及回退链路。
60
-
61
- 切换模型或改用 `remote-compaction`、`pi` 模式后,已有的有效窗口边界仍然生效:旧历史不会进入普通请求或任何压缩层。历史边界只限定输入,不能把实际压缩替换成一次无摘要清理。窗口身份仍会保留,便于切回;无法安全重建当前窗口时取消操作,不退回全部归档历史。旧配置中的 `leaveManagedMode` 仍会解析,但不再触发批量 close-out 压缩。
62
-
63
- 原生文本压缩无法读取已有的加密检查点。如果当前上下文由该检查点承接,原生压缩或回退会取消并保留现状,避免把占位文本当作摘要、丢失信息;兼容的远程压缩仍可复用它。
64
-
65
- 完整历史仍保存在本地 Pi 会话 JSONL,远端 `history`、`notes` 则是独立的后端 API。窗口标记本身不是 Pi 原生截断点,运行时隔离仍依赖扩展正常加载。旧会话若恰好以无摘要清理记录结尾,Pi 可能在进入扩展钩子前提示 `Already compacted`;先发送一条正常用户消息再重试。Toolkit 不改写原日志,也不绕过 Pi 的压缩资格检查。
66
-
67
- 远程窗口依赖 alpha 接口,上游可能随时调整。切换模型时远程窗口状态仍会持久化并可复用,详见[窗口生命周期](docs/internals.md#rollover-lifecycle)。
56
+ **Remote Windows 已完整移除**,包括四个工具和旧模型选择恢复逻辑。旧窗口会话不能续跑:Toolkit 会拒绝包含旧标记的分支,避免把已退休历史重新发送给模型。请新建会话;原文件不会被改写或删除。闲置窗口配置只提示退役,仍选择 `remote-windows` 的配置则必须明确改用受支持模式。详见[退役说明](docs/configuration.md#removed-remote-windows)。压缩与生图共用的 Codex gateway 传输支持仍然保留。
68
57
 
69
58
  ## Codex Fast
70
59
 
71
60
  Fast 默认关闭。在 Pi 终端或 pi-web 等支持 UI 的 RPC 客户端中输入 `/fast` 开启,再输入一次关闭。切换结果通过通知确认;状态为 `Fast ON`、`Fast OFF`,不适用的路由为 `Fast N/A`,显示位置由客户端决定。print/JSON 和无 UI 模式不能切换 Fast。无需添加 Fast 配置。
72
61
 
73
- 支持原生 Codex,以及兼容 Responses 网关中可识别的 GPT/Codex 模型。开关只保存在当前会话:reload、续聊和 `new_context` 保留状态,新建或 fork 的会话默认关闭。开启时请求 Fast,关闭时请求标准档,会覆盖符合条件的对话请求中原有的服务档位,但不改变 reasoning effort 或配置文件。
62
+ 支持原生 Codex,以及兼容 Responses 网关中可识别的 GPT/Codex 模型。开关只保存在当前会话:reload 和续聊保留状态,新建或 fork 的会话默认关闭。开启时请求 Fast,关闭时请求标准档,会覆盖符合条件的对话请求中原有的服务档位,但不改变 reasoning effort 或配置文件。
74
63
 
75
64
  Fast 可能增加额度消耗或费用。状态栏表示请求模式,不代表后端已确认加速;网关可能拒绝、忽略或降级请求。无法识别的网关模型别名需要已有的 Codex 网关路由标识。适用范围和生命周期见 [Fast 规则](docs/internals.md#codex-fast-session-control)。
76
65
 
@@ -63,8 +63,7 @@
63
63
  "mode": {
64
64
  "enum": [
65
65
  "pi",
66
- "remote-compaction",
67
- "remote-windows"
66
+ "remote-compaction"
68
67
  ]
69
68
  },
70
69
  "remoteCompaction": {
@@ -74,7 +73,7 @@
74
73
  "$ref": "#/$defs/nativeFallback"
75
74
  },
76
75
  "remoteWindows": {
77
- "$ref": "#/$defs/remoteWindows"
76
+ "$ref": "#/$defs/retiredRemoteWindows"
78
77
  }
79
78
  }
80
79
  },
@@ -122,22 +121,9 @@
122
121
  }
123
122
  }
124
123
  },
125
- "remoteWindows": {
126
- "type": "object",
127
- "additionalProperties": false,
128
- "properties": {
129
- "leaveManagedMode": {
130
- "enum": [
131
- "warn",
132
- "compact"
133
- ]
134
- },
135
- "reminderThresholdPercent": {
136
- "type": "integer",
137
- "minimum": 0,
138
- "maximum": 100
139
- }
140
- }
124
+ "retiredRemoteWindows": {
125
+ "deprecated": true,
126
+ "description": "Remote Windows has been removed. This opaque ancillary value is ignored with a warning; remove it from your configuration. Selecting the removed mode blocks context operations until pi or remote-compaction is explicitly selected."
141
127
  },
142
128
  "webSearch": {
143
129
  "type": "object",
@@ -46,7 +46,7 @@ Known nested objects merge by field. Missing fields inherit, arrays replace inst
46
46
 
47
47
  A missing file uses independent built-in defaults. Invalid JSON, an unreadable file, missing/unsupported `schemaVersion` on a v2-shaped document, or mixed legacy/v2 fields are reported distinctly. Unknown v2 policy keys are errors in their owning scope. Invalid selected settings block dependent operations; they never silently pick a more permissive route. Errors in other models remain visible without replacing a valid current model's policy. A valid exact leaf may shadow an invalid default leaf, but cannot hide a malformed containing object or unknown field in that feature scope.
48
48
 
49
- Each public callback, tool execution, compaction, or config command uses an immutable snapshot across its awaited helpers. The next operation reads again. This does not make separate Pi headers, payload, and tool events one atomic transaction. Windows and results stay out of the config file.
49
+ Each public callback, tool execution, compaction, or config command uses an immutable snapshot across its awaited helpers. The next operation reads again. This does not make separate Pi headers, payload, and tool events one atomic transaction. Session state and results stay out of the config file.
50
50
 
51
51
  ---
52
52
 
@@ -56,36 +56,24 @@ Place `context` under `defaults` or an exact `models` entry.
56
56
 
57
57
  | Relative field | Default | Contract |
58
58
  | --- | --- | --- |
59
- | `mode` | `"remote-compaction"` | `"pi"` delegates ordinary context management to Pi; `"remote-compaction"` uses the eligible Responses checkpoint path; `"remote-windows"` selects Codex windows where supported. |
60
- | `remoteCompaction.model` | `null` | Exact synthetic producer reference for `remote-compaction`, on the same effective base URL. `null` uses the active model; a separate producer never changes the active model. `remote-windows` user `/compact` uses Pi native compression instead. |
61
- | `remoteCompaction.inputSource` | `"legacy"` | `"legacy"` uses canonical session input without request-time context hooks; `"pi-context-hook"` opts into Pi's ordered context projection. An inherited window restricts either source to its current context. Checkpoint provenance must match. |
59
+ | `mode` | `"remote-compaction"` | `"pi"` delegates ordinary context management to Pi; `"remote-compaction"` uses the eligible Responses checkpoint path. |
60
+ | `remoteCompaction.model` | `null` | Exact synthetic producer reference on the same effective base URL. `null` uses the active model. An exact current `provider/model-id` reuses its runtime/auth/session directly without another producer selection; a separate producer never changes the selected session model. |
61
+ | `remoteCompaction.inputSource` | `"legacy"` | `"legacy"` uses canonical session input without request-time context hooks; `"pi-context-hook"` opts into Pi's ordered context projection. Checkpoint provenance must match. |
62
62
  | `remoteCompaction.allowContinuityBreak` | `false` | Allow restarting from Pi context after a foreign compaction entry. It does not make malformed opaque checkpoints replayable. |
63
63
  | `remoteCompaction.apis` | `["openai-responses", "openai-codex-responses", "azure-openai-responses"]` | May narrow this set; `[]` permits no remote-compaction API. Azure uses Pi's resolved `AZURE_OPENAI_*` environment values for the `/openai/v1` Responses path, deployment mapping, and `api-version`; unsupported entries are errors. |
64
64
  | `nativeFallback.enabled` | `true` | Enable the existing native-method fallback tier. |
65
65
  | `nativeFallback.model` | `null` | Summary-model reference on the remote-ineligible path. Character-count estimates do not bypass it; resolution, auth or summary failure cancels compaction without retrying the active model. After a remote attempt fails, the existing producer-first selection is retained. Disabled/unset/same-model selections keep Pi's default path. |
66
66
  | `nativeFallback.thinkingLevel` | `"off"` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`; actual model support still applies. |
67
- | `remoteWindows.leaveManagedMode` | `"warn"` | Legacy compatibility field. Both values preserve the same behavior: non-window models receive only the current local window, and no bulk close-out compaction is started for retired Remote Context history. |
68
- | `remoteWindows.reminderThresholdPercent` | `5` | Integer 0-100. `0` disables both the once-per-window reminder and exhausted-window fallback. |
69
67
 
70
68
  Ordinary remote compaction tries V2 first. One automatic standalone `/v1/responses/compact` attempt is available only for the official HTTPS OpenAI endpoint, an `openai-responses` physical producer, public Pi auth metadata explicitly indicating configured non-OAuth auth, and an outgoing Bearer header matching Pi's resolved key. Missing/unknown auth metadata, an unrelated Authorization override, Codex affinity, OAuth, Azure, and third-party gateways do not opt in. A protocol-compatible rejection or invalid successful V2 checkpoint can qualify; auth/subscription, quota/rate-limit, network, abort, and unrelated server failures do not. No protocol selector, credential switch, or capability cache is added; a selected standalone attempt may add latency/cost.
71
69
 
72
70
  Standalone success preserves the full canonical output window, including retained items, rather than treating retained assistant text as a summary. When actual remote attempts are exhausted, Toolkit warns that no encrypted checkpoint was produced and starts the existing native text-summary chain: the configured remote producer after a remote attempt, or `nativeFallback.model` when remote compaction is unavailable. `nativeFallback.enabled: false` disables only the configured-model tier; disabled/unset/same-model selections still permit Pi's default summary. Explicit summary-model failures and checkpoint-integrity failures cancel. OpenAI subscription-sharing OAuth can reject compaction; separately authenticating native Codex is a different route, not a way to reuse that grant. See the [wire contract](internals.md#remote-compaction-v2-wire-contract).
73
71
 
74
- Native Codex eligibility derives from the actual Pi provider/API. Gateways additionally need the exact transport opt-in below. An effective Remote Window boundary survives model and context-mode changes, including `remote-compaction`, `pi`, and legacy disabled/off settings. Retired history stays outside live requests and all compaction tiers without activating Remote tools for a non-window consumer. Historical boundaries constrain inputs; they do not choose a compression engine or replace requested compression with no-summary cleanup. Normal `new_context` retains its persisted-notes, duplicate and cooldown gates. See [Toolkit internals](internals.md).
72
+ The effective mode determines `/compact [instructions]` policy. `remote-compaction` uses the same ordinary Remote V2, eligible standalone, configured native and Pi-default chain for manual, threshold and overflow compaction. `pi` keeps Pi's normal native policy for clean sessions. An exact same-model remote producer still uses Remote Compaction; equality is not a native-summary shortcut. Different providers with the same bare model ID remain distinct identities.
75
73
 
76
- The effective mode determines user `/compact [instructions]` policy:
74
+ Manual success saves compressed output into the current session and waits for normal user continuation. Toolkit does not switch the selected model/thinking, create another session, synthesize a continuation, or consume/reorder host queues. Pi owns eligibility, scheduling and retry. Existing opaque checkpoints retain their provenance, context-edit, replay and recursive-compaction safety checks.
77
75
 
78
- - `remote-compaction`: Toolkit's ordinary Remote V2, eligible standalone, configured native and Pi-default chain. Manual, threshold and overflow compaction use this same policy, including immediately after leaving window mode.
79
- - `remote-windows`: Pi native text compression of **only the current window**. It does not invoke Toolkit's remote producer or configured fallback, write notes, switch models, call `new_context`, or send a post-compact continuation.
80
- - `pi`: native compression; any inherited effective window still limits the input to current context.
81
-
82
- Input isolation is independent of engine selection. Native compression may run through a scoped public adapter when Pi's original preparation includes archived windows. Missing/edited ownership or an unsafe system/tool head cancels; whole archived history is not a repair source. Compaction results use real visible source IDs, preserve context edits and complete tool pairs, and leave raw session entries unchanged. Owned rollover trim remains a separate maintenance operation, not a successful user compression.
83
-
84
- Scoped native compression uses Pi's public `compact()` and bound model-registry transport, preserving auth, provider environment and current thinking. Host-private custom stream/retry callbacks are not available through this adapter; sessions without a window keep Pi's original default path. An encrypted current owner cannot be converted into a text summary: native/default/fallback cancels and preserves that checkpoint rather than summarizing its placeholder. Compatible remote recursion remains eligible.
85
-
86
- Manual success saves actual compressed output and waits for normal user continuation; Toolkit does not consume or reorder host queues. Pi still owns automatic scheduling and retry. Its pre-hook “nothing to compact” and “already compacted” checks remain: a legacy session already ending at no-summary cleanup needs a genuine new user message before another attempt. Old notes-handoff records remain readable only for owned selection recovery, without retrying inference.
87
-
88
- Local history remains in Pi's session JSONL; `history` and `notes` call separate backend APIs. Window markers alone are not native Pi cutoffs, so request-time filtering cannot guarantee isolation if the extension never loads. Existing native-recognized compaction boundaries remain effective without that filter; Toolkit does not split/delete raw logs or modify the host to create stronger unload guarantees.
76
+ Remote Windows and its compatibility execution chain have been removed. Any active branch carrying old window or manual-handoff evidence is refused before provider dispatch or compression, including in `pi` or disabled mode. This is not a transparent upgrade of old windows; start a new session. See [removed Remote Windows](#removed-remote-windows).
89
77
 
90
78
  ---
91
79
 
@@ -251,6 +239,16 @@ At the compaction and replay boundary, Toolkit applies the declared resize profi
251
239
 
252
240
  ---
253
241
 
242
+ ### Removed Remote Windows
243
+
244
+ Remote Windows, `remote-windows` mode, `new_context`, `get_context_remaining`, `history`, `notes`, window metadata/reminders/rollover, and old manual model-selection recovery have been removed. No alpha history/notes/thread-hint requests or replacement handoff driver remain. Shared Codex gateway compatibility for ordinary compaction, images and other retained features is unchanged.
245
+
246
+ Old window sessions are intentionally not continuable. Toolkit checks only the current branch for reserved window messages, cleanup strategies/sentinel, or old manual-compaction records, even if malformed or superseded by a later checkpoint. Such branches cannot send model requests or compact; start a new session. A clean branch before those records is not blocked by evidence on an abandoned sibling. Existing local/remote files are never deleted, rewritten, migrated or repaired automatically, and saved temporary selections are not restored. The extension must be loaded to enforce this boundary; removing it does not turn window markers into native Pi cutoffs.
247
+
248
+ Dormant v2 `context.remoteWindows` and legacy `leaveManagedMode` / `contextReminderThresholdPercent` values are ignored as opaque retired settings with warnings, not effective policy. Remove them manually. Explicit `mode: "remote-windows"` or legacy `contextManagement: "remote"` is a context error, including after whitespace normalization: explicitly choose `pi` or `remote-compaction`. Toolkit does not silently substitute a potentially paid route. Migration previews flag removed behavior for manual review and do not write configuration or sessions.
249
+
250
+ ---
251
+
254
252
  ### Removed Auto Mode
255
253
 
256
254
  Auto Mode, `/auto`, and `--auto` have been removed. Toolkit no longer performs this feature's tool-call review, background classification, or review confirmations. No replacement approval gate is installed.
@@ -286,10 +284,10 @@ The preview maps recognized fields into a candidate, supplies leaf origins, list
286
284
 
287
285
  | Legacy input | v2 destination |
288
286
  | --- | --- |
289
- | `compaction.enabled` / `contextManagement` | `defaults.context.mode` |
287
+ | `compaction.enabled` | `defaults.context.mode`; removed `contextManagement: "remote"` requires manual review, not automatic substitution |
290
288
  | `compaction.remoteCompactModel`, `remoteV2ContextSource`, `allowCompactionContinuityBreak`, `responsesApis` | `defaults.context.remoteCompaction` fields |
291
289
  | `compaction.nativeFallback` | `defaults.context.nativeFallback` |
292
- | `compaction.leaveManagedMode`, `contextReminderThresholdPercent` | `defaults.context.remoteWindows` fields |
290
+ | `compaction.leaveManagedMode`, `contextReminderThresholdPercent` | Removed; omit with retirement guidance and manual review |
293
291
  | `compaction.gatewayContextModels` | Exact `models[key].compatibility.transport` |
294
292
  | `webSearch.defaultRoute`, `routes`, `models` | Default/exact search route candidates, subject to review below |
295
293
  | `imageGeneration.models` | `allowedModels` plus an explicit default taken from the legacy first entry |
package/docs/internals.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Toolkit Internals
2
2
 
3
- Developer-facing reference for [pi-openai-toolkit](../README.md). The README keeps this protocol and implementation detail out of the installation path. If you are changing wire behavior, fixtures, or the compaction strategy code, start here.
3
+ Developer-facing reference for [pi-openai-toolkit](../README.md). See the [configuration reference](configuration.md) for supported settings and retirement guidance.
4
4
 
5
5
  ---
6
6
 
@@ -8,9 +8,7 @@ Developer-facing reference for [pi-openai-toolkit](../README.md). The README kee
8
8
 
9
9
  - [Configuration resolution](#configuration-resolution)
10
10
  - [Codex Fast session control](#codex-fast-session-control)
11
- - [Remote Context protocol](#remote-context-protocol)
12
- - [Rollover lifecycle](#rollover-lifecycle)
13
- - [Managed manual compact](#managed-manual-compact)
11
+ - [Remote Windows retirement](#remote-windows-retirement)
14
12
  - [Remote Compaction v2 wire contract](#remote-compaction-v2-wire-contract)
15
13
  - [Artifacts and debugging](#artifacts-and-debugging)
16
14
  - [Provenance](#provenance)
@@ -19,166 +17,82 @@ Developer-facing reference for [pi-openai-toolkit](../README.md). The README kee
19
17
 
20
18
  ### Configuration resolution
21
19
 
22
- The single global document is loaded through [src/config.ts](../src/config.ts). [src/config/legacy.ts](../src/config/legacy.ts) owns unversioned compatibility; [src/config/v2.ts](../src/config/v2.ts) validates v2 scopes, resolves exact policy, and records leaf origins. [src/config/policy.ts](../src/config/policy.ts) defines effective values independently of persisted session data. See the [configuration reference](configuration.md) for supported fields and migration limits.
20
+ The single global document is loaded through [src/config.ts](../src/config.ts). [src/config/legacy.ts](../src/config/legacy.ts) owns unversioned compatibility; [src/config/v2.ts](../src/config/v2.ts) validates v2 scopes, resolves exact policy, and records leaf origins. [src/config/policy.ts](../src/config/policy.ts) defines effective values independently of persisted session data.
23
21
 
24
- Feature entrypoints resolve once per public operation and pass that immutable snapshot through awaited helpers. A separately named compaction producer is resolved from the same decoded document for its own identity. Subsequent independent callbacks reload; a compression uses its initiating policy snapshot. Legacy recovery reads only its persisted owned selection record and never initiates a handoff. There is no general cross-event provider transaction, project lookup, singleton cache, or config state writer. Internal legacy-shaped engine adapters preserve compaction/search algorithms without exposing v2 parsing to consumers. Cross-feature gateway policy belongs to the resolver, not the context enable switch.
22
+ Feature entrypoints resolve once per public operation and pass that immutable snapshot through awaited helpers. A separately named compaction producer is resolved from the same decoded document for its own identity. Subsequent independent callbacks reload. There is no general cross-event provider transaction, project lookup, singleton policy cache, or config writer. Shared gateway compatibility belongs to the resolver, independently of context mode.
25
23
 
26
- Selected invalid policy blocks dependent operations; unrelated model errors remain reportable without replacing the selected model. Retired `autoMode` sections are ignored with a warning; they never create effective policy or invalidate other features. Image choices are checked before auth, uploads, or paid requests. The human `/toolkit-config` command inspects effective values, validation, or a migration candidate without action APIs or network access. Migration is preview-only; source bytes and unknown/dormant content stay untouched.
24
+ Selected invalid policy blocks dependent operations; unrelated model errors remain reportable without replacing the selected policy. Retired Auto Mode and ancillary window sections are ignored with controlled warnings and create no effective policy. Selecting the removed window mode blocks context instead of implicitly choosing another route. Image choices are checked before auth, uploads, or paid requests. Human /toolkit-config commands inspect effective values, validation or preview-only migration without action APIs or network access; source bytes remain unchanged.
27
25
 
28
26
  ---
29
27
 
30
28
  ### Codex Fast session control
31
29
 
32
- [src/codex-fast/extension.ts](../src/codex-fast/extension.ts) registers the human-only, no-argument `/fast` toggle and an owned `ctx.ui.setStatus()` item. The command accepts UI-backed TUI/RPC (including pi-web) and older UI contexts without `mode`; print/JSON and headless commands cannot toggle. Notifications confirm changes, while status rendering belongs to the client. Default OFF requests `service_tier: "default"`; ON requests `"priority"`, the Codex Fast wire value. The status is the local request preference, not verified server acceptance or latency. Fast can increase usage/cost. No config setting, model tool, credential probe, retry, new header, reasoning-effort change or custom footer is added.
30
+ [src/codex-fast/extension.ts](../src/codex-fast/extension.ts) registers the human-only, no-argument /fast toggle and an owned ctx.ui.setStatus() item. It accepts UI-backed TUI/RPC (including pi-web) and older UI contexts without mode; print/JSON and headless commands cannot toggle. Notifications confirm changes, while rendering belongs to the client. Default OFF requests service_tier default; ON requests priority. This is the local request preference, not verified backend acceleration. Fast may increase cost; no config setting, model tool, credential probe, reasoning change or custom footer is added.
33
31
 
34
- Native `openai-codex-responses` routes qualify. Non-official HTTP(S) `openai-responses` gateways qualify for recognizable GPT/Codex IDs or an existing 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. A capability marker is not backend entitlement.
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.
35
33
 
36
- Version-1 `pi-openai-toolkit:codex-fast` custom entries contain only the owning Pi `sessionId` and `enabled` boolean. They are excluded from model context. Reload/resume and active-branch navigation reconstruct the latest valid owned preference; malformed latest metadata defaults OFF. Independent new/forked sessions ignore copied foreign preferences and start OFF. Remote window UUID changes do not reset the Pi session selection. A model switch shows N/A without discarding it. Missing identity or a failed append does not report a successful toggle.
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.
37
35
 
38
- The payload hook takes one selection snapshot and returns a new object only when a matching ordinary Responses request needs a tier change. Explicit OFF also overrides an existing Fast/Flex tier to Standard. Dedicated compaction shapes and malformed/foreign payloads are left unchanged. Fast loads after Web Search/image registration and before the final Astra effort pass, so its tier does not alter the pre-search cached extras used by separate search/image/compaction clients.
39
-
40
- Native Pi and Toolkit gateway WebSocket adapters already compare non-input body fields before incremental reuse. A changed `service_tier` invalidates the incompatible `previous_response_id` delta; the existing transport/retry logic is retained. Offline official-Pi fixtures in [test/pi-codex-fast.test.ts](../test/pi-codex-fast.test.ts) cover TUI/RPC command/status/notifications, actual native/gateway HTTP/WebSocket bodies, saved reopen/reload, fork isolation and continuation transitions. They do not establish live Fast availability.
41
-
42
- ---
43
-
44
- ### Remote Context protocol
45
-
46
- Internal alpha endpoints, adapted from `@howaboua/pi-codex-conversion`:
47
-
48
- ```text
49
- POST {base}/alpha/history/v2/list_windows | list_items | read_item | search_contents
50
- POST {base}/alpha/notes/v2/list_files_by_prefix | read_file | search_contents | append_to_file | write_file
51
- POST {base}/alpha/notes/v2/thread_hint
52
- ```
53
-
54
- The native route uses `{base} = <backend-api>/codex` with `Authorization: Bearer <oauth token>`, `ChatGPT-Account-ID`, and Codex CLI headers. The gateway route uses the configured `/v1` base with the API key configured for that provider, `originator: codex_cli_rs`, `X-Codex-Affinity-Scope`, and `X-Codex-Model` carrying the bare model ID. Inherited OAuth headers, cookies, and account IDs are stripped before the request leaves the process. Both routes set `Session-Id` and `X-Client-Request-Id` to the bounded Pi session ID, plus `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, so the upstream backend may change them at any time.
55
-
56
- 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.
57
-
58
- Coverage is never inferred from model names. A native session uses provider `openai-codex` with API `openai-codex-responses` for any model ID. A gateway session uses API `openai-responses` and must carry an exact `provider/model` key whose `models[exact].compatibility.transport` is `"codex-gateway"` (legacy `compaction.gatewayContextModels`); no gateway is opted in by default. See [src/context-management/codex-provider.ts](../src/context-management/codex-provider.ts). The toolkit registers no provider or model with Pi. It resolves credentials and base URLs through Pi's `ModelRegistry`.
59
-
60
- ---
61
-
62
- ### Tool-selection boundary and unavailable Context Management
63
-
64
- The four Toolkit context tools are `new_context`, `get_context_remaining`, `history`, and `notes`. The canonical names live in [src/context-management/tool-contract.ts](../src/context-management/tool-contract.ts). A launcher that creates a Pi session for an exact `compaction.gatewayContextModels` model should union those names into an explicit `tools` allowlist before `createAgentSession`, unless the caller selected `noTools`/`--no-tools`; an explicit `excludeTools` entry remains authoritative and is never re-added. This package does not contain the `pi-subagent` or child-session launcher source, so the helper and contract here do not claim to modify that external layer.
65
-
66
- After registration, Pi's published registry is authoritative. Toolkit distinguishes `verified` (all four owned definitions), `excluded` (a readable registry contains none of them), `unverified` (a transient read or partial publication), and `conflict` (registration/API/ownership failure). Only `excluded` is a live-turn downgrade: `context_with_system` applies the safe local projection at any effective inherited window boundary and strips internal markers, provider payload/header hooks return no-op results, and the lifecycle artifact records `context-tools-excluded`. Without an owned boundary, ordinary child requests remain unchanged apart from marker filtering. Conflicts, unreadable/partial registries, malformed window state and missing gateway identity remain fail-closed for live provider requests.
67
-
68
- If a covered Remote Context session reaches `session_before_compact` without an active context runtime, the first compaction path is the configured `compaction.remoteCompactModel` through Remote V2. The active session model remains the checkpoint consumer; the configured remote model is only the compactor. If that model is missing/unusable, only an explicitly configured/enabled `nativeFallback.model` may run. Otherwise the hook cancels rather than silently invoking the active model or Pi's default compaction. This compaction fallback does not weaken the live-provider safety rules above.
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.
69
37
 
70
38
  ---
71
39
 
72
- ### Rollover lifecycle
73
-
74
- The `new_context` happy path, end to end:
75
-
76
- ```mermaid
77
- sequenceDiagram
78
- accTitle: Remote Context rollover
79
- accDescr: A Pi model checkpoints notes, requests a local new_context boundary, and sends the next request with the new window identity.
80
- participant Model
81
- participant Toolkit
82
- participant Pi
83
- participant Backend
84
- Model->>Toolkit: notes append_to_file (checkpoint)
85
- Toolkit->>Backend: alpha notes request (encrypted args)
86
- Backend-->>Toolkit: encrypted_output
87
- Model->>Toolkit: new_context
88
- Toolkit->>Toolkit: verify successful notes write in this window
89
- Toolkit-->>Model: checkpoint receipt with the successful note path
90
- Toolkit-->>Pi: new window marker persisted
91
- Note over Model: Context switch is complete; read the receipt once, then resume the active task
92
- Model->>Backend: next request with the new x-codex-window-id
93
- Pi->>Toolkit: session_before_compact
94
- Toolkit->>Toolkit: resolve boundary against Pi's effective context
95
- Toolkit-->>Pi: safe no-summary boundary, or cancel obsolete cleanup
96
- ```
97
-
98
- State invariants the lifecycle code must keep honest:
99
-
100
- - The checkpoint gate verifies a successful `notes` `append_to_file` or `write_file` against the persisted session branch after the latest window boundary, so it survives restarts and forks. A response with `ok: false` or `success: false` is not successful, even when HTTP returns 200.
101
- - The gate uses the live session/branch identity from `ctx.sessionManager`; cached manager identity must not hide a valid current-window pair, and old or foreign-session evidence must remain rejected.
102
- - Every rollover carries the most recent successful checkpoint path in its handoff message. The optional `thread_hint` is supplemental; a hint failure must not erase the local receipt.
103
- - A successful rollover closes the pre-rollover checkpoint phase. The first turn in the new window reads the receipt once and resumes the active user task; it must not immediately create another checkpoint or call `new_context` as part of that handoff. A later checkpoint is only for a later rollover, and `canRolloverFromCurrentWindow()` enforces it: a window entered by a rollover has to produce a tool result from a tool that is not one of `new_context`, `get_context_remaining`, `history`, or `notes` before it can roll over again.
104
- - Pi 0.87 separates conversation-only `context` handlers from full-transcript `context_with_system` handlers. Toolkit uses the latter to trim windows and re-anchor the merged prompt/tool state with `preserveSystemHead()`. The output owns its leading system message; Pi does not repair it after this phase.
105
- - When even that rebuild would lose declared tools, the trim is refused and the full message list is sent: a window that still carries the previous turns is usable, a window with no tools silently degrades into a chat the model can only narrate. Each refusal is reported once per window and lost-tool set through `takeProjectionDiagnostics()`, which writes a `context.projection.tool_loadout_shrink` compaction artifact and warns in the UI.
106
- - The manager also remembers the head it last anchored. When a boundary compaction retires the transcript entry that declared the tools, the branch itself no longer contains a system message, and the remembered head is re-anchored instead of sending a tool-less window. The cache is request-time only, refreshed by every projection, and cleared by `reset()`.
107
- - `new_context` has no force escape hatch: a persisted successful notes checkpoint in the current window is always required before rollover. The model must wait for the notes result to be persisted before retrying.
108
- - After a marker is accepted for sending, the manager keeps a session/window-anchored pending guard until that exact target marker is persisted or the session changes. A duplicate `new_context` during this persistence gap returns `started: false` and sends no second marker; projected/in-memory messages do not retire the guard. The exact queued target can already trim the current Remote request and select its metadata, but this preview is recomputed per request and never authorizes maintenance compaction before persistence.
109
- - Budget checks are skipped until the current window has produced its own assistant usage. Acting on the previous window's usage anchor would burn the once-per-window reminder on a false alarm.
110
- - Pi's canonical session projection is the source of effective history. Toolkit may further restrict that projection, but never reconstruct omitted or summarized messages from the raw branch. Boundary resolution uses projected source entries and the active branch's latest compaction; an older marker retained inside a newer compaction does not authorize dropping that compaction's summary.
111
- - Window identity and cleanup eligibility are separate. A persisted `codex-context-window` message restores identity after reload/fork, but its historical `trimPreviousWindow` flag is not an outstanding command. A newer native summary or opaque checkpoint supersedes old cleanup without erasing window identity. Missing or edited boundary evidence is never repaired by loading raw history.
112
- - Genuine owned rollover maintenance may persist a safe no-summary boundary. It must not move the retained start backwards or replace a newer summary/checkpoint. User `/compact` and remote-compaction threshold/overflow do not treat that cleanup as successful compression: they prepare a strictly scoped current-window input and complete actual compression in the same host operation. Preparation alone changes no durable state.
113
- - An effective persisted window boundary belongs to the session, not the selected model or context mode. `context_with_system`, `before_provider_request`, and `session_before_compact` synchronize it before mode-specific exits, including `remote-compaction`, `pi`, and legacy disabled/off selections. A non-window consumer receives only the effective current context, with the current system/tool head preserved and internal markers removed; no Remote tools, metadata or affinity headers are activated by the local safety check. A pre-window opaque checkpoint cannot rehydrate retired history after local projection. A historical boundary limits the input of configured, remote, native and Pi-default compactors; it does not select an engine or cause an intermediate no-summary commit. Once a later ordinary compaction owns effective context, the historical window does not suppress its summary or valid opaque replay. A genuinely new window can retire that checkpoint. Disabling opaque checkpoint generation through `responsesApis` does not disable required replay of an inherited checkpoint; an unsupported transport, authentication failure, or endpoint mismatch aborts the request instead of exposing its placeholder. The legacy `leaveManagedMode` setting remains compatible but does not start a bulk close-out from `model_select` or `agent_settled`.
114
- - Native text summarization delegates prompt construction, tool-result truncation, split-turn requests and output limits to Pi's `compact()`. Toolkit does not use character-count estimates to reject the configured summary model. If its resolution, authentication or summary generation fails, compaction is cancelled with the error and context is preserved; the active model is not an implicit retry target. Disabled/unset/same-model selections retain native current-model policy. If the host preparation contains retired windows, a scoped adapter must produce the genuine native result instead of returning undefined with unsafe input. Remote-window projection excludes retired history before every producer call.
115
-
116
- ---
40
+ ### Remote Windows retirement
117
41
 
118
- ### Managed manual compact
42
+ Remote Windows and its execution/compatibility chain are removed: no window tools, history/notes/thread-hint client, window metadata/ingest rewriting, reminders, rollover, maintenance, scoped-window compaction or manual selection recovery remain. Shared ordinary gateway/auth/session-affinity support is separate and retained.
119
43
 
120
- There is no dedicated Remote Windows user `/compact` execution or post-idle continuation. The built-in command and Pi scheduler remain unchanged. Engine selection is independent of persisted window ownership:
44
+ A minimal pure detector recognizes reserved evidence on the **current branch**: codex-context-window custom messages, cleanup compaction strategies or the exact old no-summary sentinel, and pi-openai-toolkit:manual-compact custom records. Malformed, terminal or superseded evidence is also refused; abandoned sibling entries do not affect a clean branch. No old ownership/projector is reconstructed.
121
45
 
122
- 1. Recognize explicitly owned rollover maintenance before user-manual routing, even though both can have reason `manual`.
123
- 2. Only effective `context.mode=remote-compaction` chooses Toolkit's ordinary remote/fallback policy. `remote-windows` and `pi` select Pi native text compression, not the Toolkit producer or configured fallback.
124
- 3. Build immutable current-window input from Pi's canonical projection whenever a window constrains context. Exclude retired plaintext, opaque checkpoints and file-operation metadata. Preserve the current prompt/tools, edits, complete tool pairs, owning checkpoint and real retained source IDs. Missing ownership or unsafe head repair cancels instead of reopening raw history.
125
- 4. Remote compression uses the entire scoped window, including verified opaque replay and current tool declarations. Hook-source preparation executes both ordered phases once in a read-only async scope; legacy skips those hooks. Native compression rebuilds cut/split-prefix/previous-summary/file-operation preparation within the same scope. Merely filtering messages or cloning a hook event cannot make an unsafe host default preparation safe.
126
- 5. Native execution uses public `compact()` with bound `ctx.modelRegistry.streamSimple`, model-specific auth/base URL/env and current thinking. The extension context does not expose host-private custom stream/retry callbacks; unscoped defaults remain host-owned. An existing opaque owner, even with malformed reserved details, cannot be merged by text summarization: cancel native/default/fallback and preserve it. A compatible remote compactor may still replay it; never resurrect its retired plaintext.
127
- 6. Return actual compressed output to Pi for normal persistence. No intermediate cleanup commit, model switch, notes-writing duty, window rollover or synthetic continuation is part of user `/compact`. General cancellation and ownership checks remain required through consumption of the hook result; host queues stay untouched.
46
+ Full-context and provider-dispatch boundaries abort legacy-window requests before old plaintext/sentinels can be transmitted. Compression returns an explicit cancellation before remote, standalone, native or host-default dispatch, including Pi/disabled modes. Throwing alone is insufficient because Pi can treat a rejected before-compact hook as absent. Startup/navigation notices do not replace per-operation checks.
128
47
 
129
- Normal notes/history and explicit `new_context` are preserved. The raw session JSONL retains previous windows for audit; the backend history/notes APIs are separate storage. Request-time filtering is not a durable isolation guarantee when the extension never loads: Pi recognizes native compaction cutoffs, not Toolkit window markers by themselves.
130
-
131
- Pi's pre-hook empty/already-compacted outcomes remain unchanged. A legacy session already ending at no-summary cleanup must receive a genuine new user entry before retrying. Toolkit does not fabricate entries, rewrite old logs or patch host eligibility. Old version-1 `pi-openai-toolkit:manual-compact` records remain decodable for owned selection recovery only; reload/navigation never retries notes, rollover or inference, and a newer user selection wins.
132
-
133
- The public SDK fixtures in [test/pi-compaction-policy.test.ts](../test/pi-compaction-policy.test.ts) verify actual producer/native input, disk persistence, manual no-continuation behavior and native threshold/overflow recovery with isolated HOME/settings and mocked native/gateway traffic.
48
+ Start a new session to continue. Toolkit does not rewrite/delete files, migrate backend notes, restore temporary models/thinking, create a new session automatically or synthesize a continuation. The extension must be loaded to enforce refusal; historical markers alone are not native Pi cutoffs. See [retirement configuration](configuration.md#removed-remote-windows).
134
49
 
135
50
  ---
136
51
 
137
52
  ### Remote Compaction v2 wire contract
138
53
 
139
- V2 serves eligible `remote-compaction` operations, including manual, threshold and overflow. A model that Remote Context declines, such as a gateway without an exact transport opt-in, can still use this path when its API appears in `context.remoteCompaction.apis`. `remote-windows` user-manual operations use native compression instead. An effective inherited window constrains input without changing that policy. Compaction generation follows the active strategy. Across mode changes, an already-persisted checkpoint remains authoritative until a safe newer window or compaction replaces it; a historical window identity alone must not suppress checkpoint replay.
54
+ Eligible remote-compaction operations use the same ordinary policy for manual, threshold and overflow. APIs are narrowed by context.remoteCompaction.apis. Pi mode leaves clean-session compaction with Pi; retired sessions remain refused in every mode. Pi owns eligibility, scheduling, persistence and continuation; there is no replacement scheduler or manual post-idle driver.
55
+
56
+ The selected model is the checkpoint **consumer**. An optional configured model is the synthetic **producer**, never a selected-model change. An unset producer or an exact full provider/model-id match reuses the current runtime, auth snapshot and session directly; a current virtual selection reuses its resolved physical runtime. Different provider/model identities still resolve separately and must share the consumer's normalized authenticated effective base URL. Matching bare model IDs or endpoint alone is not same-model equality. A successful exact-match remote path is not a native-summary shortcut.
140
57
 
141
- 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, with 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.
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.
142
59
 
143
- 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 HTTP body stays open; reader cancellation is best-effort cleanup and is not awaited. Incomplete frames at EOF, conflicting checkpoint evidence and terminal errors cannot become successful checkpoints.
60
+ 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.
144
61
 
145
- A missing, empty, or invalid V2 checkpoint is never stored. Ordinary compaction may then try the gated standalone protocol below; exhausted remote attempts warn once and enter the unchanged native text-summary chain. A failed remote operation selects `remoteCompactModel` for the configured native tier; a remote-ineligible model selects `nativeFallback.model`. Disabled/unset/same-model selections delegate to Pi's default summary, including when `nativeFallback.enabled` is false. Explicit summary-model failures cancel instead of retrying with the active model. Aborts and projection/provenance/context-edit failures still cancel immediately. `remoteCompactModel` must resolve to the same effective base URL as the active consumer, which is never switched for synthetic requests.
62
+ 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.
146
63
 
147
64
  #### Official API-key standalone fallback
148
65
 
149
- The ordinary path reuses one resolved physical producer, auth snapshot, and prepared full input. After a qualifying V2 failure, it makes at most one POST to `https://api.openai.com/v1/responses/compact`. Eligibility requires `openai-responses`, no Codex gateway affinity, public `ModelRegistry.hasConfiguredAuth(model) === true` and `isUsingOAuth(model) === false`, and the final Authorization header matching the resolved Bearer key. Missing/throwing/nonboolean metadata is unknown, not API-key evidence. Provider aliases may qualify at the official endpoint; OAuth, native Codex, Azure, custom gateways and inactive automatic Remote Context recovery do not opt into this standalone fallback. No token-shape inspection, extra auth resolution, model/account switch, redirect, capability cache, or generated version/beta header is introduced.
66
+ The ordinary path reuses one resolved physical producer, auth snapshot and prepared input. After a qualifying V2 failure, at most one POST goes to https://api.openai.com/v1/responses/compact. Eligibility requires openai-responses, no Codex affinity, public hasConfiguredAuth(model) true and isUsingOAuth(model) false, and final Authorization matching the resolved Bearer key. Missing/throwing/nonboolean metadata is unknown. OAuth, native Codex, Azure and custom gateways do not opt in; provider aliases can qualify at the official endpoint. There is no token-shape inference, extra auth resolution, account/model switch, redirect, capability cache or automatic version/beta header.
150
67
 
151
- Qualifying failures are HTTP 400/404/405/422/501 without auth/quota exclusions, invalid/empty successful V2 checkpoint responses, or streamed errors with a recognized unsupported-protocol code. HTTP 401/403/429, known subscription/auth/billing/rate-limit restrictions, network failures, aborts, and generic server outages never trigger another protocol probe. OpenAI subscription-sharing OAuth and native Codex OAuth are distinct grants; selecting a separately authenticated Codex route does not authorize copying its credential to OpenAI.
68
+ Qualifying failures include HTTP 400/404/405/422/501 without auth/quota exclusions, invalid/empty successful V2 checkpoints and recognized unsupported-protocol streamed errors. HTTP 401/403/429, subscription/auth/billing/rate-limit restrictions, network errors, aborts and generic server outages never authorize a probe. OpenAI subscription-sharing OAuth and native Codex OAuth are separate grants, not interchangeable credentials.
152
69
 
153
- Standalone JSON contains `model`, `input`, `instructions` and only validated SDK-supported service-tier/cache fields. It omits `previous_response_id`, stream/store/tools/reasoning/text and the V2 trigger. A nonempty output must contain at least one nonempty encrypted `compaction` item and no malformed checkpoint. Every returned item and unknown structured field survives in original order, including retained user/assistant messages. Unlike V2, this protocol does not impose a single-output-item invariant. The existing `openai-native-compact-v1` strategy and an honest opaque window marker are persisted with consumer/producer identity, input provenance, deferred tools and Pi's `tokensBefore`. Retained assistant text is not a portable summary.
70
+ Standalone JSON contains model, input, instructions and only validated service-tier/cache fields. It omits previous_response_id, stream/store/tools/reasoning/text and the V2 trigger. A nonempty output needs at least one valid encrypted checkpoint; all items and unknown structured fields, including an own __proto__ key, survive in order. Unlike V2, multiple checkpoints are allowed. Persist the existing openai-native-compact-v1 strategy and honest opaque sentinel with consumer/producer/provenance/deferred metadata and Pi's tokensBefore. Retained assistant text is not a portable summary.
154
71
 
155
- Existing persistence/replay splices the entire canonical window between the leading prompt and live tail. Recursion uses that window plus current live tail once; verified Pi-retained copies are removed, current deferred schemas load after the end of the whole window, and historical declarations remain intact. Standalone cancellation can win before JSON checkpoint acceptance; V2's validated terminal remains authoritative over later reader cleanup cancellation.
72
+ Replay splices the **whole canonical array** between leading prompts and the live tail. Recursion sends the array plus live tail once; retained copies are verified/removed, current deferred schemas load after the whole array and historical declarations stay intact. Standalone cancellation can win before JSON acceptance; a validated V2 terminal wins over later cleanup cancellation. Isolated mock wire and real-Pi persistence/reopen/continuation fixtures cover both input modes; they do not establish live API-key acceptance.
156
73
 
157
- The API-key path is covered by isolated mocked wire tests and real Pi persistence/reopen/continuation fixtures in both input-source modes. This is not live API-key acceptance. Earlier credentialed evidence used native Codex OAuth only; it does not establish API-key or OpenAI subscription-sharing OAuth support for every model/account.
74
+ #### Canonical context and replay
158
75
 
159
- Pi 0.87 makes `SessionManager` the source of model-visible context. An omitted `context.remoteCompaction.inputSource` keeps `"legacy"` behavior: first compaction reads `buildSessionProjection()` (falling back to Pi's preparation if unavailable), and recursion uses the opaque window plus the canonically projected branch tail. Both paths honor persisted context edits. Legacy mode still bypasses request-time extension transforms.
76
+ Pi SessionManager supplies model-visible context. The default legacy source reads buildSessionProjection() for first compaction (using Pi preparation only when projection is unavailable) and uses the opaque checkpoint plus canonical branch tail recursively. Persisted context edits remain effective; this mode bypasses request-time extension transforms.
160
77
 
161
- Setting `context.remoteCompaction.inputSource: "pi-context-hook"` opts into a narrow runtime bridge around Pi's public `ExtensionRunner.createContext()`. It adds a non-enumerable `ctx.projectContextForCompaction(messages)` method backed by `ExtensionRunner.emitContext()`. This runs the ordered conversation-only and full-transcript phases on the canonical projection. If the bridge, session projection, or recursive summary anchor is unavailable, the extension cancels rather than sending unprojected history.
78
+ The pi-context-hook source uses the existing narrow bridge around ExtensionRunner.createContext(), exposing non-enumerable ctx.projectContextForCompaction(messages) backed by emitContext(). Both ordered conversation-only and full-transcript phases run on canonical input. Missing bridge/projection/recursive summary anchor cancels rather than sending raw unprojected history.
162
79
 
163
- Retained-message matching uses the SDK projection and source entry IDs, including omissions and replacements made before compaction. Older retained compaction entries contribute no second summary. A compaction whose kept boundary is its own ID retains no earlier messages. Edits to post-checkpoint input are applied to the live tail; an edit targeting history already sealed in an opaque checkpoint blocks replay and recursive compaction with `checkpoint-context-edited`. The encrypted checkpoint cannot be selectively rewritten. Start a new session or navigate before that checkpoint to rebuild from editable history; the raw log remains unchanged.
80
+ Retained-copy matching uses canonical contributions and real source IDs. Older retained compactions contribute no second summary; a kept boundary equal to the checkpoint itself retains none. Post-checkpoint edits apply to the live tail. An edit targeting sealed history blocks replay/recursion with checkpoint-context-edited: encrypted content cannot be selectively rewritten. Navigate before it or start a new session to rebuild; raw logs stay unchanged.
164
81
 
165
- New checkpoints record `inputProvenance: "pi-context-hook-v1"` or `"legacy-raw-context-v1"`, and replay/recursion reject missing or mode-mismatched markers without searching past the latest compaction. Retained `role: "custom"` messages are optional during replay because they may be changed or removed by context hooks; required user, assistant, and complete tool-call/result content remains ordered and fail-closed.
82
+ Checkpoints record pi-context-hook-v1 or legacy-raw-context-v1 provenance. Missing/mismatched provenance is not repaired by searching past the newest checkpoint. Effective endpoint compatibility is authoritative; consumer/producer provider/API/model fields are diagnostic. Optional custom retained messages may be changed/removed by hooks, but required user/assistant/complete tool pairs remain ordered and fail-closed.
83
+
84
+ Deferred-tool carryover uses valid cache-stack activation metadata without taking ownership of it. Only uniquely matched real schemas are moved to supported additional_tools/tool_search load points immediately after the full checkpoint boundary. Preserve unrelated tools, immutable payloads, unknown fields and current prompt state.
166
85
 
167
86
  ---
168
87
 
169
88
  ### Artifacts and debugging
170
89
 
171
- With `diagnostics.level: "debug"`, the toolkit writes lifecycle and compaction artifacts under `diagnostics.artifactRoot` (default `~/.pi/agent/artifacts/pi-openai-toolkit/compaction`):
90
+ Debug diagnostics write lifecycle/compaction artifacts under diagnostics.artifactRoot, defaulting to ~/.pi/agent/artifacts/pi-openai-toolkit/compaction. Request capture and compact-response capture are independently opt-in; neither is a reason to log ordinary conversation responses. Keep them off unless diagnosing a specific operation.
172
91
 
173
- - Each `session_start` writes a lifecycle artifact whose `activation` field records `active` or the exact inactive reason, such as `unsupported-model`, `unsupported-api`, `missing-api-key`, `auth-resolution-failed`, or `tool-name-conflict`.
174
- - `diagnostics.captureRequests` independently writes provider request metadata and payloads, while `diagnostics.captureResponses` writes compact status and structural summaries with complete response and body fields critically redacted. Keep both off unless inspecting a specific request.
175
- - Artifacts always redact Authorization credentials, API keys and tokens, Codex account IDs, and opaque `encrypted_content` or `encrypted_output`, even when `diagnostics.redactSensitiveData` is `false`.
176
- - Compaction failures record protocol, stable reason/status, controlled public error identifiers/hints and the next step. Arbitrary provider messages and raw bodies are never promoted into diagnostics; unknown identifiers are omitted, and network exceptions use a generic content-free message. Debug-enabled headless runs record the same remote-to-native transition without requiring UI notifications.
92
+ Credentials, account IDs and opaque encrypted_content/encrypted_output are critically redacted even when optional redaction is disabled. Failures retain protocol, stable reason/status, controlled public identifiers/hints and next step, not arbitrary provider messages or raw bodies. Debug headless operation records remote-to-native transitions without dumping configuration to stdout. Retired-session diagnostics contain controlled reasons and guidance, never saved note/transcript content.
177
93
 
178
94
  ---
179
95
 
180
96
  ### Provenance
181
97
 
182
- 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).
183
-
184
- Protocol fixtures live in [src/context-management/](../src/context-management/) and must be updated together with any upstream alpha endpoint change. New wire behavior requires fixture-based tests.
98
+ Historical Remote Context work was adapted from @howaboua/pi-codex-conversion@3.0.29 (commit 7021ae48e8efe36a3becc5830d529696ff798e5e); that active feature has been removed. Astra compatibility 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 is preserved in [NOTICE](../NOTICE). Current protocol changes require fixture-based ordinary compaction/search/image/transport regressions, not resurrected window fixtures.
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-openai-toolkit",
3
- "version": "0.23.2",
3
+ "version": "0.24.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=22.19.0"
8
8
  },
9
- "description": "OpenAI toolkit for Pi: Codex Remote Context windows, remote compaction v2, routed Web Search, image gen.",
9
+ "description": "OpenAI toolkit for Pi: remote compaction v2, routed Web Search, image generation and Codex utilities.",
10
10
  "author": "awoaCrim and contributors",
11
11
  "license": "MIT",
12
12
  "repository": {
@@ -58,20 +58,7 @@
58
58
  "src/details-store.ts",
59
59
  "src/deferred-tool-carryover.ts",
60
60
  "src/extension-runtime.ts",
61
- "src/context-management/types.ts",
62
- "src/context-management/messages.ts",
63
- "src/context-management/window-budget.ts",
64
- "src/context-management/window-request.ts",
65
- "src/context-management/window-bulk.ts",
66
- "src/context-management/window-manager.ts",
67
- "src/context-management/scoped-compaction.ts",
68
- "src/context-management/manual-compact.ts",
69
- "src/context-management/codex-provider.ts",
70
- "src/context-management/history-notes.ts",
71
- "src/context-management/tools.ts",
72
- "src/context-management/namespace-tools.ts",
73
- "src/context-management/responses-tools.ts",
74
- "src/context-management/tool-contract.ts",
61
+ "src/retired-remote-windows.ts",
75
62
  "src/image-generation/artifacts.ts",
76
63
  "src/image-generation/client.ts",
77
64
  "src/image-generation/eligibility.ts",