pi-cache-optimizer 2.8.0 → 2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/README.zh-CN.md +4 -2
- package/index.ts +85 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,6 +71,8 @@ This extension is validated against Pi 0.83.0 and remains designed for Pi 0.82+.
|
|
|
71
71
|
| `/cache-optimizer config footer-mode total\|session\|process` | Persist the footer stats mode. Persistent command configuration overrides the environment variable. |
|
|
72
72
|
| `/cache-optimizer fix` | Auto-repairs safe compat issues for the active model (adaptive thinking, DeepSeek reasoning, OpenAI proxy session affinity). Shows preview + risk warning, requires confirmation. **Only modifies `models.json` after explicit user approval.** |
|
|
73
73
|
|
|
74
|
+
`/cache-optimizer` uses Pi's native Tab completion. Type `/cache-optimizer <Tab>` for the supported subcommands, `/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.
|
|
75
|
+
|
|
74
76
|
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.
|
|
75
77
|
|
|
76
78
|
## Persistent opt-out
|
|
@@ -281,10 +283,10 @@ Pi 0.79+ also includes a built-in footer `CH` marker for the latest prompt cache
|
|
|
281
283
|
Example footer:
|
|
282
284
|
|
|
283
285
|
```text
|
|
284
|
-
OpenAI cache 3/10 · 0.002M/0.005M tok (40%) ⚠️ compat
|
|
286
|
+
· OpenAI cache 3/10 · 0.002M/0.005M tok (40%) ⚠️ compat
|
|
285
287
|
```
|
|
286
288
|
|
|
287
|
-
|
|
289
|
+
The leading `· ` is owned by this extension and separates its status from statuses published by other extensions in the same footer. It is present for normal, disabled, router-restored, and warning-suffixed statuses. The stats format remains `<label> <hit requests>/<total requests> · <cached input tokens>/<total input tokens> tok (<token hit rate>)`; `/cache-optimizer stats` output is unchanged. Some adapters may also append `· write <tokens> tok`, and runtime diagnostics may append `⚠️ compat` or `⚠️ integrity`.
|
|
288
290
|
|
|
289
291
|
Supported footer labels include: DS, Claude, OpenAI, Gemini, Kimi, Qwen, GLM, MiniMax, Mimo, Hunyuan, Mistral, Grok, Llama, Nemotron, Cohere, Yi, Doubao, ERNIE, Baichuan, StepFun, Spark, InternLM, Gemma, Phi, Jamba, Solar, Sonar, Nova, Reka, Falcon, DBRX, MPT, StableLM, Aquila, EXAONE, HyperCLOVA, Luminous, Hermes, Granite, Arctic, Pangu, SenseNova, Zhinao, MiniCPM, XVERSE, Orion, OpenChat, Vicuna, Wizard, Zephyr, Dolphin, OpenOrca, Starling, BLOOM, RWKV, and Aya.
|
|
290
292
|
|
package/README.zh-CN.md
CHANGED
|
@@ -71,6 +71,8 @@ Pi 0.79.7 及之后,`pi update` 默认只更新 Pi 本体。若要更新已安
|
|
|
71
71
|
| `/cache-optimizer config footer-mode total\|session\|process` | 持久设置 footer 统计模式;持久命令配置优先于环境变量。 |
|
|
72
72
|
| `/cache-optimizer fix` | 为当前模型自动修复安全的 compat 问题(adaptive thinking、DeepSeek reasoning、OpenAI proxy session affinity)。展示预览 + 风险提示,需要用户确认。**仅在用户明确批准后才修改 `models.json`。** |
|
|
73
73
|
|
|
74
|
+
`/cache-optimizer` 使用 Pi 原生 Tab 补全:输入 `/cache-optimizer <Tab>` 查看支持的子命令,输入 `/cache-optimizer c<Tab>` 补全 `config`,输入 `/cache-optimizer config <Tab>` 补全 `footer-mode`,输入 `/cache-optimizer config footer-mode <Tab>` 补全 `total`、`session` 或 `process`。建议会按当前前缀过滤;无效前缀返回空结果,由 Pi 正常回退处理。
|
|
75
|
+
|
|
74
76
|
交互式 `/cache-optimizer` 菜单包含 `Footer mode`,可以选择 `total`、`session` 或 `process`。`enable` / `disable` 是当前进程内开关。若要持久关闭某些能力,请使用下面的环境变量。
|
|
75
77
|
|
|
76
78
|
## 持久 Opt-out
|
|
@@ -280,10 +282,10 @@ Pi 0.79+ 已内置 footer `CH` 标记,用于显示最近一次 prompt cache hi
|
|
|
280
282
|
示例 footer:
|
|
281
283
|
|
|
282
284
|
```text
|
|
283
|
-
OpenAI cache 3/10 · 0.002M/0.005M tok (40%) ⚠️ compat
|
|
285
|
+
· OpenAI cache 3/10 · 0.002M/0.005M tok (40%) ⚠️ compat
|
|
284
286
|
```
|
|
285
287
|
|
|
286
|
-
|
|
288
|
+
开头的 `· ` 由本扩展负责,用于把本扩展状态与同一 footer 中其他扩展发布的状态隔开。普通、disabled、router 恢复以及带 warning 的状态都会保留此前缀。统计格式仍是 `<label> <命中请求数>/<总请求数> · <cached input tokens>/<total input tokens> tok (<token 命中率>)`;`/cache-optimizer stats` 的输出不变。部分 adapter 还可能追加 `· write <tokens> tok`,运行时诊断可能追加 `⚠️ compat` 或 `⚠️ integrity`。
|
|
287
289
|
|
|
288
290
|
支持的 footer label 包括:DS、Claude、OpenAI、Gemini、Kimi、Qwen、GLM、MiniMax、Mimo、Hunyuan、Mistral、Grok、Llama、Nemotron、Cohere、Yi、Doubao、ERNIE、Baichuan、StepFun、Spark、InternLM、Gemma、Phi、Jamba、Solar、Sonar、Nova、Reka、Falcon、DBRX、MPT、StableLM、Aquila、EXAONE、HyperCLOVA、Luminous、Hermes、Granite、Arctic、Pangu、SenseNova、Zhinao、MiniCPM、XVERSE、Orion、OpenChat、Vicuna、Wizard、Zephyr、Dolphin、OpenOrca、Starling、BLOOM、RWKV、Aya。
|
|
289
291
|
|
package/index.ts
CHANGED
|
@@ -1146,6 +1146,82 @@ function parseFooterStatsMode(value: unknown): FooterStatsMode | undefined {
|
|
|
1146
1146
|
return normalized === "session" || normalized === "total" || normalized === "process" ? normalized : undefined;
|
|
1147
1147
|
}
|
|
1148
1148
|
|
|
1149
|
+
type CommandCompletionItem = {
|
|
1150
|
+
value: string;
|
|
1151
|
+
label: string;
|
|
1152
|
+
description?: string;
|
|
1153
|
+
};
|
|
1154
|
+
|
|
1155
|
+
const CACHE_OPTIMIZER_COMMANDS = [
|
|
1156
|
+
"enable",
|
|
1157
|
+
"disable",
|
|
1158
|
+
"doctor",
|
|
1159
|
+
"stats",
|
|
1160
|
+
"config",
|
|
1161
|
+
"compat",
|
|
1162
|
+
"reset",
|
|
1163
|
+
"fix",
|
|
1164
|
+
] as const;
|
|
1165
|
+
const CACHE_OPTIMIZER_CONFIG_ARGUMENTS = ["footer-mode"] as const;
|
|
1166
|
+
const CACHE_OPTIMIZER_FOOTER_MODES = ["total", "session", "process"] as const;
|
|
1167
|
+
|
|
1168
|
+
function filterCommandCompletionItems(
|
|
1169
|
+
values: readonly string[],
|
|
1170
|
+
prefix: string,
|
|
1171
|
+
argumentPath = "",
|
|
1172
|
+
): CommandCompletionItem[] | null {
|
|
1173
|
+
const normalizedPrefix = prefix.trim().toLowerCase();
|
|
1174
|
+
const matches = values
|
|
1175
|
+
.filter((value) => value.startsWith(normalizedPrefix))
|
|
1176
|
+
.map((value) => ({
|
|
1177
|
+
// Pi replaces the complete argumentPrefix when applying a command
|
|
1178
|
+
// completion, so nested suggestions must include their full path.
|
|
1179
|
+
value: argumentPath ? `${argumentPath} ${value}` : value,
|
|
1180
|
+
label: value,
|
|
1181
|
+
}));
|
|
1182
|
+
return matches.length > 0 ? matches : null;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
function getCacheOptimizerArgumentCompletions(argumentPrefix: string): CommandCompletionItem[] | null {
|
|
1186
|
+
if (typeof argumentPrefix !== "string") return null;
|
|
1187
|
+
const trimmed = argumentPrefix.trim();
|
|
1188
|
+
const parts = trimmed ? trimmed.split(/\s+/) : [];
|
|
1189
|
+
|
|
1190
|
+
if (parts.length === 0) {
|
|
1191
|
+
return filterCommandCompletionItems(CACHE_OPTIMIZER_COMMANDS, "");
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
if (parts.length === 1) {
|
|
1195
|
+
const subcommandPrefix = parts[0].toLowerCase();
|
|
1196
|
+
// `config` is the primary `c` completion; `compat` remains available
|
|
1197
|
+
// through its more specific `co` prefix. Surrounding whitespace is
|
|
1198
|
+
// ignored so ` c ` behaves the same as `c`.
|
|
1199
|
+
if (subcommandPrefix === "c") {
|
|
1200
|
+
return [{ value: "config", label: "config" }];
|
|
1201
|
+
}
|
|
1202
|
+
if (subcommandPrefix === "config") {
|
|
1203
|
+
return filterCommandCompletionItems(CACHE_OPTIMIZER_CONFIG_ARGUMENTS, "", "config");
|
|
1204
|
+
}
|
|
1205
|
+
return filterCommandCompletionItems(CACHE_OPTIMIZER_COMMANDS, parts[0]);
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
if (parts[0].toLowerCase() !== "config") return null;
|
|
1209
|
+
|
|
1210
|
+
if (parts.length === 2) {
|
|
1211
|
+
const nestedPrefix = parts[1].toLowerCase();
|
|
1212
|
+
if (nestedPrefix === "footer-mode") {
|
|
1213
|
+
return filterCommandCompletionItems(CACHE_OPTIMIZER_FOOTER_MODES, "", "config footer-mode");
|
|
1214
|
+
}
|
|
1215
|
+
return filterCommandCompletionItems(CACHE_OPTIMIZER_CONFIG_ARGUMENTS, parts[1], "config");
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
if (parts.length === 3 && parts[1].toLowerCase() === "footer-mode") {
|
|
1219
|
+
return filterCommandCompletionItems(CACHE_OPTIMIZER_FOOTER_MODES, parts[2], "config footer-mode");
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
return null;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1149
1225
|
function parsePersistedCacheOptimizerConfig(value: unknown): PersistedCacheOptimizerConfigV1 | undefined {
|
|
1150
1226
|
const record = asRecord(value);
|
|
1151
1227
|
if (!record || record.version !== 1) return undefined;
|
|
@@ -3666,6 +3742,11 @@ function formatCacheStats(adapter: CacheProviderAdapter, stats: CacheStats): str
|
|
|
3666
3742
|
return `${adapter.label} ${stats.hitRequests}/${stats.totalRequests} · ${formatTokenCount(stats.cachedInputTokens)}/${formatTokenCount(stats.totalInputTokens)} tok${percent}${writeText}`;
|
|
3667
3743
|
}
|
|
3668
3744
|
|
|
3745
|
+
function prefixFooterStatus(statusText: string | undefined): string | undefined {
|
|
3746
|
+
if (!statusText || statusText.startsWith("· ")) return statusText;
|
|
3747
|
+
return `· ${statusText}`;
|
|
3748
|
+
}
|
|
3749
|
+
|
|
3669
3750
|
/**
|
|
3670
3751
|
* Compute a hit-ratio percentage string for a value between 0 and 1.
|
|
3671
3752
|
* Returns e.g. "75%", "0%", "100%", or "N/A" for zero total.
|
|
@@ -6653,6 +6734,8 @@ export const __internals_for_tests = {
|
|
|
6653
6734
|
// Cache stats helpers (module-level, usable from verify script)
|
|
6654
6735
|
addUsageToCacheStats,
|
|
6655
6736
|
formatCacheStats,
|
|
6737
|
+
prefixFooterStatus,
|
|
6738
|
+
getCacheOptimizerArgumentCompletions,
|
|
6656
6739
|
emptyCacheStats,
|
|
6657
6740
|
emptyAllCacheStats,
|
|
6658
6741
|
parseCacheStats,
|
|
@@ -7240,6 +7323,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
7240
7323
|
}
|
|
7241
7324
|
}
|
|
7242
7325
|
|
|
7326
|
+
statusText = prefixFooterStatus(statusText);
|
|
7243
7327
|
if (statusText === lastStatusText) return;
|
|
7244
7328
|
|
|
7245
7329
|
lastStatusText = statusText;
|
|
@@ -7647,6 +7731,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
7647
7731
|
// ────────────────────────────────────────────────────────────────
|
|
7648
7732
|
pi.registerCommand("cache-optimizer", {
|
|
7649
7733
|
description: "Configure and diagnose Pi cache behavior",
|
|
7734
|
+
getArgumentCompletions: getCacheOptimizerArgumentCompletions,
|
|
7650
7735
|
handler: async (args: string, cmdCtx) => {
|
|
7651
7736
|
syncSessionHash(cmdCtx);
|
|
7652
7737
|
const selectedModel = cmdCtx.model;
|
package/package.json
CHANGED