pi-cache-optimizer 2.8.15 → 2.8.17

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
@@ -33,10 +33,9 @@ Pi extension for improving provider-side KV / prompt cache hit rates. It keeps s
33
33
 
34
34
  ## What it does
35
35
 
36
- - Reorders uniquely identifiable stable system-prompt content before dynamic context. If the same candidate appears more than once (for example, quoted inside dynamic context), it is left unchanged to avoid removing the wrong occurrence.
37
- - Compresses Pi skill listings and strips session-overview churn.
36
+ - Compresses Pi's skill list into a grouped Markdown list that keeps every skill name and description (only the XML envelope and repeated paths are removed), and strips session-overview churn. Both are in-place edits that never move content between Pi's prompt sections, and they also apply to OpenAI Responses/Codex models. (Earlier versions also lifted "stable" content to the front of the prompt; Pi >= 0.86 already orders its sections from stable to variable, and measured prefix stability was identical, so that step was removed.)
38
37
  - Requests long cache retention when Pi/provider compat supports it.
39
- - Adds a session-id `prompt_cache_key` fallback for `openai-completions` / `openai-responses` payloads when no effective key exists, including Pi's built-in `llama.cpp` provider as Pi 0.82+ core does.
38
+ - Adds a conservative session-id `prompt_cache_key` fallback for `openai-completions` proxy payloads when no effective key exists. Pi 1.0+ owns this field for Responses/Codex transports.
40
39
  - Warns once for third-party OpenAI-compatible proxies missing cache/session-affinity compat flags.
41
40
  - Detects adaptive-thinking compat for Claude (opus-4.6+ including Opus 5, sonnet-4.6+ including Sonnet 5, fable-5+) and Kimi Coding K3 / `kimi-for-coding` custom channels.
42
41
  - Stores cache statistics in per-extension-instance atomic shards, so parent sessions, child Pi agents, and parallel Pi processes cannot overwrite one another.
@@ -63,7 +62,7 @@ Run `/reload` in Pi after install/update/remove so extension hooks refresh.
63
62
 
64
63
  On Pi 0.79.7 and newer, `pi update` updates Pi itself only. To update installed Pi packages such as this extension, run `pi update --extensions` (packages only) or `pi update --all` (Pi + packages).
65
64
 
66
- This extension requires Pi 0.82+ and is validated against Pi 0.99.2. It uses the official Pi package types directly for type-checking, along with extension hooks, `getAgentDir()`, and prompt options shared by those versions; it does not depend on Pi 0.83+ APIs such as `ctx.scopedModels` or the bundled TypeBox 1.3 aliases. Native virtual model support and codemode nested-call coalescing activate only on Pi 0.99+ hosts that produce them; older hosts keep the previous behavior.
65
+ This extension requires Pi 0.82+ and is validated against Pi 1.0.0. It uses the official Pi package types directly for type-checking, along with extension hooks, `getAgentDir()`, and prompt options shared by those versions; it does not depend on Pi 0.83+ APIs such as `ctx.scopedModels` or the bundled TypeBox 1.3 aliases. Native virtual model support and codemode nested-call coalescing activate only on Pi 0.99+ hosts that produce them; older hosts keep the previous behavior. The local development baseline uses Node.js 22.19.0 or newer, matching Pi 1.0.0's engine requirement.
67
66
 
68
67
  ## Commands
69
68
 
@@ -72,7 +71,7 @@ This extension requires Pi 0.82+ and is validated against Pi 0.99.2. It uses the
72
71
  | `/cache-optimizer` | Interactive menu when UI supports it; otherwise prints help and current state. |
73
72
  | `/cache-optimizer enable` | Enables runtime optimizations for the current Pi process, resets local footer stats, and starts a fresh “enabled” measurement. |
74
73
  | `/cache-optimizer disable` | Disables optimization for the current Pi process, resets local footer stats, and keeps collecting footer stats in disabled comparison mode. Run `/reload` or restart Pi to return to startup behavior. |
75
- | `/cache-optimizer doctor` | Shows active model/provider/API/base URL/compat plus low-hit diagnosis. |
74
+ | `/cache-optimizer doctor` | Shows active model/provider/API/base URL/compat, whether the skill list was compressed on the last prompt (and why not, e.g. an unrecognised Pi format), plus low-hit diagnosis. |
76
75
  | `/cache-optimizer compat` | Shows copyable compat advice for the active model, if applicable. |
77
76
  | `/cache-optimizer stats` | Shows detailed counters for every cache-adapter-matched model used by the current conversation session today. |
78
77
  | `/cache-optimizer stats all` | Shows detailed per-model totals across all valid local sessions/shards today, including request and token counts. |
@@ -87,6 +86,8 @@ This extension requires Pi 0.82+ and is validated against Pi 0.99.2. It uses the
87
86
 
88
87
  The interactive `/cache-optimizer` menu includes `Footer mode`, where you can choose `total`, `session`, or `process`. `enable` / `disable` are current-process switches. For a persistent opt-out, use environment variables below.
89
88
 
89
+ Doctor displays endpoint URLs without username/password, query parameters, or fragments. Invalid URLs are shown as unavailable; the actual transport URL is never changed.
90
+
90
91
  ## Persistent opt-out
91
92
 
92
93
  | Env var | Effect |
@@ -97,7 +98,7 @@ The interactive `/cache-optimizer` menu includes `Footer mode`, where you can ch
97
98
  | `PI_CACHE_OPTIMIZER_NO_OPENAI_CACHE_KEY=1` | Disable the OpenAI-compatible `prompt_cache_key` fallback. Preferred explicit opt-out. |
98
99
  | `PI_CACHE_OPTIMIZER_OPENAI_CACHE_KEY=0` | Disable the same fallback via the legacy inverse switch. Values `0`, `false`, `no`, or `off` disable it. |
99
100
 
100
- Persistent feature settings are managed under the Pi agent directory by the native command interface. They take precedence over their corresponding environment variables:
101
+ Persistent feature settings are managed under the Pi agent directory by the native command interface. They take precedence over their corresponding environment variables, including both OpenAI cache-key switches above. Runtime `disable` still suppresses optimization regardless of persistent settings:
101
102
 
102
103
  ```text
103
104
  /cache-optimizer config prompt-rewrite on|off
@@ -109,7 +110,7 @@ Persistent feature settings are managed under the Pi agent directory by the nati
109
110
  /cache-optimizer config reset
110
111
  ```
111
112
 
112
- `config reset` removes persistent feature overrides while preserving the existing footer mode and model-specific prompt-cache-key settings. These commands do not modify shell startup files or `PI_CACHE_RETENTION`; `enable` and `disable` remain current-process runtime switches.
113
+ `config reset` reads the latest disk configuration under the shared transaction lock and removes only persistent feature overrides, preserving the latest footer mode, model-specific prompt-cache-key settings, and file permissions. Invalid JSON/schema, symlinks, non-regular targets, and concurrent manual changes are refused rather than overwritten. These commands do not modify shell startup files or `PI_CACHE_RETENTION`; `enable` and `disable` remain current-process runtime switches.
113
114
 
114
115
  ## Opt-in deterministic tool ordering
115
116
 
@@ -131,6 +132,8 @@ The fixture verifier reports numeric tool-order changes and confirms cache-marke
131
132
 
132
133
  Current versions store stats under `pi-cache-optimizer-stats.d/shards/` in Pi's agent directory. Each loaded extension instance owns one UUID-named shard and writes it through temp-file + atomic rename. This prevents parent/child/parallel Pi processes from overwriting one another. Upgrading from the old v6 single-file format deletes the old local stats files and starts footer counters from zero; upstream provider caches are not affected.
133
134
 
135
+ Response stats stay with the dispatched catalog/request-local model even if you switch to another model on the same provider while waiting. Legacy response aliases use the request snapshot, not the new selection; the footer continues showing the selected direct model. Old corrupt JSON/schema shards expire by file modification time after 48 hours; young corrupt files, valid current-day shards, live old instances, and symlink targets remain protected.
136
+
134
137
  The footer defaults to `session`, which reflects the current Pi conversation rather than another parallel Pi terminal using the same provider/model. Use either the command or environment variable to select the scope:
135
138
 
136
139
  | Value | Effect |
@@ -151,7 +154,7 @@ The explicit setting is stored in `pi-cache-optimizer-config.json` under Pi's ag
151
154
 
152
155
  ## Per-model `prompt_cache_key` opt-out
153
156
 
154
- Some OpenAI-compatible endpoints reject `prompt_cache_key` with HTTP 400 even though the same field is valid for other providers. Pi 0.99.2 has no native `supportsPromptCacheKey` compat field; do **not** add that unknown field to `models.json`. `supportsLongCacheRetention` is not an equivalent switch and should not be used for this purpose.
157
+ Some OpenAI-compatible Completions endpoints reject `prompt_cache_key` with HTTP 400 even though the same field is valid for other providers. Pi 1.0.0 owns the key for Responses/Codex transports; this extension's key opt-out and fallback apply only to `openai-completions`. Pi 1.0.0 has no native `supportsPromptCacheKey` compat field; do **not** add that unknown field to `models.json`. `supportsLongCacheRetention` is not an equivalent switch and should not be used for this purpose.
155
158
 
156
159
  When the extension observes an explicit field-level `prompt_cache_key` unsupported error for the exact provider/model, ordinary `/cache-optimizer fix` offers a confirmed model-scoped repair. Value-validation failures and conditional restrictions such as “not allowed when temperature is set” do not qualify. If concurrent responses from different models cannot be correlated because Pi provides no request ID, header-only evidence is ignored unless the finalized assistant message supplies exact provider/model identity. If you already know that the endpoint rejects the field, use the explicit command:
157
160
 
@@ -165,7 +168,7 @@ The preview explains that the setting is stored in the extension-owned `pi-cache
165
168
 
166
169
  Third-party `openai-completions` proxies (LiteLLM / OneAPI / NewAPI / OpenRouter-like channels) often route one session across multiple upstream backends. That splits provider-side prompt caches.
167
170
 
168
- Pi 0.84.1 also fixes built-in Fireworks compatibility for models that reject `prompt_cache_retention`; the extension avoids provider-name special cases and resolves exact provider/model compat from `models.json` plus the runtime model. Pi 0.81+ also has a built-in `llama.cpp` provider using an OpenAI-shaped transport. Pi 0.82+ core generates a session `prompt_cache_key` for it when cache retention is enabled, so this extension preserves that key and may add the same conservative fallback when missing. The built-in provider's explicit compat fingerprint is excluded from generic proxy routing/session-affinity advice, but a custom or overridden provider that merely reuses the id `llama.cpp` is treated like any other OpenAI-compatible channel. `prompt_cache_retention` remains subject to the normal safety rule: keep it only for official OpenAI or an explicit effective `supportsLongCacheRetention: true` opt-in in `models.json`; otherwise strip it before sending. Pi 0.99.2 has no native `supportsPromptCacheKey` compat field, so the per-model key opt-out is stored in this extension's `pi-cache-optimizer-config.json` instead of `models.json`. The extension config is independent of Pi's compat precedence and only affects the exact provider/model listed there.
171
+ Pi 0.84.1 also fixes built-in Fireworks compatibility for models that reject `prompt_cache_retention`; the extension avoids provider-name special cases and resolves exact provider/model compat from `models.json` plus the runtime model. Pi 0.81+ also has a built-in `llama.cpp` provider using an OpenAI-shaped transport. The extension keeps its session-id key fallback for third-party `openai-completions` channels, while Pi 1.0+ owns the key for Responses/Codex transports. The built-in provider's explicit compat fingerprint is excluded from generic proxy routing/session-affinity advice, but a custom or overridden provider that merely reuses the id `llama.cpp` is treated like any other OpenAI-compatible channel. `prompt_cache_retention` remains subject to the normal safety rule: keep it only for official OpenAI or an explicit effective `supportsLongCacheRetention: true` opt-in in `models.json`; otherwise strip it before sending. The extension-owned `pi-cache-optimizer-config.json` stores per-model key opt-outs only for `openai-completions`.
169
172
 
170
173
  For real proxies, start with session affinity:
171
174
 
@@ -191,7 +194,7 @@ Notes:
191
194
 
192
195
  - `sendSessionAffinityHeaders: true` is the safe default when your proxy supports sticky routing.
193
196
  - `supportsLongCacheRetention: true` is optional. Add it only when the endpoint explicitly supports OpenAI long prompt cache retention.
194
- - Do not add `supportsPromptCacheKey` to `models.json`: Pi 0.99.2 does not define that compat field. Use `/cache-optimizer fix prompt-cache-key` to store an exact provider/model omit rule in the extension-owned config; it removes both key spellings, including a key supplied by Pi.
197
+ - Do not add `supportsPromptCacheKey` to `models.json`: Pi 1.0.0 does not define that compat field. Use `/cache-optimizer fix prompt-cache-key` to store an exact provider/model omit rule in the extension-owned config; it removes both key spellings, including a key supplied by Pi.
195
198
  - If you see `400 Unsupported parameter: prompt_cache_retention`, remove/avoid `supportsLongCacheRetention` for that channel. Keep `sendSessionAffinityHeaders` if supported. The extension detects the explicit error from response headers or the finalized assistant error message and strips the parameter from subsequent requests in the current process.
196
199
  - Use `/cache-optimizer compat` or `/cache-optimizer doctor` to see model-specific advice.
197
200
  - DeepSeek model names select the `DS cache` adapter only; they do not prove a reasoning wire protocol. Generic cache/routing advice remains active for absent or non-DeepSeek formats. DeepSeek replay advice is shown only when effective `compat.thinkingFormat: "deepseek"` is explicitly configured; it never treats `thinkingFormat` as a missing fix key.
@@ -382,7 +385,7 @@ Pi 0.99 lets extensions register virtual models with `pi.registerVirtualModel()`
382
385
  - Request hooks read the dispatched model id from the provider payload and match it against physical models with configured credentials. The `prompt_cache_key` fallback, `prompt_cache_retention` safety, Anthropic TTL repair, and per-model `prompt_cache_key` omit rules then apply to that physical model. If several credentialed providers share the id and would be treated differently, the extension does not guess; identity-dependent request changes are skipped.
383
386
  - Footer stats and `/cache-optimizer doctor`, `compat`, `stats`, `reset`, and `fix` use the physical model that answered last on the current session branch, matching Pi's own routed-model display and context limits. Doctor and compat name both the virtual selection and that physical model.
384
387
  - Before Pi routes the first request, the footer stays empty and diagnostics ask you to send a prompt first.
385
- - Prompt rewriting is skipped for virtual selections by default: Pi picks the physical model after the system prompt is built, and a reordered prompt must not reach a safety-filtered Codex route. `PI_CACHE_OPTIMIZER_VIRTUAL_REWRITE=1` is an explicit opt-in only when the routing registry exposes a complete candidate chain and every candidate is a known non-Responses, non-Codex transport; unknown or incomplete routes remain unchanged.
388
+ - Prompt rewriting is skipped for virtual selections by default: Pi picks the physical model after the system prompt is built, and the rewritten prompt is not sent to a route whose backend is unknown. `PI_CACHE_OPTIMIZER_VIRTUAL_REWRITE=1` is an explicit opt-in only when the routing registry exposes a complete candidate chain and every candidate is a known non-Responses, non-Codex transport; unknown or incomplete routes remain unchanged.
386
389
  - The session-affinity header bridge is skipped as well, because Pi builds request headers before the payload exists. Pi still sends the physical model's own configured affinity headers.
387
390
 
388
391
  ## For router / virtual-channel extension authors
@@ -413,7 +416,7 @@ For seamless final cache-stat attribution, relay the real upstream identity on c
413
416
 
414
417
  ### Optional: live route registry for pre-response UX
415
418
 
416
- Final message metadata is enough for post-response stats. For pre-response flows — footer display before the first response, `/cache-optimizer doctor`, `/cache-optimizer compat`, `/cache-optimizer reset`, and OpenAI-compatible `prompt_cache_key` fallback — register a live route adapter under `Symbol.for("pi.routing.registry.v1")`.
419
+ Final message metadata is enough for post-response stats. For pre-response flows — footer display before the first response, `/cache-optimizer doctor`, `/cache-optimizer compat`, `/cache-optimizer reset`, and the `openai-completions` `prompt_cache_key` fallback — register a live route adapter under `Symbol.for("pi.routing.registry.v1")`.
417
420
 
418
421
  Protocol shape:
419
422
 
@@ -510,12 +513,11 @@ Then run `/reload` or restart Pi. Optional local state cleanup (if you use `PI_C
510
513
 
511
514
  Do not delete `models.json` during cleanup; it contains your Pi model/provider configuration and is not owned by this package.
512
515
 
513
- ## Verify effect
516
+ ## Optional: inspect cache stats
517
+
518
+ No validation step is required after installation. If you want to inspect what the provider reports, watch the footer or run `/cache-optimizer stats`. `/cache-optimizer doctor` is available when diagnosing a third-party proxy configuration.
514
519
 
515
- 1. Select a model whose provider exposes cache usage.
516
- 2. Send several similar turns in the same Pi session.
517
- 3. Watch the footer or run `/cache-optimizer stats`.
518
- 4. For third-party proxies, also run `/cache-optimizer doctor` and confirm sticky routing / session affinity on the proxy side.
520
+ The repository also contains maintainer-only benchmark and A/B research tools under `benchmarks/`. They are not part of the published package and are not required for normal use.
519
521
 
520
522
  ## License
521
523
 
package/README.zh-CN.md CHANGED
@@ -33,10 +33,9 @@
33
33
 
34
34
  ## 功能
35
35
 
36
- - 将能唯一定位的稳定 system prompt 内容移动到动态上下文之前。如果同一候选出现多次(例如动态上下文引用了它),则保持原样,避免删除错误的那一处。
37
- - 压缩 Pi skill 列表,并移除 session-overview 中的易变字段。
36
+ - 将 Pi 的 skill 列表压缩为按目录分组的 Markdown 列表,保留每个 skill 的名称和完整描述(只去掉 XML 外壳和重复路径),并移除 session-overview 中的易变字段。这两项都是原位修改,不会在 Pi 的提示段之间搬移内容,对 OpenAI Responses/Codex 模型同样生效。(早期版本还会把“稳定”内容提到提示最前面;Pi 0.86 起已按从稳定到易变的顺序拼段,实测前缀稳定性没有差别,因此移除了这一步。)
38
37
  - 在 Pi / provider compat 支持时请求长缓存保留。
39
- - 对 `openai-completions` / `openai-responses` 请求,在没有有效 key 时使用 Pi session id 补 `prompt_cache_key`;Pi 0.82+ core 对内置 `llama.cpp` 也使用这一语义。
38
+ - 仅对 `openai-completions` 代理请求,在没有有效 key 时使用 Pi session id 保守补 `prompt_cache_key`;Pi 1.0+ 已负责 Responses/Codex transport 的 key。
40
39
  - 对缺少缓存 / session-affinity compat 的第三方 OpenAI-compatible 代理给出一次性提醒。
41
40
  - 检测 Claude(opus-4.6+ 含 Opus 5、sonnet-4.6+ 含 Sonnet 5、fable-5+)以及 Kimi Coding K3 / `kimi-for-coding` 自定义渠道的 adaptive-thinking compat。
42
41
  - 使用每个 extension instance 独占的原子 shard 保存缓存统计,避免父会话、子 Pi agent 和并行 Pi 进程互相覆盖。
@@ -63,7 +62,7 @@ pi remove npm:pi-deepseek-cache-optimizer && pi install npm:pi-cache-optimizer
63
62
 
64
63
  Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安装的 Pi package(包括本扩展),请运行 `pi update --extensions`(只更新 packages)或 `pi update --all`(Pi 与 packages 一起更新)。
65
64
 
66
- 本扩展要求 Pi 0.82+,并已使用 Pi 0.99.2 验证。TypeScript 校验直接使用官方 Pi package 类型,同时只使用这些版本共有的 extension hooks、`getAgentDir()` 和 prompt options;不依赖 Pi 0.83+ 专有 API(例如 `ctx.scopedModels` 或 bundled TypeBox 1.3 aliases)。原生虚拟模型支持与 codemode 嵌套工具调用合并只在会产生它们的 Pi 0.99+ 上生效,较早版本保持原有行为。
65
+ 本扩展要求 Pi 0.82+,并已使用 Pi 1.0.0 验证。TypeScript 校验直接使用官方 Pi package 类型,同时只使用这些版本共有的 extension hooks、`getAgentDir()` 和 prompt options;不依赖 Pi 0.83+ 专有 API(例如 `ctx.scopedModels` 或 bundled TypeBox 1.3 aliases)。原生虚拟模型支持与 codemode 嵌套工具调用合并只在会产生它们的 Pi 0.99+ 上生效,较早版本保持原有行为。本地开发基线需要 Node.js 22.19.0 或更高版本,与 Pi 1.0.0 的 engine 要求一致。
67
66
 
68
67
  ## 命令
69
68
 
@@ -72,7 +71,7 @@ Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安
72
71
  | `/cache-optimizer` | UI 支持时打开交互菜单;否则打印帮助和当前状态。 |
73
72
  | `/cache-optimizer enable` | 在当前 Pi 进程中开启运行时优化,清零本地 footer 统计,并开始新的“开启状态”测量。 |
74
73
  | `/cache-optimizer disable` | 在当前 Pi 进程中关闭优化,清零本地 footer 统计,并继续以 disabled 对比模式采集 footer 统计。运行 `/reload` 或重启 Pi 后回到启动时行为。 |
75
- | `/cache-optimizer doctor` | 显示当前模型 / provider / API / base URL / compat 与低命中诊断。 |
74
+ | `/cache-optimizer doctor` | 显示当前模型 / provider / API / base URL / compat、上一次提示中 skill 列表是否被压缩(未压缩时给出原因,例如无法识别 Pi 的格式)以及低命中诊断。 |
76
75
  | `/cache-optimizer compat` | 对当前模型显示可复制的 compat 建议(如适用)。 |
77
76
  | `/cache-optimizer stats` | 显示当前 conversation session 今天使用过的各 cache-adapter-matched 模型详细统计。 |
78
77
  | `/cache-optimizer stats all` | 显示所有有效本地 session/shard 今天的逐模型详细总计,包括请求数与 token 数。 |
@@ -87,6 +86,8 @@ Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安
87
86
 
88
87
  交互式 `/cache-optimizer` 菜单包含 `Footer mode`,可以选择 `total`、`session` 或 `process`。`enable` / `disable` 是当前进程内开关。若要持久关闭某些能力,请使用下面的环境变量。
89
88
 
89
+ Doctor 显示的 endpoint URL 会移除用户名/密码、查询参数和 fragment。无效 URL 显示为不可用;实际 transport URL 不会被修改。
90
+
90
91
  ## 持久 Opt-out
91
92
 
92
93
  | 环境变量 | 作用 |
@@ -97,7 +98,7 @@ Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安
97
98
  | `PI_CACHE_OPTIMIZER_NO_OPENAI_CACHE_KEY=1` | 关闭 OpenAI-compatible `prompt_cache_key` fallback。推荐使用这个显式 opt-out。 |
98
99
  | `PI_CACHE_OPTIMIZER_OPENAI_CACHE_KEY=0` | 通过旧的反向开关关闭同一个 fallback。取值 `0`、`false`、`no`、`off` 时关闭。 |
99
100
 
100
- 持久化 feature 配置由 Pi agent 目录中的原生命令管理,并且优先于对应环境变量:
101
+ 持久化 feature 配置由 Pi agent 目录中的原生命令管理,并且优先于对应环境变量,包括上面的两个 OpenAI cache-key 开关。运行时 `disable` 仍会抑制优化,不受持久配置影响:
101
102
 
102
103
  ```text
103
104
  /cache-optimizer config prompt-rewrite on|off
@@ -109,7 +110,7 @@ Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安
109
110
  /cache-optimizer config reset
110
111
  ```
111
112
 
112
- `config reset` 会移除持久化 feature 覆盖,同时保留现有 footer mode 和按模型配置的 prompt-cache-key 设置。这些命令不会修改 shell 启动文件或 `PI_CACHE_RETENTION`;`enable` 和 `disable` 仍然是当前进程的运行时开关。
113
+ `config reset` 在共享事务锁内读取最新磁盘配置,只移除持久化 feature 覆盖,保留最新 footer mode、按模型配置的 prompt-cache-key 设置和文件权限。JSON/schema 无效、symlink、非普通文件或并发手动修改时会拒绝覆盖。这些命令不会修改 shell 启动文件或 `PI_CACHE_RETENTION`;`enable` 和 `disable` 仍然是当前进程的运行时开关。
113
114
 
114
115
  ## Opt-in 确定性工具排序
115
116
 
@@ -131,6 +132,8 @@ bun .trellis/tasks/09-03-context-epoch-tool-ordering/verify.ts
131
132
 
132
133
  当前版本把统计保存在 Pi agent 目录的 `pi-cache-optimizer-stats.d/shards/` 下。每个已加载的 extension instance 独占一个 UUID 命名 shard,并通过临时文件 + 原子 rename 写入,因此父/子/并行 Pi 进程不会互相覆盖。旧 v6 单文件统计在升级时直接删除,本地 footer 计数从零开始;不会影响上游 provider 的实际缓存。
133
134
 
135
+ 即使等待响应时切换到同一 provider 的另一个模型,响应统计仍归属于实际请求的 catalog/request-local 模型。旧 transport 的响应别名只根据请求快照处理,不使用新选择的模型;footer 继续显示当前选择的 direct 模型。损坏 JSON/schema 的旧 shard 按文件修改时间在 48 小时后清理;较新的损坏文件、有效的当天 shard、仍存活的旧 instance 和 symlink 目标均受保护。
136
+
134
137
  Footer 默认使用 `session`,避免另一个并行 Pi 终端使用相同 provider/model 时污染当前窗口。可以通过命令或环境变量切换显示范围:
135
138
 
136
139
  | 值 | 作用 |
@@ -151,7 +154,7 @@ Footer 默认使用 `session`,避免另一个并行 Pi 终端使用相同 prov
151
154
 
152
155
  ## 按模型关闭 `prompt_cache_key`
153
156
 
154
- 某些 OpenAI-compatible endpoint 会因 `prompt_cache_key` 返回 HTTP 400,但同一个字段对其他 provider 可能有效。Pi 0.99.2 没有原生的 `supportsPromptCacheKey` compat 字段,**不要**把这个未知字段加入 `models.json`。`supportsLongCacheRetention` 也不是等价开关,不应借用来实现此目的。
157
+ 某些 OpenAI-compatible Completions endpoint 会因 `prompt_cache_key` 返回 HTTP 400,但同一个字段对其他 provider 可能有效。Pi 1.0+ 已负责 Responses/Codex transport 的 key;本扩展的 fallback 和 opt-out 只作用于 `openai-completions`。Pi 1.0.0 没有原生的 `supportsPromptCacheKey` compat 字段,**不要**把这个未知字段加入 `models.json`。`supportsLongCacheRetention` 也不是等价开关,不应借用来实现此目的。
155
158
 
156
159
  当扩展观察到精确 provider/model 对 `prompt_cache_key` 的明确字段级拒绝后,普通 `/cache-optimizer fix` 会提供经过确认的模型级修复。参数值校验失败,以及“设置 temperature 时不允许”这类条件限制都不构成证据。若不同模型的响应并发交错,而 Pi 又没有提供 request ID,扩展会忽略无法安全关联的 response-header 证据;只有最终 assistant message 提供精确 provider/model 身份时才恢复归因。如果你已经确定 endpoint 不支持该字段,可以主动执行:
157
160
 
@@ -165,7 +168,7 @@ Footer 默认使用 `session`,避免另一个并行 Pi 终端使用相同 prov
165
168
 
166
169
  LiteLLM / OneAPI / NewAPI / 类 OpenRouter 渠道等第三方 `openai-completions` 代理,常会把同一个 session 分散到多个上游后端,导致 provider 侧 prompt cache 被拆散。
167
170
 
168
- Pi 0.84.1 还修复了内置 Fireworks 渠道对拒绝 `prompt_cache_retention` 的模型兼容性;本扩展不按 provider 名称增加特殊分支,而是结合 `models.json` 与 runtime model,按精确 provider/model 解析有效 compat。Pi 0.81+ 也内置了使用 OpenAI-shaped transport 的 `llama.cpp` provider。Pi 0.82+ core 在启用 cache retention 时会为它生成 session `prompt_cache_key`,因此本扩展会保留该 key,并在缺失时使用同样的保守 fallback。只有符合 Pi 内置 provider 明确 compat 指纹的模型会跳过通用 proxy 路由 / session-affinity 建议;仅复用 `llama.cpp` id 的自定义或覆盖 provider 仍按普通 OpenAI-compatible 渠道处理。`prompt_cache_retention` 继续遵循统一安全规则:仅官方 OpenAI 或 `models.json` 中有效配置为 `supportsLongCacheRetention: true` 时保留,否则发送前移除。Pi 0.99.2 没有原生的 `supportsPromptCacheKey` compat 字段,因此按模型关闭 key 的策略保存在本扩展的 `pi-cache-optimizer-config.json` 中,而不是 `models.json`。扩展配置独立于 Pi 的 compat 优先级,只影响其中列出的精确 provider/model。
171
+ Pi 0.84.1 还修复了内置 Fireworks 渠道对拒绝 `prompt_cache_retention` 的模型兼容性;本扩展不按 provider 名称增加特殊分支,而是结合 `models.json` 与 runtime model,按精确 provider/model 解析有效 compat。Pi 0.81+ 也内置了使用 OpenAI-shaped transport 的 `llama.cpp` provider。本扩展只对第三方 `openai-completions` 保留 session-id key fallback;Pi 1.0+ 已负责 Responses/Codex transport 的 key。只有符合 Pi 内置 provider 明确 compat 指纹的模型会跳过通用 proxy 路由 / session-affinity 建议;仅复用 `llama.cpp` id 的自定义或覆盖 provider 仍按普通 OpenAI-compatible 渠道处理。`prompt_cache_retention` 继续遵循统一安全规则:仅官方 OpenAI 或 `models.json` 中有效配置为 `supportsLongCacheRetention: true` 时保留,否则发送前移除。Pi 1.0.0 没有原生的 `supportsPromptCacheKey` compat 字段,因此仅对 `openai-completions` 按模型关闭 key 的策略保存在本扩展的 `pi-cache-optimizer-config.json` 中,而不是 `models.json`。扩展配置独立于 Pi 的 compat 优先级,只影响其中列出的精确 provider/model。
169
172
 
170
173
  对真正的代理,建议先启用 session affinity:
171
174
 
@@ -191,7 +194,7 @@ Pi 0.84.1 还修复了内置 Fireworks 渠道对拒绝 `prompt_cache_retention`
191
194
 
192
195
  - `sendSessionAffinityHeaders: true` 是安全默认项,前提是你的代理支持 sticky routing。
193
196
  - `supportsLongCacheRetention: true` 是可选项。只有 endpoint 明确支持 OpenAI long prompt cache retention 时才添加。
194
- - 不要把 `supportsPromptCacheKey` 加入 `models.json`:Pi 0.99.2 没有定义这个 compat 字段。请使用 `/cache-optimizer fix prompt-cache-key` 在扩展自有配置中保存精确 provider/model 的 omit 规则;它会移除两种 key 写法,包括 Pi 提供的 key。
197
+ - 不要把 `supportsPromptCacheKey` 加入 `models.json`:Pi 1.0.0 没有定义这个 compat 字段。请使用 `/cache-optimizer fix prompt-cache-key` 在扩展自有配置中保存精确 provider/model 的 omit 规则;它会移除两种 key 写法,包括 Pi 提供的 key。
195
198
  - 如果出现 `400 Unsupported parameter: prompt_cache_retention`,请为该渠道移除 / 避免 `supportsLongCacheRetention`;如支持,可保留 `sendSessionAffinityHeaders`。扩展会从响应头或最终 assistant error message 中识别这条明确错误,并在当前进程的后续请求中移除该参数。
196
199
  - 使用 `/cache-optimizer compat` 或 `/cache-optimizer doctor` 查看当前模型的具体建议。
197
200
  - DeepSeek 模型名只用于选择 `DS cache` adapter,不能证明 reasoning wire protocol。缺少或使用非 DeepSeek format 时仍保留通用缓存 / 路由建议;只有 effective `compat.thinkingFormat: "deepseek"` 被明确配置时,才显示 DeepSeek replay 建议,且不会把 `thinkingFormat` 列为缺失修复项。
@@ -381,7 +384,7 @@ Pi 0.99 允许扩展通过 `pi.registerVirtualModel()` 注册虚拟模型。选
381
384
  - 请求 hook 从 provider payload 中读取实际派发的模型 id,并在已配置凭证的物理模型中匹配。`prompt_cache_key` fallback、`prompt_cache_retention` 安全规则、Anthropic TTL 修复以及按模型关闭 `prompt_cache_key` 的规则都按该物理模型生效。如果多个已配置凭证的 provider 共用同一个 id 且处理方式不同,扩展不会猜测,而是跳过依赖模型身份的请求修改。
382
385
  - Footer 统计以及 `/cache-optimizer doctor`、`compat`、`stats`、`reset`、`fix` 使用当前会话分支上最近一次应答的物理模型,与 Pi 自身显示的路由模型和 context 上限一致。doctor 与 compat 会同时标出虚拟选择和该物理模型。
383
386
  - 在 Pi 路由第一个请求之前,footer 保持为空,诊断会提示先发送一个 prompt。
384
- - 虚拟选择默认不做 prompt 改写:Pi 在构建 system prompt 之后才决定物理模型,重排后的 prompt 不应被送到有安全过滤的 Codex 路由。只有设置 `PI_CACHE_OPTIMIZER_VIRTUAL_REWRITE=1` 且 routing registry 暴露完整候选链、所有候选都是已知的非 Responses / 非 Codex transport 时,才允许改写;路由未知或信息不完整时仍保持原 prompt。
387
+ - 虚拟选择默认不做 prompt 改写:Pi 在构建 system prompt 之后才决定物理模型,改写后的 prompt 不应被送到后端未知的路由。只有设置 `PI_CACHE_OPTIMIZER_VIRTUAL_REWRITE=1` 且 routing registry 暴露完整候选链、所有候选都是已知的非 Responses / 非 Codex transport 时,才允许改写;路由未知或信息不完整时仍保持原 prompt。
385
388
  - Session-affinity header 桥接同样跳过,因为 Pi 在 payload 生成之前就构造请求 header。Pi 仍会发送物理模型自身配置的 affinity header。
386
389
 
387
390
  ## Router / Virtual-channel 扩展作者指南
@@ -412,7 +415,7 @@ Pi 0.99 允许扩展通过 `pi.registerVirtualModel()` 注册虚拟模型。选
412
415
 
413
416
  ### 可选:用于预响应 UX 的实时路由注册表
414
417
 
415
- 最终 message metadata 足以支持响应后的统计。若要支持响应前流程——首次响应前的 footer 显示、`/cache-optimizer doctor`、`/cache-optimizer compat`、`/cache-optimizer reset` 和 OpenAI-compatible `prompt_cache_key` fallback——请在 `Symbol.for("pi.routing.registry.v1")` 下注册 live route adapter。
418
+ 最终 message metadata 足以支持响应后的统计。若要支持响应前流程——首次响应前的 footer 显示、`/cache-optimizer doctor`、`/cache-optimizer compat`、`/cache-optimizer reset` 和 `openai-completions` 的 `prompt_cache_key` fallback——请在 `Symbol.for("pi.routing.registry.v1")` 下注册 live route adapter。
416
419
 
417
420
  协议形状:
418
421
 
@@ -509,12 +512,11 @@ pi remove npm:pi-cache-optimizer
509
512
 
510
513
  清理时不要删除 `models.json`;它保存你的 Pi 模型 / provider 配置,不属于本包。
511
514
 
512
- ## 验证效果
515
+ ## 可选:查看缓存统计
516
+
517
+ 安装后不需要再做任何验证步骤,正常使用即可。如果希望查看 provider 实际报告的缓存情况,可以观察 footer,或运行 `/cache-optimizer stats`;排查第三方代理配置时可使用 `/cache-optimizer doctor`。
513
518
 
514
- 1. 选择一个 provider 会暴露 cache usage 的模型。
515
- 2. 在同一个 Pi session 中连续发送几轮相似请求。
516
- 3. 观察 footer,或运行 `/cache-optimizer stats`。
517
- 4. 对第三方代理,再运行 `/cache-optimizer doctor`,并在代理侧确认 sticky routing / session affinity。
519
+ 仓库中的 `benchmarks/` 仅用于维护者做基准测试、A/B 实验和研究验证。它们不会进入发布包,也不是普通用户正常使用本扩展所需要的步骤。
518
520
 
519
521
  ## License
520
522