opencode-visual-cache 1.5.0 → 1.6.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 +12 -6
- package/README_EN.md +13 -5
- package/dist/_version.d.ts +1 -1
- package/dist/_version.js +1 -1
- package/dist/i18n.d.ts +102 -0
- package/dist/i18n.js +368 -0
- package/dist/index.js +461 -260
- package/dist/tui.js +1203 -478
- package/package.json +6 -3
- package/src/_version.ts +1 -1
- package/src/i18n.ts +380 -0
- package/src/index.tsx +547 -315
package/dist/tui.js
CHANGED
|
@@ -13,7 +13,7 @@ import { createElement as _$createElement } from "@opentui/solid";
|
|
|
13
13
|
import { createMemo, createSignal, createEffect, onMount, onCleanup, Show, untrack } from "solid-js";
|
|
14
14
|
|
|
15
15
|
// src/_version.ts
|
|
16
|
-
var PLUGIN_VERSION = "1.
|
|
16
|
+
var PLUGIN_VERSION = "1.6.1";
|
|
17
17
|
|
|
18
18
|
// src/balance-providers.ts
|
|
19
19
|
var BalanceError = class extends Error {
|
|
@@ -117,51 +117,7 @@ function maskKey(k) {
|
|
|
117
117
|
return k.slice(0, 5) + "*".repeat(Math.max(3, k.length - 10)) + k.slice(-5);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
// src/
|
|
121
|
-
function charColumns(c) {
|
|
122
|
-
const code = c.codePointAt(0) ?? 0;
|
|
123
|
-
if (code < 32) return 0;
|
|
124
|
-
if (code < 127) return 1;
|
|
125
|
-
if (code < 160) return 0;
|
|
126
|
-
if (code >= 4352 && code <= 4447 || // Hangul Jamo
|
|
127
|
-
code >= 11904 && code <= 42191 || // CJK Radicals … Yi
|
|
128
|
-
code >= 44032 && code <= 55203 || // Hangul
|
|
129
|
-
code >= 63744 && code <= 64255 || // CJK Compat
|
|
130
|
-
code >= 65040 && code <= 65135 || // Vertical / Compat
|
|
131
|
-
code >= 65281 && code <= 65376 || // Fullwidth
|
|
132
|
-
code >= 65504 && code <= 65510 || // Fullwidth signs
|
|
133
|
-
code >= 127744 && code <= 128591 || // Misc Symbols (emoji)
|
|
134
|
-
code >= 131072 && code <= 262141)
|
|
135
|
-
return 2;
|
|
136
|
-
return 1;
|
|
137
|
-
}
|
|
138
|
-
function visualWidth(s) {
|
|
139
|
-
let w = 0;
|
|
140
|
-
for (const c of s) w += charColumns(c);
|
|
141
|
-
return w;
|
|
142
|
-
}
|
|
143
|
-
function truncateVisual(s, maxCols) {
|
|
144
|
-
if (visualWidth(s) <= maxCols) return s;
|
|
145
|
-
let result = "", w = 0;
|
|
146
|
-
for (const c of s) {
|
|
147
|
-
const cw = charColumns(c);
|
|
148
|
-
if (w + cw > maxCols - 1) {
|
|
149
|
-
result += "\u2026";
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
result += c;
|
|
153
|
-
w += cw;
|
|
154
|
-
}
|
|
155
|
-
return result;
|
|
156
|
-
}
|
|
157
|
-
var DEBUG_LANG = typeof process !== "undefined" ? process.env?.CACHE_TUI_LANG : void 0;
|
|
158
|
-
var LANG_ZH = DEBUG_LANG ? DEBUG_LANG === "zh" : (() => {
|
|
159
|
-
try {
|
|
160
|
-
return Intl.DateTimeFormat().resolvedOptions().locale.startsWith("zh");
|
|
161
|
-
} catch {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
})();
|
|
120
|
+
// src/i18n.ts
|
|
165
121
|
var ZH_T = {
|
|
166
122
|
title: "\u7F13\u5B58\u7EDF\u8BA1",
|
|
167
123
|
hit: "\u547D\u4E2D\u7387",
|
|
@@ -184,11 +140,11 @@ var ZH_T = {
|
|
|
184
140
|
distTitle: "\u4F30\u7B97 Token \u5206\u5E03",
|
|
185
141
|
distSys: "\u7CFB\u7EDF\u63D0\u793A:",
|
|
186
142
|
distUser: "\u7528\u6237:",
|
|
187
|
-
distAgent: "
|
|
143
|
+
distAgent: "\u5B50\u4EE3\u7406\u6307\u4EE4:",
|
|
188
144
|
distTool: "Tool \u8C03\u7528:",
|
|
189
145
|
distRes: "Tool \u7ED3\u679C:",
|
|
190
|
-
|
|
191
|
-
|
|
146
|
+
distReason: "\u63A8\u7406:",
|
|
147
|
+
stepsCount: "\u672C\u56DE\u5408 {n} \u6B21\u8C03\u7528:",
|
|
192
148
|
secDetail: "\u660E\u7EC6",
|
|
193
149
|
secModel: "\u6A21\u578B",
|
|
194
150
|
secSkills: "\u5DF2\u52A0\u8F7D\u6280\u80FD",
|
|
@@ -199,7 +155,49 @@ var ZH_T = {
|
|
|
199
155
|
balErr401: "API Key \u65E0\u6548",
|
|
200
156
|
balErr403: "\u4F59\u989D\u67E5\u8BE2\u88AB\u62D2\u7EDD",
|
|
201
157
|
balErrEmpty: "\u672A\u83B7\u53D6\u5230\u4F59\u989D\u6570\u636E",
|
|
202
|
-
balErrTimeout: "\u67E5\u8BE2\u8D85\u65F6"
|
|
158
|
+
balErrTimeout: "\u67E5\u8BE2\u8D85\u65F6",
|
|
159
|
+
balUnsupported: "\u5F53\u524D\u63D0\u4F9B\u5546\u4E0D\u652F\u6301\u4F59\u989D\u67E5\u8BE2",
|
|
160
|
+
barHit: "\u547D\u4E2D\u7387",
|
|
161
|
+
barBal: "\u4F59\u989D",
|
|
162
|
+
barTok: "Tokens",
|
|
163
|
+
// ── /cache-section 面板 ──
|
|
164
|
+
secToggle: "\u5207\u6362\u533A\u5757",
|
|
165
|
+
secBalance: "\u4F59\u989D",
|
|
166
|
+
secBottom: "\u5E95\u90E8\u72B6\u6001\u680F",
|
|
167
|
+
secBorder: "\u9762\u677F\u8FB9\u6846",
|
|
168
|
+
// ── toast ──
|
|
169
|
+
keySaved: "API Key \u5DF2\u4FDD\u5B58\uFF0C\u6B63\u5728\u67E5\u8BE2\u4F59\u989D...",
|
|
170
|
+
keyCleared: "API Key \u5DF2\u6E05\u9664",
|
|
171
|
+
currencySet: "\u5E01\u79CD: {v} ({s}), \u6C47\u7387: {r}",
|
|
172
|
+
rateSet: "\u6C47\u7387\u5DF2\u8BBE\u4E3A {r}",
|
|
173
|
+
panelConfigTitle: "\u7F13\u5B58\u9762\u677F\u914D\u7F6E",
|
|
174
|
+
panelConfigMsg: "\u5E01\u79CD: {c} | \u6C47\u7387: {r} | \u660E\u7EC6: {d} | \u6A21\u578B: {m} | \u5206\u5E03: {t} | \u6280\u80FD: {k} | \u4F59\u989D: {b} | \u5E95\u90E8: {f}",
|
|
175
|
+
borderShown: "\u9762\u677F\u8FB9\u6846 \u5DF2\u663E\u793A",
|
|
176
|
+
borderHidden: "\u9762\u677F\u8FB9\u6846 \u5DF2\u9690\u85CF",
|
|
177
|
+
sectionShown: "{s} \u5DF2\u663E\u793A",
|
|
178
|
+
sectionHidden: "{s} \u5DF2\u9690\u85CF",
|
|
179
|
+
langSwitched: "\u8BED\u8A00\u5DF2\u5207\u6362\u4E3A\u4E2D\u6587",
|
|
180
|
+
autoSwitchOn: "\u81EA\u52A8\u5207\u6362\u4F59\u989D\u63D0\u4F9B\u5546: \u5F00",
|
|
181
|
+
autoSwitchOff: "\u81EA\u52A8\u5207\u6362\u4F59\u989D\u63D0\u4F9B\u5546: \u5173",
|
|
182
|
+
providerManual: "\u4F59\u989D\u63D0\u4F9B\u5546: {p}\uFF08\u81EA\u52A8\u5207\u6362\u5DF2\u5173\u95ED\uFF09",
|
|
183
|
+
runInSession: "\u8BF7\u5728\u4F1A\u8BDD\u5185\u8FD0\u884C\u6B64\u547D\u4EE4",
|
|
184
|
+
backToMain: "\u5DF2\u5207\u56DE\u4E3B\u4F1A\u8BDD",
|
|
185
|
+
subAgentSwitched: "\u5DF2\u5207\u6362\u81F3\u5B50\u4EE3\u7406: {s}",
|
|
186
|
+
// ── 对话框 / 菜单 ──
|
|
187
|
+
langTitle: "\u663E\u793A\u8BED\u8A00",
|
|
188
|
+
subPrefix: "\u5B50\u4EE3\u7406: ",
|
|
189
|
+
keyUser: "\uFF08\u7528\u6237 key\uFF09",
|
|
190
|
+
keyOpenCode: "\uFF08OpenCode\uFF09",
|
|
191
|
+
keyNotSet: "\uFF08\u672A\u914D\u7F6E\uFF09",
|
|
192
|
+
balKeyPrompt: "\u8F93\u5165 {p} API Key \u4EE5\u663E\u793A\u8D26\u6237\u4F59\u989D\uFF08\u7559\u7A7A\u6E05\u9664\uFF09",
|
|
193
|
+
balProvTitle: "\u4F59\u989D\u63D0\u4F9B\u5546 / \u81EA\u52A8\u5207\u6362",
|
|
194
|
+
autoSwitchOpt: "\u81EA\u52A8\u5207\u6362\u63D0\u4F9B\u5546",
|
|
195
|
+
balSelectTitle: "\u9009\u62E9\u4F59\u989D\u63D0\u4F9B\u5546",
|
|
196
|
+
backToMainTitle: "\u56DE\u5230\u4E3B\u4F1A\u8BDD",
|
|
197
|
+
subSelectTitle: "\u9009\u62E9\u5B50\u4EE3\u7406",
|
|
198
|
+
subSwitchTitle: "\u5207\u6362\u5B50\u4EE3\u7406",
|
|
199
|
+
subViewTitle: "\u67E5\u770B\u5B50\u4EE3\u7406\u7F13\u5B58",
|
|
200
|
+
subNoFound: "\u672A\u627E\u5230\u5B50\u4EE3\u7406\uFF0C\u8BF7\u624B\u52A8\u7C98\u8D34 Session ID"
|
|
203
201
|
};
|
|
204
202
|
var EN_T = {
|
|
205
203
|
title: "Token Cache",
|
|
@@ -223,11 +221,11 @@ var EN_T = {
|
|
|
223
221
|
distTitle: "Estimated Token Dist.",
|
|
224
222
|
distSys: "System:",
|
|
225
223
|
distUser: "User:",
|
|
226
|
-
distAgent: "Agent Instr:",
|
|
224
|
+
distAgent: "Sub-Agent Instr:",
|
|
227
225
|
distTool: "Tool Call:",
|
|
228
226
|
distRes: "Tool Result:",
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
distReason: "Reasoning:",
|
|
228
|
+
stepsCount: "Turn #{n} calls:",
|
|
231
229
|
secDetail: "Detail",
|
|
232
230
|
secModel: "Model",
|
|
233
231
|
secSkills: "Loaded Skills",
|
|
@@ -238,8 +236,284 @@ var EN_T = {
|
|
|
238
236
|
balErr401: "Invalid API Key",
|
|
239
237
|
balErr403: "Balance request rejected",
|
|
240
238
|
balErrEmpty: "No balance data",
|
|
241
|
-
balErrTimeout: "Request timed out"
|
|
239
|
+
balErrTimeout: "Request timed out",
|
|
240
|
+
balUnsupported: "Balance query unsupported",
|
|
241
|
+
barHit: "Hit",
|
|
242
|
+
barBal: "Balance",
|
|
243
|
+
barTok: "Tokens",
|
|
244
|
+
// ── /cache-section panel ──
|
|
245
|
+
secToggle: "Toggle Section",
|
|
246
|
+
secBalance: "Balance",
|
|
247
|
+
secBottom: "Bottom Bar",
|
|
248
|
+
secBorder: "Panel Border",
|
|
249
|
+
// ── toasts ──
|
|
250
|
+
keySaved: "API Key saved, fetching balance...",
|
|
251
|
+
keyCleared: "API Key cleared",
|
|
252
|
+
currencySet: "Currency: {v} ({s}), rate: {r}",
|
|
253
|
+
rateSet: "Exchange rate set to {r}",
|
|
254
|
+
panelConfigTitle: "Cache Panel Config",
|
|
255
|
+
panelConfigMsg: "Currency: {c} | Rate: {r} | Detail: {d} | Model: {m} | Dist: {t} | Skills: {k} | Balance: {b} | Bottom: {f}",
|
|
256
|
+
borderShown: "Panel border shown",
|
|
257
|
+
borderHidden: "Panel border hidden",
|
|
258
|
+
sectionShown: "{s} section shown",
|
|
259
|
+
sectionHidden: "{s} section hidden",
|
|
260
|
+
langSwitched: "Switched to English",
|
|
261
|
+
autoSwitchOn: "Auto-switch balance provider: ON",
|
|
262
|
+
autoSwitchOff: "Auto-switch balance provider: OFF",
|
|
263
|
+
providerManual: "Balance provider: {p} (auto-switch off)",
|
|
264
|
+
runInSession: "Please run this command inside a session",
|
|
265
|
+
backToMain: "Switched to main session",
|
|
266
|
+
subAgentSwitched: "Showing sub-agent: {s}",
|
|
267
|
+
// ── dialogs / menus ──
|
|
268
|
+
langTitle: "Display Language",
|
|
269
|
+
subPrefix: "Sub: ",
|
|
270
|
+
keyUser: " (user key)",
|
|
271
|
+
keyOpenCode: " (OpenCode)",
|
|
272
|
+
keyNotSet: " (not set)",
|
|
273
|
+
balKeyPrompt: "Enter your {p} API key to show account balance (leave empty to clear)",
|
|
274
|
+
balProvTitle: "Balance Provider / Auto-switch",
|
|
275
|
+
autoSwitchOpt: "Auto-switch provider",
|
|
276
|
+
balSelectTitle: "Select Balance Provider",
|
|
277
|
+
backToMainTitle: "Back to Main",
|
|
278
|
+
subSelectTitle: "Select Sub-Agent",
|
|
279
|
+
subSwitchTitle: "Switch Sub",
|
|
280
|
+
subViewTitle: "View Sub Cache",
|
|
281
|
+
subNoFound: "No sub-agents found. Paste a Session ID manually"
|
|
282
|
+
};
|
|
283
|
+
var JA_T = {
|
|
284
|
+
title: "\u30AD\u30E3\u30C3\u30B7\u30E5\u7D71\u8A08",
|
|
285
|
+
hit: "\u30D2\u30C3\u30C8\u7387",
|
|
286
|
+
totalHit: "\u7DCF\u30D2\u30C3\u30C8:",
|
|
287
|
+
read: "\u30AD\u30E3\u30C3\u30B7\u30E5\u8AAD\u8FBC:",
|
|
288
|
+
write: "\u30AD\u30E3\u30C3\u30B7\u30E5\u66F8\u8FBC:",
|
|
289
|
+
miss: "\u672A\u30D2\u30C3\u30C8:",
|
|
290
|
+
out: "\u51FA\u529B:",
|
|
291
|
+
cost: "\u8CBB\u7528:",
|
|
292
|
+
saved: "\u7D2F\u8A08\u7BC0\u7D04:",
|
|
293
|
+
model: "\u30E2\u30C7\u30EB:",
|
|
294
|
+
provider: "\u30D7\u30ED\u30D0\u30A4\u30C0:",
|
|
295
|
+
rate: "\u5358\u4FA1:",
|
|
296
|
+
hitFolded: "\u30D2\u30C3\u30C8",
|
|
297
|
+
inputRate: "\u5165\u529B",
|
|
298
|
+
cacheRate: "\u30AD\u30E3\u30C3\u30B7\u30E5",
|
|
299
|
+
writeRate: "\u66F8\u8FBC",
|
|
300
|
+
noData: "\u30AD\u30E3\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u5F85\u6A5F\u4E2D...",
|
|
301
|
+
tok: "tok",
|
|
302
|
+
distTitle: "Token \u5206\u5E03\uFF08\u63A8\u5B9A\uFF09",
|
|
303
|
+
distSys: "\u30B7\u30B9\u30C6\u30E0:",
|
|
304
|
+
distUser: "\u30E6\u30FC\u30B6\u30FC:",
|
|
305
|
+
distAgent: "\u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u6307\u793A:",
|
|
306
|
+
distTool: "Tool \u547C\u3073\u51FA\u3057:",
|
|
307
|
+
distRes: "Tool \u7D50\u679C:",
|
|
308
|
+
distReason: "\u63A8\u8AD6:",
|
|
309
|
+
stepsCount: "\u4ECA\u56DE {n} \u56DE\u547C\u51FA:",
|
|
310
|
+
secDetail: "\u660E\u7D30",
|
|
311
|
+
secModel: "\u30E2\u30C7\u30EB",
|
|
312
|
+
secSkills: "\u8AAD\u307F\u8FBC\u307F\u6E08\u307F\u30B9\u30AD\u30EB",
|
|
313
|
+
balTotal: "\u7DCF\u6B8B\u9AD8:",
|
|
314
|
+
balNoKey: "{p} \u306E API Key \u672A\u8A2D\u5B9A",
|
|
315
|
+
balLoading: "\u53D6\u5F97\u4E2D...",
|
|
316
|
+
balError: "\u53D6\u5F97\u5931\u6557",
|
|
317
|
+
balErr401: "API Key \u7121\u52B9",
|
|
318
|
+
balErr403: "\u6B8B\u9AD8\u7167\u4F1A\u304C\u62D2\u5426\u3055\u308C\u307E\u3057\u305F",
|
|
319
|
+
balErrEmpty: "\u6B8B\u9AD8\u30C7\u30FC\u30BF\u306A\u3057",
|
|
320
|
+
balErrTimeout: "\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8",
|
|
321
|
+
balUnsupported: "\u3053\u306E\u30D7\u30ED\u30D0\u30A4\u30C0\u306F\u6B8B\u9AD8\u7167\u4F1A\u975E\u5BFE\u5FDC",
|
|
322
|
+
barHit: "\u30D2\u30C3\u30C8\u7387",
|
|
323
|
+
barBal: "\u6B8B\u9AD8",
|
|
324
|
+
barTok: "Tokens",
|
|
325
|
+
// ── /cache-section パネル ──
|
|
326
|
+
secToggle: "\u30BB\u30AF\u30B7\u30E7\u30F3\u5207\u66FF",
|
|
327
|
+
secBalance: "\u6B8B\u9AD8",
|
|
328
|
+
secBottom: "\u4E0B\u90E8\u30B9\u30C6\u30FC\u30BF\u30B9\u30D0\u30FC",
|
|
329
|
+
secBorder: "\u30D1\u30CD\u30EB\u67A0\u7DDA",
|
|
330
|
+
// ── toast ──
|
|
331
|
+
keySaved: "API Key \u4FDD\u5B58\u6E08\u307F\u3001\u6B8B\u9AD8\u3092\u53D6\u5F97\u4E2D...",
|
|
332
|
+
keyCleared: "API Key \u3092\u30AF\u30EA\u30A2\u3057\u307E\u3057\u305F",
|
|
333
|
+
currencySet: "\u901A\u8CA8: {v} ({s}), \u30EC\u30FC\u30C8: {r}",
|
|
334
|
+
rateSet: "\u30EC\u30FC\u30C8\u3092 {r} \u306B\u8A2D\u5B9A\u3057\u307E\u3057\u305F",
|
|
335
|
+
panelConfigTitle: "\u30D1\u30CD\u30EB\u8A2D\u5B9A",
|
|
336
|
+
panelConfigMsg: "\u901A\u8CA8: {c} | \u30EC\u30FC\u30C8: {r} | \u660E\u7D30: {d} | \u30E2\u30C7\u30EB: {m} | \u5206\u5E03: {t} | \u30B9\u30AD\u30EB: {k} | \u6B8B\u9AD8: {b} | \u4E0B\u90E8: {f}",
|
|
337
|
+
borderShown: "\u30D1\u30CD\u30EB\u67A0\u7DDA \u8868\u793A",
|
|
338
|
+
borderHidden: "\u30D1\u30CD\u30EB\u67A0\u7DDA \u975E\u8868\u793A",
|
|
339
|
+
sectionShown: "{s} \u8868\u793A",
|
|
340
|
+
sectionHidden: "{s} \u975E\u8868\u793A",
|
|
341
|
+
langSwitched: "\u65E5\u672C\u8A9E\u306B\u5207\u308A\u66FF\u3048\u307E\u3057\u305F",
|
|
342
|
+
autoSwitchOn: "\u6B8B\u9AD8\u30D7\u30ED\u30D0\u30A4\u30C0\u81EA\u52D5\u5207\u66FF: \u30AA\u30F3",
|
|
343
|
+
autoSwitchOff: "\u6B8B\u9AD8\u30D7\u30ED\u30D0\u30A4\u30C0\u81EA\u52D5\u5207\u66FF: \u30AA\u30D5",
|
|
344
|
+
providerManual: "\u6B8B\u9AD8\u30D7\u30ED\u30D0\u30A4\u30C0: {p}\uFF08\u81EA\u52D5\u5207\u66FF\u30AA\u30D5\uFF09",
|
|
345
|
+
runInSession: "\u30BB\u30C3\u30B7\u30E7\u30F3\u5185\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
346
|
+
backToMain: "\u30E1\u30A4\u30F3\u30BB\u30C3\u30B7\u30E7\u30F3\u306B\u623B\u308A\u307E\u3057\u305F",
|
|
347
|
+
subAgentSwitched: "\u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3078\u5207\u66FF: {s}",
|
|
348
|
+
// ── ダイアログ / メニュー ──
|
|
349
|
+
langTitle: "\u8868\u793A\u8A00\u8A9E",
|
|
350
|
+
subPrefix: "\u30B5\u30D6: ",
|
|
351
|
+
keyUser: "\uFF08\u30E6\u30FC\u30B6\u30FC key\uFF09",
|
|
352
|
+
keyOpenCode: "\uFF08OpenCode\uFF09",
|
|
353
|
+
keyNotSet: "\uFF08\u672A\u8A2D\u5B9A\uFF09",
|
|
354
|
+
balKeyPrompt: "{p} \u306E API Key \u3092\u5165\u529B\u3057\u3066\u6B8B\u9AD8\u3092\u8868\u793A\uFF08\u7A7A\u6B04\u3067\u30AF\u30EA\u30A2\uFF09",
|
|
355
|
+
balProvTitle: "\u6B8B\u9AD8\u30D7\u30ED\u30D0\u30A4\u30C0 / \u81EA\u52D5\u5207\u66FF",
|
|
356
|
+
autoSwitchOpt: "\u81EA\u52D5\u5207\u66FF\u30D7\u30ED\u30D0\u30A4\u30C0",
|
|
357
|
+
balSelectTitle: "\u6B8B\u9AD8\u30D7\u30ED\u30D0\u30A4\u30C0\u9078\u629E",
|
|
358
|
+
backToMainTitle: "\u30E1\u30A4\u30F3\u306B\u623B\u308B",
|
|
359
|
+
subSelectTitle: "\u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u9078\u629E",
|
|
360
|
+
subSwitchTitle: "\u30B5\u30D6\u5207\u66FF",
|
|
361
|
+
subViewTitle: "\u30B5\u30D6\u30AD\u30E3\u30C3\u30B7\u30E5\u8868\u793A",
|
|
362
|
+
subNoFound: "\u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002Session ID \u3092\u624B\u52D5\u3067\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044"
|
|
363
|
+
};
|
|
364
|
+
var KO_T = {
|
|
365
|
+
title: "\uCE90\uC2DC \uD1B5\uACC4",
|
|
366
|
+
hit: "\uD788\uD2B8\uC728",
|
|
367
|
+
totalHit: "\uCD1D \uD788\uD2B8:",
|
|
368
|
+
read: "\uCE90\uC2DC \uC77D\uAE30:",
|
|
369
|
+
write: "\uCE90\uC2DC \uC4F0\uAE30:",
|
|
370
|
+
miss: "\uBBF8\uD788\uD2B8:",
|
|
371
|
+
out: "\uCD9C\uB825:",
|
|
372
|
+
cost: "\uBE44\uC6A9:",
|
|
373
|
+
saved: "\uB204\uC801 \uC808\uC57D:",
|
|
374
|
+
model: "\uBAA8\uB378:",
|
|
375
|
+
provider: "\uD504\uB85C\uBC14\uC774\uB354:",
|
|
376
|
+
rate: "\uB2E8\uAC00:",
|
|
377
|
+
hitFolded: "\uD788\uD2B8",
|
|
378
|
+
inputRate: "\uC785\uB825",
|
|
379
|
+
cacheRate: "\uCE90\uC2DC",
|
|
380
|
+
writeRate: "\uC4F0\uAE30",
|
|
381
|
+
noData: "\uCE90\uC2DC \uB370\uC774\uD130 \uB300\uAE30 \uC911...",
|
|
382
|
+
tok: "tok",
|
|
383
|
+
distTitle: "Token \uBD84\uD3EC(\uCD94\uC815)",
|
|
384
|
+
distSys: "\uC2DC\uC2A4\uD15C:",
|
|
385
|
+
distUser: "\uC0AC\uC6A9\uC790:",
|
|
386
|
+
distAgent: "\uC11C\uBE0C \uC5D0\uC774\uC804\uD2B8 \uC9C0\uC2DC:",
|
|
387
|
+
distTool: "Tool \uD638\uCD9C:",
|
|
388
|
+
distRes: "Tool \uACB0\uACFC:",
|
|
389
|
+
distReason: "\uCD94\uB860:",
|
|
390
|
+
stepsCount: "\uC774\uBC88 \uD134 {n}\uD68C \uD638\uCD9C:",
|
|
391
|
+
secDetail: "\uC0C1\uC138",
|
|
392
|
+
secModel: "\uBAA8\uB378",
|
|
393
|
+
secSkills: "\uB85C\uB4DC\uB41C \uC2A4\uD0AC",
|
|
394
|
+
balTotal: "\uCD1D \uC794\uC561:",
|
|
395
|
+
balNoKey: "{p} API Key \uBBF8\uC124\uC815",
|
|
396
|
+
balLoading: "\uC870\uD68C \uC911...",
|
|
397
|
+
balError: "\uC870\uD68C \uC2E4\uD328",
|
|
398
|
+
balErr401: "API Key \uBB34\uD6A8",
|
|
399
|
+
balErr403: "\uC794\uC561 \uC870\uD68C\uAC00 \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4",
|
|
400
|
+
balErrEmpty: "\uC794\uC561 \uB370\uC774\uD130 \uC5C6\uC74C",
|
|
401
|
+
balErrTimeout: "\uC2DC\uAC04 \uCD08\uACFC",
|
|
402
|
+
balUnsupported: "\uC774 \uD504\uB85C\uBC14\uC774\uB354\uB294 \uC794\uC561 \uC870\uD68C \uBBF8\uC9C0\uC6D0",
|
|
403
|
+
barHit: "\uD788\uD2B8\uC728",
|
|
404
|
+
barBal: "\uC794\uC561",
|
|
405
|
+
barTok: "Tokens",
|
|
406
|
+
// ── /cache-section 패널 ──
|
|
407
|
+
secToggle: "\uC139\uC158 \uC804\uD658",
|
|
408
|
+
secBalance: "\uC794\uC561",
|
|
409
|
+
secBottom: "\uD558\uB2E8 \uC0C1\uD0DC\uBC14",
|
|
410
|
+
secBorder: "\uD328\uB110 \uD14C\uB450\uB9AC",
|
|
411
|
+
// ── toast ──
|
|
412
|
+
keySaved: "API Key \uC800\uC7A5\uB428, \uC794\uC561 \uC870\uD68C \uC911...",
|
|
413
|
+
keyCleared: "API Key \uC0AD\uC81C\uB428",
|
|
414
|
+
currencySet: "\uD1B5\uD654: {v} ({s}), \uD658\uC728: {r}",
|
|
415
|
+
rateSet: "\uD658\uC728\uC744 {r}(\uC73C)\uB85C \uC124\uC815\uD588\uC2B5\uB2C8\uB2E4",
|
|
416
|
+
panelConfigTitle: "\uD328\uB110 \uC124\uC815",
|
|
417
|
+
panelConfigMsg: "\uD1B5\uD654: {c} | \uD658\uC728: {r} | \uC0C1\uC138: {d} | \uBAA8\uB378: {m} | \uBD84\uD3EC: {t} | \uC2A4\uD0AC: {k} | \uC794\uC561: {b} | \uD558\uB2E8: {f}",
|
|
418
|
+
borderShown: "\uD328\uB110 \uD14C\uB450\uB9AC \uD45C\uC2DC",
|
|
419
|
+
borderHidden: "\uD328\uB110 \uD14C\uB450\uB9AC \uC228\uAE40",
|
|
420
|
+
sectionShown: "{s} \uD45C\uC2DC",
|
|
421
|
+
sectionHidden: "{s} \uC228\uAE40",
|
|
422
|
+
langSwitched: "\uD55C\uAD6D\uC5B4\uB85C \uC804\uD658\uD588\uC2B5\uB2C8\uB2E4",
|
|
423
|
+
autoSwitchOn: "\uC794\uC561 \uD504\uB85C\uBC14\uC774\uB354 \uC790\uB3D9 \uC804\uD658: \uCF1C\uC9D0",
|
|
424
|
+
autoSwitchOff: "\uC794\uC561 \uD504\uB85C\uBC14\uC774\uB354 \uC790\uB3D9 \uC804\uD658: \uAEBC\uC9D0",
|
|
425
|
+
providerManual: "\uC794\uC561 \uD504\uB85C\uBC14\uC774\uB354: {p}(\uC790\uB3D9 \uC804\uD658 \uAEBC\uC9D0)",
|
|
426
|
+
runInSession: "\uC138\uC158 \uB0B4\uC5D0\uC11C \uC2E4\uD589\uD574 \uC8FC\uC138\uC694",
|
|
427
|
+
backToMain: "\uBA54\uC778 \uC138\uC158\uC73C\uB85C \uB3CC\uC544\uAC14\uC2B5\uB2C8\uB2E4",
|
|
428
|
+
subAgentSwitched: "\uC11C\uBE0C \uC5D0\uC774\uC804\uD2B8\uB85C \uC804\uD658: {s}",
|
|
429
|
+
// ── 다이얼로그 / 메뉴 ──
|
|
430
|
+
langTitle: "\uD45C\uC2DC \uC5B8\uC5B4",
|
|
431
|
+
subPrefix: "\uC11C\uBE0C: ",
|
|
432
|
+
keyUser: "(\uC0AC\uC6A9\uC790 key)",
|
|
433
|
+
keyOpenCode: "(OpenCode)",
|
|
434
|
+
keyNotSet: "(\uBBF8\uC124\uC815)",
|
|
435
|
+
balKeyPrompt: "{p} API Key\uB97C \uC785\uB825\uD558\uC5EC \uC794\uC561 \uD45C\uC2DC(\uBE44\uC6B0\uBA74 \uC0AD\uC81C)",
|
|
436
|
+
balProvTitle: "\uC794\uC561 \uD504\uB85C\uBC14\uC774\uB354 / \uC790\uB3D9 \uC804\uD658",
|
|
437
|
+
autoSwitchOpt: "\uC790\uB3D9 \uC804\uD658 \uD504\uB85C\uBC14\uC774\uB354",
|
|
438
|
+
balSelectTitle: "\uC794\uC561 \uD504\uB85C\uBC14\uC774\uB354 \uC120\uD0DD",
|
|
439
|
+
backToMainTitle: "\uBA54\uC778\uC73C\uB85C \uB3CC\uC544\uAC00\uAE30",
|
|
440
|
+
subSelectTitle: "\uC11C\uBE0C \uC5D0\uC774\uC804\uD2B8 \uC120\uD0DD",
|
|
441
|
+
subSwitchTitle: "\uC11C\uBE0C \uC804\uD658",
|
|
442
|
+
subViewTitle: "\uC11C\uBE0C \uCE90\uC2DC \uBCF4\uAE30",
|
|
443
|
+
subNoFound: "\uC11C\uBE0C \uC5D0\uC774\uC804\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. Session ID\uB97C \uC9C1\uC811 \uBD99\uC5EC\uB123\uC73C\uC138\uC694"
|
|
242
444
|
};
|
|
445
|
+
var LANGS = { zh: ZH_T, en: EN_T, ja: JA_T, ko: KO_T };
|
|
446
|
+
var LANG_META = [
|
|
447
|
+
{ code: "zh", label: "\u4E2D\u6587" },
|
|
448
|
+
{ code: "en", label: "English" },
|
|
449
|
+
{ code: "ja", label: "\u65E5\u672C\u8A9E" },
|
|
450
|
+
{ code: "ko", label: "\uD55C\uAD6D\uC5B4" }
|
|
451
|
+
];
|
|
452
|
+
function applyParams(tpl, params) {
|
|
453
|
+
if (!params) return tpl;
|
|
454
|
+
return tpl.replace(
|
|
455
|
+
/\{(\w+)\}/g,
|
|
456
|
+
(m, k) => k in params ? String(params[k]) : m
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
function createT(getCode) {
|
|
460
|
+
return (key, params) => applyParams(LANGS[getCode()][key], params);
|
|
461
|
+
}
|
|
462
|
+
function detectLang() {
|
|
463
|
+
try {
|
|
464
|
+
const loc = Intl.DateTimeFormat().resolvedOptions().locale.toLowerCase();
|
|
465
|
+
if (loc.startsWith("zh")) return "zh";
|
|
466
|
+
if (loc.startsWith("ja")) return "ja";
|
|
467
|
+
if (loc.startsWith("ko")) return "ko";
|
|
468
|
+
return "en";
|
|
469
|
+
} catch {
|
|
470
|
+
return "en";
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// src/index.tsx
|
|
475
|
+
function charColumns(c) {
|
|
476
|
+
const code = c.codePointAt(0) ?? 0;
|
|
477
|
+
if (code < 32) return 0;
|
|
478
|
+
if (code < 127) return 1;
|
|
479
|
+
if (code < 160) return 0;
|
|
480
|
+
if (code >= 4352 && code <= 4447 || // Hangul Jamo
|
|
481
|
+
code >= 11904 && code <= 42191 || // CJK Radicals … Yi
|
|
482
|
+
code >= 44032 && code <= 55203 || // Hangul
|
|
483
|
+
code >= 63744 && code <= 64255 || // CJK Compat
|
|
484
|
+
code >= 65040 && code <= 65135 || // Vertical / Compat
|
|
485
|
+
code >= 65281 && code <= 65376 || // Fullwidth
|
|
486
|
+
code >= 65504 && code <= 65510 || // Fullwidth signs
|
|
487
|
+
code >= 127744 && code <= 128591 || // Misc Symbols (emoji)
|
|
488
|
+
code >= 131072 && code <= 262141)
|
|
489
|
+
return 2;
|
|
490
|
+
return 1;
|
|
491
|
+
}
|
|
492
|
+
function visualWidth(s) {
|
|
493
|
+
let w = 0;
|
|
494
|
+
for (const c of s) w += charColumns(c);
|
|
495
|
+
return w;
|
|
496
|
+
}
|
|
497
|
+
function visualPadEnd(s, cols) {
|
|
498
|
+
const pad = cols - visualWidth(s);
|
|
499
|
+
return pad > 0 ? s + " ".repeat(pad) : s;
|
|
500
|
+
}
|
|
501
|
+
function truncateVisual(s, maxCols) {
|
|
502
|
+
if (visualWidth(s) <= maxCols) return s;
|
|
503
|
+
let result = "", w = 0;
|
|
504
|
+
for (const c of s) {
|
|
505
|
+
const cw = charColumns(c);
|
|
506
|
+
if (w + cw > maxCols - 1) {
|
|
507
|
+
result += "\u2026";
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
result += c;
|
|
511
|
+
w += cw;
|
|
512
|
+
}
|
|
513
|
+
return result;
|
|
514
|
+
}
|
|
515
|
+
var DEBUG_LANG = typeof process !== "undefined" ? process.env?.CACHE_TUI_LANG : void 0;
|
|
516
|
+
var INIT_LANG = DEBUG_LANG !== void 0 && LANG_META.some((m) => m.code === DEBUG_LANG) ? DEBUG_LANG : detectLang();
|
|
243
517
|
function rgb(raw) {
|
|
244
518
|
if (typeof raw === "string" && raw.startsWith("#")) {
|
|
245
519
|
const h = raw.slice(1);
|
|
@@ -374,6 +648,33 @@ function balanceSymbol(currency) {
|
|
|
374
648
|
const sym = CURRENCIES[currency];
|
|
375
649
|
return sym ?? currency + " ";
|
|
376
650
|
}
|
|
651
|
+
function fmtCompact(n) {
|
|
652
|
+
if (n >= 1e6) return (n / 1e6).toFixed(1) + "M";
|
|
653
|
+
if (n >= 1e3) return (n / 1e3).toFixed(1) + "K";
|
|
654
|
+
return String(Math.round(n));
|
|
655
|
+
}
|
|
656
|
+
function formatBalanceAmount(total) {
|
|
657
|
+
const n = parseFloat(total);
|
|
658
|
+
if (!Number.isFinite(n)) return total;
|
|
659
|
+
if (n === 0 || n >= 1) return n.toLocaleString("en-US", {
|
|
660
|
+
minimumFractionDigits: 2,
|
|
661
|
+
maximumFractionDigits: 2
|
|
662
|
+
});
|
|
663
|
+
return n.toLocaleString("en-US", {
|
|
664
|
+
maximumFractionDigits: 6
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
function formatBalanceText(list, pref, rate) {
|
|
668
|
+
const native = pref ? list.find((x) => x.currency === pref) : void 0;
|
|
669
|
+
if (native) return balanceSymbol(native.currency) + formatBalanceAmount(native.total);
|
|
670
|
+
const base = list[0];
|
|
671
|
+
const baseAmt = parseFloat(base.total);
|
|
672
|
+
const converted = Number.isFinite(baseAmt) ? convertBalance(pref || base.currency, rate, baseAmt, base.currency) : baseAmt;
|
|
673
|
+
const shown = pref && base.currency !== pref ? converted.toLocaleString("en-US", {
|
|
674
|
+
maximumFractionDigits: 2
|
|
675
|
+
}) : formatBalanceAmount(base.total);
|
|
676
|
+
return balanceSymbol(pref || base.currency) + shown;
|
|
677
|
+
}
|
|
377
678
|
var CURRENCIES = {
|
|
378
679
|
USD: "$",
|
|
379
680
|
CNY: "\xA5",
|
|
@@ -411,8 +712,7 @@ function TokenCachePanel(props) {
|
|
|
411
712
|
setCurrencySymbol,
|
|
412
713
|
exchangeRate,
|
|
413
714
|
setExchangeRate,
|
|
414
|
-
|
|
415
|
-
setLangZH,
|
|
715
|
+
langCode,
|
|
416
716
|
sectionDetail,
|
|
417
717
|
setSectionDetail,
|
|
418
718
|
sectionModel,
|
|
@@ -428,12 +728,15 @@ function TokenCachePanel(props) {
|
|
|
428
728
|
setBalanceProviderId,
|
|
429
729
|
autoBalance,
|
|
430
730
|
setAutoBalance,
|
|
731
|
+
balanceUnsupported,
|
|
732
|
+
setBalanceUnsupported,
|
|
733
|
+
balanceState,
|
|
431
734
|
balanceCurrency,
|
|
432
735
|
setBalanceCurrency,
|
|
433
736
|
borderVisible,
|
|
434
737
|
setBorderVisible
|
|
435
738
|
} = props.signals;
|
|
436
|
-
const t =
|
|
739
|
+
const t = createT(() => langCode());
|
|
437
740
|
const [lastDist, setLastDist] = createSignal({
|
|
438
741
|
system: 0,
|
|
439
742
|
user: 0,
|
|
@@ -441,9 +744,11 @@ function TokenCachePanel(props) {
|
|
|
441
744
|
toolCall: 0,
|
|
442
745
|
toolResult: 0,
|
|
443
746
|
output: 0,
|
|
747
|
+
reasoning: 0,
|
|
444
748
|
apiOutput: 0,
|
|
445
749
|
apiInput: 0,
|
|
446
|
-
stepCost: 0
|
|
750
|
+
stepCost: 0,
|
|
751
|
+
stepCount: 0
|
|
447
752
|
});
|
|
448
753
|
const [lastHasDist, setLastHasDist] = createSignal(false);
|
|
449
754
|
const [dataSignal, setDataSignal] = createSignal({
|
|
@@ -471,81 +776,18 @@ function TokenCachePanel(props) {
|
|
|
471
776
|
toolCall: 0,
|
|
472
777
|
toolResult: 0,
|
|
473
778
|
output: 0,
|
|
779
|
+
reasoning: 0,
|
|
474
780
|
apiOutput: 0,
|
|
475
781
|
apiInput: 0,
|
|
476
|
-
stepCost: 0
|
|
782
|
+
stepCost: 0,
|
|
783
|
+
stepCount: 0
|
|
477
784
|
},
|
|
478
785
|
hasDistData: false,
|
|
479
786
|
skills: [],
|
|
480
787
|
hasSkills: false
|
|
481
788
|
});
|
|
482
789
|
const [refreshTick, setRefreshTick] = createSignal(0);
|
|
483
|
-
const [balanceState, setBalanceState] = createSignal({
|
|
484
|
-
status: "idle",
|
|
485
|
-
data: null,
|
|
486
|
-
lastFetch: 0
|
|
487
|
-
});
|
|
488
|
-
let balanceSeq = 0;
|
|
489
790
|
const providerName = createMemo(() => getBalanceProvider(balanceProviderId()).name);
|
|
490
|
-
const pollBalance = async () => {
|
|
491
|
-
const provider = getBalanceProvider(balanceProviderId());
|
|
492
|
-
const key = props.api.kv.get(`${KV_PREFIX}.balance.${provider.id}.key`, "") || findOpencodeKey(props.api, provider);
|
|
493
|
-
if (!key) {
|
|
494
|
-
setBalanceState({
|
|
495
|
-
status: "idle",
|
|
496
|
-
data: null,
|
|
497
|
-
lastFetch: 0,
|
|
498
|
-
error: void 0,
|
|
499
|
-
key: void 0
|
|
500
|
-
});
|
|
501
|
-
return;
|
|
502
|
-
}
|
|
503
|
-
const now = Date.now();
|
|
504
|
-
const prev = balanceState();
|
|
505
|
-
if (prev.status === "ok" && prev.key === key && now - prev.lastFetch < BALANCE_POLL_MS) return;
|
|
506
|
-
const seq = ++balanceSeq;
|
|
507
|
-
setBalanceState({
|
|
508
|
-
...prev,
|
|
509
|
-
status: "loading",
|
|
510
|
-
error: void 0,
|
|
511
|
-
key
|
|
512
|
-
});
|
|
513
|
-
const controller = new AbortController();
|
|
514
|
-
let timedOut = false;
|
|
515
|
-
const timer = setTimeout(() => {
|
|
516
|
-
timedOut = true;
|
|
517
|
-
controller.abort();
|
|
518
|
-
}, 1e4);
|
|
519
|
-
try {
|
|
520
|
-
const data2 = await provider.fetchBalance(key, controller.signal);
|
|
521
|
-
clearTimeout(timer);
|
|
522
|
-
if (seq !== balanceSeq) return;
|
|
523
|
-
setBalanceState({
|
|
524
|
-
status: "ok",
|
|
525
|
-
data: data2,
|
|
526
|
-
lastFetch: Date.now(),
|
|
527
|
-
error: void 0,
|
|
528
|
-
key
|
|
529
|
-
});
|
|
530
|
-
} catch (err) {
|
|
531
|
-
clearTimeout(timer);
|
|
532
|
-
if (seq !== balanceSeq) return;
|
|
533
|
-
const code = timedOut ? "TIMEOUT" : err instanceof Error ? err.message : "";
|
|
534
|
-
setBalanceState({
|
|
535
|
-
status: "error",
|
|
536
|
-
data: null,
|
|
537
|
-
lastFetch: 0,
|
|
538
|
-
error: code,
|
|
539
|
-
key
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
createEffect(() => {
|
|
544
|
-
void balanceRefresh();
|
|
545
|
-
untrack(() => {
|
|
546
|
-
void pollBalance();
|
|
547
|
-
});
|
|
548
|
-
});
|
|
549
791
|
createEffect(() => {
|
|
550
792
|
if (!autoBalance()) return;
|
|
551
793
|
const sid = props.signals.overrideSessionId() ?? props.sessionId;
|
|
@@ -567,9 +809,14 @@ function TokenCachePanel(props) {
|
|
|
567
809
|
}
|
|
568
810
|
if (!pid) return;
|
|
569
811
|
const hit = matchBalanceProvider(pid);
|
|
570
|
-
if (hit
|
|
571
|
-
|
|
572
|
-
|
|
812
|
+
if (hit) {
|
|
813
|
+
setBalanceUnsupported(false);
|
|
814
|
+
if (hit.id !== balanceProviderId()) {
|
|
815
|
+
setBalanceProviderId(hit.id);
|
|
816
|
+
props.signals.setBalanceRefresh(props.signals.balanceRefresh() + 1);
|
|
817
|
+
}
|
|
818
|
+
} else {
|
|
819
|
+
setBalanceUnsupported(true);
|
|
573
820
|
}
|
|
574
821
|
});
|
|
575
822
|
let lastMainSid = props.sessionId;
|
|
@@ -602,18 +849,18 @@ function TokenCachePanel(props) {
|
|
|
602
849
|
let prevMsgHitRate = -1, lastMsgHitRate = -1;
|
|
603
850
|
for (const msg of msgs) {
|
|
604
851
|
if (msg.role !== "assistant") continue;
|
|
605
|
-
const
|
|
606
|
-
if (!
|
|
607
|
-
const mit = num(
|
|
852
|
+
const tok = msg.tokens;
|
|
853
|
+
if (!tok) continue;
|
|
854
|
+
const mit = num(tok.input) + num(tok.cache?.read) + num(tok.cache?.write), mrt = num(tok.cache?.read);
|
|
608
855
|
if (mit > 0) {
|
|
609
856
|
prevMsgHitRate = lastMsgHitRate;
|
|
610
857
|
lastMsgHitRate = mrt / mit * 100;
|
|
611
858
|
}
|
|
612
859
|
if (fallbackTokens) {
|
|
613
|
-
input += num(
|
|
614
|
-
read += num(
|
|
615
|
-
write += num(
|
|
616
|
-
output += num(
|
|
860
|
+
input += num(tok.input);
|
|
861
|
+
read += num(tok.cache?.read);
|
|
862
|
+
write += num(tok.cache?.write);
|
|
863
|
+
output += num(tok.output);
|
|
617
864
|
}
|
|
618
865
|
if (fallbackCost) {
|
|
619
866
|
cost += num(msg.cost);
|
|
@@ -635,7 +882,7 @@ function TokenCachePanel(props) {
|
|
|
635
882
|
break;
|
|
636
883
|
}
|
|
637
884
|
const hitRate = lastMsgHitRate >= 0 ? lastMsgHitRate : 0;
|
|
638
|
-
const freshTotal = input + read, sessionHitRate = freshTotal > 0 ? read / freshTotal * 100 : 0;
|
|
885
|
+
const freshTotal = input + read + write, sessionHitRate = freshTotal > 0 ? read / freshTotal * 100 : 0;
|
|
639
886
|
const model = mid.split("/").pop() ?? mid, hasPricing = inputRate > 0 || cacheReadRate > 0 || cacheWriteRate > 0;
|
|
640
887
|
const hasTrendData = prevMsgHitRate >= 0 && lastMsgHitRate >= 0;
|
|
641
888
|
const trend = hasTrendData ? lastMsgHitRate - prevMsgHitRate : 0, providerName2 = pid || "";
|
|
@@ -647,9 +894,11 @@ function TokenCachePanel(props) {
|
|
|
647
894
|
toolCall: 0,
|
|
648
895
|
toolResult: 0,
|
|
649
896
|
output: 0,
|
|
897
|
+
reasoning: 0,
|
|
650
898
|
apiOutput: 0,
|
|
651
899
|
apiInput: 0,
|
|
652
|
-
stepCost: 0
|
|
900
|
+
stepCost: 0,
|
|
901
|
+
stepCount: 0
|
|
653
902
|
};
|
|
654
903
|
let hasDistData = false;
|
|
655
904
|
const loadedSkills = /* @__PURE__ */ new Map();
|
|
@@ -680,6 +929,7 @@ function TokenCachePanel(props) {
|
|
|
680
929
|
} else if (msg.role === "assistant") {
|
|
681
930
|
const am = msg;
|
|
682
931
|
dist.output += num(am.tokens?.output);
|
|
932
|
+
dist.reasoning += num(am.tokens?.reasoning);
|
|
683
933
|
let parts = [];
|
|
684
934
|
try {
|
|
685
935
|
parts = props.api.state.part(msg.id);
|
|
@@ -694,6 +944,12 @@ function TokenCachePanel(props) {
|
|
|
694
944
|
} catch {
|
|
695
945
|
}
|
|
696
946
|
if (rawInput) dist.toolCall += estimateTokens(rawInput);
|
|
947
|
+
if (tp.tool === "task" && tp.state?.input) {
|
|
948
|
+
const ti = tp.state.input;
|
|
949
|
+
const prompt = typeof ti.prompt === "string" ? ti.prompt : "";
|
|
950
|
+
const desc = typeof ti.description === "string" ? ti.description : "";
|
|
951
|
+
dist.agent += estimateTokens(prompt || desc);
|
|
952
|
+
}
|
|
697
953
|
if (tp.state.status === "completed") {
|
|
698
954
|
const c = tp.state;
|
|
699
955
|
if (c.output) dist.toolResult += estimateTokens(c.output);
|
|
@@ -718,8 +974,7 @@ function TokenCachePanel(props) {
|
|
|
718
974
|
}
|
|
719
975
|
}
|
|
720
976
|
}
|
|
721
|
-
} else if (p.type === "
|
|
722
|
-
else if (p.type === "subtask") {
|
|
977
|
+
} else if (p.type === "subtask") {
|
|
723
978
|
const sub = p;
|
|
724
979
|
dist.agent += estimateTokens(sub.prompt || sub.description || "");
|
|
725
980
|
}
|
|
@@ -728,15 +983,36 @@ function TokenCachePanel(props) {
|
|
|
728
983
|
}
|
|
729
984
|
for (let i = msgs.length - 1; i >= 0; i--) {
|
|
730
985
|
if (msgs[i].role !== "assistant") continue;
|
|
731
|
-
const
|
|
732
|
-
if (
|
|
986
|
+
const tok = msgs[i].tokens;
|
|
987
|
+
if (tok && ((tok.input ?? 0) > 0 || (tok.cache?.read ?? 0) > 0 || (tok.cache?.write ?? 0) > 0)) {
|
|
733
988
|
lastAssMsg = msgs[i];
|
|
734
989
|
break;
|
|
735
990
|
}
|
|
736
991
|
}
|
|
737
|
-
dist.apiInput = num(lastAssMsg?.tokens?.input) + num(lastAssMsg?.tokens?.cache?.read);
|
|
992
|
+
dist.apiInput = num(lastAssMsg?.tokens?.input) + num(lastAssMsg?.tokens?.cache?.read) + num(lastAssMsg?.tokens?.cache?.write);
|
|
738
993
|
dist.apiOutput = num(lastAssMsg?.tokens?.output);
|
|
739
|
-
|
|
994
|
+
if (lastAssMsg) {
|
|
995
|
+
const roundParent = lastAssMsg.parentID;
|
|
996
|
+
let lastCost;
|
|
997
|
+
for (let i = msgs.length - 1; i >= 0; i--) {
|
|
998
|
+
const m = msgs[i];
|
|
999
|
+
if (m.role !== "assistant") continue;
|
|
1000
|
+
if (m.parentID !== roundParent) break;
|
|
1001
|
+
let parts = [];
|
|
1002
|
+
try {
|
|
1003
|
+
parts = props.api.state.part(m.id);
|
|
1004
|
+
} catch {
|
|
1005
|
+
}
|
|
1006
|
+
for (const p of parts) {
|
|
1007
|
+
if (p.type !== "step-finish") continue;
|
|
1008
|
+
dist.stepCount++;
|
|
1009
|
+
const sc = p.cost;
|
|
1010
|
+
if (lastCost === void 0 && typeof sc === "number" && Number.isFinite(sc)) lastCost = sc;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
if (lastCost !== void 0) dist.stepCost = lastCost;
|
|
1014
|
+
}
|
|
1015
|
+
hasDistData = dist.system + dist.user + dist.agent + dist.toolCall + dist.toolResult > 0 || dist.apiOutput > 0 || dist.apiInput > 0 || dist.reasoning > 0;
|
|
740
1016
|
} catch {
|
|
741
1017
|
}
|
|
742
1018
|
const finalDist = hasDistData ? dist : lastDist(), finalHasDist = hasDistData || lastHasDist();
|
|
@@ -818,6 +1094,7 @@ function TokenCachePanel(props) {
|
|
|
818
1094
|
const savedProvider = props.api.kv.get(`${KV_PREFIX}.balance.provider`);
|
|
819
1095
|
if (typeof savedProvider === "string" && balanceProviders.some((p) => p.id === savedProvider)) {
|
|
820
1096
|
setBalanceProviderId(savedProvider);
|
|
1097
|
+
setBalanceUnsupported(false);
|
|
821
1098
|
}
|
|
822
1099
|
const savedAuto = props.api.kv.get(`${KV_PREFIX}.balance.auto`);
|
|
823
1100
|
if (typeof savedAuto === "boolean") setAutoBalance(savedAuto);
|
|
@@ -835,10 +1112,6 @@ function TokenCachePanel(props) {
|
|
|
835
1112
|
setSectionBalance(Boolean(props.api.kv.get(`${KV_PREFIX}.section.balance`, true)));
|
|
836
1113
|
const bv = props.api.kv.get(`${KV_PREFIX}.border`, true);
|
|
837
1114
|
setBorderVisible(bv !== false);
|
|
838
|
-
const savedLang = props.api.kv.get(`${KV_PREFIX}.lang`);
|
|
839
|
-
if (savedLang === "zh" || savedLang === "en") {
|
|
840
|
-
setLangZH(savedLang === "zh");
|
|
841
|
-
}
|
|
842
1115
|
const cachedDist = props.api.kv.get(`${KV_PREFIX}.dist_snapshot`);
|
|
843
1116
|
if (cachedDist) {
|
|
844
1117
|
setLastDist(cachedDist);
|
|
@@ -885,10 +1158,8 @@ function TokenCachePanel(props) {
|
|
|
885
1158
|
setRefreshTick((v) => v + 1);
|
|
886
1159
|
});
|
|
887
1160
|
setRefreshTick((v) => v + 1);
|
|
888
|
-
const balanceTimer = setInterval(pollBalance, BALANCE_POLL_MS);
|
|
889
1161
|
onCleanup(() => {
|
|
890
1162
|
clearTimeout(partTimer);
|
|
891
|
-
clearInterval(balanceTimer);
|
|
892
1163
|
unsubPart();
|
|
893
1164
|
unsubMsg();
|
|
894
1165
|
unsubSession();
|
|
@@ -916,11 +1187,12 @@ function TokenCachePanel(props) {
|
|
|
916
1187
|
const gutter = createMemo(() => borderVisible() ? 6 : 0);
|
|
917
1188
|
const sep = createMemo(() => "\u2500".repeat(Math.max(1, panelWidth() - gutter())));
|
|
918
1189
|
function trendLabel(t2) {
|
|
919
|
-
|
|
1190
|
+
if (Math.abs(t2) < 0.05) return "-";
|
|
1191
|
+
return (t2 > 0 ? "\u2191" : "\u2193") + Math.abs(t2).toFixed(1) + "%";
|
|
920
1192
|
}
|
|
921
1193
|
const barW = createMemo(() => {
|
|
922
1194
|
const trendSpace = data().hasTrendData ? LABEL_GAP + visualWidth(trendLabel(data().trend)) : 0;
|
|
923
|
-
const overhead = visualWidth(t(
|
|
1195
|
+
const overhead = visualWidth(t("hit")) + LABEL_GAP + BAR_BRACKETS + BAR_GAP + PCT_FIXED_WIDTH + trendSpace + gutter();
|
|
924
1196
|
return Math.max(3, panelWidth() - overhead);
|
|
925
1197
|
});
|
|
926
1198
|
const bar = createMemo(() => progressBar(data().hitRate, barW()));
|
|
@@ -974,7 +1246,7 @@ function TokenCachePanel(props) {
|
|
|
974
1246
|
}));
|
|
975
1247
|
_$insert(_el$3, () => open() ? "\u25BC " : "\u25B6 ");
|
|
976
1248
|
_$insertNode(_el$4, _el$5);
|
|
977
|
-
_$insert(_el$5, () => t(
|
|
1249
|
+
_$insert(_el$5, () => t("title"));
|
|
978
1250
|
_$insert(_el$4, _$createComponent(Show, {
|
|
979
1251
|
get when() {
|
|
980
1252
|
return open();
|
|
@@ -1001,13 +1273,13 @@ function TokenCachePanel(props) {
|
|
|
1001
1273
|
get children() {
|
|
1002
1274
|
return [(() => {
|
|
1003
1275
|
var _el$8 = _$createElement("span");
|
|
1004
|
-
_$insert(_el$8, () => " ".repeat(Math.max(1, panelWidth() - gutter() - HEADER_PREFIX - visualWidth(t(
|
|
1276
|
+
_$insert(_el$8, () => " ".repeat(Math.max(1, panelWidth() - gutter() - HEADER_PREFIX - visualWidth(t("title")) - visualWidth(pct() + " " + t("hitFolded") + " " + trendLabel(data().trend)))));
|
|
1005
1277
|
return _el$8;
|
|
1006
1278
|
})(), (() => {
|
|
1007
1279
|
var _el$9 = _$createElement("span"), _el$0 = _$createTextNode(` `);
|
|
1008
1280
|
_$insertNode(_el$9, _el$0);
|
|
1009
1281
|
_$insert(_el$9, pct, _el$0);
|
|
1010
|
-
_$insert(_el$9, () => t()
|
|
1282
|
+
_$insert(_el$9, () => t("hitFolded"), null);
|
|
1011
1283
|
_$effect((_$p) => _$setProp(_el$9, "style", {
|
|
1012
1284
|
fg: hitColor()
|
|
1013
1285
|
}, _$p));
|
|
@@ -1017,7 +1289,7 @@ function TokenCachePanel(props) {
|
|
|
1017
1289
|
_$insertNode(_el$1, _el$10);
|
|
1018
1290
|
_$insert(_el$1, () => trendLabel(data().trend), null);
|
|
1019
1291
|
_$effect((_$p) => _$setProp(_el$1, "style", {
|
|
1020
|
-
fg: data().trend
|
|
1292
|
+
fg: Math.abs(data().trend) >= 0.05 ? data().trend > 0 ? pal().success : pal().error : pal().text
|
|
1021
1293
|
}, _$p));
|
|
1022
1294
|
return _el$1;
|
|
1023
1295
|
})()];
|
|
@@ -1029,13 +1301,13 @@ function TokenCachePanel(props) {
|
|
|
1029
1301
|
get children() {
|
|
1030
1302
|
return [(() => {
|
|
1031
1303
|
var _el$11 = _$createElement("span");
|
|
1032
|
-
_$insert(_el$11, () => " ".repeat(Math.max(1, panelWidth() - gutter() - HEADER_PREFIX - visualWidth(t(
|
|
1304
|
+
_$insert(_el$11, () => " ".repeat(Math.max(1, panelWidth() - gutter() - HEADER_PREFIX - visualWidth(t("title")) - visualWidth(pct() + " " + t("hitFolded")))));
|
|
1033
1305
|
return _el$11;
|
|
1034
1306
|
})(), (() => {
|
|
1035
1307
|
var _el$12 = _$createElement("span"), _el$13 = _$createTextNode(` `);
|
|
1036
1308
|
_$insertNode(_el$12, _el$13);
|
|
1037
1309
|
_$insert(_el$12, pct, _el$13);
|
|
1038
|
-
_$insert(_el$12, () => t()
|
|
1310
|
+
_$insert(_el$12, () => t("hitFolded"), null);
|
|
1039
1311
|
_$effect((_$p) => _$setProp(_el$12, "style", {
|
|
1040
1312
|
fg: hitColor()
|
|
1041
1313
|
}, _$p));
|
|
@@ -1056,28 +1328,28 @@ function TokenCachePanel(props) {
|
|
|
1056
1328
|
},
|
|
1057
1329
|
get children() {
|
|
1058
1330
|
return (() => {
|
|
1059
|
-
const prefix = " \u21B3 " + (
|
|
1331
|
+
const prefix = " \u21B3 " + t("subPrefix");
|
|
1060
1332
|
const maxSidW = Math.max(6, panelWidth() - visualWidth(prefix));
|
|
1061
1333
|
return (() => {
|
|
1062
|
-
var _el$
|
|
1063
|
-
_$insertNode(_el$
|
|
1064
|
-
_$insertNode(_el$
|
|
1065
|
-
_$insert(_el$
|
|
1066
|
-
_$insert(_el$
|
|
1334
|
+
var _el$70 = _$createElement("text"), _el$71 = _$createElement("span"), _el$72 = _$createElement("span");
|
|
1335
|
+
_$insertNode(_el$70, _el$71);
|
|
1336
|
+
_$insertNode(_el$70, _el$72);
|
|
1337
|
+
_$insert(_el$71, prefix);
|
|
1338
|
+
_$insert(_el$72, () => truncateVisual(props.signals.overrideSessionId(), maxSidW));
|
|
1067
1339
|
_$effect((_p$) => {
|
|
1068
|
-
var _v$
|
|
1340
|
+
var _v$17 = {
|
|
1069
1341
|
fg: pal().muted
|
|
1070
|
-
}, _v$
|
|
1342
|
+
}, _v$18 = {
|
|
1071
1343
|
fg: pal().text
|
|
1072
1344
|
};
|
|
1073
|
-
_v$
|
|
1074
|
-
_v$
|
|
1345
|
+
_v$17 !== _p$.e && (_p$.e = _$setProp(_el$71, "style", _v$17, _p$.e));
|
|
1346
|
+
_v$18 !== _p$.t && (_p$.t = _$setProp(_el$72, "style", _v$18, _p$.t));
|
|
1075
1347
|
return _p$;
|
|
1076
1348
|
}, {
|
|
1077
1349
|
e: void 0,
|
|
1078
1350
|
t: void 0
|
|
1079
1351
|
});
|
|
1080
|
-
return _el$
|
|
1352
|
+
return _el$70;
|
|
1081
1353
|
})();
|
|
1082
1354
|
})();
|
|
1083
1355
|
}
|
|
@@ -1087,30 +1359,30 @@ function TokenCachePanel(props) {
|
|
|
1087
1359
|
},
|
|
1088
1360
|
get fallback() {
|
|
1089
1361
|
return [(() => {
|
|
1090
|
-
var _el$
|
|
1091
|
-
_$insert(_el$
|
|
1092
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1093
|
-
return _el$
|
|
1362
|
+
var _el$73 = _$createElement("text");
|
|
1363
|
+
_$insert(_el$73, sep);
|
|
1364
|
+
_$effect((_$p) => _$setProp(_el$73, "fg", pal().muted, _$p));
|
|
1365
|
+
return _el$73;
|
|
1094
1366
|
})(), (() => {
|
|
1095
|
-
var _el$
|
|
1096
|
-
_$insertNode(_el$
|
|
1097
|
-
_$insertNode(_el$
|
|
1098
|
-
_$insertNode(_el$
|
|
1099
|
-
_$insert(_el$
|
|
1367
|
+
var _el$74 = _$createElement("text"), _el$75 = _$createElement("span"), _el$77 = _$createElement("span");
|
|
1368
|
+
_$insertNode(_el$74, _el$75);
|
|
1369
|
+
_$insertNode(_el$74, _el$77);
|
|
1370
|
+
_$insertNode(_el$75, _$createTextNode(`> `));
|
|
1371
|
+
_$insert(_el$77, () => t("noData"));
|
|
1100
1372
|
_$effect((_p$) => {
|
|
1101
|
-
var _v$
|
|
1373
|
+
var _v$19 = {
|
|
1102
1374
|
fg: pal().muted
|
|
1103
|
-
}, _v$
|
|
1375
|
+
}, _v$20 = {
|
|
1104
1376
|
fg: pal().muted
|
|
1105
1377
|
};
|
|
1106
|
-
_v$
|
|
1107
|
-
_v$
|
|
1378
|
+
_v$19 !== _p$.e && (_p$.e = _$setProp(_el$75, "style", _v$19, _p$.e));
|
|
1379
|
+
_v$20 !== _p$.t && (_p$.t = _$setProp(_el$77, "style", _v$20, _p$.t));
|
|
1108
1380
|
return _p$;
|
|
1109
1381
|
}, {
|
|
1110
1382
|
e: void 0,
|
|
1111
1383
|
t: void 0
|
|
1112
1384
|
});
|
|
1113
|
-
return _el$
|
|
1385
|
+
return _el$74;
|
|
1114
1386
|
})()];
|
|
1115
1387
|
},
|
|
1116
1388
|
get children() {
|
|
@@ -1125,7 +1397,7 @@ function TokenCachePanel(props) {
|
|
|
1125
1397
|
_$insertNode(_el$15, _el$18);
|
|
1126
1398
|
_$insertNode(_el$15, _el$21);
|
|
1127
1399
|
_$insertNode(_el$16, _el$17);
|
|
1128
|
-
_$insert(_el$16, () => t()
|
|
1400
|
+
_$insert(_el$16, () => t("hit"), _el$17);
|
|
1129
1401
|
_$insertNode(_el$18, _el$19);
|
|
1130
1402
|
_$insertNode(_el$18, _el$20);
|
|
1131
1403
|
_$insert(_el$18, bar, _el$20);
|
|
@@ -1139,7 +1411,7 @@ function TokenCachePanel(props) {
|
|
|
1139
1411
|
_$insertNode(_el$22, _el$23);
|
|
1140
1412
|
_$insert(_el$22, () => trendLabel(data().trend), null);
|
|
1141
1413
|
_$effect((_$p) => _$setProp(_el$22, "style", {
|
|
1142
|
-
fg: data().trend
|
|
1414
|
+
fg: Math.abs(data().trend) >= 0.05 ? data().trend > 0 ? pal().success : pal().error : pal().text
|
|
1143
1415
|
}, _$p));
|
|
1144
1416
|
return _el$22;
|
|
1145
1417
|
}
|
|
@@ -1164,7 +1436,7 @@ function TokenCachePanel(props) {
|
|
|
1164
1436
|
return _el$15;
|
|
1165
1437
|
})(), (() => {
|
|
1166
1438
|
var _el$24 = _$createElement("text");
|
|
1167
|
-
_$insert(_el$24, () => justify(t()
|
|
1439
|
+
_$insert(_el$24, () => justify(t("totalHit"), (Math.floor(data().sessionHitRate * 10) / 10).toFixed(1) + "%"));
|
|
1168
1440
|
_$effect((_$p) => _$setProp(_el$24, "fg", pal().muted, _$p));
|
|
1169
1441
|
return _el$24;
|
|
1170
1442
|
})(), _$createComponent(Show, {
|
|
@@ -1184,8 +1456,8 @@ function TokenCachePanel(props) {
|
|
|
1184
1456
|
}));
|
|
1185
1457
|
_$insert(_el$26, () => detailOpen() ? "\u25BC " : "\u25B6 ");
|
|
1186
1458
|
_$insertNode(_el$27, _el$28);
|
|
1187
|
-
_$insert(_el$28, () => t(
|
|
1188
|
-
_$insert(_el$29, () => sep().slice(visualWidth((detailOpen() ? "\u25BC " : "\u25B6 ") + t(
|
|
1459
|
+
_$insert(_el$28, () => t("secDetail"));
|
|
1460
|
+
_$insert(_el$29, () => sep().slice(visualWidth((detailOpen() ? "\u25BC " : "\u25B6 ") + t("secDetail"))));
|
|
1189
1461
|
_$effect((_p$) => {
|
|
1190
1462
|
var _v$4 = {
|
|
1191
1463
|
fg: pal().muted
|
|
@@ -1215,7 +1487,7 @@ function TokenCachePanel(props) {
|
|
|
1215
1487
|
},
|
|
1216
1488
|
get children() {
|
|
1217
1489
|
var _el$30 = _$createElement("text");
|
|
1218
|
-
_$insert(_el$30, () => justify(t()
|
|
1490
|
+
_$insert(_el$30, () => justify(t("read"), fmt(data().read), t("tok")));
|
|
1219
1491
|
_$effect((_$p) => _$setProp(_el$30, "fg", pal().muted, _$p));
|
|
1220
1492
|
return _el$30;
|
|
1221
1493
|
}
|
|
@@ -1225,47 +1497,59 @@ function TokenCachePanel(props) {
|
|
|
1225
1497
|
},
|
|
1226
1498
|
get children() {
|
|
1227
1499
|
var _el$31 = _$createElement("text");
|
|
1228
|
-
_$insert(_el$31, () => justify(t()
|
|
1500
|
+
_$insert(_el$31, () => justify(t("write"), fmt(data().write), t("tok")));
|
|
1229
1501
|
_$effect((_$p) => _$setProp(_el$31, "fg", pal().muted, _$p));
|
|
1230
1502
|
return _el$31;
|
|
1231
1503
|
}
|
|
1232
1504
|
}), (() => {
|
|
1233
1505
|
var _el$32 = _$createElement("text");
|
|
1234
|
-
_$insert(_el$32, () => justify(t()
|
|
1506
|
+
_$insert(_el$32, () => justify(t("miss"), fmt(data().freshInput + data().write), t("tok")));
|
|
1235
1507
|
_$effect((_$p) => _$setProp(_el$32, "fg", pal().muted, _$p));
|
|
1236
1508
|
return _el$32;
|
|
1237
1509
|
})(), (() => {
|
|
1238
1510
|
var _el$33 = _$createElement("text");
|
|
1239
|
-
_$insert(_el$33, () => justify(t()
|
|
1511
|
+
_$insert(_el$33, () => justify(t("out"), fmt(data().output), t("tok")));
|
|
1240
1512
|
_$effect((_$p) => _$setProp(_el$33, "fg", pal().muted, _$p));
|
|
1241
1513
|
return _el$33;
|
|
1242
1514
|
})(), _$createComponent(Show, {
|
|
1515
|
+
get when() {
|
|
1516
|
+
return data().dist.stepCount >= 2;
|
|
1517
|
+
},
|
|
1518
|
+
get children() {
|
|
1519
|
+
var _el$34 = _$createElement("text");
|
|
1520
|
+
_$insert(_el$34, () => justify(t("stepsCount", {
|
|
1521
|
+
n: data().dist.stepCount
|
|
1522
|
+
}), fmtCost(data().dist.stepCost, currencySymbol(), exchangeRate())));
|
|
1523
|
+
_$effect((_$p) => _$setProp(_el$34, "fg", pal().muted, _$p));
|
|
1524
|
+
return _el$34;
|
|
1525
|
+
}
|
|
1526
|
+
}), _$createComponent(Show, {
|
|
1243
1527
|
get when() {
|
|
1244
1528
|
return data().saved > 0;
|
|
1245
1529
|
},
|
|
1246
1530
|
get children() {
|
|
1247
|
-
var _el$
|
|
1248
|
-
_$insertNode(_el$
|
|
1249
|
-
_$insertNode(_el$
|
|
1250
|
-
_$insertNode(_el$
|
|
1251
|
-
_$insert(_el$
|
|
1252
|
-
_$insert(_el$
|
|
1253
|
-
_$insertNode(_el$
|
|
1254
|
-
_$insert(_el$
|
|
1531
|
+
var _el$35 = _$createElement("text"), _el$36 = _$createElement("span"), _el$37 = _$createElement("span"), _el$38 = _$createElement("span"), _el$39 = _$createTextNode(`~`);
|
|
1532
|
+
_$insertNode(_el$35, _el$36);
|
|
1533
|
+
_$insertNode(_el$35, _el$37);
|
|
1534
|
+
_$insertNode(_el$35, _el$38);
|
|
1535
|
+
_$insert(_el$36, () => t("saved"));
|
|
1536
|
+
_$insert(_el$37, () => " ".repeat(Math.max(1, panelWidth() - gutter() - visualWidth(t("saved")) - visualWidth("~" + fmtCost(data().saved, currencySymbol(), exchangeRate())))));
|
|
1537
|
+
_$insertNode(_el$38, _el$39);
|
|
1538
|
+
_$insert(_el$38, () => fmtCost(data().saved, currencySymbol(), exchangeRate()), null);
|
|
1255
1539
|
_$effect((_p$) => {
|
|
1256
1540
|
var _v$7 = {
|
|
1257
1541
|
fg: pal().muted
|
|
1258
1542
|
}, _v$8 = {
|
|
1259
1543
|
fg: pal().success
|
|
1260
1544
|
};
|
|
1261
|
-
_v$7 !== _p$.e && (_p$.e = _$setProp(_el$
|
|
1262
|
-
_v$8 !== _p$.t && (_p$.t = _$setProp(_el$
|
|
1545
|
+
_v$7 !== _p$.e && (_p$.e = _$setProp(_el$36, "style", _v$7, _p$.e));
|
|
1546
|
+
_v$8 !== _p$.t && (_p$.t = _$setProp(_el$38, "style", _v$8, _p$.t));
|
|
1263
1547
|
return _p$;
|
|
1264
1548
|
}, {
|
|
1265
1549
|
e: void 0,
|
|
1266
1550
|
t: void 0
|
|
1267
1551
|
});
|
|
1268
|
-
return _el$
|
|
1552
|
+
return _el$35;
|
|
1269
1553
|
}
|
|
1270
1554
|
})];
|
|
1271
1555
|
}
|
|
@@ -1277,91 +1561,91 @@ function TokenCachePanel(props) {
|
|
|
1277
1561
|
},
|
|
1278
1562
|
get children() {
|
|
1279
1563
|
return [_$memo(() => (() => {
|
|
1280
|
-
var _el$
|
|
1281
|
-
_$insertNode(_el$
|
|
1282
|
-
_$insertNode(_el$
|
|
1283
|
-
_$insertNode(_el$
|
|
1284
|
-
_$setProp(_el$
|
|
1564
|
+
var _el$78 = _$createElement("text"), _el$79 = _$createElement("span"), _el$80 = _$createElement("span"), _el$81 = _$createElement("b"), _el$82 = _$createElement("span");
|
|
1565
|
+
_$insertNode(_el$78, _el$79);
|
|
1566
|
+
_$insertNode(_el$78, _el$80);
|
|
1567
|
+
_$insertNode(_el$78, _el$82);
|
|
1568
|
+
_$setProp(_el$78, "onMouseUp", () => setModelOpen((o) => {
|
|
1285
1569
|
const n = !o;
|
|
1286
1570
|
persistFold("model", n);
|
|
1287
1571
|
return n;
|
|
1288
1572
|
}));
|
|
1289
|
-
_$insert(_el$
|
|
1290
|
-
_$insertNode(_el$
|
|
1291
|
-
_$insert(_el$
|
|
1292
|
-
_$insert(_el$
|
|
1573
|
+
_$insert(_el$79, () => modelOpen() ? "\u25BC " : "\u25B6 ");
|
|
1574
|
+
_$insertNode(_el$80, _el$81);
|
|
1575
|
+
_$insert(_el$81, () => t("secModel"));
|
|
1576
|
+
_$insert(_el$82, () => sep().slice(visualWidth((modelOpen() ? "\u25BC " : "\u25B6 ") + t("secModel"))));
|
|
1293
1577
|
_$effect((_p$) => {
|
|
1294
|
-
var _v$
|
|
1578
|
+
var _v$21 = {
|
|
1295
1579
|
fg: pal().muted
|
|
1296
|
-
}, _v$
|
|
1580
|
+
}, _v$22 = {
|
|
1297
1581
|
fg: pal().primary
|
|
1298
|
-
}, _v$
|
|
1582
|
+
}, _v$23 = {
|
|
1299
1583
|
fg: pal().muted
|
|
1300
1584
|
};
|
|
1301
|
-
_v$
|
|
1302
|
-
_v$
|
|
1303
|
-
_v$
|
|
1585
|
+
_v$21 !== _p$.e && (_p$.e = _$setProp(_el$79, "style", _v$21, _p$.e));
|
|
1586
|
+
_v$22 !== _p$.t && (_p$.t = _$setProp(_el$80, "style", _v$22, _p$.t));
|
|
1587
|
+
_v$23 !== _p$.a && (_p$.a = _$setProp(_el$82, "style", _v$23, _p$.a));
|
|
1304
1588
|
return _p$;
|
|
1305
1589
|
}, {
|
|
1306
1590
|
e: void 0,
|
|
1307
1591
|
t: void 0,
|
|
1308
1592
|
a: void 0
|
|
1309
1593
|
});
|
|
1310
|
-
return _el$
|
|
1594
|
+
return _el$78;
|
|
1311
1595
|
})()), _$createComponent(Show, {
|
|
1312
1596
|
get when() {
|
|
1313
1597
|
return modelOpen();
|
|
1314
1598
|
},
|
|
1315
1599
|
get children() {
|
|
1316
1600
|
return [(() => {
|
|
1317
|
-
var _el$
|
|
1318
|
-
_$insert(_el$
|
|
1319
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1320
|
-
return _el$
|
|
1601
|
+
var _el$40 = _$createElement("text");
|
|
1602
|
+
_$insert(_el$40, () => justify(t("cost"), fmtCost(data().cost, currencySymbol(), exchangeRate())));
|
|
1603
|
+
_$effect((_$p) => _$setProp(_el$40, "fg", pal().text, _$p));
|
|
1604
|
+
return _el$40;
|
|
1321
1605
|
})(), _$createComponent(Show, {
|
|
1322
1606
|
get when() {
|
|
1323
1607
|
return data().providerName;
|
|
1324
1608
|
},
|
|
1325
1609
|
get children() {
|
|
1326
|
-
var _el$
|
|
1327
|
-
_$insert(_el$
|
|
1328
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1329
|
-
return _el$
|
|
1610
|
+
var _el$41 = _$createElement("text");
|
|
1611
|
+
_$insert(_el$41, () => justify(t("provider"), data().providerName));
|
|
1612
|
+
_$effect((_$p) => _$setProp(_el$41, "fg", pal().muted, _$p));
|
|
1613
|
+
return _el$41;
|
|
1330
1614
|
}
|
|
1331
1615
|
}), (() => {
|
|
1332
|
-
var _el$
|
|
1333
|
-
_$insert(_el$
|
|
1334
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1335
|
-
return _el$
|
|
1616
|
+
var _el$42 = _$createElement("text");
|
|
1617
|
+
_$insert(_el$42, () => justify(t("model"), data().model));
|
|
1618
|
+
_$effect((_$p) => _$setProp(_el$42, "fg", pal().muted, _$p));
|
|
1619
|
+
return _el$42;
|
|
1336
1620
|
})(), _$createComponent(Show, {
|
|
1337
1621
|
get when() {
|
|
1338
1622
|
return data().hasPricing;
|
|
1339
1623
|
},
|
|
1340
1624
|
get children() {
|
|
1341
1625
|
return [(() => {
|
|
1342
|
-
var _el$
|
|
1343
|
-
_$insert(_el$
|
|
1344
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1345
|
-
return _el$
|
|
1626
|
+
var _el$43 = _$createElement("text");
|
|
1627
|
+
_$insert(_el$43, () => justify(t("rate"), currencySymbol() + (data().inputRate * exchangeRate()).toFixed(2) + "/M " + t("inputRate")));
|
|
1628
|
+
_$effect((_$p) => _$setProp(_el$43, "fg", pal().muted, _$p));
|
|
1629
|
+
return _el$43;
|
|
1346
1630
|
})(), _$createComponent(Show, {
|
|
1347
1631
|
get when() {
|
|
1348
1632
|
return data().cacheReadRate > 0;
|
|
1349
1633
|
},
|
|
1350
1634
|
get children() {
|
|
1351
|
-
var _el$
|
|
1352
|
-
_$insert(_el$
|
|
1353
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1354
|
-
return _el$
|
|
1635
|
+
var _el$44 = _$createElement("text");
|
|
1636
|
+
_$insert(_el$44, () => justify("", currencySymbol() + (data().cacheReadRate * exchangeRate()).toFixed(2) + "/M " + t("cacheRate")));
|
|
1637
|
+
_$effect((_$p) => _$setProp(_el$44, "fg", pal().muted, _$p));
|
|
1638
|
+
return _el$44;
|
|
1355
1639
|
}
|
|
1356
1640
|
}), _$createComponent(Show, {
|
|
1357
1641
|
get when() {
|
|
1358
1642
|
return data().cacheWriteRate > 0;
|
|
1359
1643
|
},
|
|
1360
1644
|
get children() {
|
|
1361
|
-
var _el$
|
|
1362
|
-
_$insert(_el$
|
|
1363
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1364
|
-
return _el$
|
|
1645
|
+
var _el$45 = _$createElement("text");
|
|
1646
|
+
_$insert(_el$45, () => justify("", currencySymbol() + (data().cacheWriteRate * exchangeRate()).toFixed(2) + "/M " + t("writeRate")));
|
|
1647
|
+
_$effect((_$p) => _$setProp(_el$45, "fg", pal().muted, _$p));
|
|
1648
|
+
return _el$45;
|
|
1365
1649
|
}
|
|
1366
1650
|
})];
|
|
1367
1651
|
}
|
|
@@ -1380,37 +1664,37 @@ function TokenCachePanel(props) {
|
|
|
1380
1664
|
},
|
|
1381
1665
|
get children() {
|
|
1382
1666
|
return [_$memo(() => (() => {
|
|
1383
|
-
var _el$
|
|
1384
|
-
_$insertNode(_el$
|
|
1385
|
-
_$insertNode(_el$
|
|
1386
|
-
_$insertNode(_el$
|
|
1387
|
-
_$setProp(_el$
|
|
1667
|
+
var _el$83 = _$createElement("text"), _el$84 = _$createElement("span"), _el$85 = _$createElement("span"), _el$86 = _$createElement("b"), _el$87 = _$createElement("span");
|
|
1668
|
+
_$insertNode(_el$83, _el$84);
|
|
1669
|
+
_$insertNode(_el$83, _el$85);
|
|
1670
|
+
_$insertNode(_el$83, _el$87);
|
|
1671
|
+
_$setProp(_el$83, "onMouseUp", () => setDistOpen((o) => {
|
|
1388
1672
|
const n = !o;
|
|
1389
1673
|
persistFold("dist", n);
|
|
1390
1674
|
return n;
|
|
1391
1675
|
}));
|
|
1392
|
-
_$insert(_el$
|
|
1393
|
-
_$insertNode(_el$
|
|
1394
|
-
_$insert(_el$
|
|
1395
|
-
_$insert(_el$
|
|
1676
|
+
_$insert(_el$84, () => distOpen() ? "\u25BC " : "\u25B6 ");
|
|
1677
|
+
_$insertNode(_el$85, _el$86);
|
|
1678
|
+
_$insert(_el$86, () => t("distTitle"));
|
|
1679
|
+
_$insert(_el$87, () => sep().slice(visualWidth((distOpen() ? "\u25BC " : "\u25B6 ") + t("distTitle"))));
|
|
1396
1680
|
_$effect((_p$) => {
|
|
1397
|
-
var _v$
|
|
1681
|
+
var _v$24 = {
|
|
1398
1682
|
fg: pal().muted
|
|
1399
|
-
}, _v$
|
|
1683
|
+
}, _v$25 = {
|
|
1400
1684
|
fg: pal().primary
|
|
1401
|
-
}, _v$
|
|
1685
|
+
}, _v$26 = {
|
|
1402
1686
|
fg: pal().muted
|
|
1403
1687
|
};
|
|
1404
|
-
_v$
|
|
1405
|
-
_v$
|
|
1406
|
-
_v$
|
|
1688
|
+
_v$24 !== _p$.e && (_p$.e = _$setProp(_el$84, "style", _v$24, _p$.e));
|
|
1689
|
+
_v$25 !== _p$.t && (_p$.t = _$setProp(_el$85, "style", _v$25, _p$.t));
|
|
1690
|
+
_v$26 !== _p$.a && (_p$.a = _$setProp(_el$87, "style", _v$26, _p$.a));
|
|
1407
1691
|
return _p$;
|
|
1408
1692
|
}, {
|
|
1409
1693
|
e: void 0,
|
|
1410
1694
|
t: void 0,
|
|
1411
1695
|
a: void 0
|
|
1412
1696
|
});
|
|
1413
|
-
return _el$
|
|
1697
|
+
return _el$83;
|
|
1414
1698
|
})()), _$createComponent(Show, {
|
|
1415
1699
|
get when() {
|
|
1416
1700
|
return distOpen();
|
|
@@ -1420,58 +1704,63 @@ function TokenCachePanel(props) {
|
|
|
1420
1704
|
get when() {
|
|
1421
1705
|
return data().dist.system > 0;
|
|
1422
1706
|
},
|
|
1423
|
-
get children() {
|
|
1424
|
-
var _el$45 = _$createElement("text");
|
|
1425
|
-
_$insert(_el$45, () => justify(t().distSys, fmt(data().dist.system), t().tok));
|
|
1426
|
-
_$effect((_$p) => _$setProp(_el$45, "fg", pal().muted, _$p));
|
|
1427
|
-
return _el$45;
|
|
1428
|
-
}
|
|
1429
|
-
}), _$createComponent(Show, {
|
|
1430
|
-
get when() {
|
|
1431
|
-
return data().dist.user > 0;
|
|
1432
|
-
},
|
|
1433
1707
|
get children() {
|
|
1434
1708
|
var _el$46 = _$createElement("text");
|
|
1435
|
-
_$insert(_el$46, () => justify(t()
|
|
1709
|
+
_$insert(_el$46, () => justify(t("distSys"), fmt(data().dist.system), t("tok")));
|
|
1436
1710
|
_$effect((_$p) => _$setProp(_el$46, "fg", pal().muted, _$p));
|
|
1437
1711
|
return _el$46;
|
|
1438
1712
|
}
|
|
1439
1713
|
}), _$createComponent(Show, {
|
|
1440
1714
|
get when() {
|
|
1441
|
-
return data().dist.
|
|
1715
|
+
return data().dist.user > 0;
|
|
1442
1716
|
},
|
|
1443
1717
|
get children() {
|
|
1444
1718
|
var _el$47 = _$createElement("text");
|
|
1445
|
-
_$insert(_el$47, () => justify(t()
|
|
1719
|
+
_$insert(_el$47, () => justify(t("distUser"), fmt(data().dist.user), t("tok")));
|
|
1446
1720
|
_$effect((_$p) => _$setProp(_el$47, "fg", pal().muted, _$p));
|
|
1447
1721
|
return _el$47;
|
|
1448
1722
|
}
|
|
1449
1723
|
}), _$createComponent(Show, {
|
|
1450
1724
|
get when() {
|
|
1451
|
-
return data().dist.
|
|
1725
|
+
return data().dist.agent > 0;
|
|
1452
1726
|
},
|
|
1453
1727
|
get children() {
|
|
1454
1728
|
var _el$48 = _$createElement("text");
|
|
1455
|
-
_$insert(_el$48, () => justify(t()
|
|
1729
|
+
_$insert(_el$48, () => justify(t("distAgent"), fmt(data().dist.agent), t("tok")));
|
|
1456
1730
|
_$effect((_$p) => _$setProp(_el$48, "fg", pal().muted, _$p));
|
|
1457
1731
|
return _el$48;
|
|
1458
1732
|
}
|
|
1459
1733
|
}), _$createComponent(Show, {
|
|
1460
1734
|
get when() {
|
|
1461
|
-
return data().dist.
|
|
1735
|
+
return data().dist.toolCall > 0;
|
|
1462
1736
|
},
|
|
1463
1737
|
get children() {
|
|
1464
1738
|
var _el$49 = _$createElement("text");
|
|
1465
|
-
_$insert(_el$49, () => justify(t()
|
|
1739
|
+
_$insert(_el$49, () => justify(t("distTool"), fmt(data().dist.toolCall), t("tok")));
|
|
1466
1740
|
_$effect((_$p) => _$setProp(_el$49, "fg", pal().muted, _$p));
|
|
1467
1741
|
return _el$49;
|
|
1468
1742
|
}
|
|
1469
|
-
}), (
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1743
|
+
}), _$createComponent(Show, {
|
|
1744
|
+
get when() {
|
|
1745
|
+
return data().dist.toolResult > 0;
|
|
1746
|
+
},
|
|
1747
|
+
get children() {
|
|
1748
|
+
var _el$50 = _$createElement("text");
|
|
1749
|
+
_$insert(_el$50, () => justify(t("distRes"), fmt(data().dist.toolResult), t("tok")));
|
|
1750
|
+
_$effect((_$p) => _$setProp(_el$50, "fg", pal().muted, _$p));
|
|
1751
|
+
return _el$50;
|
|
1752
|
+
}
|
|
1753
|
+
}), _$createComponent(Show, {
|
|
1754
|
+
get when() {
|
|
1755
|
+
return data().dist.reasoning > 0;
|
|
1756
|
+
},
|
|
1757
|
+
get children() {
|
|
1758
|
+
var _el$51 = _$createElement("text");
|
|
1759
|
+
_$insert(_el$51, () => justify(t("distReason"), fmt(data().dist.reasoning), t("tok")));
|
|
1760
|
+
_$effect((_$p) => _$setProp(_el$51, "fg", pal().muted, _$p));
|
|
1761
|
+
return _el$51;
|
|
1762
|
+
}
|
|
1763
|
+
})];
|
|
1475
1764
|
}
|
|
1476
1765
|
})];
|
|
1477
1766
|
}
|
|
@@ -1488,37 +1777,37 @@ function TokenCachePanel(props) {
|
|
|
1488
1777
|
},
|
|
1489
1778
|
get children() {
|
|
1490
1779
|
return [_$memo(() => (() => {
|
|
1491
|
-
var _el$
|
|
1492
|
-
_$insertNode(_el$
|
|
1493
|
-
_$insertNode(_el$
|
|
1494
|
-
_$insertNode(_el$
|
|
1495
|
-
_$insertNode(_el$
|
|
1496
|
-
_$setProp(_el$
|
|
1780
|
+
var _el$88 = _$createElement("text"), _el$89 = _$createElement("span"), _el$90 = _$createElement("span"), _el$91 = _$createElement("b"), _el$92 = _$createElement("span"), _el$93 = _$createTextNode(` (`), _el$94 = _$createTextNode(`)`), _el$95 = _$createElement("span");
|
|
1781
|
+
_$insertNode(_el$88, _el$89);
|
|
1782
|
+
_$insertNode(_el$88, _el$90);
|
|
1783
|
+
_$insertNode(_el$88, _el$92);
|
|
1784
|
+
_$insertNode(_el$88, _el$95);
|
|
1785
|
+
_$setProp(_el$88, "onMouseUp", () => setSkillsOpen((o) => {
|
|
1497
1786
|
const n = !o;
|
|
1498
1787
|
persistFold("skills", n);
|
|
1499
1788
|
return n;
|
|
1500
1789
|
}));
|
|
1501
|
-
_$insert(_el$
|
|
1502
|
-
_$insertNode(_el$
|
|
1503
|
-
_$insert(_el$
|
|
1504
|
-
_$insertNode(_el$
|
|
1505
|
-
_$insertNode(_el$
|
|
1506
|
-
_$insert(_el$
|
|
1507
|
-
_$insert(_el$
|
|
1790
|
+
_$insert(_el$89, () => skillsOpen() ? "\u25BC " : "\u25B6 ");
|
|
1791
|
+
_$insertNode(_el$90, _el$91);
|
|
1792
|
+
_$insert(_el$91, () => t("secSkills"));
|
|
1793
|
+
_$insertNode(_el$92, _el$93);
|
|
1794
|
+
_$insertNode(_el$92, _el$94);
|
|
1795
|
+
_$insert(_el$92, () => data().skills.length, _el$94);
|
|
1796
|
+
_$insert(_el$95, () => sep().slice(visualWidth((skillsOpen() ? "\u25BC " : "\u25B6 ") + t("secSkills") + ` (${data().skills.length})`)));
|
|
1508
1797
|
_$effect((_p$) => {
|
|
1509
|
-
var _v$
|
|
1798
|
+
var _v$27 = {
|
|
1510
1799
|
fg: pal().muted
|
|
1511
|
-
}, _v$
|
|
1800
|
+
}, _v$28 = {
|
|
1512
1801
|
fg: pal().primary
|
|
1513
|
-
}, _v$
|
|
1802
|
+
}, _v$29 = {
|
|
1514
1803
|
fg: pal().muted
|
|
1515
|
-
}, _v$
|
|
1804
|
+
}, _v$30 = {
|
|
1516
1805
|
fg: pal().muted
|
|
1517
1806
|
};
|
|
1518
|
-
_v$
|
|
1519
|
-
_v$
|
|
1520
|
-
_v$
|
|
1521
|
-
_v$
|
|
1807
|
+
_v$27 !== _p$.e && (_p$.e = _$setProp(_el$89, "style", _v$27, _p$.e));
|
|
1808
|
+
_v$28 !== _p$.t && (_p$.t = _$setProp(_el$90, "style", _v$28, _p$.t));
|
|
1809
|
+
_v$29 !== _p$.a && (_p$.a = _$setProp(_el$92, "style", _v$29, _p$.a));
|
|
1810
|
+
_v$30 !== _p$.o && (_p$.o = _$setProp(_el$95, "style", _v$30, _p$.o));
|
|
1522
1811
|
return _p$;
|
|
1523
1812
|
}, {
|
|
1524
1813
|
e: void 0,
|
|
@@ -1526,21 +1815,21 @@ function TokenCachePanel(props) {
|
|
|
1526
1815
|
a: void 0,
|
|
1527
1816
|
o: void 0
|
|
1528
1817
|
});
|
|
1529
|
-
return _el$
|
|
1818
|
+
return _el$88;
|
|
1530
1819
|
})()), _$createComponent(Show, {
|
|
1531
1820
|
get when() {
|
|
1532
1821
|
return skillsOpen();
|
|
1533
1822
|
},
|
|
1534
1823
|
get children() {
|
|
1535
1824
|
return data().skills.map((sk) => {
|
|
1536
|
-
const rightW = visualWidth(fmt(sk.tokens)) + UNIT_GAP + visualWidth(t(
|
|
1825
|
+
const rightW = visualWidth(fmt(sk.tokens)) + UNIT_GAP + visualWidth(t("tok"));
|
|
1537
1826
|
const maxLabel = Math.max(4, panelWidth() - gutter() - rightW - 1);
|
|
1538
1827
|
const label = truncateVisual(sk.name, maxLabel);
|
|
1539
1828
|
return (() => {
|
|
1540
|
-
var _el$
|
|
1541
|
-
_$insert(_el$
|
|
1542
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1543
|
-
return _el$
|
|
1829
|
+
var _el$96 = _$createElement("text");
|
|
1830
|
+
_$insert(_el$96, () => justify(label, fmt(sk.tokens), t("tok")));
|
|
1831
|
+
_$effect((_$p) => _$setProp(_el$96, "fg", pal().muted, _$p));
|
|
1832
|
+
return _el$96;
|
|
1544
1833
|
})();
|
|
1545
1834
|
});
|
|
1546
1835
|
}
|
|
@@ -1554,116 +1843,127 @@ function TokenCachePanel(props) {
|
|
|
1554
1843
|
},
|
|
1555
1844
|
get children() {
|
|
1556
1845
|
return [(() => {
|
|
1557
|
-
var _el$
|
|
1558
|
-
_$insert(_el$
|
|
1559
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1560
|
-
return _el$
|
|
1846
|
+
var _el$52 = _$createElement("text");
|
|
1847
|
+
_$insert(_el$52, sep);
|
|
1848
|
+
_$effect((_$p) => _$setProp(_el$52, "fg", pal().muted, _$p));
|
|
1849
|
+
return _el$52;
|
|
1561
1850
|
})(), _$createComponent(Show, {
|
|
1562
1851
|
get when() {
|
|
1563
|
-
return
|
|
1852
|
+
return balanceUnsupported();
|
|
1564
1853
|
},
|
|
1565
1854
|
get children() {
|
|
1566
|
-
var _el$
|
|
1567
|
-
_$insertNode(_el$
|
|
1568
|
-
_$insertNode(_el$
|
|
1569
|
-
_$insertNode(_el$
|
|
1570
|
-
_$insert(_el$
|
|
1855
|
+
var _el$53 = _$createElement("text"), _el$54 = _$createElement("span"), _el$56 = _$createElement("span");
|
|
1856
|
+
_$insertNode(_el$53, _el$54);
|
|
1857
|
+
_$insertNode(_el$53, _el$56);
|
|
1858
|
+
_$insertNode(_el$54, _$createTextNode(`> `));
|
|
1859
|
+
_$insert(_el$56, () => t("balUnsupported"));
|
|
1571
1860
|
_$effect((_p$) => {
|
|
1572
1861
|
var _v$9 = pal().muted, _v$0 = {
|
|
1573
1862
|
fg: pal().muted
|
|
1574
1863
|
};
|
|
1575
|
-
_v$9 !== _p$.e && (_p$.e = _$setProp(_el$
|
|
1576
|
-
_v$0 !== _p$.t && (_p$.t = _$setProp(_el$
|
|
1577
|
-
return _p$;
|
|
1578
|
-
}, {
|
|
1579
|
-
e: void 0,
|
|
1580
|
-
t: void 0
|
|
1581
|
-
});
|
|
1582
|
-
return _el$52;
|
|
1583
|
-
}
|
|
1584
|
-
}), _$createComponent(Show, {
|
|
1585
|
-
get when() {
|
|
1586
|
-
return balanceState().status === "loading";
|
|
1587
|
-
},
|
|
1588
|
-
get children() {
|
|
1589
|
-
var _el$56 = _$createElement("text"), _el$57 = _$createElement("span"), _el$59 = _$createElement("span");
|
|
1590
|
-
_$insertNode(_el$56, _el$57);
|
|
1591
|
-
_$insertNode(_el$56, _el$59);
|
|
1592
|
-
_$insertNode(_el$57, _$createTextNode(`> `));
|
|
1593
|
-
_$insert(_el$59, () => t().balLoading);
|
|
1594
|
-
_$effect((_p$) => {
|
|
1595
|
-
var _v$1 = pal().muted, _v$10 = {
|
|
1596
|
-
fg: pal().muted
|
|
1597
|
-
};
|
|
1598
|
-
_v$1 !== _p$.e && (_p$.e = _$setProp(_el$56, "fg", _v$1, _p$.e));
|
|
1599
|
-
_v$10 !== _p$.t && (_p$.t = _$setProp(_el$57, "style", _v$10, _p$.t));
|
|
1600
|
-
return _p$;
|
|
1601
|
-
}, {
|
|
1602
|
-
e: void 0,
|
|
1603
|
-
t: void 0
|
|
1604
|
-
});
|
|
1605
|
-
return _el$56;
|
|
1606
|
-
}
|
|
1607
|
-
}), _$createComponent(Show, {
|
|
1608
|
-
get when() {
|
|
1609
|
-
return balanceState().status === "error";
|
|
1610
|
-
},
|
|
1611
|
-
get children() {
|
|
1612
|
-
var _el$60 = _$createElement("text"), _el$61 = _$createElement("span"), _el$63 = _$createElement("span");
|
|
1613
|
-
_$insertNode(_el$60, _el$61);
|
|
1614
|
-
_$insertNode(_el$60, _el$63);
|
|
1615
|
-
_$insertNode(_el$61, _$createTextNode(`> `));
|
|
1616
|
-
_$insert(_el$63, () => {
|
|
1617
|
-
const code = balanceState().error;
|
|
1618
|
-
if (code === "401") return t().balErr401;
|
|
1619
|
-
if (code === "403") return t().balErr403;
|
|
1620
|
-
if (code === "EMPTY") return t().balErrEmpty;
|
|
1621
|
-
if (code === "TIMEOUT") return t().balErrTimeout;
|
|
1622
|
-
return t().balError + (code ? ` (${code})` : "");
|
|
1623
|
-
});
|
|
1624
|
-
_$effect((_p$) => {
|
|
1625
|
-
var _v$11 = pal().error, _v$12 = {
|
|
1626
|
-
fg: pal().muted
|
|
1627
|
-
};
|
|
1628
|
-
_v$11 !== _p$.e && (_p$.e = _$setProp(_el$60, "fg", _v$11, _p$.e));
|
|
1629
|
-
_v$12 !== _p$.t && (_p$.t = _$setProp(_el$61, "style", _v$12, _p$.t));
|
|
1864
|
+
_v$9 !== _p$.e && (_p$.e = _$setProp(_el$53, "fg", _v$9, _p$.e));
|
|
1865
|
+
_v$0 !== _p$.t && (_p$.t = _$setProp(_el$54, "style", _v$0, _p$.t));
|
|
1630
1866
|
return _p$;
|
|
1631
1867
|
}, {
|
|
1632
1868
|
e: void 0,
|
|
1633
1869
|
t: void 0
|
|
1634
1870
|
});
|
|
1635
|
-
return _el$
|
|
1871
|
+
return _el$53;
|
|
1636
1872
|
}
|
|
1637
1873
|
}), _$createComponent(Show, {
|
|
1638
1874
|
get when() {
|
|
1639
|
-
return
|
|
1875
|
+
return !balanceUnsupported();
|
|
1640
1876
|
},
|
|
1641
1877
|
get children() {
|
|
1642
|
-
return (
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1878
|
+
return [_$createComponent(Show, {
|
|
1879
|
+
get when() {
|
|
1880
|
+
return balanceState().status === "idle";
|
|
1881
|
+
},
|
|
1882
|
+
get children() {
|
|
1883
|
+
var _el$57 = _$createElement("text"), _el$58 = _$createElement("span"), _el$60 = _$createElement("span");
|
|
1884
|
+
_$insertNode(_el$57, _el$58);
|
|
1885
|
+
_$insertNode(_el$57, _el$60);
|
|
1886
|
+
_$insertNode(_el$58, _$createTextNode(`> `));
|
|
1887
|
+
_$insert(_el$60, () => t("balNoKey", {
|
|
1888
|
+
p: providerName()
|
|
1889
|
+
}));
|
|
1890
|
+
_$effect((_p$) => {
|
|
1891
|
+
var _v$1 = pal().muted, _v$10 = {
|
|
1892
|
+
fg: pal().muted
|
|
1893
|
+
};
|
|
1894
|
+
_v$1 !== _p$.e && (_p$.e = _$setProp(_el$57, "fg", _v$1, _p$.e));
|
|
1895
|
+
_v$10 !== _p$.t && (_p$.t = _$setProp(_el$58, "style", _v$10, _p$.t));
|
|
1896
|
+
return _p$;
|
|
1897
|
+
}, {
|
|
1898
|
+
e: void 0,
|
|
1899
|
+
t: void 0
|
|
1900
|
+
});
|
|
1901
|
+
return _el$57;
|
|
1653
1902
|
}
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
_$
|
|
1663
|
-
_$
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1903
|
+
}), _$createComponent(Show, {
|
|
1904
|
+
get when() {
|
|
1905
|
+
return balanceState().status === "loading";
|
|
1906
|
+
},
|
|
1907
|
+
get children() {
|
|
1908
|
+
var _el$61 = _$createElement("text"), _el$62 = _$createElement("span"), _el$64 = _$createElement("span");
|
|
1909
|
+
_$insertNode(_el$61, _el$62);
|
|
1910
|
+
_$insertNode(_el$61, _el$64);
|
|
1911
|
+
_$insertNode(_el$62, _$createTextNode(`> `));
|
|
1912
|
+
_$insert(_el$64, () => t("balLoading"));
|
|
1913
|
+
_$effect((_p$) => {
|
|
1914
|
+
var _v$11 = pal().muted, _v$12 = {
|
|
1915
|
+
fg: pal().muted
|
|
1916
|
+
};
|
|
1917
|
+
_v$11 !== _p$.e && (_p$.e = _$setProp(_el$61, "fg", _v$11, _p$.e));
|
|
1918
|
+
_v$12 !== _p$.t && (_p$.t = _$setProp(_el$62, "style", _v$12, _p$.t));
|
|
1919
|
+
return _p$;
|
|
1920
|
+
}, {
|
|
1921
|
+
e: void 0,
|
|
1922
|
+
t: void 0
|
|
1923
|
+
});
|
|
1924
|
+
return _el$61;
|
|
1925
|
+
}
|
|
1926
|
+
}), _$createComponent(Show, {
|
|
1927
|
+
get when() {
|
|
1928
|
+
return balanceState().status === "error";
|
|
1929
|
+
},
|
|
1930
|
+
get children() {
|
|
1931
|
+
var _el$65 = _$createElement("text"), _el$66 = _$createElement("span"), _el$68 = _$createElement("span");
|
|
1932
|
+
_$insertNode(_el$65, _el$66);
|
|
1933
|
+
_$insertNode(_el$65, _el$68);
|
|
1934
|
+
_$insertNode(_el$66, _$createTextNode(`> `));
|
|
1935
|
+
_$insert(_el$68, () => {
|
|
1936
|
+
const code = balanceState().error;
|
|
1937
|
+
if (code === "401") return t("balErr401");
|
|
1938
|
+
if (code === "403") return t("balErr403");
|
|
1939
|
+
if (code === "EMPTY") return t("balErrEmpty");
|
|
1940
|
+
if (code === "TIMEOUT") return t("balErrTimeout");
|
|
1941
|
+
return t("balError") + (code ? ` (${code})` : "");
|
|
1942
|
+
});
|
|
1943
|
+
_$effect((_p$) => {
|
|
1944
|
+
var _v$13 = pal().error, _v$14 = {
|
|
1945
|
+
fg: pal().muted
|
|
1946
|
+
};
|
|
1947
|
+
_v$13 !== _p$.e && (_p$.e = _$setProp(_el$65, "fg", _v$13, _p$.e));
|
|
1948
|
+
_v$14 !== _p$.t && (_p$.t = _$setProp(_el$66, "style", _v$14, _p$.t));
|
|
1949
|
+
return _p$;
|
|
1950
|
+
}, {
|
|
1951
|
+
e: void 0,
|
|
1952
|
+
t: void 0
|
|
1953
|
+
});
|
|
1954
|
+
return _el$65;
|
|
1955
|
+
}
|
|
1956
|
+
}), _$createComponent(Show, {
|
|
1957
|
+
get when() {
|
|
1958
|
+
return _$memo(() => balanceState().status === "ok")() && balanceState().data;
|
|
1959
|
+
},
|
|
1960
|
+
get children() {
|
|
1961
|
+
var _el$69 = _$createElement("text");
|
|
1962
|
+
_$insert(_el$69, () => justify(t("balTotal"), formatBalanceText(balanceState().data, balanceCurrency(), exchangeRate())));
|
|
1963
|
+
_$effect((_$p) => _$setProp(_el$69, "fg", pal().text, _$p));
|
|
1964
|
+
return _el$69;
|
|
1965
|
+
}
|
|
1966
|
+
})];
|
|
1667
1967
|
}
|
|
1668
1968
|
})];
|
|
1669
1969
|
}
|
|
@@ -1673,13 +1973,13 @@ function TokenCachePanel(props) {
|
|
|
1673
1973
|
}
|
|
1674
1974
|
}), null);
|
|
1675
1975
|
_$effect((_p$) => {
|
|
1676
|
-
var _v$
|
|
1976
|
+
var _v$15 = {
|
|
1677
1977
|
fg: pal().muted
|
|
1678
|
-
}, _v$
|
|
1978
|
+
}, _v$16 = {
|
|
1679
1979
|
fg: pal().primary
|
|
1680
1980
|
};
|
|
1681
|
-
_v$
|
|
1682
|
-
_v$
|
|
1981
|
+
_v$15 !== _p$.e && (_p$.e = _$setProp(_el$3, "style", _v$15, _p$.e));
|
|
1982
|
+
_v$16 !== _p$.t && (_p$.t = _$setProp(_el$4, "style", _v$16, _p$.t));
|
|
1683
1983
|
return _p$;
|
|
1684
1984
|
}, {
|
|
1685
1985
|
e: void 0,
|
|
@@ -1688,6 +1988,233 @@ function TokenCachePanel(props) {
|
|
|
1688
1988
|
return _el$;
|
|
1689
1989
|
})();
|
|
1690
1990
|
}
|
|
1991
|
+
function BottomStatusBar(props) {
|
|
1992
|
+
const KV_PREFIX = "cache_panel";
|
|
1993
|
+
const t = createT(() => props.signals.langCode());
|
|
1994
|
+
const sid = props.sessionId;
|
|
1995
|
+
const stats = createMemo(() => {
|
|
1996
|
+
const id = sid;
|
|
1997
|
+
if (!id) return null;
|
|
1998
|
+
const msgs = props.api.state.session.messages(id);
|
|
1999
|
+
const session = typeof props.api.state.session.get === "function" ? props.api.state.session.get(id) : void 0;
|
|
2000
|
+
let input = session?.tokens?.input ?? 0;
|
|
2001
|
+
let read = session?.tokens?.cache?.read ?? 0;
|
|
2002
|
+
let write = session?.tokens?.cache?.write ?? 0;
|
|
2003
|
+
if (session?.tokens == null) {
|
|
2004
|
+
for (const m of msgs) {
|
|
2005
|
+
if (m.role !== "assistant") continue;
|
|
2006
|
+
const tk = m.tokens;
|
|
2007
|
+
if (!tk) continue;
|
|
2008
|
+
input += num(tk.input);
|
|
2009
|
+
read += num(tk.cache?.read);
|
|
2010
|
+
write += num(tk.cache?.write);
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
let hitRate = -1, prevHitRate = -1;
|
|
2014
|
+
for (let i = msgs.length - 1; i >= 0; i--) {
|
|
2015
|
+
const m = msgs[i];
|
|
2016
|
+
if (m.role !== "assistant") continue;
|
|
2017
|
+
const tk = m.tokens;
|
|
2018
|
+
if (!tk) continue;
|
|
2019
|
+
const mit = num(tk.input) + num(tk.cache?.read) + num(tk.cache?.write);
|
|
2020
|
+
const mrt = num(tk.cache?.read);
|
|
2021
|
+
if (mit <= 0) continue;
|
|
2022
|
+
const rate = mrt / mit * 100;
|
|
2023
|
+
if (hitRate < 0) {
|
|
2024
|
+
hitRate = rate;
|
|
2025
|
+
continue;
|
|
2026
|
+
}
|
|
2027
|
+
prevHitRate = rate;
|
|
2028
|
+
break;
|
|
2029
|
+
}
|
|
2030
|
+
return {
|
|
2031
|
+
hitRate,
|
|
2032
|
+
prevHitRate,
|
|
2033
|
+
input,
|
|
2034
|
+
read,
|
|
2035
|
+
write
|
|
2036
|
+
};
|
|
2037
|
+
});
|
|
2038
|
+
createEffect(() => {
|
|
2039
|
+
if (!props.signals.autoBalance()) return;
|
|
2040
|
+
const id = sid;
|
|
2041
|
+
if (!id) return;
|
|
2042
|
+
const msgs = props.api.state.session.messages(id);
|
|
2043
|
+
let pid = "";
|
|
2044
|
+
for (let i = msgs.length - 1; i >= 0; i--) {
|
|
2045
|
+
const m = msgs[i];
|
|
2046
|
+
if (m.role === "assistant" && m.providerID) {
|
|
2047
|
+
pid = m.providerID;
|
|
2048
|
+
break;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
if (!pid) {
|
|
2052
|
+
try {
|
|
2053
|
+
pid = props.api.state.session.get(id)?.model?.providerID ?? "";
|
|
2054
|
+
} catch {
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
if (!pid) return;
|
|
2058
|
+
const hit = matchBalanceProvider(pid);
|
|
2059
|
+
if (hit) {
|
|
2060
|
+
props.signals.setBalanceUnsupported(false);
|
|
2061
|
+
if (hit.id !== props.signals.balanceProviderId()) {
|
|
2062
|
+
props.signals.setBalanceProviderId(hit.id);
|
|
2063
|
+
props.signals.setBalanceRefresh(props.signals.balanceRefresh() + 1);
|
|
2064
|
+
}
|
|
2065
|
+
} else {
|
|
2066
|
+
props.signals.setBalanceUnsupported(true);
|
|
2067
|
+
}
|
|
2068
|
+
});
|
|
2069
|
+
const pal = createMemo(() => {
|
|
2070
|
+
const th = props.api.theme.current;
|
|
2071
|
+
const sat = (k, fb) => desaturateTo(th[k], MAX_SAT, fb);
|
|
2072
|
+
return {
|
|
2073
|
+
text: sat("text", FALLBACK.text),
|
|
2074
|
+
muted: sat("textMuted", FALLBACK.muted),
|
|
2075
|
+
success: sat("success", FALLBACK.success),
|
|
2076
|
+
warning: sat("warning", FALLBACK.warning),
|
|
2077
|
+
error: sat("error", FALLBACK.error)
|
|
2078
|
+
};
|
|
2079
|
+
});
|
|
2080
|
+
const hitColor = createMemo(() => {
|
|
2081
|
+
const r = stats()?.hitRate ?? -1;
|
|
2082
|
+
if (r >= 85) return pal().success;
|
|
2083
|
+
if (r >= 70) return pal().warning;
|
|
2084
|
+
return pal().error;
|
|
2085
|
+
});
|
|
2086
|
+
const trend = createMemo(() => {
|
|
2087
|
+
const s = stats();
|
|
2088
|
+
if (!s || s.prevHitRate < 0 || s.hitRate < 0) return null;
|
|
2089
|
+
const d = s.hitRate - s.prevHitRate;
|
|
2090
|
+
return Math.abs(d) < 0.05 ? null : d;
|
|
2091
|
+
});
|
|
2092
|
+
const balanceText = createMemo(() => {
|
|
2093
|
+
const s = props.signals.balanceState();
|
|
2094
|
+
if (s.status === "ok" && s.data) return formatBalanceText(s.data, props.signals.balanceCurrency(), props.signals.exchangeRate());
|
|
2095
|
+
if (s.status === "loading") return "\u2026";
|
|
2096
|
+
if (s.status === "error") return "\u26A0";
|
|
2097
|
+
return "-";
|
|
2098
|
+
});
|
|
2099
|
+
const directory = createMemo(() => {
|
|
2100
|
+
try {
|
|
2101
|
+
return props.api.state.path.directory;
|
|
2102
|
+
} catch {
|
|
2103
|
+
return "";
|
|
2104
|
+
}
|
|
2105
|
+
});
|
|
2106
|
+
onMount(() => {
|
|
2107
|
+
try {
|
|
2108
|
+
const v = props.api.kv.get(`${KV_PREFIX}.section.bottom`, true);
|
|
2109
|
+
props.signals.setSectionBottom(v !== false);
|
|
2110
|
+
} catch {
|
|
2111
|
+
}
|
|
2112
|
+
});
|
|
2113
|
+
return _$createComponent(Show, {
|
|
2114
|
+
get when() {
|
|
2115
|
+
return props.signals.sectionBottom();
|
|
2116
|
+
},
|
|
2117
|
+
get fallback() {
|
|
2118
|
+
return (() => {
|
|
2119
|
+
var _el$111 = _$createElement("text");
|
|
2120
|
+
_$insert(_el$111, directory);
|
|
2121
|
+
_$effect((_$p) => _$setProp(_el$111, "fg", pal().muted, _$p));
|
|
2122
|
+
return _el$111;
|
|
2123
|
+
})();
|
|
2124
|
+
},
|
|
2125
|
+
get children() {
|
|
2126
|
+
var _el$97 = _$createElement("box"), _el$98 = _$createElement("text"), _el$99 = _$createElement("box"), _el$100 = _$createElement("text"), _el$101 = _$createElement("span"), _el$102 = _$createTextNode(` `), _el$103 = _$createElement("span"), _el$105 = _$createElement("span"), _el$106 = _$createElement("span"), _el$109 = _$createElement("text");
|
|
2127
|
+
_$insertNode(_el$97, _el$98);
|
|
2128
|
+
_$insertNode(_el$97, _el$99);
|
|
2129
|
+
_$setProp(_el$97, "marginLeft", 1);
|
|
2130
|
+
_$setProp(_el$97, "flexGrow", 1);
|
|
2131
|
+
_$setProp(_el$97, "flexShrink", 0);
|
|
2132
|
+
_$setProp(_el$97, "flexDirection", "row");
|
|
2133
|
+
_$setProp(_el$97, "justifyContent", "space-between");
|
|
2134
|
+
_$insert(_el$98, directory);
|
|
2135
|
+
_$insertNode(_el$99, _el$100);
|
|
2136
|
+
_$insertNode(_el$99, _el$109);
|
|
2137
|
+
_$setProp(_el$99, "flexDirection", "row");
|
|
2138
|
+
_$insertNode(_el$100, _el$101);
|
|
2139
|
+
_$insertNode(_el$100, _el$103);
|
|
2140
|
+
_$insertNode(_el$100, _el$105);
|
|
2141
|
+
_$insertNode(_el$100, _el$106);
|
|
2142
|
+
_$insertNode(_el$101, _el$102);
|
|
2143
|
+
_$insert(_el$101, () => t("barHit"), _el$102);
|
|
2144
|
+
_$insert(_el$103, (() => {
|
|
2145
|
+
var _c$ = _$memo(() => (stats()?.hitRate ?? -1) >= 0);
|
|
2146
|
+
return () => _c$() ? (Math.floor(stats().hitRate * 10) / 10).toFixed(1) + "%" : "--";
|
|
2147
|
+
})());
|
|
2148
|
+
_$insert(_el$100, _$createComponent(Show, {
|
|
2149
|
+
get when() {
|
|
2150
|
+
return trend() !== null;
|
|
2151
|
+
},
|
|
2152
|
+
get children() {
|
|
2153
|
+
var _el$104 = _$createElement("span");
|
|
2154
|
+
_$insert(_el$104, () => " " + (trend() > 0 ? "\u2191" : "\u2193") + Math.abs(trend()).toFixed(1) + "%");
|
|
2155
|
+
_$effect((_$p) => _$setProp(_el$104, "style", {
|
|
2156
|
+
fg: trend() > 0 ? pal().success : pal().error
|
|
2157
|
+
}, _$p));
|
|
2158
|
+
return _el$104;
|
|
2159
|
+
}
|
|
2160
|
+
}), _el$105);
|
|
2161
|
+
_$insert(_el$105, () => " \xB7 " + t("barTok") + " ");
|
|
2162
|
+
_$insert(_el$106, (() => {
|
|
2163
|
+
var _c$2 = _$memo(() => !!stats());
|
|
2164
|
+
return () => _c$2() ? fmtCompact(stats().input + stats().read + stats().write) : "--";
|
|
2165
|
+
})());
|
|
2166
|
+
_$insert(_el$100, _$createComponent(Show, {
|
|
2167
|
+
get when() {
|
|
2168
|
+
return !props.signals.balanceUnsupported();
|
|
2169
|
+
},
|
|
2170
|
+
get children() {
|
|
2171
|
+
return [(() => {
|
|
2172
|
+
var _el$107 = _$createElement("span");
|
|
2173
|
+
_$insert(_el$107, () => " \xB7 " + t("barBal") + " ");
|
|
2174
|
+
_$effect((_$p) => _$setProp(_el$107, "style", {
|
|
2175
|
+
fg: pal().muted
|
|
2176
|
+
}, _$p));
|
|
2177
|
+
return _el$107;
|
|
2178
|
+
})(), (() => {
|
|
2179
|
+
var _el$108 = _$createElement("span");
|
|
2180
|
+
_$insert(_el$108, balanceText);
|
|
2181
|
+
_$effect((_$p) => _$setProp(_el$108, "style", {
|
|
2182
|
+
fg: pal().text
|
|
2183
|
+
}, _$p));
|
|
2184
|
+
return _el$108;
|
|
2185
|
+
})()];
|
|
2186
|
+
}
|
|
2187
|
+
}), null);
|
|
2188
|
+
_$insertNode(_el$109, _$createTextNode(` \xB7 `));
|
|
2189
|
+
_$effect((_p$) => {
|
|
2190
|
+
var _v$31 = pal().muted, _v$32 = {
|
|
2191
|
+
fg: pal().muted
|
|
2192
|
+
}, _v$33 = {
|
|
2193
|
+
fg: hitColor()
|
|
2194
|
+
}, _v$34 = {
|
|
2195
|
+
fg: pal().muted
|
|
2196
|
+
}, _v$35 = {
|
|
2197
|
+
fg: pal().text
|
|
2198
|
+
}, _v$36 = pal().muted;
|
|
2199
|
+
_v$31 !== _p$.e && (_p$.e = _$setProp(_el$98, "fg", _v$31, _p$.e));
|
|
2200
|
+
_v$32 !== _p$.t && (_p$.t = _$setProp(_el$101, "style", _v$32, _p$.t));
|
|
2201
|
+
_v$33 !== _p$.a && (_p$.a = _$setProp(_el$103, "style", _v$33, _p$.a));
|
|
2202
|
+
_v$34 !== _p$.o && (_p$.o = _$setProp(_el$105, "style", _v$34, _p$.o));
|
|
2203
|
+
_v$35 !== _p$.i && (_p$.i = _$setProp(_el$106, "style", _v$35, _p$.i));
|
|
2204
|
+
_v$36 !== _p$.n && (_p$.n = _$setProp(_el$109, "fg", _v$36, _p$.n));
|
|
2205
|
+
return _p$;
|
|
2206
|
+
}, {
|
|
2207
|
+
e: void 0,
|
|
2208
|
+
t: void 0,
|
|
2209
|
+
a: void 0,
|
|
2210
|
+
o: void 0,
|
|
2211
|
+
i: void 0,
|
|
2212
|
+
n: void 0
|
|
2213
|
+
});
|
|
2214
|
+
return _el$97;
|
|
2215
|
+
}
|
|
2216
|
+
});
|
|
2217
|
+
}
|
|
1691
2218
|
function createSidebarSlot(api, signals) {
|
|
1692
2219
|
let lastSlotSid = "";
|
|
1693
2220
|
return {
|
|
@@ -1723,20 +2250,28 @@ var tui = async (api) => {
|
|
|
1723
2250
|
const [sectionDist, setSectionDist] = createSignal(true);
|
|
1724
2251
|
const [sectionSkills, setSectionSkills] = createSignal(true);
|
|
1725
2252
|
const [sectionBalance, setSectionBalance] = createSignal(true);
|
|
2253
|
+
const [sectionBottom, setSectionBottom] = createSignal(true);
|
|
1726
2254
|
const [balanceRefresh, setBalanceRefresh] = createSignal(0);
|
|
1727
2255
|
const [balanceProviderId, setBalanceProviderId] = createSignal("deepseek");
|
|
1728
2256
|
const [autoBalance, setAutoBalance] = createSignal(true);
|
|
2257
|
+
const [balanceUnsupported, setBalanceUnsupported] = createSignal(false);
|
|
1729
2258
|
const [balanceCurrency, setBalanceCurrency] = createSignal("");
|
|
1730
2259
|
const [borderVisible, setBorderVisible] = createSignal(true);
|
|
1731
|
-
const [
|
|
2260
|
+
const [langCode, setLangCode] = createSignal(INIT_LANG);
|
|
1732
2261
|
const [overrideSessionId, setOverrideSessionId] = createSignal(void 0);
|
|
2262
|
+
const [balanceState, setBalanceState] = createSignal({
|
|
2263
|
+
status: "idle",
|
|
2264
|
+
data: null,
|
|
2265
|
+
lastFetch: 0
|
|
2266
|
+
});
|
|
2267
|
+
let balanceSeq = 0;
|
|
1733
2268
|
const signals = {
|
|
1734
2269
|
currencySymbol,
|
|
1735
2270
|
setCurrencySymbol,
|
|
1736
2271
|
exchangeRate,
|
|
1737
2272
|
setExchangeRate,
|
|
1738
|
-
|
|
1739
|
-
|
|
2273
|
+
langCode,
|
|
2274
|
+
setLangCode,
|
|
1740
2275
|
sectionDetail,
|
|
1741
2276
|
setSectionDetail,
|
|
1742
2277
|
sectionModel,
|
|
@@ -1747,12 +2282,17 @@ var tui = async (api) => {
|
|
|
1747
2282
|
setSectionSkills,
|
|
1748
2283
|
sectionBalance,
|
|
1749
2284
|
setSectionBalance,
|
|
2285
|
+
sectionBottom,
|
|
2286
|
+
setSectionBottom,
|
|
1750
2287
|
balanceRefresh,
|
|
1751
2288
|
setBalanceRefresh,
|
|
1752
2289
|
balanceProviderId,
|
|
1753
2290
|
setBalanceProviderId,
|
|
1754
2291
|
autoBalance,
|
|
1755
2292
|
setAutoBalance,
|
|
2293
|
+
balanceUnsupported,
|
|
2294
|
+
setBalanceUnsupported,
|
|
2295
|
+
balanceState,
|
|
1756
2296
|
balanceCurrency,
|
|
1757
2297
|
setBalanceCurrency,
|
|
1758
2298
|
borderVisible,
|
|
@@ -1761,16 +2301,139 @@ var tui = async (api) => {
|
|
|
1761
2301
|
setOverrideSessionId
|
|
1762
2302
|
};
|
|
1763
2303
|
api.slots.register(createSidebarSlot(api, signals));
|
|
2304
|
+
api.slots.register({
|
|
2305
|
+
order: 55,
|
|
2306
|
+
slots: {
|
|
2307
|
+
session_prompt(_ctx, input) {
|
|
2308
|
+
return _$createComponent(api.ui.Prompt, {
|
|
2309
|
+
get sessionID() {
|
|
2310
|
+
return input.session_id;
|
|
2311
|
+
},
|
|
2312
|
+
get visible() {
|
|
2313
|
+
return input.visible;
|
|
2314
|
+
},
|
|
2315
|
+
get disabled() {
|
|
2316
|
+
return input.disabled;
|
|
2317
|
+
},
|
|
2318
|
+
get onSubmit() {
|
|
2319
|
+
return input.on_submit;
|
|
2320
|
+
},
|
|
2321
|
+
ref(r$) {
|
|
2322
|
+
var _ref$2 = input.ref;
|
|
2323
|
+
typeof _ref$2 === "function" ? _ref$2(r$) : input.ref = r$;
|
|
2324
|
+
},
|
|
2325
|
+
get hint() {
|
|
2326
|
+
return _$createComponent(BottomStatusBar, {
|
|
2327
|
+
api,
|
|
2328
|
+
signals,
|
|
2329
|
+
get sessionId() {
|
|
2330
|
+
return input.session_id;
|
|
2331
|
+
}
|
|
2332
|
+
});
|
|
2333
|
+
}
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
});
|
|
1764
2338
|
const KV_PREFIX = "cache_panel";
|
|
2339
|
+
const restoreLang = () => {
|
|
2340
|
+
try {
|
|
2341
|
+
const saved = api.kv.get(`${KV_PREFIX}.lang`);
|
|
2342
|
+
if (saved && LANG_META.some((m) => m.code === saved)) setLangCode(saved);
|
|
2343
|
+
} catch {
|
|
2344
|
+
}
|
|
2345
|
+
};
|
|
2346
|
+
if (api.kv.ready) {
|
|
2347
|
+
restoreLang();
|
|
2348
|
+
} else {
|
|
2349
|
+
const langTimer = setInterval(() => {
|
|
2350
|
+
if (api.kv.ready) {
|
|
2351
|
+
clearInterval(langTimer);
|
|
2352
|
+
restoreLang();
|
|
2353
|
+
}
|
|
2354
|
+
}, 10);
|
|
2355
|
+
api.lifecycle.onDispose(() => clearInterval(langTimer));
|
|
2356
|
+
}
|
|
2357
|
+
const pollBalance = async () => {
|
|
2358
|
+
const provider = getBalanceProvider(balanceProviderId());
|
|
2359
|
+
const key = api.kv.get(`${KV_PREFIX}.balance.${provider.id}.key`, "") || findOpencodeKey(api, provider);
|
|
2360
|
+
if (balanceUnsupported()) {
|
|
2361
|
+
setBalanceState({
|
|
2362
|
+
status: "idle",
|
|
2363
|
+
data: null,
|
|
2364
|
+
lastFetch: 0,
|
|
2365
|
+
error: void 0,
|
|
2366
|
+
key: void 0
|
|
2367
|
+
});
|
|
2368
|
+
return;
|
|
2369
|
+
}
|
|
2370
|
+
if (!key) {
|
|
2371
|
+
setBalanceState({
|
|
2372
|
+
status: "idle",
|
|
2373
|
+
data: null,
|
|
2374
|
+
lastFetch: 0,
|
|
2375
|
+
error: void 0,
|
|
2376
|
+
key: void 0
|
|
2377
|
+
});
|
|
2378
|
+
return;
|
|
2379
|
+
}
|
|
2380
|
+
const now = Date.now();
|
|
2381
|
+
const prev = balanceState();
|
|
2382
|
+
if (prev.status === "ok" && prev.key === key && now - prev.lastFetch < BALANCE_POLL_MS) return;
|
|
2383
|
+
const seq = ++balanceSeq;
|
|
2384
|
+
setBalanceState({
|
|
2385
|
+
...prev,
|
|
2386
|
+
status: "loading",
|
|
2387
|
+
error: void 0,
|
|
2388
|
+
key
|
|
2389
|
+
});
|
|
2390
|
+
const controller = new AbortController();
|
|
2391
|
+
let timedOut = false;
|
|
2392
|
+
const timer = setTimeout(() => {
|
|
2393
|
+
timedOut = true;
|
|
2394
|
+
controller.abort();
|
|
2395
|
+
}, 1e4);
|
|
2396
|
+
try {
|
|
2397
|
+
const data = await provider.fetchBalance(key, controller.signal);
|
|
2398
|
+
clearTimeout(timer);
|
|
2399
|
+
if (seq !== balanceSeq) return;
|
|
2400
|
+
setBalanceState({
|
|
2401
|
+
status: "ok",
|
|
2402
|
+
data,
|
|
2403
|
+
lastFetch: Date.now(),
|
|
2404
|
+
error: void 0,
|
|
2405
|
+
key
|
|
2406
|
+
});
|
|
2407
|
+
} catch (err) {
|
|
2408
|
+
clearTimeout(timer);
|
|
2409
|
+
if (seq !== balanceSeq) return;
|
|
2410
|
+
const code = timedOut ? "TIMEOUT" : err instanceof Error ? err.message : "";
|
|
2411
|
+
setBalanceState({
|
|
2412
|
+
status: "error",
|
|
2413
|
+
data: null,
|
|
2414
|
+
lastFetch: 0,
|
|
2415
|
+
error: code,
|
|
2416
|
+
key
|
|
2417
|
+
});
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
2420
|
+
createEffect(() => {
|
|
2421
|
+
void balanceRefresh();
|
|
2422
|
+
untrack(() => {
|
|
2423
|
+
void pollBalance();
|
|
2424
|
+
});
|
|
2425
|
+
});
|
|
2426
|
+
const balanceTimer = setInterval(pollBalance, BALANCE_POLL_MS);
|
|
2427
|
+
api.lifecycle.onDispose(() => clearInterval(balanceTimer));
|
|
1765
2428
|
const providerOptionTitle = (p, current) => {
|
|
1766
|
-
const
|
|
2429
|
+
const t = createT(() => langCode());
|
|
1767
2430
|
const hasManual = !!api.kv.get(`${KV_PREFIX}.balance.${p.id}.key`, "");
|
|
1768
2431
|
const hasAuto = !hasManual && !!findOpencodeKey(api, p);
|
|
1769
|
-
const mark = hasManual ?
|
|
2432
|
+
const mark = hasManual ? t("keyUser") : hasAuto ? t("keyOpenCode") : t("keyNotSet");
|
|
1770
2433
|
return p.name + mark + (current && p.id === current ? " *" : "");
|
|
1771
2434
|
};
|
|
1772
2435
|
const promptBalanceKey = (dialog, provider) => {
|
|
1773
|
-
const
|
|
2436
|
+
const t = createT(() => langCode());
|
|
1774
2437
|
const current = api.kv.get(`${KV_PREFIX}.balance.${provider.id}.key`, "");
|
|
1775
2438
|
const masked = maskKey(current);
|
|
1776
2439
|
dialog?.replace(() => _$createComponent(api.ui.DialogPrompt, {
|
|
@@ -1778,9 +2441,11 @@ var tui = async (api) => {
|
|
|
1778
2441
|
return provider.name;
|
|
1779
2442
|
},
|
|
1780
2443
|
description: () => (() => {
|
|
1781
|
-
var _el$
|
|
1782
|
-
_$insert(_el$
|
|
1783
|
-
|
|
2444
|
+
var _el$112 = _$createElement("text");
|
|
2445
|
+
_$insert(_el$112, () => t("balKeyPrompt", {
|
|
2446
|
+
p: provider.name
|
|
2447
|
+
}));
|
|
2448
|
+
return _el$112;
|
|
1784
2449
|
})(),
|
|
1785
2450
|
get placeholder() {
|
|
1786
2451
|
return provider.keyPlaceholder ?? "sk-...";
|
|
@@ -1800,11 +2465,11 @@ var tui = async (api) => {
|
|
|
1800
2465
|
setBalanceRefresh((v) => v + 1);
|
|
1801
2466
|
if (key) {
|
|
1802
2467
|
api.ui.toast({
|
|
1803
|
-
message:
|
|
2468
|
+
message: t("keySaved")
|
|
1804
2469
|
});
|
|
1805
2470
|
} else {
|
|
1806
2471
|
api.ui.toast({
|
|
1807
|
-
message:
|
|
2472
|
+
message: t("keyCleared")
|
|
1808
2473
|
});
|
|
1809
2474
|
}
|
|
1810
2475
|
dialog?.clear();
|
|
@@ -1829,6 +2494,7 @@ var tui = async (api) => {
|
|
|
1829
2494
|
}));
|
|
1830
2495
|
},
|
|
1831
2496
|
onSelect: (opt) => {
|
|
2497
|
+
const t = createT(() => langCode());
|
|
1832
2498
|
const sym = CURRENCIES[opt.value] ?? "$";
|
|
1833
2499
|
const defRate = DEFAULT_RATES[opt.value] ?? 1;
|
|
1834
2500
|
api.kv.set(`${KV_PREFIX}.currency`, sym);
|
|
@@ -1838,7 +2504,11 @@ var tui = async (api) => {
|
|
|
1838
2504
|
signals.setCurrencySymbol(sym);
|
|
1839
2505
|
signals.setExchangeRate(defRate);
|
|
1840
2506
|
api.ui.toast({
|
|
1841
|
-
message:
|
|
2507
|
+
message: t("currencySet", {
|
|
2508
|
+
v: opt.value,
|
|
2509
|
+
s: sym,
|
|
2510
|
+
r: defRate
|
|
2511
|
+
})
|
|
1842
2512
|
});
|
|
1843
2513
|
dialog?.clear();
|
|
1844
2514
|
}
|
|
@@ -1855,21 +2525,24 @@ var tui = async (api) => {
|
|
|
1855
2525
|
dialog?.replace(() => _$createComponent(api.ui.DialogPrompt, {
|
|
1856
2526
|
title: "Exchange Rate",
|
|
1857
2527
|
description: () => (() => {
|
|
1858
|
-
var _el$
|
|
1859
|
-
_$insertNode(_el$
|
|
1860
|
-
return _el$
|
|
2528
|
+
var _el$113 = _$createElement("text");
|
|
2529
|
+
_$insertNode(_el$113, _$createTextNode(`Enter the exchange rate from USD to your currency (e.g. 7.2 for CNY)`));
|
|
2530
|
+
return _el$113;
|
|
1861
2531
|
})(),
|
|
1862
2532
|
placeholder: "1.0",
|
|
1863
2533
|
get value() {
|
|
1864
2534
|
return String(api.kv.get(`${KV_PREFIX}.rate`, 1));
|
|
1865
2535
|
},
|
|
1866
2536
|
onConfirm: (val) => {
|
|
2537
|
+
const t = createT(() => langCode());
|
|
1867
2538
|
const n = parseFloat(val);
|
|
1868
2539
|
if (n > 0) {
|
|
1869
2540
|
api.kv.set(`${KV_PREFIX}.rate`, n);
|
|
1870
2541
|
signals.setExchangeRate(n);
|
|
1871
2542
|
api.ui.toast({
|
|
1872
|
-
message:
|
|
2543
|
+
message: t("rateSet", {
|
|
2544
|
+
r: n
|
|
2545
|
+
})
|
|
1873
2546
|
});
|
|
1874
2547
|
}
|
|
1875
2548
|
dialog?.clear();
|
|
@@ -1884,40 +2557,59 @@ var tui = async (api) => {
|
|
|
1884
2557
|
name: "cache-section"
|
|
1885
2558
|
},
|
|
1886
2559
|
onSelect: (dialog) => {
|
|
2560
|
+
const t = createT(() => langCode());
|
|
1887
2561
|
const detailOn = Boolean(api.kv.get(`${KV_PREFIX}.section.detail`, true));
|
|
1888
2562
|
const modelOn = Boolean(api.kv.get(`${KV_PREFIX}.section.model`, true));
|
|
1889
2563
|
const distOn = Boolean(api.kv.get(`${KV_PREFIX}.section.dist`, true));
|
|
1890
2564
|
const skillsOn = Boolean(api.kv.get(`${KV_PREFIX}.section.skills`, true));
|
|
1891
2565
|
const balanceOn = Boolean(api.kv.get(`${KV_PREFIX}.section.balance`, true));
|
|
2566
|
+
const bottomOn = Boolean(api.kv.get(`${KV_PREFIX}.section.bottom`, true));
|
|
1892
2567
|
const borderOn = Boolean(api.kv.get(`${KV_PREFIX}.border`, true));
|
|
2568
|
+
const labels = {
|
|
2569
|
+
detail: t("secDetail"),
|
|
2570
|
+
model: t("secModel"),
|
|
2571
|
+
dist: t("distTitle"),
|
|
2572
|
+
skills: t("secSkills"),
|
|
2573
|
+
balance: t("secBalance"),
|
|
2574
|
+
bottom: t("secBottom"),
|
|
2575
|
+
border: t("secBorder")
|
|
2576
|
+
};
|
|
2577
|
+
const optTitle = (label, on) => `${visualPadEnd(label, 15)}[${on ? "ON" : "OFF"}]`;
|
|
1893
2578
|
dialog?.replace(() => _$createComponent(api.ui.DialogSelect, {
|
|
1894
|
-
title
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
2579
|
+
get title() {
|
|
2580
|
+
return t("secToggle");
|
|
2581
|
+
},
|
|
2582
|
+
get options() {
|
|
2583
|
+
return [{
|
|
2584
|
+
title: optTitle(labels.detail, detailOn),
|
|
2585
|
+
value: "detail"
|
|
2586
|
+
}, {
|
|
2587
|
+
title: optTitle(labels.model, modelOn),
|
|
2588
|
+
value: "model"
|
|
2589
|
+
}, {
|
|
2590
|
+
title: optTitle(labels.dist, distOn),
|
|
2591
|
+
value: "dist"
|
|
2592
|
+
}, {
|
|
2593
|
+
title: optTitle(labels.skills, skillsOn),
|
|
2594
|
+
value: "skills"
|
|
2595
|
+
}, {
|
|
2596
|
+
title: optTitle(labels.balance, balanceOn),
|
|
2597
|
+
value: "balance"
|
|
2598
|
+
}, {
|
|
2599
|
+
title: optTitle(labels.bottom, bottomOn),
|
|
2600
|
+
value: "bottom"
|
|
2601
|
+
}, {
|
|
2602
|
+
title: optTitle(labels.border, borderOn),
|
|
2603
|
+
value: "border"
|
|
2604
|
+
}];
|
|
2605
|
+
},
|
|
1914
2606
|
onSelect: (opt) => {
|
|
1915
2607
|
if (opt.value === "border") {
|
|
1916
2608
|
const cur = Boolean(api.kv.get(`${KV_PREFIX}.border`, true));
|
|
1917
2609
|
api.kv.set(`${KV_PREFIX}.border`, !cur);
|
|
1918
2610
|
signals.setBorderVisible(!cur);
|
|
1919
2611
|
api.ui.toast({
|
|
1920
|
-
message:
|
|
2612
|
+
message: !cur ? t("borderShown") : t("borderHidden")
|
|
1921
2613
|
});
|
|
1922
2614
|
} else {
|
|
1923
2615
|
const key = `${KV_PREFIX}.section.${opt.value}`;
|
|
@@ -1928,8 +2620,12 @@ var tui = async (api) => {
|
|
|
1928
2620
|
if (opt.value === "dist") signals.setSectionDist(!cur);
|
|
1929
2621
|
if (opt.value === "skills") signals.setSectionSkills(!cur);
|
|
1930
2622
|
if (opt.value === "balance") signals.setSectionBalance(!cur);
|
|
2623
|
+
if (opt.value === "bottom") signals.setSectionBottom(!cur);
|
|
2624
|
+
const name = labels[opt.value] ?? opt.value;
|
|
1931
2625
|
api.ui.toast({
|
|
1932
|
-
message:
|
|
2626
|
+
message: t(!cur ? "sectionShown" : "sectionHidden", {
|
|
2627
|
+
s: name
|
|
2628
|
+
})
|
|
1933
2629
|
});
|
|
1934
2630
|
}
|
|
1935
2631
|
dialog?.clear();
|
|
@@ -1944,6 +2640,7 @@ var tui = async (api) => {
|
|
|
1944
2640
|
name: "cache-config"
|
|
1945
2641
|
},
|
|
1946
2642
|
onSelect: (dialog) => {
|
|
2643
|
+
const t = createT(() => langCode());
|
|
1947
2644
|
const sym = api.kv.get(`${KV_PREFIX}.currency`) ?? "$";
|
|
1948
2645
|
const rate = api.kv.get(`${KV_PREFIX}.rate`) ?? 1;
|
|
1949
2646
|
const detail = Boolean(api.kv.get(`${KV_PREFIX}.section.detail`, true));
|
|
@@ -1951,9 +2648,20 @@ var tui = async (api) => {
|
|
|
1951
2648
|
const dist = Boolean(api.kv.get(`${KV_PREFIX}.section.dist`, true));
|
|
1952
2649
|
const skills = Boolean(api.kv.get(`${KV_PREFIX}.section.skills`, true));
|
|
1953
2650
|
const balance = Boolean(api.kv.get(`${KV_PREFIX}.section.balance`, true));
|
|
2651
|
+
const bottom = Boolean(api.kv.get(`${KV_PREFIX}.section.bottom`, true));
|
|
2652
|
+
const on = (v) => v ? "ON" : "OFF";
|
|
1954
2653
|
api.ui.toast({
|
|
1955
|
-
title: "
|
|
1956
|
-
message:
|
|
2654
|
+
title: t("panelConfigTitle"),
|
|
2655
|
+
message: t("panelConfigMsg", {
|
|
2656
|
+
c: sym,
|
|
2657
|
+
r: rate,
|
|
2658
|
+
d: on(detail),
|
|
2659
|
+
m: on(model),
|
|
2660
|
+
t: on(dist),
|
|
2661
|
+
k: on(skills),
|
|
2662
|
+
b: on(balance),
|
|
2663
|
+
f: on(bottom)
|
|
2664
|
+
}),
|
|
1957
2665
|
duration: 8e3
|
|
1958
2666
|
});
|
|
1959
2667
|
dialog?.clear();
|
|
@@ -1966,22 +2674,24 @@ var tui = async (api) => {
|
|
|
1966
2674
|
name: "cache-lang"
|
|
1967
2675
|
},
|
|
1968
2676
|
onSelect: (dialog) => {
|
|
1969
|
-
const
|
|
2677
|
+
const t = createT(() => langCode());
|
|
2678
|
+
const cur = langCode();
|
|
1970
2679
|
dialog?.replace(() => _$createComponent(api.ui.DialogSelect, {
|
|
1971
|
-
title
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2680
|
+
get title() {
|
|
2681
|
+
return t("langTitle");
|
|
2682
|
+
},
|
|
2683
|
+
get options() {
|
|
2684
|
+
return LANG_META.map((m) => ({
|
|
2685
|
+
title: `${visualPadEnd(m.label, 9)}${cur === m.code ? "\u2713" : ""}`,
|
|
2686
|
+
value: m.code
|
|
2687
|
+
}));
|
|
2688
|
+
},
|
|
1979
2689
|
onSelect: (opt) => {
|
|
1980
|
-
const
|
|
1981
|
-
api.kv.set(`${KV_PREFIX}.lang`,
|
|
1982
|
-
|
|
2690
|
+
const code = opt.value;
|
|
2691
|
+
api.kv.set(`${KV_PREFIX}.lang`, code);
|
|
2692
|
+
setLangCode(code);
|
|
1983
2693
|
api.ui.toast({
|
|
1984
|
-
message:
|
|
2694
|
+
message: t("langSwitched")
|
|
1985
2695
|
});
|
|
1986
2696
|
dialog?.clear();
|
|
1987
2697
|
}
|
|
@@ -1995,12 +2705,14 @@ var tui = async (api) => {
|
|
|
1995
2705
|
name: "cache-balance"
|
|
1996
2706
|
},
|
|
1997
2707
|
onSelect: (dialog) => {
|
|
1998
|
-
const
|
|
2708
|
+
const t = createT(() => langCode());
|
|
1999
2709
|
const current = signals.balanceProviderId();
|
|
2000
2710
|
const auto = signals.autoBalance();
|
|
2001
|
-
const autoLabel =
|
|
2711
|
+
const autoLabel = `${t("autoSwitchOpt")} [${auto ? "ON" : "OFF"}]`;
|
|
2002
2712
|
dialog?.replace(() => _$createComponent(api.ui.DialogSelect, {
|
|
2003
|
-
title
|
|
2713
|
+
get title() {
|
|
2714
|
+
return t("balProvTitle");
|
|
2715
|
+
},
|
|
2004
2716
|
get options() {
|
|
2005
2717
|
return [{
|
|
2006
2718
|
title: autoLabel,
|
|
@@ -2016,7 +2728,7 @@ var tui = async (api) => {
|
|
|
2016
2728
|
api.kv.set(`${KV_PREFIX}.balance.auto`, next);
|
|
2017
2729
|
signals.setAutoBalance(next);
|
|
2018
2730
|
api.ui.toast({
|
|
2019
|
-
message:
|
|
2731
|
+
message: next ? t("autoSwitchOn") : t("autoSwitchOff")
|
|
2020
2732
|
});
|
|
2021
2733
|
dialog?.clear();
|
|
2022
2734
|
} else {
|
|
@@ -2025,13 +2737,16 @@ var tui = async (api) => {
|
|
|
2025
2737
|
api.kv.set(`${KV_PREFIX}.balance.auto`, false);
|
|
2026
2738
|
signals.setBalanceProviderId(provider.id);
|
|
2027
2739
|
signals.setAutoBalance(false);
|
|
2740
|
+
signals.setBalanceUnsupported(false);
|
|
2028
2741
|
signals.setBalanceRefresh(signals.balanceRefresh() + 1);
|
|
2029
2742
|
const hasKey = !!api.kv.get(`${KV_PREFIX}.balance.${provider.id}.key`, "");
|
|
2030
2743
|
if (!hasKey) {
|
|
2031
2744
|
promptBalanceKey(dialog, provider);
|
|
2032
2745
|
} else {
|
|
2033
2746
|
api.ui.toast({
|
|
2034
|
-
message:
|
|
2747
|
+
message: t("providerManual", {
|
|
2748
|
+
p: provider.name
|
|
2749
|
+
})
|
|
2035
2750
|
});
|
|
2036
2751
|
dialog?.clear();
|
|
2037
2752
|
}
|
|
@@ -2047,9 +2762,11 @@ var tui = async (api) => {
|
|
|
2047
2762
|
name: "cache-balance-key"
|
|
2048
2763
|
},
|
|
2049
2764
|
onSelect: (dialog) => {
|
|
2050
|
-
const
|
|
2765
|
+
const t = createT(() => langCode());
|
|
2051
2766
|
dialog?.replace(() => _$createComponent(api.ui.DialogSelect, {
|
|
2052
|
-
title
|
|
2767
|
+
get title() {
|
|
2768
|
+
return t("balSelectTitle");
|
|
2769
|
+
},
|
|
2053
2770
|
get options() {
|
|
2054
2771
|
return balanceProviders.map((p) => ({
|
|
2055
2772
|
title: providerOptionTitle(p),
|
|
@@ -2075,10 +2792,11 @@ var tui = async (api) => {
|
|
|
2075
2792
|
name: "cache-debug-skills"
|
|
2076
2793
|
},
|
|
2077
2794
|
onSelect: () => {
|
|
2795
|
+
const t = createT(() => langCode());
|
|
2078
2796
|
const rt = api.route.current;
|
|
2079
2797
|
if (rt.name !== "session" || !rt.params) {
|
|
2080
2798
|
api.ui.toast({
|
|
2081
|
-
message: "
|
|
2799
|
+
message: t("runInSession"),
|
|
2082
2800
|
variant: "warning"
|
|
2083
2801
|
});
|
|
2084
2802
|
return;
|
|
@@ -2096,9 +2814,9 @@ var tui = async (api) => {
|
|
|
2096
2814
|
}
|
|
2097
2815
|
for (const p of parts) {
|
|
2098
2816
|
if (p.type === "tool") {
|
|
2099
|
-
const
|
|
2100
|
-
byTool[
|
|
2101
|
-
if (
|
|
2817
|
+
const t2 = String(p.tool ?? "?");
|
|
2818
|
+
byTool[t2] = (byTool[t2] ?? 0) + 1;
|
|
2819
|
+
if (t2 === "skill") {
|
|
2102
2820
|
const meta = p.state?.metadata;
|
|
2103
2821
|
const rootMeta = p.metadata;
|
|
2104
2822
|
skillParts.push(`state.metadata=${JSON.stringify(meta)} | root.metadata=${JSON.stringify(rootMeta)} | state.title="${p.state?.title}" | state.output[:80]="${String(p.state?.output ?? "").slice(0, 80)}"`);
|
|
@@ -2167,7 +2885,7 @@ var tui = async (api) => {
|
|
|
2167
2885
|
return true;
|
|
2168
2886
|
});
|
|
2169
2887
|
if (unique.length > 0) {
|
|
2170
|
-
const
|
|
2888
|
+
const t = createT(() => langCode());
|
|
2171
2889
|
const currentSid = signals.overrideSessionId() ?? api.kv.get(`${KV_PREFIX}.session`, "");
|
|
2172
2890
|
const options = unique.map((c, i) => ({
|
|
2173
2891
|
title: `${i + 1}. ${c.title}`,
|
|
@@ -2175,7 +2893,7 @@ var tui = async (api) => {
|
|
|
2175
2893
|
description: c.description
|
|
2176
2894
|
}));
|
|
2177
2895
|
const backValue = "__main__";
|
|
2178
|
-
const backTitle = `\u2500 ${
|
|
2896
|
+
const backTitle = `\u2500 ${t("backToMainTitle")}`;
|
|
2179
2897
|
options.unshift({
|
|
2180
2898
|
title: backTitle,
|
|
2181
2899
|
value: backValue,
|
|
@@ -2188,7 +2906,9 @@ var tui = async (api) => {
|
|
|
2188
2906
|
});
|
|
2189
2907
|
const currentIdx = currentSid ? options.findIndex((o) => o.value === currentSid) : -1;
|
|
2190
2908
|
dialog?.replace(() => _$createComponent(api.ui.DialogSelect, {
|
|
2191
|
-
title
|
|
2909
|
+
get title() {
|
|
2910
|
+
return t("subSelectTitle");
|
|
2911
|
+
},
|
|
2192
2912
|
options,
|
|
2193
2913
|
get current() {
|
|
2194
2914
|
return currentIdx >= 0 ? options[currentIdx].value : void 0;
|
|
@@ -2198,28 +2918,30 @@ var tui = async (api) => {
|
|
|
2198
2918
|
signals.setOverrideSessionId(void 0);
|
|
2199
2919
|
api.kv.set(`${KV_PREFIX}.session`, "");
|
|
2200
2920
|
api.ui.toast({
|
|
2201
|
-
message:
|
|
2921
|
+
message: t("backToMain")
|
|
2202
2922
|
});
|
|
2203
2923
|
} else {
|
|
2204
2924
|
signals.setOverrideSessionId(opt.value);
|
|
2205
2925
|
api.kv.set(`${KV_PREFIX}.session`, opt.value);
|
|
2206
2926
|
api.ui.toast({
|
|
2207
|
-
message: (
|
|
2927
|
+
message: t("subAgentSwitched", {
|
|
2928
|
+
s: opt.value.slice(0, 24) + "\u2026"
|
|
2929
|
+
})
|
|
2208
2930
|
});
|
|
2209
2931
|
}
|
|
2210
2932
|
dialog?.clear();
|
|
2211
2933
|
}
|
|
2212
2934
|
}));
|
|
2213
2935
|
} else {
|
|
2214
|
-
const
|
|
2936
|
+
const t = createT(() => langCode());
|
|
2215
2937
|
dialog?.replace(() => _$createComponent(api.ui.DialogPrompt, {
|
|
2216
2938
|
get title() {
|
|
2217
|
-
return signals.overrideSessionId() ?
|
|
2939
|
+
return _$memo(() => !!signals.overrideSessionId())() ? t("subSwitchTitle") : t("subViewTitle");
|
|
2218
2940
|
},
|
|
2219
2941
|
description: () => (() => {
|
|
2220
|
-
var _el$
|
|
2221
|
-
_$insert(_el$
|
|
2222
|
-
return _el$
|
|
2942
|
+
var _el$115 = _$createElement("text");
|
|
2943
|
+
_$insert(_el$115, () => t("subNoFound"));
|
|
2944
|
+
return _el$115;
|
|
2223
2945
|
})(),
|
|
2224
2946
|
placeholder: "ses_...",
|
|
2225
2947
|
get value() {
|
|
@@ -2231,7 +2953,9 @@ var tui = async (api) => {
|
|
|
2231
2953
|
signals.setOverrideSessionId(sid);
|
|
2232
2954
|
api.kv.set(`${KV_PREFIX}.session`, sid);
|
|
2233
2955
|
api.ui.toast({
|
|
2234
|
-
message: (
|
|
2956
|
+
message: t("subAgentSwitched", {
|
|
2957
|
+
s: sid.slice(0, 24) + "\u2026"
|
|
2958
|
+
})
|
|
2235
2959
|
});
|
|
2236
2960
|
}
|
|
2237
2961
|
dialog?.clear();
|
|
@@ -2248,10 +2972,11 @@ var tui = async (api) => {
|
|
|
2248
2972
|
name: "cache-session-back"
|
|
2249
2973
|
},
|
|
2250
2974
|
onSelect: (dialog) => {
|
|
2975
|
+
const t = createT(() => langCode());
|
|
2251
2976
|
signals.setOverrideSessionId(void 0);
|
|
2252
2977
|
api.kv.set(`${KV_PREFIX}.session`, "");
|
|
2253
2978
|
api.ui.toast({
|
|
2254
|
-
message:
|
|
2979
|
+
message: t("backToMain")
|
|
2255
2980
|
});
|
|
2256
2981
|
dialog?.clear();
|
|
2257
2982
|
}
|