pi-cache-optimizer 2.8.5 → 2.8.7
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 +50 -7
- package/README.zh-CN.md +48 -6
- package/index.ts +2308 -204
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
Pi extension for improving provider-side KV / prompt cache hit rates. It keeps stable prompt content near the front, adds a conservative OpenAI-compatible `prompt_cache_key` fallback, warns about common proxy cache-routing gaps, and shows read-only footer cache stats.
|
|
11
11
|
|
|
12
|
-
> Renamed from `pi-deepseek-cache-optimizer`. Existing footer counters migrate automatically. The extension does **not** touch Pi's `models.json` during normal operation (default: `~/.pi/agent/models.json`; custom agent dirs use `PI_CODING_AGENT_DIR`)
|
|
12
|
+
> Renamed from `pi-deepseek-cache-optimizer`. Existing footer counters migrate automatically. The extension does **not** touch Pi's `models.json` during normal hook operation (default: `~/.pi/agent/models.json`; custom agent dirs use `PI_CODING_AGENT_DIR`). Only `/cache-optimizer fix` and `/cache-optimizer rollback` may edit it, both after an explicit interactive preview + confirmation with an automatic timestamped backup.
|
|
13
13
|
|
|
14
14
|
## Contents
|
|
15
15
|
|
|
@@ -17,10 +17,12 @@ Pi extension for improving provider-side KV / prompt cache hit rates. It keeps s
|
|
|
17
17
|
- [Install](#install)
|
|
18
18
|
- [Commands](#commands)
|
|
19
19
|
- [Persistent opt-out](#persistent-opt-out)
|
|
20
|
+
- [Opt-in deterministic tool ordering](#opt-in-deterministic-tool-ordering)
|
|
20
21
|
- [Footer cache stats mode](#footer-cache-stats-mode)
|
|
21
22
|
- [OpenAI-compatible proxy setup](#openai-compatible-proxy-setup)
|
|
22
23
|
- [Adaptive thinking models](#adaptive-thinking-models)
|
|
23
24
|
- [Auto-repair with `/cache-optimizer fix`](#auto-repair-with-cache-optimizer-fix)
|
|
25
|
+
- [DeepSeek protocol safety and rollback](#deepseek-protocol-safety-and-rollback)
|
|
24
26
|
- [Footer stats](#footer-stats)
|
|
25
27
|
- [For router / virtual-channel extension authors](#for-router--virtual-channel-extension-authors)
|
|
26
28
|
- [Uninstall](#uninstall)
|
|
@@ -38,6 +40,7 @@ Pi extension for improving provider-side KV / prompt cache hit rates. It keeps s
|
|
|
38
40
|
- Stores cache statistics in per-extension-instance atomic shards, so parent sessions, child Pi agents, and parallel Pi processes cannot overwrite one another.
|
|
39
41
|
- Shows current conversation-session provider/model footer stats by default; `total` aggregates all valid local shards for the exact provider/model.
|
|
40
42
|
- Supports optional router-extension integration through versioned global protocols (`Symbol.for("pi.routing.registry.v1")` and `Symbol.for("pi.cache.hints.v1")`) without importing router packages.
|
|
43
|
+
- Includes disabled-by-default deterministic ordering for verified built-in tool payloads.
|
|
41
44
|
|
|
42
45
|
Caching is provider-side and best-effort. Third-party proxies and router extensions can still hide cache usage, reject unsupported parameters, or route requests across multiple upstreams.
|
|
43
46
|
|
|
@@ -57,7 +60,7 @@ Run `/reload` in Pi after install/update/remove so extension hooks refresh.
|
|
|
57
60
|
|
|
58
61
|
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).
|
|
59
62
|
|
|
60
|
-
This extension requires Pi 0.82+ and is validated against Pi 0.84.
|
|
63
|
+
This extension requires Pi 0.82+ and is validated against Pi 0.84.4. 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.
|
|
61
64
|
|
|
62
65
|
## Commands
|
|
63
66
|
|
|
@@ -73,7 +76,8 @@ This extension requires Pi 0.82+ and is validated against Pi 0.84.2. It uses the
|
|
|
73
76
|
| `/cache-optimizer stats contributors` | Shows current/other contributing sessions for the active exact provider/model without exposing session ids. |
|
|
74
77
|
| `/cache-optimizer reset` | Resets local footer stats for the active provider/model; upstream provider cache is not modified. |
|
|
75
78
|
| `/cache-optimizer config footer-mode total\|session\|process` | Persist the footer stats mode. Persistent command configuration overrides the environment variable. |
|
|
76
|
-
| `/cache-optimizer fix` | Auto-repairs safe compat issues for the active model
|
|
79
|
+
| `/cache-optimizer fix` | Auto-repairs safe compat issues for the active model. Shows preview + risk warning, requires confirmation. **Only modifies `models.json` after explicit user approval.** |
|
|
80
|
+
| `/cache-optimizer rollback` | Reviews the latest matching confirmed fix and, after UI confirmation, restores it safely without overwriting unrelated `models.json` changes. |
|
|
77
81
|
|
|
78
82
|
`/cache-optimizer` uses Pi's native Tab completion. Type `/cache-optimizer <Tab>` for the supported subcommands, `/cache-optimizer stats <Tab>` for `all` or `contributors`, `/cache-optimizer c<Tab>` for `config`, `/cache-optimizer config <Tab>` for `footer-mode`, and `/cache-optimizer config footer-mode <Tab>` for `total`, `session`, or `process`. Suggestions are prefix-filtered and invalid prefixes are left to Pi's normal fallback behavior.
|
|
79
83
|
|
|
@@ -88,6 +92,22 @@ The interactive `/cache-optimizer` menu includes `Footer mode`, where you can ch
|
|
|
88
92
|
| `PI_CACHE_OPTIMIZER_NO_OPENAI_CACHE_KEY=1` | Disable the OpenAI-compatible `prompt_cache_key` fallback. Preferred explicit opt-out. |
|
|
89
93
|
| `PI_CACHE_OPTIMIZER_OPENAI_CACHE_KEY=0` | Disable the same fallback via the legacy inverse switch. Values `0`, `false`, `no`, or `off` disable it. |
|
|
90
94
|
|
|
95
|
+
## Opt-in deterministic tool ordering
|
|
96
|
+
|
|
97
|
+
`PI_CACHE_OPTIMIZER_TOOL_ORDER=1` enables deterministic ordering for verified tool definitions in Pi's built-in OpenAI Completions, Anthropic, Google, and Bedrock payload shapes. Truthy values are `1`, `true`, `yes`, or `on` (case-insensitive). The feature is off by default, process-local, and suppressed by `/cache-optimizer disable`.
|
|
98
|
+
|
|
99
|
+
Tools are sorted by exact name with their original index as the stable tie-breaker. The normalizer shallow-clones only the verified object/array path that changes. Tool objects and unrelated request fields retain their identity, including Google/Vertex `AbortSignal`; tool schemas, choices, routing fields, and caller input are preserved.
|
|
100
|
+
|
|
101
|
+
For safety, payloads with any top-level tool `cache_control` marker or Anthropic `defer_loading` grouping are unchanged. Unknown/custom APIs, malformed tools, missing names, and unsupported shapes are also unchanged. The pure helper recognizes OpenAI Responses fixtures, but the request hook preserves the existing Responses/Codex bypass and does not reorder those requests.
|
|
102
|
+
|
|
103
|
+
Rollback is immediate: unset the variable (or set a non-truthy value) and run `/reload`. To verify the transformation with local fixtures without contacting a provider, run:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
bun .trellis/tasks/09-03-context-epoch-tool-ordering/verify.ts
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The fixture verifier reports numeric tool-order changes and confirms cache-marked payloads remain unchanged. Because it does not contact a provider, provider cache usage is explicitly unavailable and no synthetic cache hit is claimed.
|
|
110
|
+
|
|
91
111
|
## Footer cache stats mode
|
|
92
112
|
|
|
93
113
|
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.
|
|
@@ -142,7 +162,8 @@ Notes:
|
|
|
142
162
|
- `supportsLongCacheRetention: true` is optional. Add it only when the endpoint explicitly supports OpenAI long prompt cache retention.
|
|
143
163
|
- 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.
|
|
144
164
|
- Use `/cache-optimizer compat` or `/cache-optimizer doctor` to see model-specific advice.
|
|
145
|
-
-
|
|
165
|
+
- 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.
|
|
166
|
+
- Do not add `thinkingFormat: "deepseek"` merely because a model id contains `deepseek`; `openai`, `qwen`, `openrouter`, `together`, or no explicit format are all valid catalog cases.
|
|
146
167
|
- This extension's `doctor` and `compat` commands only advise; they do not modify `models.json`.
|
|
147
168
|
|
|
148
169
|
## Anthropic cache TTL compatibility
|
|
@@ -223,7 +244,7 @@ Pi 0.80.9+ already includes Kimi K3 in built-in Kimi Coding, Moonshot AI / China
|
|
|
223
244
|
**v2.6.0+** adds a `fix` subcommand that can auto-repair safe compat issues:
|
|
224
245
|
|
|
225
246
|
- Adaptive thinking (`forceAdaptiveThinking: true`; Kimi Coding K3 / `kimi-for-coding` also `allowEmptySignature: true`)
|
|
226
|
-
- DeepSeek Pi Mono
|
|
247
|
+
- DeepSeek Pi Mono replay compat (`requiresReasoningContentOnAssistantMessages: true` only when `thinkingFormat: "deepseek"` is already explicit; `/fix` never invents that format)
|
|
227
248
|
- OpenAI-compatible proxy session affinity (`sendSessionAffinityHeaders: true` for `openai-completions`). Pi 0.80.7+ controls `openai-responses` header shape with `sessionAffinityFormat` and auto-detects its default; this extension no longer writes the removed `sendSessionIdHeader` field.
|
|
228
249
|
|
|
229
250
|
**Scope:** only the currently active model. Other channels require switching models and running `fix` again.
|
|
@@ -236,14 +257,21 @@ Pi 0.80.9+ already includes Kimi K3 in built-in Kimi Coding, Moonshot AI / China
|
|
|
236
257
|
4. Requires explicit user confirmation (interactive prompt or `ui.select`)
|
|
237
258
|
5. Writes and restores atomically (temp + rename); self-validates after write
|
|
238
259
|
6. Preserves the existing `models.json` access mode exactly — it does not tighten or loosen permissions (for example, `0600` stays `0600`, `0644` stays `0644`)
|
|
239
|
-
7.
|
|
260
|
+
7. Writes a privacy-safe, versioned receipt atomically only after a successful write; the receipt contains transaction/model identity, placement, scalar compat before/after values, file hashes, backup filename, timestamps/status, and no credentials or request data
|
|
261
|
+
8. Uses unique, non-overwriting backup names and falls back to manual guidance if the JSONC scanner cannot confidently locate the target
|
|
240
262
|
|
|
241
|
-
Existing `modelOverrides[modelId]` entries have Pi's highest precedence, so `fix` repairs them directly. For built-in or API-login models without a custom `models[]` entry, `fix` creates a compat-only `modelOverrides` entry instead of inventing a custom model definition. Self-validation checks the
|
|
263
|
+
Existing `modelOverrides[modelId]` entries have Pi's highest precedence, so `fix` repairs them directly. For built-in or API-login models without a custom `models[]` entry, `fix` creates a compat-only `modelOverrides` entry instead of inventing a custom model definition. Runtime-observed provider failures are always written to that highest-precedence model override so extension-provided runtime compat cannot shadow the repair. Self-validation checks the full provider → custom model → runtime model → modelOverride result and rejects an ineffective lower-layer edit.
|
|
242
264
|
|
|
243
265
|
**Non-interactive mode:** refuses to write; shows manual edit guidance instead.
|
|
244
266
|
|
|
245
267
|
**Run:** `/cache-optimizer fix` when the active model has detected compat issues. The command shows "nothing to fix" when compat is already complete.
|
|
246
268
|
|
|
269
|
+
## `/cache-optimizer rollback`
|
|
270
|
+
|
|
271
|
+
Rollback is available through completion, direct execution, and the interactive menu. It always requires UI confirmation; without an interactive UI it gives manual-review guidance and does not write. The command selects the latest unapplied receipt for the active provider/model, validates the recorded backup and current file hashes, creates a new access-mode-preserving rollback backup, and uses temp-file + atomic rename. Fix and rollback transactions are serialized across extension instances; rollback also binds the receipt transaction id/hash from preview through commit and refuses if another transaction replaces it.
|
|
272
|
+
|
|
273
|
+
If `models.json` is unchanged since the fix, rollback can restore the exact pre-fix JSONC. If the file changed, it never blindly replaces it: it may restore only receipt-owned scalar compat keys whose recorded post-fix values are still present, preserving later user changes. If a receipt-owned key changed, the target was removed/moved, or the fix created a new target entry, it refuses and points to the recorded backup for manual review. Successful rollback marks the receipt and requires `/reload` or a restart.
|
|
274
|
+
|
|
247
275
|
### Channels without a `models.json` provider entry
|
|
248
276
|
|
|
249
277
|
Some Pi channels may be available even when there is no provider block in Pi's agent `models.json` yet (default: `~/.pi/agent/models.json`; with `PI_CODING_AGENT_DIR`, use `$PI_CODING_AGENT_DIR/models.json`). Keep existing authentication as-is and do not copy credentials, tokens, or API keys. Add only cache/routing compatibility overrides in `models.json`.
|
|
@@ -282,6 +310,21 @@ If only one model should change, use `modelOverrides`:
|
|
|
282
310
|
}
|
|
283
311
|
```
|
|
284
312
|
|
|
313
|
+
## DeepSeek protocol safety and rollback
|
|
314
|
+
|
|
315
|
+
Pi's model-family name and its reasoning wire protocol are separate. A DeepSeek-named model using an OpenAI-compatible endpoint may send standard top-level `reasoning_effort`, DeepSeek-style `thinking`, or another provider-specific format. `supportsReasoningEffort: true` alone is not proof either way. `/cache-optimizer fix` therefore never invents `thinkingFormat: "deepseek"`; configure an explicit `thinkingFormat` only when the endpoint documentation or an explicit provider signal supports it.
|
|
316
|
+
|
|
317
|
+
The novice-safe workflow is staged:
|
|
318
|
+
|
|
319
|
+
1. Run `/cache-optimizer fix` for protocol-neutral cache/routing repairs such as session affinity. It shows the exact placement and requires confirmation.
|
|
320
|
+
2. Make a normal request. If an OpenAI-compatible DeepSeek-like model explicitly rejects the `thinking` parameter in favor of `reasoning_effort`, the extension keeps only a model-scoped, process-local category. It does not persist or display the complete provider error, send a hidden probe, or edit configuration from a response hook.
|
|
321
|
+
3. Run `/cache-optimizer fix` again to review an evidence-based model-level protocol repair. It is written through the highest-precedence `modelOverrides[modelId].compat` layer and validated against runtime compat, so an extension-provided model cannot silently shadow it. A provider-level change is never broadened from a model name alone. Explicit `openai`, `qwen`, `openrouter`, and `together` formats remain respected.
|
|
322
|
+
4. If the latest confirmed fix caused the problem, run `/cache-optimizer rollback`. Rollback always requires UI confirmation.
|
|
323
|
+
|
|
324
|
+
Every successful interactive fix writes one atomic, versioned receipt at `pi-cache-optimizer-fix-receipt.json`. It contains only a transaction id, provider/model identity, placement, changed scalar compat keys with before/after values, file hashes, backup filename, and timestamps/status. It never stores API keys, credentials, prompts, payloads, headers, response bodies, or raw errors.
|
|
325
|
+
|
|
326
|
+
Rollback creates a new access-mode-preserving backup and uses atomic replacement. If `models.json` is unchanged since the fix and the receipt backup matches the pre-fix hash, it can restore the exact pre-fix file. If the file changed, it only reverts receipt-owned scalar keys that still have their recorded post-fix values and preserves unrelated user changes; otherwise it refuses safely and points to the recorded backup for manual review. The receipt is marked rolled back after validation, and `/reload` or a restart is required.
|
|
327
|
+
|
|
285
328
|
## Footer stats
|
|
286
329
|
|
|
287
330
|
Stats are read-only local counters stored as UUID-owned shards under `pi-cache-optimizer-stats.d/shards/` in Pi's agent directory (custom agent dirs use `PI_CODING_AGENT_DIR`). Shards contain only dates, opaque session hashes, exact provider/model counters, reset epochs, and process lifecycle metadata — no API keys, prompts, payloads, headers, responses, or model output. The footer defaults to the current conversation session; `total` aggregates all valid current-day shards for the exact provider/model, and `process` shows only the current extension instance. Footer mode configuration is stored separately in `pi-cache-optimizer-config.json`. Upgrading from the old v6 shared stats files deletes those local counters instead of migrating them.
|
package/README.zh-CN.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
用于提升 Pi 中 provider 侧 KV Cache / Prompt Cache 命中率的扩展:把稳定 prompt 内容前置,给 OpenAI-compatible 请求补保守的 `prompt_cache_key`,提示代理渠道常见缓存路由兼容问题,并在底部显示只读缓存统计。
|
|
11
11
|
|
|
12
|
-
> 本包已从 `pi-deepseek-cache-optimizer`
|
|
12
|
+
> 本包已从 `pi-deepseek-cache-optimizer` 改名。已有底部统计会自动迁移。正常 hook 运行时扩展不会触碰 Pi 的 `models.json`(默认 `~/.pi/agent/models.json`;自定义 agent 目录使用 `PI_CODING_AGENT_DIR`);只有 `/cache-optimizer fix` 和 `/cache-optimizer rollback` 可在展示交互式预览、风险提示并得到明确确认后写入,且都会先创建带时间戳的自动备份。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -17,10 +17,12 @@
|
|
|
17
17
|
- [安装](#安装)
|
|
18
18
|
- [命令](#命令)
|
|
19
19
|
- [持久 Opt-out](#持久-opt-out)
|
|
20
|
+
- [Opt-in 确定性工具排序](#opt-in-确定性工具排序)
|
|
20
21
|
- [Footer 缓存统计模式](#footer-缓存统计模式)
|
|
21
22
|
- [OpenAI-compatible 代理配置](#openai-compatible-代理配置)
|
|
22
23
|
- [Adaptive thinking 模型](#adaptive-thinking-模型)
|
|
23
24
|
- [使用 `/cache-optimizer fix` 自动修复](#使用-cache-optimizer-fix-自动修复)
|
|
25
|
+
- [DeepSeek 协议安全与回滚](#deepseek-协议安全与回滚)
|
|
24
26
|
- [Footer 统计](#footer-统计)
|
|
25
27
|
- [Router / Virtual-channel 扩展作者指南](#router--virtual-channel-扩展作者指南)
|
|
26
28
|
- [卸载](#卸载)
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
- 使用每个 extension instance 独占的原子 shard 保存缓存统计,避免父会话、子 Pi agent 和并行 Pi 进程互相覆盖。
|
|
39
41
|
- Footer 默认显示当前 conversation session 的 provider/model 统计;`total` 可聚合同一精确 provider/model 的所有有效本地 shard。
|
|
40
42
|
- 通过版本化全局协议(`Symbol.for("pi.routing.registry.v1")` 与 `Symbol.for("pi.cache.hints.v1")`)支持可选的 router extension 集成,而不导入任何 router 包。
|
|
43
|
+
- 提供默认关闭的确定性排序,用于已验证的 Pi 内置工具 payload。
|
|
41
44
|
|
|
42
45
|
缓存是 provider 侧的 best-effort 行为。第三方代理和 router extension 仍可能隐藏缓存 usage、拒绝不支持的参数,或把请求路由到多个上游。
|
|
43
46
|
|
|
@@ -57,7 +60,7 @@ pi remove npm:pi-deepseek-cache-optimizer && pi install npm:pi-cache-optimizer
|
|
|
57
60
|
|
|
58
61
|
Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安装的 Pi package(包括本扩展),请运行 `pi update --extensions`(只更新 packages)或 `pi update --all`(Pi 与 packages 一起更新)。
|
|
59
62
|
|
|
60
|
-
本扩展要求 Pi 0.82+,并已使用 Pi 0.84.
|
|
63
|
+
本扩展要求 Pi 0.82+,并已使用 Pi 0.84.4 验证。TypeScript 校验直接使用官方 Pi package 类型,同时只使用这些版本共有的 extension hooks、`getAgentDir()` 和 prompt options;不依赖 Pi 0.83+ 专有 API(例如 `ctx.scopedModels` 或 bundled TypeBox 1.3 aliases)。
|
|
61
64
|
|
|
62
65
|
## 命令
|
|
63
66
|
|
|
@@ -73,7 +76,8 @@ Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安
|
|
|
73
76
|
| `/cache-optimizer stats contributors` | 显示当前精确 provider/model 的当前/其他贡献 session,不暴露 session id。 |
|
|
74
77
|
| `/cache-optimizer reset` | 重置当前 provider/model 的本地 footer 统计;不会修改上游 provider 缓存。 |
|
|
75
78
|
| `/cache-optimizer config footer-mode total\|session\|process` | 持久设置 footer 统计模式;持久命令配置优先于环境变量。 |
|
|
76
|
-
| `/cache-optimizer fix` | 为当前模型自动修复安全的 compat
|
|
79
|
+
| `/cache-optimizer fix` | 为当前模型自动修复安全的 compat 问题。展示预览 + 风险提示,需要用户确认。**仅在用户明确批准后才修改 `models.json`。** |
|
|
80
|
+
| `/cache-optimizer rollback` | 查看最近一次匹配的已确认修复;经 UI 确认后安全撤销,不覆盖无关的 `models.json` 用户修改。 |
|
|
77
81
|
|
|
78
82
|
`/cache-optimizer` 使用 Pi 原生 Tab 补全:输入 `/cache-optimizer <Tab>` 查看支持的子命令,输入 `/cache-optimizer stats <Tab>` 补全 `all` 或 `contributors`,输入 `/cache-optimizer c<Tab>` 补全 `config`,输入 `/cache-optimizer config <Tab>` 补全 `footer-mode`,输入 `/cache-optimizer config footer-mode <Tab>` 补全 `total`、`session` 或 `process`。建议会按当前前缀过滤;无效前缀返回空结果,由 Pi 正常回退处理。
|
|
79
83
|
|
|
@@ -88,6 +92,22 @@ Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安
|
|
|
88
92
|
| `PI_CACHE_OPTIMIZER_NO_OPENAI_CACHE_KEY=1` | 关闭 OpenAI-compatible `prompt_cache_key` fallback。推荐使用这个显式 opt-out。 |
|
|
89
93
|
| `PI_CACHE_OPTIMIZER_OPENAI_CACHE_KEY=0` | 通过旧的反向开关关闭同一个 fallback。取值 `0`、`false`、`no`、`off` 时关闭。 |
|
|
90
94
|
|
|
95
|
+
## Opt-in 确定性工具排序
|
|
96
|
+
|
|
97
|
+
`PI_CACHE_OPTIMIZER_TOOL_ORDER=1` 会对 Pi 内置 OpenAI Completions、Anthropic、Google 与 Bedrock payload 中已验证的工具定义进行确定性排序。Truthy 取值为(不区分大小写)`1`、`true`、`yes` 或 `on`。该能力默认关闭、仅在当前进程生效,并会被 `/cache-optimizer disable` 抑制。
|
|
98
|
+
|
|
99
|
+
工具按精确名称排序,并用原始 index 作为稳定的同名 tie-breaker。排序只对发生变化的已验证对象/数组路径做浅 clone。工具对象和无关请求字段保持原引用,包括 Google/Vertex 的 `AbortSignal`;工具 schema、tool choice、routing 字段和调用方输入都保持不变。
|
|
100
|
+
|
|
101
|
+
出于安全考虑,只要工具存在顶层 `cache_control` marker,或 Anthropic payload 包含 `defer_loading` 分组,payload 就保持不变。未知 / 自定义 API、畸形工具、缺少名称或不支持的 shape 同样保持不变。纯 helper 可识别 OpenAI Responses fixture,但 request hook 保留既有 Responses/Codex bypass,不会重排这些请求。
|
|
102
|
+
|
|
103
|
+
回滚很简单:删除变量或设为非 truthy 值,然后运行 `/reload`。如需使用本地 fixture 验证转换、且不连接 provider,可运行:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
bun .trellis/tasks/09-03-context-epoch-tool-ordering/verify.ts
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
该 verifier 只报告数字形式的工具排序变化,并确认带 cache marker 的 payload 不会变化。由于它不会连接 provider,provider cache usage 会明确报告为 unavailable,也不会虚构 cache hit。
|
|
110
|
+
|
|
91
111
|
## Footer 缓存统计模式
|
|
92
112
|
|
|
93
113
|
当前版本把统计保存在 Pi agent 目录的 `pi-cache-optimizer-stats.d/shards/` 下。每个已加载的 extension instance 独占一个 UUID 命名 shard,并通过临时文件 + 原子 rename 写入,因此父/子/并行 Pi 进程不会互相覆盖。旧 v6 单文件统计在升级时直接删除,本地 footer 计数从零开始;不会影响上游 provider 的实际缓存。
|
|
@@ -142,7 +162,8 @@ Pi 0.84.1 还修复了内置 Fireworks 渠道对拒绝 `prompt_cache_retention`
|
|
|
142
162
|
- `supportsLongCacheRetention: true` 是可选项。只有 endpoint 明确支持 OpenAI long prompt cache retention 时才添加。
|
|
143
163
|
- 如果出现 `400 Unsupported parameter: prompt_cache_retention`,请为该渠道移除 / 避免 `supportsLongCacheRetention`;如支持,可保留 `sendSessionAffinityHeaders`。扩展会从响应头或最终 assistant error message 中识别这条明确错误,并在当前进程的后续请求中移除该参数。
|
|
144
164
|
- 使用 `/cache-optimizer compat` 或 `/cache-optimizer doctor` 查看当前模型的具体建议。
|
|
145
|
-
-
|
|
165
|
+
- DeepSeek 模型名只用于选择 `DS cache` adapter,不能证明 reasoning wire protocol。缺少或使用非 DeepSeek format 时仍保留通用缓存 / 路由建议;只有 effective `compat.thinkingFormat: "deepseek"` 被明确配置时,才显示 DeepSeek replay 建议,且不会把 `thinkingFormat` 列为缺失修复项。
|
|
166
|
+
- 不要因为模型 id 含有 `deepseek` 就添加 `thinkingFormat: "deepseek"`;catalog 中也存在 `openai`、`qwen`、`openrouter`、`together` 或没有显式 format 的情况。
|
|
146
167
|
- 本扩展的 `doctor` 和 `compat` 命令只给建议,不会修改 `models.json`。
|
|
147
168
|
|
|
148
169
|
## Anthropic 缓存 TTL 兼容
|
|
@@ -223,7 +244,7 @@ Pi 0.80.9+ 已在内置 Kimi Coding、Moonshot AI / 中国区、OpenRouter 和 V
|
|
|
223
244
|
**v2.6.0+** 新增 `fix` 子命令,可自动修复安全的 compat 问题:
|
|
224
245
|
|
|
225
246
|
- Adaptive thinking(`forceAdaptiveThinking: true`;Kimi Coding K3 / `kimi-for-coding` 还包括 `allowEmptySignature: true`)
|
|
226
|
-
- DeepSeek Pi Mono
|
|
247
|
+
- DeepSeek Pi Mono replay compat(仅当已明确配置 `thinkingFormat: "deepseek"` 时使用 `requiresReasoningContentOnAssistantMessages: true`;`/fix` 不会自行推断该 format)
|
|
227
248
|
- OpenAI-compatible proxy session affinity(`openai-completions` 使用 `sendSessionAffinityHeaders: true`)。Pi 0.80.7+ 使用 `sessionAffinityFormat` 控制 `openai-responses` header 形式并自动检测默认值;本扩展不再写入已移除的 `sendSessionIdHeader`。
|
|
228
249
|
|
|
229
250
|
**范围:** 仅当前 active model。其他渠道需切换模型后再次运行 `fix`。
|
|
@@ -238,12 +259,18 @@ Pi 0.80.9+ 已在内置 Kimi Coding、Moonshot AI / 中国区、OpenRouter 和 V
|
|
|
238
259
|
6. 完全保留 `models.json` 原有访问权限,不主动收紧或放宽(例如 `0600` 保持 `0600`,`0644` 保持 `0644`)
|
|
239
260
|
7. 备份名唯一且不会覆盖已有备份;如果 JSONC 扫描器无法置信定位目标,则回退到手动修改指引
|
|
240
261
|
|
|
241
|
-
已有的 `modelOverrides[modelId]` 具有 Pi 的最高优先级,因此 `fix` 会直接修复该 entry。对于没有自定义 `models[]` entry 的内置模型或 API-login 模型,`fix` 会创建仅含 compat 的 `modelOverrides` entry
|
|
262
|
+
已有的 `modelOverrides[modelId]` 具有 Pi 的最高优先级,因此 `fix` 会直接修复该 entry。对于没有自定义 `models[]` entry 的内置模型或 API-login 模型,`fix` 会创建仅含 compat 的 `modelOverrides` entry,而不会凭空添加自定义模型定义。运行时观察到的 provider 失败也始终写入这一最高优先级 model override,避免 extension-provided runtime compat 遮挡修复。自检会验证完整的 provider → custom model → runtime model → modelOverride 结果;无效的低层写入会被拒绝。
|
|
242
263
|
|
|
243
264
|
**非交互模式:** 拒绝写入,显示手动编辑指引。
|
|
244
265
|
|
|
245
266
|
**运行:** 当 active model 检测到 compat 问题时执行 `/cache-optimizer fix`。compat 已完整时,命令显示"无需修复"。
|
|
246
267
|
|
|
268
|
+
## `/cache-optimizer rollback`
|
|
269
|
+
|
|
270
|
+
Rollback 可通过补全、直接命令和交互菜单使用,并始终需要 UI 确认。命令会选择匹配当前 provider/model 的最新未回滚 receipt,验证备份与文件 hash,创建新的保留访问权限的 rollback backup,并使用临时文件 + 原子替换。Fix 与 rollback 在多个 extension instance 间串行执行;rollback 还会把预览时的 receipt transaction id/hash 绑定到提交阶段,若另一事务替换 receipt 就安全拒绝。没有交互式 UI 时只提供手动恢复指引,不会写入文件。
|
|
271
|
+
|
|
272
|
+
如果 `models.json` 自 fix 后没有变化,rollback 可以恢复完整的 pre-fix JSONC;如果文件发生变化,则绝不会盲目替换整个文件,只会在 receipt-owned scalar key 仍等于记录的 post-fix 值时撤销该 key,并保留之后的用户修改。如果 receipt-owned key 已变化、目标被删除/移动,或 fix 新建了目标项,命令会安全拒绝并指向记录的 backup 供手动检查。成功后 receipt 会标记为已回滚,并需要 `/reload` 或重启。
|
|
273
|
+
|
|
247
274
|
### 没有 `models.json` provider entry 的渠道
|
|
248
275
|
|
|
249
276
|
有些 Pi 渠道可用时,Pi agent `models.json`(默认 `~/.pi/agent/models.json`;若设置了 `PI_CODING_AGENT_DIR`,则为 `$PI_CODING_AGENT_DIR/models.json`)里可能还没有对应 provider block。保留现有认证方式,不要复制 credential、token 或 API key。只在 `models.json` 里添加缓存 / 路由兼容覆盖。
|
|
@@ -282,6 +309,21 @@ Pi Cache Optimizer 按 Pi 的优先级解析有效 compat(`provider.compat`
|
|
|
282
309
|
}
|
|
283
310
|
```
|
|
284
311
|
|
|
312
|
+
## DeepSeek 协议安全与回滚
|
|
313
|
+
|
|
314
|
+
模型家族名称与 reasoning wire protocol 是两件事。使用 OpenAI-compatible endpoint 的 DeepSeek 名称模型,可能使用标准顶层 `reasoning_effort`、DeepSeek 风格 `thinking`,或其它 provider-specific format。单独的 `supportsReasoningEffort: true` 不能证明协议。为此,`/cache-optimizer fix` 永远不会凭模型名推断或添加 `thinkingFormat: "deepseek"`;只有 endpoint 文档或 provider 的明确证据支持时,才应配置显式 format。
|
|
315
|
+
|
|
316
|
+
面向新手的安全流程是分阶段的:
|
|
317
|
+
|
|
318
|
+
1. 先运行 `/cache-optimizer fix`,只处理协议无关的缓存 / 路由修复,例如 session affinity;命令会展示具体位置并要求确认。
|
|
319
|
+
2. 发起一次普通请求。如果 OpenAI-compatible 的 DeepSeek-like 模型明确拒绝 `thinking` 并要求使用 `reasoning_effort`,扩展只在当前进程保留 model-scoped 分类,不会持久化或显示完整错误,不会发送隐藏探测请求,也不会在 response hook 中自动修改配置。
|
|
320
|
+
3. 再次运行 `/cache-optimizer fix`,查看基于证据的 model-level 协议修复;该修复写入最高优先级的 `modelOverrides[modelId].compat`,并结合 runtime compat 自检,避免 extension-provided model 静默遮挡。不会仅凭共享 provider 或模型名字扩大修改范围,显式 `openai`、`qwen`、`openrouter`、`together` format 会被尊重。
|
|
321
|
+
4. 如果最近一次已确认修复导致问题,运行 `/cache-optimizer rollback`;回滚始终需要 UI 确认。
|
|
322
|
+
|
|
323
|
+
每次成功的交互式 fix 都会以原子方式写入版本化 receipt:`pi-cache-optimizer-fix-receipt.json`。它只包含 transaction id、provider/model identity、placement、发生变化的 scalar compat key 及 before/after 值、文件 hash、备份文件名和时间戳/status。不会保存 API key、credential、prompt、payload、header、response body 或原始错误。
|
|
324
|
+
|
|
325
|
+
Rollback 会创建新的、保留访问权限的备份并使用原子替换。如果 `models.json` 自 fix 后未变化,且 receipt 备份匹配 pre-fix hash,则可恢复完整 pre-fix 文件。如果文件发生变化,只会在 receipt-owned scalar key 仍等于记录的 post-fix 值时撤销该 key,并保留其它用户修改;否则安全拒绝并指向记录的备份供手动检查。验证后 receipt 会标记为已回滚,需要 `/reload` 或重启 Pi。
|
|
326
|
+
|
|
285
327
|
## Footer 统计
|
|
286
328
|
|
|
287
329
|
统计是只读本地计数,保存在 Pi agent 目录的 UUID shard(`pi-cache-optimizer-stats.d/shards/`;自定义 agent 目录使用 `PI_CODING_AGENT_DIR`)。Shard 只包含日期、opaque session hash、精确 provider/model 计数、reset epoch 和进程生命周期元数据,不包含 API key、prompt、payload、headers、响应或模型输出。Footer 默认显示当前 conversation session;`total` 聚合同一精确 provider/model 的所有有效本地 shard,`process` 只显示当前 extension instance。旧 v6 共享统计文件升级时直接删除,不迁移旧计数。
|