opencode-visual-cache 1.7.0-beta.4 → 1.7.0-beta.5
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/dist/_version.d.ts +1 -1
- package/dist/_version.js +1 -1
- package/dist/tui.js +1 -1
- package/dist/v2/index.js +1 -1
- package/dist/v2/status.d.ts +3 -1
- package/dist/v2/status.js +12 -2
- package/dist/v2.js +82 -72
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/v2/index.tsx +1 -1
- package/src/v2/status.tsx +15 -3
package/dist/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PLUGIN_VERSION = "1.7.0-beta.
|
|
1
|
+
export declare const PLUGIN_VERSION = "1.7.0-beta.5";
|
package/dist/_version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// auto-generated
|
|
2
|
-
export const PLUGIN_VERSION = "1.7.0-beta.
|
|
2
|
+
export const PLUGIN_VERSION = "1.7.0-beta.5";
|
package/dist/tui.js
CHANGED
|
@@ -705,7 +705,7 @@ import { createElement as _$createElement } from "@opentui/solid";
|
|
|
705
705
|
import { createMemo, createSignal, createEffect, onMount, onCleanup, Show, untrack } from "solid-js";
|
|
706
706
|
|
|
707
707
|
// src/_version.ts
|
|
708
|
-
var PLUGIN_VERSION = "1.7.0-beta.
|
|
708
|
+
var PLUGIN_VERSION = "1.7.0-beta.5";
|
|
709
709
|
|
|
710
710
|
// src/panel/TokenCachePanel.tsx
|
|
711
711
|
var MIN_PANEL_WIDTH = 20;
|
package/dist/v2/index.js
CHANGED
|
@@ -154,7 +154,7 @@ const mod = {
|
|
|
154
154
|
// 底部状态栏(完整口径与 V1 一致;余额读共享 signals.balanceState)
|
|
155
155
|
context.ui.slot({
|
|
156
156
|
append: "prompt.footer.status",
|
|
157
|
-
render: (props) => (_jsx(StatusView, { context: context, signals: signals, sessionID: String(props.sessionID ?? "") })),
|
|
157
|
+
render: (props) => (_jsx(StatusView, { context: context, api: api, signals: signals, sessionID: String(props.sessionID ?? "") })),
|
|
158
158
|
});
|
|
159
159
|
// 偏好持久化(实验:storage.store 用法验证)
|
|
160
160
|
context.storage.store("opencode-visual-cache.panel", { initial: { collapsed: false } });
|
package/dist/v2/status.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/** @jsxImportSource @opentui/solid */
|
|
2
2
|
import type { Context } from "./types";
|
|
3
|
-
import type { PanelSignals } from "../panel/panel-api";
|
|
3
|
+
import type { PanelApi, PanelSignals } from "../panel/panel-api";
|
|
4
4
|
/**
|
|
5
5
|
* 底部状态栏(prompt.footer.status)——对齐 V1 BottomStatusBar 统计段口径:
|
|
6
6
|
* 单条命中率(最后一条有 token 的 assistant 消息)+ 趋势 + Tokens 总量 + 余额。
|
|
7
7
|
* 余额读共享 signals.balanceState(PluginRoot 驱动轮询);provider 不支持余额时隐藏余额段(对齐 V1)。
|
|
8
8
|
* 颜色经 mapTheme(V1 形状)——与侧边栏命中率颜色同源,保证两处一致。
|
|
9
|
+
* 显隐受 signals.sectionBottom 控制(/cache-section 切换),启动时从 kv 恢复偏好(对齐 V1)。
|
|
9
10
|
*/
|
|
10
11
|
export declare function StatusView(props: {
|
|
11
12
|
context: Context;
|
|
13
|
+
api: PanelApi;
|
|
12
14
|
signals: PanelSignals;
|
|
13
15
|
sessionID: string;
|
|
14
16
|
}): import("solid-js").JSX.Element;
|
package/dist/v2/status.js
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { jsx as _jsx } from "@opentui/solid/jsx-runtime";
|
|
2
2
|
/** @jsxImportSource @opentui/solid */
|
|
3
|
-
import { createMemo, For, Show } from "solid-js";
|
|
3
|
+
import { createMemo, For, onMount, Show } from "solid-js";
|
|
4
4
|
import { collectLastHitRate } from "./data";
|
|
5
5
|
import { desaturateTo, fmtCompact, formatBalanceText, MAX_SAT, FALLBACK, visualWidth } from "../core";
|
|
6
6
|
import { createT } from "../i18n";
|
|
7
7
|
import { mapTheme } from "./theme";
|
|
8
|
+
const KV_PREFIX = "cache_panel";
|
|
8
9
|
/**
|
|
9
10
|
* 底部状态栏(prompt.footer.status)——对齐 V1 BottomStatusBar 统计段口径:
|
|
10
11
|
* 单条命中率(最后一条有 token 的 assistant 消息)+ 趋势 + Tokens 总量 + 余额。
|
|
11
12
|
* 余额读共享 signals.balanceState(PluginRoot 驱动轮询);provider 不支持余额时隐藏余额段(对齐 V1)。
|
|
12
13
|
* 颜色经 mapTheme(V1 形状)——与侧边栏命中率颜色同源,保证两处一致。
|
|
14
|
+
* 显隐受 signals.sectionBottom 控制(/cache-section 切换),启动时从 kv 恢复偏好(对齐 V1)。
|
|
13
15
|
*/
|
|
14
16
|
export function StatusView(props) {
|
|
15
17
|
const t = createT(() => props.signals.langCode());
|
|
18
|
+
// 恢复显隐偏好(默认显示;关闭时隐藏统计段,与宿主默认 hint 行一致)
|
|
19
|
+
onMount(() => {
|
|
20
|
+
try {
|
|
21
|
+
const v = props.api.kv.get(`${KV_PREFIX}.section.bottom`, true);
|
|
22
|
+
props.signals.setSectionBottom(v !== false);
|
|
23
|
+
}
|
|
24
|
+
catch { }
|
|
25
|
+
});
|
|
16
26
|
// 与侧边栏 TokenCachePanel 同一颜色来源(mapTheme → desaturateTo)
|
|
17
27
|
const pal = createMemo(() => {
|
|
18
28
|
const th = mapTheme(props.context.theme);
|
|
@@ -79,5 +89,5 @@ export function StatusView(props) {
|
|
|
79
89
|
w += visualWidth(sg.text);
|
|
80
90
|
return w;
|
|
81
91
|
});
|
|
82
|
-
return (_jsx(Show, { when: segsW() > 0, children: _jsx("text", { children: _jsx(For, { each: segs(), children: (sg) => _jsx("span", { style: { fg: sg.color }, children: sg.text }) }) }) }));
|
|
92
|
+
return (_jsx(Show, { when: segsW() > 0 && stats().hitRate >= 0 && props.signals.sectionBottom(), children: _jsx("text", { children: _jsx(For, { each: segs(), children: (sg) => _jsx("span", { style: { fg: sg.color }, children: sg.text }) }) }) }));
|
|
83
93
|
}
|
package/dist/v2.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/v2/index.tsx
|
|
2
2
|
import { createComponent as _$createComponent3 } from "@opentui/solid";
|
|
3
|
-
import { createSignal as createSignal2, createEffect as createEffect2, onMount as
|
|
3
|
+
import { createSignal as createSignal2, createEffect as createEffect2, onMount as onMount3, onCleanup as onCleanup2, untrack as untrack2 } from "solid-js";
|
|
4
4
|
|
|
5
5
|
// src/v2/v2-panel-api.ts
|
|
6
6
|
function createPanelApi(context) {
|
|
@@ -843,7 +843,7 @@ function estimateTokens(text) {
|
|
|
843
843
|
}
|
|
844
844
|
|
|
845
845
|
// src/_version.ts
|
|
846
|
-
var PLUGIN_VERSION = "1.7.0-beta.
|
|
846
|
+
var PLUGIN_VERSION = "1.7.0-beta.5";
|
|
847
847
|
|
|
848
848
|
// src/panel/TokenCachePanel.tsx
|
|
849
849
|
var MIN_PANEL_WIDTH = 20;
|
|
@@ -985,7 +985,7 @@ function TokenCachePanel(props) {
|
|
|
985
985
|
lastMainSid = sid;
|
|
986
986
|
if (props.signals.overrideSessionId()) {
|
|
987
987
|
props.signals.setOverrideSessionId(void 0);
|
|
988
|
-
props.api.kv.set(`${
|
|
988
|
+
props.api.kv.set(`${KV_PREFIX4}.session`, "");
|
|
989
989
|
}
|
|
990
990
|
}
|
|
991
991
|
});
|
|
@@ -1217,7 +1217,7 @@ function TokenCachePanel(props) {
|
|
|
1217
1217
|
});
|
|
1218
1218
|
setLastHasDist(true);
|
|
1219
1219
|
try {
|
|
1220
|
-
props.api.kv.set(`${
|
|
1220
|
+
props.api.kv.set(`${KV_PREFIX4}.dist_snapshot`, {
|
|
1221
1221
|
...d.dist
|
|
1222
1222
|
});
|
|
1223
1223
|
} catch {
|
|
@@ -1225,53 +1225,53 @@ function TokenCachePanel(props) {
|
|
|
1225
1225
|
}
|
|
1226
1226
|
});
|
|
1227
1227
|
const [partVersion, setPartVersion] = createSignal(0);
|
|
1228
|
-
const
|
|
1228
|
+
const KV_PREFIX4 = "cache_panel";
|
|
1229
1229
|
const persistFold = (key, val) => {
|
|
1230
1230
|
try {
|
|
1231
|
-
props.api.kv.set(`${
|
|
1231
|
+
props.api.kv.set(`${KV_PREFIX4}.${key}`, val);
|
|
1232
1232
|
} catch {
|
|
1233
1233
|
}
|
|
1234
1234
|
};
|
|
1235
1235
|
onMount(() => {
|
|
1236
1236
|
setPanelWidth(DEFAULT_PANEL_WIDTH);
|
|
1237
1237
|
try {
|
|
1238
|
-
setOpen(Boolean(props.api.kv.get(`${
|
|
1239
|
-
setDetailOpen(Boolean(props.api.kv.get(`${
|
|
1240
|
-
setModelOpen(Boolean(props.api.kv.get(`${
|
|
1241
|
-
setDistOpen(Boolean(props.api.kv.get(`${
|
|
1242
|
-
setSkillsOpen(Boolean(props.api.kv.get(`${
|
|
1238
|
+
setOpen(Boolean(props.api.kv.get(`${KV_PREFIX4}.open`, false)));
|
|
1239
|
+
setDetailOpen(Boolean(props.api.kv.get(`${KV_PREFIX4}.detail`, true)));
|
|
1240
|
+
setModelOpen(Boolean(props.api.kv.get(`${KV_PREFIX4}.model`, true)));
|
|
1241
|
+
setDistOpen(Boolean(props.api.kv.get(`${KV_PREFIX4}.dist`, false)));
|
|
1242
|
+
setSkillsOpen(Boolean(props.api.kv.get(`${KV_PREFIX4}.skills`, true)));
|
|
1243
1243
|
} catch {
|
|
1244
1244
|
}
|
|
1245
1245
|
const doRestore = () => {
|
|
1246
1246
|
try {
|
|
1247
|
-
const sym = props.api.kv.get(`${
|
|
1248
|
-
const rate = props.api.kv.get(`${
|
|
1247
|
+
const sym = props.api.kv.get(`${KV_PREFIX4}.currency`);
|
|
1248
|
+
const rate = props.api.kv.get(`${KV_PREFIX4}.rate`);
|
|
1249
1249
|
if (typeof sym === "string") setCurrencySymbol(sym);
|
|
1250
1250
|
if (typeof rate === "number" && rate > 0) setExchangeRate(rate);
|
|
1251
|
-
const balCur = props.api.kv.get(`${
|
|
1251
|
+
const balCur = props.api.kv.get(`${KV_PREFIX4}.balance_currency`);
|
|
1252
1252
|
if (typeof balCur === "string") setBalanceCurrency(balCur);
|
|
1253
|
-
const savedProvider = props.api.kv.get(`${
|
|
1253
|
+
const savedProvider = props.api.kv.get(`${KV_PREFIX4}.balance.provider`);
|
|
1254
1254
|
if (typeof savedProvider === "string" && balanceProviders.some((p) => p.id === savedProvider)) {
|
|
1255
1255
|
setBalanceProviderId(savedProvider);
|
|
1256
1256
|
setBalanceUnsupported(false);
|
|
1257
1257
|
}
|
|
1258
|
-
const savedAuto = props.api.kv.get(`${
|
|
1258
|
+
const savedAuto = props.api.kv.get(`${KV_PREFIX4}.balance.auto`);
|
|
1259
1259
|
if (typeof savedAuto === "boolean") setAutoBalance(savedAuto);
|
|
1260
|
-
const legacyKey = props.api.kv.get(`${
|
|
1260
|
+
const legacyKey = props.api.kv.get(`${KV_PREFIX4}.ds_key`, "");
|
|
1261
1261
|
if (legacyKey) {
|
|
1262
|
-
const dsKey = props.api.kv.get(`${
|
|
1263
|
-
if (!dsKey) props.api.kv.set(`${
|
|
1264
|
-
props.api.kv.set(`${
|
|
1262
|
+
const dsKey = props.api.kv.get(`${KV_PREFIX4}.balance.deepseek.key`, "");
|
|
1263
|
+
if (!dsKey) props.api.kv.set(`${KV_PREFIX4}.balance.deepseek.key`, legacyKey);
|
|
1264
|
+
props.api.kv.set(`${KV_PREFIX4}.ds_key`, "");
|
|
1265
1265
|
}
|
|
1266
1266
|
props.signals.setBalanceRefresh(props.signals.balanceRefresh() + 1);
|
|
1267
|
-
setSectionDetail(Boolean(props.api.kv.get(`${
|
|
1268
|
-
setSectionModel(Boolean(props.api.kv.get(`${
|
|
1269
|
-
setSectionDist(Boolean(props.api.kv.get(`${
|
|
1270
|
-
setSectionSkills(Boolean(props.api.kv.get(`${
|
|
1271
|
-
setSectionBalance(Boolean(props.api.kv.get(`${
|
|
1272
|
-
const bv = props.api.kv.get(`${
|
|
1267
|
+
setSectionDetail(Boolean(props.api.kv.get(`${KV_PREFIX4}.section.detail`, true)));
|
|
1268
|
+
setSectionModel(Boolean(props.api.kv.get(`${KV_PREFIX4}.section.model`, true)));
|
|
1269
|
+
setSectionDist(Boolean(props.api.kv.get(`${KV_PREFIX4}.section.dist`, true)));
|
|
1270
|
+
setSectionSkills(Boolean(props.api.kv.get(`${KV_PREFIX4}.section.skills`, true)));
|
|
1271
|
+
setSectionBalance(Boolean(props.api.kv.get(`${KV_PREFIX4}.section.balance`, true)));
|
|
1272
|
+
const bv = props.api.kv.get(`${KV_PREFIX4}.border`, true);
|
|
1273
1273
|
setBorderVisible(bv !== false);
|
|
1274
|
-
const cachedDist = props.api.kv.get(`${
|
|
1274
|
+
const cachedDist = props.api.kv.get(`${KV_PREFIX4}.dist_snapshot`);
|
|
1275
1275
|
if (cachedDist) {
|
|
1276
1276
|
setLastDist(cachedDist);
|
|
1277
1277
|
setLastHasDist(true);
|
|
@@ -2154,7 +2154,8 @@ import { effect as _$effect2 } from "@opentui/solid";
|
|
|
2154
2154
|
import { insert as _$insert2 } from "@opentui/solid";
|
|
2155
2155
|
import { createComponent as _$createComponent2 } from "@opentui/solid";
|
|
2156
2156
|
import { createElement as _$createElement2 } from "@opentui/solid";
|
|
2157
|
-
import {
|
|
2157
|
+
import { memo as _$memo2 } from "@opentui/solid";
|
|
2158
|
+
import { createMemo as createMemo2, For, onMount as onMount2, Show as Show2 } from "solid-js";
|
|
2158
2159
|
|
|
2159
2160
|
// src/v2/data.ts
|
|
2160
2161
|
function collectLastHitRate(context, sessionID) {
|
|
@@ -2207,8 +2208,16 @@ function mapTheme(theme) {
|
|
|
2207
2208
|
}
|
|
2208
2209
|
|
|
2209
2210
|
// src/v2/status.tsx
|
|
2211
|
+
var KV_PREFIX = "cache_panel";
|
|
2210
2212
|
function StatusView(props) {
|
|
2211
2213
|
const t = createT(() => props.signals.langCode());
|
|
2214
|
+
onMount2(() => {
|
|
2215
|
+
try {
|
|
2216
|
+
const v = props.api.kv.get(`${KV_PREFIX}.section.bottom`, true);
|
|
2217
|
+
props.signals.setSectionBottom(v !== false);
|
|
2218
|
+
} catch {
|
|
2219
|
+
}
|
|
2220
|
+
});
|
|
2212
2221
|
const pal = createMemo2(() => {
|
|
2213
2222
|
const th = mapTheme(props.context.theme);
|
|
2214
2223
|
const sat = (k, fb) => desaturateTo(th[k], MAX_SAT, fb);
|
|
@@ -2288,7 +2297,7 @@ function StatusView(props) {
|
|
|
2288
2297
|
});
|
|
2289
2298
|
return _$createComponent2(Show2, {
|
|
2290
2299
|
get when() {
|
|
2291
|
-
return segsW() > 0;
|
|
2300
|
+
return _$memo2(() => !!(segsW() > 0 && stats().hitRate >= 0))() && props.signals.sectionBottom();
|
|
2292
2301
|
},
|
|
2293
2302
|
get children() {
|
|
2294
2303
|
var _el$ = _$createElement2("text");
|
|
@@ -2311,7 +2320,7 @@ function StatusView(props) {
|
|
|
2311
2320
|
}
|
|
2312
2321
|
|
|
2313
2322
|
// src/v2/commands.ts
|
|
2314
|
-
var
|
|
2323
|
+
var KV_PREFIX2 = "cache_panel";
|
|
2315
2324
|
function extractToolParts(msg) {
|
|
2316
2325
|
if (!Array.isArray(msg?.content)) return [];
|
|
2317
2326
|
return msg.content.filter((p) => p?.type === "tool");
|
|
@@ -2340,13 +2349,13 @@ function currentSessionID(context) {
|
|
|
2340
2349
|
function makeCommands(context, api, signals) {
|
|
2341
2350
|
const t = () => createT(() => signals.langCode());
|
|
2342
2351
|
const providerOptionTitle = (p, current) => {
|
|
2343
|
-
const hasManual = !!api.kv.get(`${
|
|
2352
|
+
const hasManual = !!api.kv.get(`${KV_PREFIX2}.balance.${p.id}.key`, "");
|
|
2344
2353
|
const hasAuto = !hasManual && !!findOpencodeKeyV2(context, p);
|
|
2345
2354
|
const mark = hasManual ? t()("keyUser") : hasAuto ? t()("keyOpenCode") : t()("keyNotSet");
|
|
2346
2355
|
return p.name + mark + (current && p.id === current ? " *" : "");
|
|
2347
2356
|
};
|
|
2348
2357
|
const promptBalanceKey = async (provider) => {
|
|
2349
|
-
const current = api.kv.get(`${
|
|
2358
|
+
const current = api.kv.get(`${KV_PREFIX2}.balance.${provider.id}.key`, "") ?? "";
|
|
2350
2359
|
const val = await context.ui.dialog.prompt({
|
|
2351
2360
|
title: provider.name,
|
|
2352
2361
|
message: t()("balKeyPrompt", { p: provider.name }),
|
|
@@ -2362,7 +2371,7 @@ function makeCommands(context, api, signals) {
|
|
|
2362
2371
|
} else {
|
|
2363
2372
|
key = input;
|
|
2364
2373
|
}
|
|
2365
|
-
await api.kv.set(`${
|
|
2374
|
+
await api.kv.set(`${KV_PREFIX2}.balance.${provider.id}.key`, key);
|
|
2366
2375
|
signals.setBalanceRefresh(signals.balanceRefresh() + 1);
|
|
2367
2376
|
context.ui.toast.show({ message: key ? t()("keySaved") : t()("keyCleared") });
|
|
2368
2377
|
};
|
|
@@ -2386,9 +2395,9 @@ function makeCommands(context, api, signals) {
|
|
|
2386
2395
|
if (!opt) return;
|
|
2387
2396
|
const sym = CURRENCIES[opt] ?? "$";
|
|
2388
2397
|
const defRate = DEFAULT_RATES[opt] ?? 1;
|
|
2389
|
-
await api.kv.set(`${
|
|
2390
|
-
await api.kv.set(`${
|
|
2391
|
-
await api.kv.set(`${
|
|
2398
|
+
await api.kv.set(`${KV_PREFIX2}.currency`, sym);
|
|
2399
|
+
await api.kv.set(`${KV_PREFIX2}.rate`, defRate);
|
|
2400
|
+
await api.kv.set(`${KV_PREFIX2}.balance_currency`, opt);
|
|
2392
2401
|
signals.setBalanceCurrency(opt);
|
|
2393
2402
|
signals.setCurrencySymbol(sym);
|
|
2394
2403
|
signals.setExchangeRate(defRate);
|
|
@@ -2412,7 +2421,7 @@ function makeCommands(context, api, signals) {
|
|
|
2412
2421
|
if (val === void 0) return;
|
|
2413
2422
|
const n = parseFloat(val);
|
|
2414
2423
|
if (n > 0) {
|
|
2415
|
-
await api.kv.set(`${
|
|
2424
|
+
await api.kv.set(`${KV_PREFIX2}.rate`, n);
|
|
2416
2425
|
signals.setExchangeRate(n);
|
|
2417
2426
|
context.ui.toast.show({ message: t()("rateSet", { r: n }) });
|
|
2418
2427
|
}
|
|
@@ -2427,13 +2436,13 @@ function makeCommands(context, api, signals) {
|
|
|
2427
2436
|
palette: true,
|
|
2428
2437
|
slash: { name: "cache-section" },
|
|
2429
2438
|
run: async () => {
|
|
2430
|
-
const detailOn = Boolean(api.kv.get(`${
|
|
2431
|
-
const modelOn = Boolean(api.kv.get(`${
|
|
2432
|
-
const distOn = Boolean(api.kv.get(`${
|
|
2433
|
-
const skillsOn = Boolean(api.kv.get(`${
|
|
2434
|
-
const balanceOn = Boolean(api.kv.get(`${
|
|
2435
|
-
const bottomOn = Boolean(api.kv.get(`${
|
|
2436
|
-
const borderOn = Boolean(api.kv.get(`${
|
|
2439
|
+
const detailOn = Boolean(api.kv.get(`${KV_PREFIX2}.section.detail`, true));
|
|
2440
|
+
const modelOn = Boolean(api.kv.get(`${KV_PREFIX2}.section.model`, true));
|
|
2441
|
+
const distOn = Boolean(api.kv.get(`${KV_PREFIX2}.section.dist`, true));
|
|
2442
|
+
const skillsOn = Boolean(api.kv.get(`${KV_PREFIX2}.section.skills`, true));
|
|
2443
|
+
const balanceOn = Boolean(api.kv.get(`${KV_PREFIX2}.section.balance`, true));
|
|
2444
|
+
const bottomOn = Boolean(api.kv.get(`${KV_PREFIX2}.section.bottom`, true));
|
|
2445
|
+
const borderOn = Boolean(api.kv.get(`${KV_PREFIX2}.border`, true));
|
|
2437
2446
|
const labels = {
|
|
2438
2447
|
detail: t()("secDetail"),
|
|
2439
2448
|
model: t()("secModel"),
|
|
@@ -2458,12 +2467,12 @@ function makeCommands(context, api, signals) {
|
|
|
2458
2467
|
});
|
|
2459
2468
|
if (!opt) return;
|
|
2460
2469
|
if (opt === "border") {
|
|
2461
|
-
const cur = Boolean(api.kv.get(`${
|
|
2462
|
-
await api.kv.set(`${
|
|
2470
|
+
const cur = Boolean(api.kv.get(`${KV_PREFIX2}.border`, true));
|
|
2471
|
+
await api.kv.set(`${KV_PREFIX2}.border`, !cur);
|
|
2463
2472
|
signals.setBorderVisible(!cur);
|
|
2464
2473
|
context.ui.toast.show({ message: !cur ? t()("borderShown") : t()("borderHidden") });
|
|
2465
2474
|
} else {
|
|
2466
|
-
const key = `${
|
|
2475
|
+
const key = `${KV_PREFIX2}.section.${opt}`;
|
|
2467
2476
|
const cur = Boolean(api.kv.get(key, true));
|
|
2468
2477
|
await api.kv.set(key, !cur);
|
|
2469
2478
|
if (opt === "detail") signals.setSectionDetail(!cur);
|
|
@@ -2486,14 +2495,14 @@ function makeCommands(context, api, signals) {
|
|
|
2486
2495
|
palette: true,
|
|
2487
2496
|
slash: { name: "cache-config" },
|
|
2488
2497
|
run: () => {
|
|
2489
|
-
const sym = api.kv.get(`${
|
|
2490
|
-
const rate = api.kv.get(`${
|
|
2491
|
-
const detail = Boolean(api.kv.get(`${
|
|
2492
|
-
const model = Boolean(api.kv.get(`${
|
|
2493
|
-
const dist = Boolean(api.kv.get(`${
|
|
2494
|
-
const skills = Boolean(api.kv.get(`${
|
|
2495
|
-
const balance = Boolean(api.kv.get(`${
|
|
2496
|
-
const bottom = Boolean(api.kv.get(`${
|
|
2498
|
+
const sym = api.kv.get(`${KV_PREFIX2}.currency`) ?? "$";
|
|
2499
|
+
const rate = api.kv.get(`${KV_PREFIX2}.rate`) ?? 1;
|
|
2500
|
+
const detail = Boolean(api.kv.get(`${KV_PREFIX2}.section.detail`, true));
|
|
2501
|
+
const model = Boolean(api.kv.get(`${KV_PREFIX2}.section.model`, true));
|
|
2502
|
+
const dist = Boolean(api.kv.get(`${KV_PREFIX2}.section.dist`, true));
|
|
2503
|
+
const skills = Boolean(api.kv.get(`${KV_PREFIX2}.section.skills`, true));
|
|
2504
|
+
const balance = Boolean(api.kv.get(`${KV_PREFIX2}.section.balance`, true));
|
|
2505
|
+
const bottom = Boolean(api.kv.get(`${KV_PREFIX2}.section.bottom`, true));
|
|
2497
2506
|
const on = (v) => v ? "ON" : "OFF";
|
|
2498
2507
|
context.ui.toast.show({
|
|
2499
2508
|
title: t()("panelConfigTitle"),
|
|
@@ -2528,7 +2537,7 @@ function makeCommands(context, api, signals) {
|
|
|
2528
2537
|
}))
|
|
2529
2538
|
});
|
|
2530
2539
|
if (!opt) return;
|
|
2531
|
-
await api.kv.set(`${
|
|
2540
|
+
await api.kv.set(`${KV_PREFIX2}.lang`, opt);
|
|
2532
2541
|
signals.setLangCode(opt);
|
|
2533
2542
|
context.ui.toast.show({ message: t()("langSwitched") });
|
|
2534
2543
|
}
|
|
@@ -2558,18 +2567,18 @@ function makeCommands(context, api, signals) {
|
|
|
2558
2567
|
if (!opt) return;
|
|
2559
2568
|
if (opt === "__auto__") {
|
|
2560
2569
|
const next = !auto;
|
|
2561
|
-
await api.kv.set(`${
|
|
2570
|
+
await api.kv.set(`${KV_PREFIX2}.balance.auto`, next);
|
|
2562
2571
|
signals.setAutoBalance(next);
|
|
2563
2572
|
context.ui.toast.show({ message: next ? t()("autoSwitchOn") : t()("autoSwitchOff") });
|
|
2564
2573
|
} else {
|
|
2565
2574
|
const provider = getBalanceProvider(opt);
|
|
2566
|
-
await api.kv.set(`${
|
|
2567
|
-
await api.kv.set(`${
|
|
2575
|
+
await api.kv.set(`${KV_PREFIX2}.balance.provider`, provider.id);
|
|
2576
|
+
await api.kv.set(`${KV_PREFIX2}.balance.auto`, false);
|
|
2568
2577
|
signals.setBalanceProviderId(provider.id);
|
|
2569
2578
|
signals.setAutoBalance(false);
|
|
2570
2579
|
signals.setBalanceUnsupported(false);
|
|
2571
2580
|
signals.setBalanceRefresh(signals.balanceRefresh() + 1);
|
|
2572
|
-
const hasKey = !!api.kv.get(`${
|
|
2581
|
+
const hasKey = !!api.kv.get(`${KV_PREFIX2}.balance.${provider.id}.key`, "");
|
|
2573
2582
|
if (!hasKey) {
|
|
2574
2583
|
await promptBalanceKey(provider);
|
|
2575
2584
|
} else {
|
|
@@ -2596,8 +2605,8 @@ function makeCommands(context, api, signals) {
|
|
|
2596
2605
|
});
|
|
2597
2606
|
if (!opt) return;
|
|
2598
2607
|
const provider = getBalanceProvider(opt);
|
|
2599
|
-
await api.kv.set(`${
|
|
2600
|
-
await api.kv.set(`${
|
|
2608
|
+
await api.kv.set(`${KV_PREFIX2}.balance.provider`, provider.id);
|
|
2609
|
+
await api.kv.set(`${KV_PREFIX2}.balance.auto`, false);
|
|
2601
2610
|
signals.setBalanceProviderId(provider.id);
|
|
2602
2611
|
signals.setAutoBalance(false);
|
|
2603
2612
|
signals.setBalanceRefresh(signals.balanceRefresh() + 1);
|
|
@@ -2684,7 +2693,7 @@ function makeCommands(context, api, signals) {
|
|
|
2684
2693
|
return true;
|
|
2685
2694
|
});
|
|
2686
2695
|
if (unique.length > 0) {
|
|
2687
|
-
const currentSid = signals.overrideSessionId() ?? api.kv.get(`${
|
|
2696
|
+
const currentSid = signals.overrideSessionId() ?? api.kv.get(`${KV_PREFIX2}.session`, "");
|
|
2688
2697
|
const options = unique.map((c, i) => ({
|
|
2689
2698
|
title: `${i + 1}. ${c.title}`,
|
|
2690
2699
|
value: c.value,
|
|
@@ -2703,11 +2712,11 @@ function makeCommands(context, api, signals) {
|
|
|
2703
2712
|
if (!opt) return;
|
|
2704
2713
|
if (opt === backValue) {
|
|
2705
2714
|
signals.setOverrideSessionId(void 0);
|
|
2706
|
-
await api.kv.set(`${
|
|
2715
|
+
await api.kv.set(`${KV_PREFIX2}.session`, "");
|
|
2707
2716
|
context.ui.toast.show({ message: t()("backToMain") });
|
|
2708
2717
|
} else {
|
|
2709
2718
|
signals.setOverrideSessionId(opt);
|
|
2710
|
-
await api.kv.set(`${
|
|
2719
|
+
await api.kv.set(`${KV_PREFIX2}.session`, opt);
|
|
2711
2720
|
context.ui.toast.show({ message: t()("subAgentSwitched", { s: opt.slice(0, 24) + "\u2026" }) });
|
|
2712
2721
|
}
|
|
2713
2722
|
} else {
|
|
@@ -2720,7 +2729,7 @@ function makeCommands(context, api, signals) {
|
|
|
2720
2729
|
const sid = val.trim();
|
|
2721
2730
|
if (sid) {
|
|
2722
2731
|
signals.setOverrideSessionId(sid);
|
|
2723
|
-
await api.kv.set(`${
|
|
2732
|
+
await api.kv.set(`${KV_PREFIX2}.session`, sid);
|
|
2724
2733
|
context.ui.toast.show({ message: t()("subAgentSwitched", { s: sid.slice(0, 24) + "\u2026" }) });
|
|
2725
2734
|
}
|
|
2726
2735
|
}
|
|
@@ -2736,7 +2745,7 @@ function makeCommands(context, api, signals) {
|
|
|
2736
2745
|
slash: { name: "cache-session-back" },
|
|
2737
2746
|
run: async () => {
|
|
2738
2747
|
signals.setOverrideSessionId(void 0);
|
|
2739
|
-
await api.kv.set(`${
|
|
2748
|
+
await api.kv.set(`${KV_PREFIX2}.session`, "");
|
|
2740
2749
|
context.ui.toast.show({ message: t()("backToMain") });
|
|
2741
2750
|
}
|
|
2742
2751
|
}
|
|
@@ -2744,7 +2753,7 @@ function makeCommands(context, api, signals) {
|
|
|
2744
2753
|
}
|
|
2745
2754
|
|
|
2746
2755
|
// src/v2/index.tsx
|
|
2747
|
-
var
|
|
2756
|
+
var KV_PREFIX3 = "cache_panel";
|
|
2748
2757
|
var BALANCE_POLL_MS = 5 * 60 * 1e3;
|
|
2749
2758
|
var DEBUG_LANG = typeof process !== "undefined" ? process.env?.CACHE_TUI_LANG : void 0;
|
|
2750
2759
|
var INIT_LANG = DEBUG_LANG !== void 0 && LANG_META.some((m) => m.code === DEBUG_LANG) ? DEBUG_LANG : detectLang();
|
|
@@ -2816,9 +2825,9 @@ function PluginRoot(props) {
|
|
|
2816
2825
|
mode: "global",
|
|
2817
2826
|
commands: makeCommands(props.context, props.api, props.signals)
|
|
2818
2827
|
}));
|
|
2819
|
-
|
|
2828
|
+
onMount3(() => {
|
|
2820
2829
|
try {
|
|
2821
|
-
const saved = props.api.kv.get(`${
|
|
2830
|
+
const saved = props.api.kv.get(`${KV_PREFIX3}.lang`);
|
|
2822
2831
|
if (saved && LANG_META.some((m) => m.code === saved)) {
|
|
2823
2832
|
props.signals.setLangCode(saved);
|
|
2824
2833
|
}
|
|
@@ -2827,7 +2836,7 @@ function PluginRoot(props) {
|
|
|
2827
2836
|
});
|
|
2828
2837
|
const pollBalance = async () => {
|
|
2829
2838
|
const provider = getBalanceProvider(props.signals.balanceProviderId());
|
|
2830
|
-
const key = props.api.kv.get(`${
|
|
2839
|
+
const key = props.api.kv.get(`${KV_PREFIX3}.balance.${provider.id}.key`, "") || findOpencodeKeyV2(props.context, provider);
|
|
2831
2840
|
const set = props.signals.setBalanceState;
|
|
2832
2841
|
if (props.signals.balanceUnsupported()) {
|
|
2833
2842
|
set({
|
|
@@ -2904,7 +2913,7 @@ function PluginRoot(props) {
|
|
|
2904
2913
|
lastSlotSid = sid;
|
|
2905
2914
|
if (props.signals.overrideSessionId()) {
|
|
2906
2915
|
props.signals.setOverrideSessionId(void 0);
|
|
2907
|
-
void props.api.kv.set(`${
|
|
2916
|
+
void props.api.kv.set(`${KV_PREFIX3}.session`, "");
|
|
2908
2917
|
}
|
|
2909
2918
|
}
|
|
2910
2919
|
});
|
|
@@ -2943,6 +2952,7 @@ var mod = {
|
|
|
2943
2952
|
append: "prompt.footer.status",
|
|
2944
2953
|
render: (props) => _$createComponent3(StatusView, {
|
|
2945
2954
|
context,
|
|
2955
|
+
api,
|
|
2946
2956
|
signals,
|
|
2947
2957
|
get sessionID() {
|
|
2948
2958
|
return String(props.sessionID ?? "");
|
package/package.json
CHANGED
package/src/_version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// auto-generated
|
|
2
|
-
export const PLUGIN_VERSION="1.7.0-beta.
|
|
2
|
+
export const PLUGIN_VERSION="1.7.0-beta.5";
|
package/src/v2/index.tsx
CHANGED
|
@@ -172,7 +172,7 @@ const mod: PluginModule & { server: () => Promise<Record<string, never>> } = {
|
|
|
172
172
|
context.ui.slot({
|
|
173
173
|
append: "prompt.footer.status",
|
|
174
174
|
render: (props) => (
|
|
175
|
-
<StatusView context={context} signals={signals} sessionID={String(props.sessionID ?? "")} />
|
|
175
|
+
<StatusView context={context} api={api} signals={signals} sessionID={String(props.sessionID ?? "")} />
|
|
176
176
|
),
|
|
177
177
|
})
|
|
178
178
|
|
package/src/v2/status.tsx
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
/** @jsxImportSource @opentui/solid */
|
|
2
2
|
|
|
3
|
-
import { createMemo, For, Show } from "solid-js"
|
|
3
|
+
import { createMemo, For, onMount, Show } from "solid-js"
|
|
4
4
|
import type { Context } from "./types"
|
|
5
|
-
import type { PanelSignals } from "../panel/panel-api"
|
|
5
|
+
import type { PanelApi, PanelSignals } from "../panel/panel-api"
|
|
6
6
|
import { collectLastHitRate } from "./data"
|
|
7
7
|
import { desaturateTo, fmtCompact, formatBalanceText, MAX_SAT, FALLBACK, visualWidth } from "../core"
|
|
8
8
|
import { createT } from "../i18n"
|
|
9
9
|
import { mapTheme } from "./theme"
|
|
10
10
|
|
|
11
|
+
const KV_PREFIX = "cache_panel"
|
|
12
|
+
|
|
11
13
|
/**
|
|
12
14
|
* 底部状态栏(prompt.footer.status)——对齐 V1 BottomStatusBar 统计段口径:
|
|
13
15
|
* 单条命中率(最后一条有 token 的 assistant 消息)+ 趋势 + Tokens 总量 + 余额。
|
|
14
16
|
* 余额读共享 signals.balanceState(PluginRoot 驱动轮询);provider 不支持余额时隐藏余额段(对齐 V1)。
|
|
15
17
|
* 颜色经 mapTheme(V1 形状)——与侧边栏命中率颜色同源,保证两处一致。
|
|
18
|
+
* 显隐受 signals.sectionBottom 控制(/cache-section 切换),启动时从 kv 恢复偏好(对齐 V1)。
|
|
16
19
|
*/
|
|
17
20
|
export function StatusView(props: {
|
|
18
21
|
context: Context
|
|
22
|
+
api: PanelApi
|
|
19
23
|
signals: PanelSignals
|
|
20
24
|
sessionID: string
|
|
21
25
|
}) {
|
|
22
26
|
const t = createT(() => props.signals.langCode())
|
|
23
27
|
|
|
28
|
+
// 恢复显隐偏好(默认显示;关闭时隐藏统计段,与宿主默认 hint 行一致)
|
|
29
|
+
onMount(() => {
|
|
30
|
+
try {
|
|
31
|
+
const v = props.api.kv.get<boolean>(`${KV_PREFIX}.section.bottom`, true)
|
|
32
|
+
props.signals.setSectionBottom(v !== false)
|
|
33
|
+
} catch {}
|
|
34
|
+
})
|
|
35
|
+
|
|
24
36
|
// 与侧边栏 TokenCachePanel 同一颜色来源(mapTheme → desaturateTo)
|
|
25
37
|
const pal = createMemo(() => {
|
|
26
38
|
const th = mapTheme(props.context.theme) as unknown as Record<string, string>
|
|
@@ -87,7 +99,7 @@ export function StatusView(props: {
|
|
|
87
99
|
})
|
|
88
100
|
|
|
89
101
|
return (
|
|
90
|
-
<Show when={segsW() > 0}>
|
|
102
|
+
<Show when={segsW() > 0 && stats().hitRate >= 0 && props.signals.sectionBottom()}>
|
|
91
103
|
<text>
|
|
92
104
|
<For each={segs()}>{(sg) => <span style={{ fg: sg.color }}>{sg.text}</span>}</For>
|
|
93
105
|
</text>
|