@chenlongapps/opencode-token-usage 0.4.8 → 0.4.9
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 +13 -9
- package/README.zh-CN.md +13 -9
- package/ROADMAP.md +6 -2
- package/dist/click.d.ts +9 -0
- package/dist/click.js +20 -0
- package/dist/context-rpc.d.ts +11 -0
- package/dist/context-rpc.js +6 -0
- package/dist/controller.d.ts +14 -1
- package/dist/controller.js +74 -6
- package/dist/index.js +1 -0
- package/dist/performance.d.ts +8 -3
- package/dist/performance.js +77 -23
- package/dist/runtime-monitor.d.ts +34 -0
- package/dist/runtime-monitor.js +155 -0
- package/dist/runtime.d.ts +15 -0
- package/dist/runtime.js +34 -3
- package/dist/tui.js +250 -203
- package/dist/usage.d.ts +3 -2
- package/dist/usage.js +16 -7
- package/docs/verification.md +112 -0
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { memo as _$memo } from "@opentui/solid";
|
|
2
2
|
import { use as _$use } from "@opentui/solid";
|
|
3
|
+
import { effect as _$effect } from "@opentui/solid";
|
|
3
4
|
import { insert as _$insert } from "@opentui/solid";
|
|
4
5
|
import { createComponent as _$createComponent } from "@opentui/solid";
|
|
5
|
-
import { effect as _$effect } from "@opentui/solid";
|
|
6
6
|
import { createTextNode as _$createTextNode } from "@opentui/solid";
|
|
7
7
|
import { insertNode as _$insertNode } from "@opentui/solid";
|
|
8
|
+
import { spread as _$spread } from "@opentui/solid";
|
|
9
|
+
import { mergeProps as _$mergeProps } from "@opentui/solid";
|
|
8
10
|
import { setProp as _$setProp } from "@opentui/solid";
|
|
9
11
|
import { createElement as _$createElement } from "@opentui/solid";
|
|
10
12
|
import { Plugin } from "@opencode/plugin/tui";
|
|
@@ -12,10 +14,14 @@ import { useTerminalDimensions } from "@opentui/solid";
|
|
|
12
14
|
import { createEffect, createMemo, createSignal, For, onCleanup, Show } from "solid-js";
|
|
13
15
|
import { UsageController } from "./controller.js";
|
|
14
16
|
import { PerformanceMonitor } from "./performance.js";
|
|
17
|
+
import { RuntimeMonitor } from "./runtime-monitor.js";
|
|
18
|
+
import { ContextSourceRpc } from "./context-rpc.js";
|
|
15
19
|
import { breakdownRows } from "./context-sources.js";
|
|
20
|
+
import { createClickHandlers } from "./click.js";
|
|
16
21
|
import { createSource } from "./source.js";
|
|
17
22
|
import { bar, countLabel, fitUsageSummary, formatCompact, formatEstimatedCost, formatRateTier, formatRunTime, formatTokens, rateRows, requestRows, summaryRows, usageRows } from "./usage.js";
|
|
18
23
|
function UsageView(props) {
|
|
24
|
+
const titleClick = createClickHandlers(() => props.openDetails?.(), () => !!props.context.renderer.getSelection()?.getSelectedText());
|
|
19
25
|
const rows = createMemo(() => usageRows(props.state().summary, props.state().context, props.state().performance, props.state().runtime));
|
|
20
26
|
const performanceStart = createMemo(() => rows().findIndex(([label]) => label === "Run Time" || label === "TPS" || label === "TTFT"));
|
|
21
27
|
const status = () => ({
|
|
@@ -36,8 +42,12 @@ function UsageView(props) {
|
|
|
36
42
|
var _el$2 = _$createElement("text"),
|
|
37
43
|
_el$3 = _$createElement("b");
|
|
38
44
|
_$insertNode(_el$2, _el$3);
|
|
45
|
+
_$spread(_el$2, _$mergeProps({
|
|
46
|
+
get fg() {
|
|
47
|
+
return props.context.theme.text.base;
|
|
48
|
+
}
|
|
49
|
+
}, titleClick), true);
|
|
39
50
|
_$insertNode(_el$3, _$createTextNode(`Token Usage`));
|
|
40
|
-
_$effect(_$p => _$setProp(_el$2, "fg", props.context.theme.text.base, _$p));
|
|
41
51
|
return _el$2;
|
|
42
52
|
}
|
|
43
53
|
}), null);
|
|
@@ -92,9 +102,12 @@ function UsagePanel(props) {
|
|
|
92
102
|
});
|
|
93
103
|
const controller = new UsageController(createSource(props.context.client), listener => props.context.data.listen(({
|
|
94
104
|
details
|
|
95
|
-
}) => listener(details)), setState, 80, 3_000, 100, props.performance);
|
|
105
|
+
}) => listener(details)), setState, 80, 3_000, 100, props.performance, false, props.runtime);
|
|
96
106
|
const unregister = props.register(controller);
|
|
97
|
-
createEffect(() =>
|
|
107
|
+
createEffect(() => {
|
|
108
|
+
controller.select(props.sessionID);
|
|
109
|
+
controller.setRunning(props.context.data.session.status(props.sessionID) === "running");
|
|
110
|
+
});
|
|
98
111
|
onCleanup(() => {
|
|
99
112
|
controller.dispose();
|
|
100
113
|
unregister();
|
|
@@ -103,7 +116,8 @@ function UsagePanel(props) {
|
|
|
103
116
|
get context() {
|
|
104
117
|
return props.context;
|
|
105
118
|
},
|
|
106
|
-
state: state
|
|
119
|
+
state: state,
|
|
120
|
+
openDetails: () => props.open(props.sessionID)
|
|
107
121
|
});
|
|
108
122
|
}
|
|
109
123
|
function ChildUsageDialog(props) {
|
|
@@ -200,14 +214,18 @@ function ChildUsageLauncher(props) {
|
|
|
200
214
|
});
|
|
201
215
|
const controller = new UsageController(createSource(props.context.client), listener => props.context.data.listen(({
|
|
202
216
|
details
|
|
203
|
-
}) => listener(details)), setState, 80, 3_000, 100, props.performance);
|
|
217
|
+
}) => listener(details)), setState, 80, 3_000, 100, props.performance, false, props.runtime);
|
|
204
218
|
const unregister = props.register(controller);
|
|
205
|
-
createEffect(() =>
|
|
219
|
+
createEffect(() => {
|
|
220
|
+
controller.select(props.sessionID);
|
|
221
|
+
controller.setRunning(props.context.data.session.status(props.sessionID) === "running");
|
|
222
|
+
});
|
|
206
223
|
onCleanup(() => {
|
|
207
224
|
controller.dispose();
|
|
208
225
|
unregister();
|
|
209
226
|
});
|
|
210
227
|
const dimensions = useTerminalDimensions();
|
|
228
|
+
const runtime = createMemo(() => formatRunTime(state().runtime, true));
|
|
211
229
|
const summary = createMemo(() => {
|
|
212
230
|
const current = state();
|
|
213
231
|
if (!current.summary) return `Token Usage · ${{
|
|
@@ -219,7 +237,7 @@ function ChildUsageLauncher(props) {
|
|
|
219
237
|
const context = current.context ? `${formatTokens(current.context.used)} / ${formatTokens(current.context.limit)} (${current.context.percent.toFixed(1)}%)` : "—";
|
|
220
238
|
const cost = formatEstimatedCost(current.summary.cost, current.summary.costStatus) ?? "—";
|
|
221
239
|
const tps = current.performance?.tps !== undefined && Number.isFinite(current.performance.tps) ? `${current.performance.tpsEstimated ? "~" : ""}${Math.max(0, current.performance.tps).toFixed(1)} tok/s` : "—";
|
|
222
|
-
return fitUsageSummary([["Context", context], ["Total", formatTokens(current.summary.total)], ["Cost", cost], ["Time",
|
|
240
|
+
return fitUsageSummary([["Context", context], ["Total", formatTokens(current.summary.total)], ["Cost", cost], ["Time", runtime()], ["TPS", tps]], Math.max(20, dimensions().width - 8), current.status === "stale");
|
|
223
241
|
});
|
|
224
242
|
return (() => {
|
|
225
243
|
var _el$17 = _$createElement("box"),
|
|
@@ -231,7 +249,7 @@ function ChildUsageLauncher(props) {
|
|
|
231
249
|
_$setProp(_el$17, "flexShrink", 0);
|
|
232
250
|
_$setProp(_el$18, "wrapMode", "none");
|
|
233
251
|
_$setProp(_el$18, "onMouseUp", event => {
|
|
234
|
-
if (event.button === 0) props.open(
|
|
252
|
+
if (event.button === 0) props.open(state);
|
|
235
253
|
});
|
|
236
254
|
_$insert(_el$18, summary);
|
|
237
255
|
_$effect(_$p => _$setProp(_el$18, "fg", props.context.theme.text.muted, _$p));
|
|
@@ -246,9 +264,10 @@ function UsageDialog(props) {
|
|
|
246
264
|
const dimensions = useTerminalDimensions();
|
|
247
265
|
const controller = new UsageController(createSource(props.context.client), listener => props.context.data.listen(({
|
|
248
266
|
details
|
|
249
|
-
}) => listener(details)), setState, 80, 3_000, 100, props.performance, true);
|
|
267
|
+
}) => listener(details)), setState, 80, 3_000, 100, props.performance, true, props.runtime);
|
|
250
268
|
const unregister = props.register(controller);
|
|
251
269
|
controller.select(props.sessionID);
|
|
270
|
+
createEffect(() => controller.setRunning(props.context.data.session.status(props.sessionID) === "running"));
|
|
252
271
|
onCleanup(() => {
|
|
253
272
|
controller.dispose();
|
|
254
273
|
unregister();
|
|
@@ -298,6 +317,7 @@ function UsageDialog(props) {
|
|
|
298
317
|
}));
|
|
299
318
|
const theme = () => props.context.theme.text;
|
|
300
319
|
const context = createMemo(() => state().context);
|
|
320
|
+
const runtime = createMemo(() => formatRunTime(state().runtime));
|
|
301
321
|
const request = createMemo(() => state().details?.request);
|
|
302
322
|
const requestTime = createMemo(() => {
|
|
303
323
|
const time = request()?.time;
|
|
@@ -405,12 +425,12 @@ function UsageDialog(props) {
|
|
|
405
425
|
_el$30 = _$createElement("text"),
|
|
406
426
|
_el$31 = _$createElement("b"),
|
|
407
427
|
_el$33 = _$createElement("text"),
|
|
408
|
-
_el$
|
|
409
|
-
_el$
|
|
410
|
-
_el$
|
|
411
|
-
_el$
|
|
428
|
+
_el$63 = _$createElement("box"),
|
|
429
|
+
_el$64 = _$createElement("text"),
|
|
430
|
+
_el$66 = _$createElement("text"),
|
|
431
|
+
_el$68 = _$createElement("text");
|
|
412
432
|
_$insertNode(_el$28, _el$29);
|
|
413
|
-
_$insertNode(_el$28, _el$
|
|
433
|
+
_$insertNode(_el$28, _el$63);
|
|
414
434
|
_$setProp(_el$28, "paddingLeft", 2);
|
|
415
435
|
_$setProp(_el$28, "paddingRight", 2);
|
|
416
436
|
_$setProp(_el$28, "paddingBottom", 1);
|
|
@@ -435,7 +455,7 @@ function UsageDialog(props) {
|
|
|
435
455
|
_$effect(_$p => _$setProp(_el$35, "fg", theme().muted, _$p));
|
|
436
456
|
return _el$35;
|
|
437
457
|
}
|
|
438
|
-
}), _el$
|
|
458
|
+
}), _el$63);
|
|
439
459
|
_$insert(_el$28, _$createComponent(Show, {
|
|
440
460
|
get when() {
|
|
441
461
|
return state().status !== "ready";
|
|
@@ -446,7 +466,7 @@ function UsageDialog(props) {
|
|
|
446
466
|
_$effect(_$p => _$setProp(_el$36, "fg", theme().muted, _$p));
|
|
447
467
|
return _el$36;
|
|
448
468
|
}
|
|
449
|
-
}), _el$
|
|
469
|
+
}), _el$63);
|
|
450
470
|
_$insert(_el$28, _$createComponent(Show, {
|
|
451
471
|
get when() {
|
|
452
472
|
return state().summary;
|
|
@@ -470,10 +490,7 @@ function UsageDialog(props) {
|
|
|
470
490
|
_el$55 = _$createElement("b"),
|
|
471
491
|
_el$57 = _$createElement("box"),
|
|
472
492
|
_el$58 = _$createElement("text"),
|
|
473
|
-
_el$
|
|
474
|
-
_el$61 = _$createElement("box"),
|
|
475
|
-
_el$62 = _$createElement("text"),
|
|
476
|
-
_el$63 = _$createElement("b");
|
|
493
|
+
_el$59 = _$createElement("b");
|
|
477
494
|
_$insertNode(_el$37, _el$38);
|
|
478
495
|
_$use(value => {
|
|
479
496
|
scroll = value;
|
|
@@ -488,7 +505,7 @@ function UsageDialog(props) {
|
|
|
488
505
|
_$insertNode(_el$38, _el$43);
|
|
489
506
|
_$insertNode(_el$38, _el$48);
|
|
490
507
|
_$insertNode(_el$38, _el$53);
|
|
491
|
-
_$insertNode(_el$38, _el$
|
|
508
|
+
_$insertNode(_el$38, _el$57);
|
|
492
509
|
_$setProp(_el$38, "gap", 1);
|
|
493
510
|
_$insertNode(_el$39, _el$40);
|
|
494
511
|
_$insertNode(_el$40, _el$41);
|
|
@@ -499,48 +516,48 @@ function UsageDialog(props) {
|
|
|
499
516
|
},
|
|
500
517
|
get fallback() {
|
|
501
518
|
return (() => {
|
|
502
|
-
var _el$
|
|
503
|
-
_$insertNode(_el$
|
|
504
|
-
_$effect(_$p => _$setProp(_el$
|
|
505
|
-
return _el$
|
|
519
|
+
var _el$70 = _$createElement("text");
|
|
520
|
+
_$insertNode(_el$70, _$createTextNode(`Context usage unavailable`));
|
|
521
|
+
_$effect(_$p => _$setProp(_el$70, "fg", theme().muted, _$p));
|
|
522
|
+
return _el$70;
|
|
506
523
|
})();
|
|
507
524
|
},
|
|
508
525
|
children: details => (() => {
|
|
509
|
-
var _el$
|
|
510
|
-
_el$
|
|
511
|
-
_el$
|
|
512
|
-
_el$
|
|
513
|
-
_el$
|
|
514
|
-
_el$
|
|
515
|
-
_el$
|
|
526
|
+
var _el$72 = _$createElement("box"),
|
|
527
|
+
_el$73 = _$createElement("box"),
|
|
528
|
+
_el$74 = _$createElement("text"),
|
|
529
|
+
_el$76 = _$createElement("text"),
|
|
530
|
+
_el$77 = _$createTextNode(` / `),
|
|
531
|
+
_el$78 = _$createTextNode(` (`),
|
|
532
|
+
_el$79 = _$createTextNode(`%)`);
|
|
533
|
+
_$insertNode(_el$72, _el$73);
|
|
534
|
+
_$insertNode(_el$73, _el$74);
|
|
535
|
+
_$insertNode(_el$73, _el$76);
|
|
536
|
+
_$setProp(_el$73, "flexDirection", "row");
|
|
537
|
+
_$setProp(_el$73, "justifyContent", "space-between");
|
|
538
|
+
_$setProp(_el$73, "gap", 2);
|
|
539
|
+
_$insertNode(_el$74, _$createTextNode(`Used / Limit`));
|
|
540
|
+
_$setProp(_el$74, "flexShrink", 0);
|
|
516
541
|
_$insertNode(_el$76, _el$77);
|
|
517
|
-
_$insertNode(_el$
|
|
518
|
-
_$insertNode(_el$
|
|
519
|
-
_$setProp(_el$
|
|
520
|
-
_$setProp(_el$
|
|
521
|
-
_$
|
|
522
|
-
_$
|
|
523
|
-
_$
|
|
524
|
-
_$
|
|
525
|
-
_$insertNode(_el$80, _el$82);
|
|
526
|
-
_$insertNode(_el$80, _el$83);
|
|
527
|
-
_$setProp(_el$80, "wrapMode", "word");
|
|
528
|
-
_$setProp(_el$80, "minWidth", 0);
|
|
529
|
-
_$insert(_el$80, () => number(details().used), _el$81);
|
|
530
|
-
_$insert(_el$80, () => number(details().limit), _el$82);
|
|
531
|
-
_$insert(_el$80, () => details().percent.toFixed(1), _el$83);
|
|
532
|
-
_$insert(_el$76, () => barRow(details().percent, windowBar()), null);
|
|
542
|
+
_$insertNode(_el$76, _el$78);
|
|
543
|
+
_$insertNode(_el$76, _el$79);
|
|
544
|
+
_$setProp(_el$76, "wrapMode", "word");
|
|
545
|
+
_$setProp(_el$76, "minWidth", 0);
|
|
546
|
+
_$insert(_el$76, () => number(details().used), _el$77);
|
|
547
|
+
_$insert(_el$76, () => number(details().limit), _el$78);
|
|
548
|
+
_$insert(_el$76, () => details().percent.toFixed(1), _el$79);
|
|
549
|
+
_$insert(_el$72, () => barRow(details().percent, windowBar()), null);
|
|
533
550
|
_$effect(_p$ => {
|
|
534
|
-
var _v$
|
|
535
|
-
_v$
|
|
536
|
-
_v$
|
|
537
|
-
_v$
|
|
551
|
+
var _v$21 = theme().muted,
|
|
552
|
+
_v$22 = theme().base;
|
|
553
|
+
_v$21 !== _p$.e && (_p$.e = _$setProp(_el$74, "fg", _v$21, _p$.e));
|
|
554
|
+
_v$22 !== _p$.t && (_p$.t = _$setProp(_el$76, "fg", _v$22, _p$.t));
|
|
538
555
|
return _p$;
|
|
539
556
|
}, {
|
|
540
557
|
e: undefined,
|
|
541
558
|
t: undefined
|
|
542
559
|
});
|
|
543
|
-
return _el$
|
|
560
|
+
return _el$72;
|
|
544
561
|
})()
|
|
545
562
|
}), null);
|
|
546
563
|
_$insertNode(_el$43, _el$44);
|
|
@@ -555,10 +572,10 @@ function UsageDialog(props) {
|
|
|
555
572
|
return requestTime();
|
|
556
573
|
},
|
|
557
574
|
children: time => (() => {
|
|
558
|
-
var _el$
|
|
559
|
-
_$insert(_el$
|
|
560
|
-
_$effect(_$p => _$setProp(_el$
|
|
561
|
-
return _el$
|
|
575
|
+
var _el$80 = _$createElement("text");
|
|
576
|
+
_$insert(_el$80, time);
|
|
577
|
+
_$effect(_$p => _$setProp(_el$80, "fg", theme().muted, _$p));
|
|
578
|
+
return _el$80;
|
|
562
579
|
})()
|
|
563
580
|
}), null);
|
|
564
581
|
_$insert(_el$43, _$createComponent(Show, {
|
|
@@ -567,16 +584,16 @@ function UsageDialog(props) {
|
|
|
567
584
|
},
|
|
568
585
|
get fallback() {
|
|
569
586
|
return (() => {
|
|
570
|
-
var _el$
|
|
571
|
-
_$insertNode(_el$
|
|
572
|
-
_$effect(_$p => _$setProp(_el$
|
|
573
|
-
return _el$
|
|
587
|
+
var _el$81 = _$createElement("text");
|
|
588
|
+
_$insertNode(_el$81, _$createTextNode(`Request usage unavailable`));
|
|
589
|
+
_$effect(_$p => _$setProp(_el$81, "fg", theme().muted, _$p));
|
|
590
|
+
return _el$81;
|
|
574
591
|
})();
|
|
575
592
|
},
|
|
576
593
|
children: details => (() => {
|
|
577
|
-
var _el$
|
|
578
|
-
_$insert(_el$
|
|
579
|
-
return _el$
|
|
594
|
+
var _el$83 = _$createElement("box");
|
|
595
|
+
_$insert(_el$83, () => requestRowsList(requestRows(details(), compact())));
|
|
596
|
+
return _el$83;
|
|
580
597
|
})()
|
|
581
598
|
}), null);
|
|
582
599
|
_$insertNode(_el$48, _el$49);
|
|
@@ -591,10 +608,10 @@ function UsageDialog(props) {
|
|
|
591
608
|
return sources();
|
|
592
609
|
},
|
|
593
610
|
children: captured => (() => {
|
|
594
|
-
var _el$
|
|
595
|
-
_$insert(_el$
|
|
596
|
-
_$effect(_$p => _$setProp(_el$
|
|
597
|
-
return _el$
|
|
611
|
+
var _el$84 = _$createElement("text");
|
|
612
|
+
_$insert(_el$84, () => new Date(captured().capturedAt).toLocaleTimeString());
|
|
613
|
+
_$effect(_$p => _$setProp(_el$84, "fg", theme().muted, _$p));
|
|
614
|
+
return _el$84;
|
|
598
615
|
})()
|
|
599
616
|
}), null);
|
|
600
617
|
_$insert(_el$48, _$createComponent(Show, {
|
|
@@ -603,10 +620,10 @@ function UsageDialog(props) {
|
|
|
603
620
|
},
|
|
604
621
|
get fallback() {
|
|
605
622
|
return (() => {
|
|
606
|
-
var _el$
|
|
607
|
-
_$insertNode(_el$
|
|
608
|
-
_$effect(_$p => _$setProp(_el$
|
|
609
|
-
return _el$
|
|
623
|
+
var _el$85 = _$createElement("text");
|
|
624
|
+
_$insertNode(_el$85, _$createTextNode(`Source estimates unavailable (no request snapshot or RPC)`));
|
|
625
|
+
_$effect(_$p => _$setProp(_el$85, "fg", theme().muted, _$p));
|
|
626
|
+
return _el$85;
|
|
610
627
|
})();
|
|
611
628
|
},
|
|
612
629
|
children: captured => _$createComponent(For, {
|
|
@@ -614,39 +631,39 @@ function UsageDialog(props) {
|
|
|
614
631
|
return breakdownRows(captured(), detailed());
|
|
615
632
|
},
|
|
616
633
|
children: row => (() => {
|
|
617
|
-
var _el$
|
|
618
|
-
_el$
|
|
619
|
-
_el$
|
|
620
|
-
_el$
|
|
621
|
-
_el$
|
|
622
|
-
_el$
|
|
623
|
-
_el$
|
|
624
|
-
_$insertNode(_el$
|
|
625
|
-
_$insertNode(_el$
|
|
626
|
-
_$insertNode(_el$
|
|
627
|
-
_$insertNode(_el$
|
|
628
|
-
_$setProp(_el$
|
|
629
|
-
_$setProp(_el$
|
|
634
|
+
var _el$87 = _$createElement("box"),
|
|
635
|
+
_el$88 = _$createElement("box"),
|
|
636
|
+
_el$89 = _$createElement("text"),
|
|
637
|
+
_el$90 = _$createElement("box"),
|
|
638
|
+
_el$91 = _$createElement("text"),
|
|
639
|
+
_el$92 = _$createElement("text"),
|
|
640
|
+
_el$93 = _$createTextNode(`%`);
|
|
641
|
+
_$insertNode(_el$87, _el$88);
|
|
642
|
+
_$insertNode(_el$87, _el$90);
|
|
643
|
+
_$insertNode(_el$87, _el$91);
|
|
644
|
+
_$insertNode(_el$87, _el$92);
|
|
645
|
+
_$setProp(_el$87, "flexDirection", "row");
|
|
646
|
+
_$setProp(_el$87, "gap", 1);
|
|
647
|
+
_$insertNode(_el$88, _el$89);
|
|
648
|
+
_$setProp(_el$88, "width", 14);
|
|
649
|
+
_$setProp(_el$88, "flexShrink", 0);
|
|
650
|
+
_$insert(_el$89, () => row.label);
|
|
651
|
+
_$setProp(_el$90, "flexShrink", 0);
|
|
652
|
+
_$insert(_el$90, () => barRow(row.percent, breakdownBar()));
|
|
653
|
+
_$setProp(_el$91, "flexShrink", 0);
|
|
654
|
+
_$insert(_el$91, () => number(row.tokens));
|
|
630
655
|
_$insertNode(_el$92, _el$93);
|
|
631
|
-
_$setProp(_el$92, "width", 14);
|
|
632
656
|
_$setProp(_el$92, "flexShrink", 0);
|
|
633
|
-
_$insert(_el$
|
|
634
|
-
_$setProp(_el$94, "flexShrink", 0);
|
|
635
|
-
_$insert(_el$94, () => barRow(row.percent, breakdownBar()));
|
|
636
|
-
_$setProp(_el$95, "flexShrink", 0);
|
|
637
|
-
_$insert(_el$95, () => number(row.tokens));
|
|
638
|
-
_$insertNode(_el$96, _el$97);
|
|
639
|
-
_$setProp(_el$96, "flexShrink", 0);
|
|
640
|
-
_$insert(_el$96, () => row.percent.toFixed(1), _el$97);
|
|
657
|
+
_$insert(_el$92, () => row.percent.toFixed(1), _el$93);
|
|
641
658
|
_$effect(_p$ => {
|
|
642
|
-
var _v$
|
|
643
|
-
_v$
|
|
644
|
-
_v$
|
|
645
|
-
_v$
|
|
646
|
-
_v$
|
|
647
|
-
_v$
|
|
648
|
-
_v$
|
|
649
|
-
_v$
|
|
659
|
+
var _v$23 = theme().muted,
|
|
660
|
+
_v$24 = breakdownBar(),
|
|
661
|
+
_v$25 = theme().base,
|
|
662
|
+
_v$26 = theme().muted;
|
|
663
|
+
_v$23 !== _p$.e && (_p$.e = _$setProp(_el$89, "fg", _v$23, _p$.e));
|
|
664
|
+
_v$24 !== _p$.t && (_p$.t = _$setProp(_el$90, "width", _v$24, _p$.t));
|
|
665
|
+
_v$25 !== _p$.a && (_p$.a = _$setProp(_el$91, "fg", _v$25, _p$.a));
|
|
666
|
+
_v$26 !== _p$.o && (_p$.o = _$setProp(_el$92, "fg", _v$26, _p$.o));
|
|
650
667
|
return _p$;
|
|
651
668
|
}, {
|
|
652
669
|
e: undefined,
|
|
@@ -654,12 +671,11 @@ function UsageDialog(props) {
|
|
|
654
671
|
a: undefined,
|
|
655
672
|
o: undefined
|
|
656
673
|
});
|
|
657
|
-
return _el$
|
|
674
|
+
return _el$87;
|
|
658
675
|
})()
|
|
659
676
|
})
|
|
660
677
|
}), null);
|
|
661
678
|
_$insertNode(_el$53, _el$54);
|
|
662
|
-
_$insertNode(_el$53, _el$57);
|
|
663
679
|
_$insertNode(_el$54, _el$55);
|
|
664
680
|
_$insertNode(_el$55, _$createTextNode(`Session`));
|
|
665
681
|
_$insert(_el$53, _$createComponent(Show, {
|
|
@@ -668,10 +684,10 @@ function UsageDialog(props) {
|
|
|
668
684
|
},
|
|
669
685
|
get fallback() {
|
|
670
686
|
return (() => {
|
|
671
|
-
var _el$
|
|
672
|
-
_$insertNode(_el$
|
|
673
|
-
_$effect(_$p => _$setProp(_el$
|
|
674
|
-
return _el$
|
|
687
|
+
var _el$94 = _$createElement("text");
|
|
688
|
+
_$insertNode(_el$94, _$createTextNode(`Session usage unavailable`));
|
|
689
|
+
_$effect(_$p => _$setProp(_el$94, "fg", theme().muted, _$p));
|
|
690
|
+
return _el$94;
|
|
675
691
|
})();
|
|
676
692
|
},
|
|
677
693
|
children: summary => _$createComponent(Show, {
|
|
@@ -680,26 +696,26 @@ function UsageDialog(props) {
|
|
|
680
696
|
},
|
|
681
697
|
get fallback() {
|
|
682
698
|
return (() => {
|
|
683
|
-
var _el$
|
|
684
|
-
_el$
|
|
685
|
-
_el$
|
|
686
|
-
_el$
|
|
687
|
-
_el$
|
|
688
|
-
_$insertNode(_el$
|
|
689
|
-
_$insertNode(_el$
|
|
690
|
-
_$insertNode(_el$
|
|
691
|
-
_$insertNode(_el$
|
|
692
|
-
_$setProp(_el$
|
|
693
|
-
_$insert(_el$
|
|
694
|
-
_$insert(_el$
|
|
695
|
-
_$insert(_el$
|
|
696
|
-
_$insert(_el$
|
|
697
|
-
_$insert(_el$
|
|
699
|
+
var _el$96 = _$createElement("text"),
|
|
700
|
+
_el$97 = _$createTextNode(` · `),
|
|
701
|
+
_el$98 = _$createTextNode(` · `),
|
|
702
|
+
_el$99 = _$createTextNode(` tokens · `),
|
|
703
|
+
_el$100 = _$createTextNode(`% cached`);
|
|
704
|
+
_$insertNode(_el$96, _el$97);
|
|
705
|
+
_$insertNode(_el$96, _el$98);
|
|
706
|
+
_$insertNode(_el$96, _el$99);
|
|
707
|
+
_$insertNode(_el$96, _el$100);
|
|
708
|
+
_$setProp(_el$96, "wrapMode", "word");
|
|
709
|
+
_$insert(_el$96, () => countLabel(summary().steps, "step"), _el$97);
|
|
710
|
+
_$insert(_el$96, () => countLabel(summary().calls, "call"), _el$98);
|
|
711
|
+
_$insert(_el$96, () => formatCompact(summary().total), _el$99);
|
|
712
|
+
_$insert(_el$96, () => (summary().cacheRate * 100).toFixed(1), _el$100);
|
|
713
|
+
_$insert(_el$96, (() => {
|
|
698
714
|
var _c$ = _$memo(() => !!formatEstimatedCost(summary().cost, summary().costStatus));
|
|
699
715
|
return () => _c$() ? ` · ${formatEstimatedCost(summary().cost, summary().costStatus)}` : "";
|
|
700
716
|
})(), null);
|
|
701
|
-
_$effect(_$p => _$setProp(_el$
|
|
702
|
-
return _el$
|
|
717
|
+
_$effect(_$p => _$setProp(_el$96, "fg", theme().base, _$p));
|
|
718
|
+
return _el$96;
|
|
703
719
|
})();
|
|
704
720
|
},
|
|
705
721
|
get children() {
|
|
@@ -708,60 +724,81 @@ function UsageDialog(props) {
|
|
|
708
724
|
return summaryRows(summary());
|
|
709
725
|
},
|
|
710
726
|
children: ([label, value]) => (() => {
|
|
711
|
-
var _el$
|
|
712
|
-
_el$
|
|
713
|
-
_el$
|
|
714
|
-
_$insertNode(_el$
|
|
715
|
-
_$insertNode(_el$
|
|
716
|
-
_$setProp(_el$
|
|
717
|
-
_$setProp(_el$
|
|
718
|
-
_$setProp(_el$
|
|
719
|
-
_$setProp(_el$
|
|
720
|
-
_$insert(_el$
|
|
721
|
-
_$insert(_el$
|
|
727
|
+
var _el$101 = _$createElement("box"),
|
|
728
|
+
_el$102 = _$createElement("text"),
|
|
729
|
+
_el$103 = _$createElement("text");
|
|
730
|
+
_$insertNode(_el$101, _el$102);
|
|
731
|
+
_$insertNode(_el$101, _el$103);
|
|
732
|
+
_$setProp(_el$101, "flexDirection", "row");
|
|
733
|
+
_$setProp(_el$101, "justifyContent", "space-between");
|
|
734
|
+
_$setProp(_el$101, "gap", 2);
|
|
735
|
+
_$setProp(_el$102, "flexShrink", 0);
|
|
736
|
+
_$insert(_el$102, label);
|
|
737
|
+
_$insert(_el$103, value);
|
|
722
738
|
_$effect(_p$ => {
|
|
723
|
-
var _v$
|
|
724
|
-
_v$
|
|
725
|
-
_v$
|
|
726
|
-
_v$
|
|
739
|
+
var _v$27 = theme().muted,
|
|
740
|
+
_v$28 = theme().base;
|
|
741
|
+
_v$27 !== _p$.e && (_p$.e = _$setProp(_el$102, "fg", _v$27, _p$.e));
|
|
742
|
+
_v$28 !== _p$.t && (_p$.t = _$setProp(_el$103, "fg", _v$28, _p$.t));
|
|
727
743
|
return _p$;
|
|
728
744
|
}, {
|
|
729
745
|
e: undefined,
|
|
730
746
|
t: undefined
|
|
731
747
|
});
|
|
732
|
-
return _el$
|
|
748
|
+
return _el$101;
|
|
733
749
|
})()
|
|
734
750
|
});
|
|
735
751
|
}
|
|
736
752
|
})
|
|
737
|
-
}),
|
|
753
|
+
}), null);
|
|
754
|
+
_$insert(_el$53, _$createComponent(Show, {
|
|
755
|
+
get when() {
|
|
756
|
+
return runtime();
|
|
757
|
+
},
|
|
758
|
+
children: time => (() => {
|
|
759
|
+
var _el$104 = _$createElement("box"),
|
|
760
|
+
_el$105 = _$createElement("text"),
|
|
761
|
+
_el$107 = _$createElement("text");
|
|
762
|
+
_$insertNode(_el$104, _el$105);
|
|
763
|
+
_$insertNode(_el$104, _el$107);
|
|
764
|
+
_$setProp(_el$104, "flexDirection", "row");
|
|
765
|
+
_$setProp(_el$104, "justifyContent", "space-between");
|
|
766
|
+
_$setProp(_el$104, "gap", 2);
|
|
767
|
+
_$insertNode(_el$105, _$createTextNode(`Run Time (this session)`));
|
|
768
|
+
_$setProp(_el$105, "wrapMode", "word");
|
|
769
|
+
_$setProp(_el$105, "minWidth", 0);
|
|
770
|
+
_$setProp(_el$107, "wrapMode", "word");
|
|
771
|
+
_$setProp(_el$107, "minWidth", 0);
|
|
772
|
+
_$insert(_el$107, time);
|
|
773
|
+
_$effect(_p$ => {
|
|
774
|
+
var _v$29 = theme().muted,
|
|
775
|
+
_v$30 = theme().base;
|
|
776
|
+
_v$29 !== _p$.e && (_p$.e = _$setProp(_el$105, "fg", _v$29, _p$.e));
|
|
777
|
+
_v$30 !== _p$.t && (_p$.t = _$setProp(_el$107, "fg", _v$30, _p$.t));
|
|
778
|
+
return _p$;
|
|
779
|
+
}, {
|
|
780
|
+
e: undefined,
|
|
781
|
+
t: undefined
|
|
782
|
+
});
|
|
783
|
+
return _el$104;
|
|
784
|
+
})()
|
|
785
|
+
}), null);
|
|
738
786
|
_$insertNode(_el$57, _el$58);
|
|
739
|
-
_$insertNode(_el$
|
|
740
|
-
_$
|
|
741
|
-
_$
|
|
742
|
-
_$setProp(_el$57, "gap", 2);
|
|
743
|
-
_$insertNode(_el$58, _$createTextNode(`Run Time (this session)`));
|
|
744
|
-
_$setProp(_el$58, "wrapMode", "word");
|
|
745
|
-
_$setProp(_el$58, "minWidth", 0);
|
|
746
|
-
_$setProp(_el$60, "wrapMode", "word");
|
|
747
|
-
_$setProp(_el$60, "minWidth", 0);
|
|
748
|
-
_$insert(_el$60, () => formatRunTime(state().runtime));
|
|
749
|
-
_$insertNode(_el$61, _el$62);
|
|
750
|
-
_$insertNode(_el$62, _el$63);
|
|
751
|
-
_$insertNode(_el$63, _$createTextNode(`By Model`));
|
|
752
|
-
_$insert(_el$61, _$createComponent(Show, {
|
|
787
|
+
_$insertNode(_el$58, _el$59);
|
|
788
|
+
_$insertNode(_el$59, _$createTextNode(`By Model`));
|
|
789
|
+
_$insert(_el$57, _$createComponent(Show, {
|
|
753
790
|
get when() {
|
|
754
791
|
return _$memo(() => !!detailed())() && models().length;
|
|
755
792
|
},
|
|
756
793
|
get children() {
|
|
757
|
-
var _el$
|
|
758
|
-
_$insertNode(_el$
|
|
759
|
-
_$setProp(_el$
|
|
760
|
-
_$effect(_$p => _$setProp(_el$
|
|
761
|
-
return _el$
|
|
794
|
+
var _el$61 = _$createElement("text");
|
|
795
|
+
_$insertNode(_el$61, _$createTextNode(`Rates used for Est. Cost · USD / 1M text tokens · incoming = Input + Cache Read + Cache Write`));
|
|
796
|
+
_$setProp(_el$61, "wrapMode", "word");
|
|
797
|
+
_$effect(_$p => _$setProp(_el$61, "fg", theme().muted, _$p));
|
|
798
|
+
return _el$61;
|
|
762
799
|
}
|
|
763
800
|
}), null);
|
|
764
|
-
_$insert(_el$
|
|
801
|
+
_$insert(_el$57, _$createComponent(Show, {
|
|
765
802
|
get when() {
|
|
766
803
|
return models().length;
|
|
767
804
|
},
|
|
@@ -867,17 +904,13 @@ function UsageDialog(props) {
|
|
|
867
904
|
_v$12 = theme().base,
|
|
868
905
|
_v$13 = theme().base,
|
|
869
906
|
_v$14 = theme().base,
|
|
870
|
-
_v$15 = theme().
|
|
871
|
-
_v$16 = theme().base,
|
|
872
|
-
_v$17 = theme().base;
|
|
907
|
+
_v$15 = theme().base;
|
|
873
908
|
_v$10 !== _p$.e && (_p$.e = _$setProp(_el$37, "maxHeight", _v$10, _p$.e));
|
|
874
909
|
_v$11 !== _p$.t && (_p$.t = _$setProp(_el$40, "fg", _v$11, _p$.t));
|
|
875
910
|
_v$12 !== _p$.a && (_p$.a = _$setProp(_el$45, "fg", _v$12, _p$.a));
|
|
876
911
|
_v$13 !== _p$.o && (_p$.o = _$setProp(_el$50, "fg", _v$13, _p$.o));
|
|
877
912
|
_v$14 !== _p$.i && (_p$.i = _$setProp(_el$54, "fg", _v$14, _p$.i));
|
|
878
913
|
_v$15 !== _p$.n && (_p$.n = _$setProp(_el$58, "fg", _v$15, _p$.n));
|
|
879
|
-
_v$16 !== _p$.s && (_p$.s = _$setProp(_el$60, "fg", _v$16, _p$.s));
|
|
880
|
-
_v$17 !== _p$.h && (_p$.h = _$setProp(_el$62, "fg", _v$17, _p$.h));
|
|
881
914
|
return _p$;
|
|
882
915
|
}, {
|
|
883
916
|
e: undefined,
|
|
@@ -885,34 +918,32 @@ function UsageDialog(props) {
|
|
|
885
918
|
a: undefined,
|
|
886
919
|
o: undefined,
|
|
887
920
|
i: undefined,
|
|
888
|
-
n: undefined
|
|
889
|
-
s: undefined,
|
|
890
|
-
h: undefined
|
|
921
|
+
n: undefined
|
|
891
922
|
});
|
|
892
923
|
return _el$37;
|
|
893
924
|
}
|
|
894
|
-
}), _el$
|
|
895
|
-
_$insertNode(_el$
|
|
896
|
-
_$insertNode(_el$
|
|
897
|
-
_$insertNode(_el$
|
|
898
|
-
_$setProp(_el$
|
|
899
|
-
_$insertNode(_el$
|
|
900
|
-
_$insertNode(_el$
|
|
901
|
-
_$setProp(_el$
|
|
925
|
+
}), _el$63);
|
|
926
|
+
_$insertNode(_el$63, _el$64);
|
|
927
|
+
_$insertNode(_el$63, _el$66);
|
|
928
|
+
_$insertNode(_el$63, _el$68);
|
|
929
|
+
_$setProp(_el$63, "flexDirection", "row");
|
|
930
|
+
_$insertNode(_el$64, _$createTextNode(`↑/↓ scroll · `));
|
|
931
|
+
_$insertNode(_el$66, _$createTextNode(`d details`));
|
|
932
|
+
_$setProp(_el$66, "onMouseUp", event => {
|
|
902
933
|
if (event.button === 0) toggleDetails();
|
|
903
934
|
});
|
|
904
|
-
_$insertNode(_el$
|
|
935
|
+
_$insertNode(_el$68, _$createTextNode(` · esc close`));
|
|
905
936
|
_$effect(_p$ => {
|
|
906
|
-
var _v$
|
|
937
|
+
var _v$16 = theme().base,
|
|
938
|
+
_v$17 = theme().muted,
|
|
939
|
+
_v$18 = theme().muted,
|
|
907
940
|
_v$19 = theme().muted,
|
|
908
|
-
_v$20 = theme().muted
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
_v$18 !== _p$.
|
|
912
|
-
_v$19 !== _p$.
|
|
913
|
-
_v$20 !== _p$.
|
|
914
|
-
_v$21 !== _p$.o && (_p$.o = _$setProp(_el$70, "fg", _v$21, _p$.o));
|
|
915
|
-
_v$22 !== _p$.i && (_p$.i = _$setProp(_el$72, "fg", _v$22, _p$.i));
|
|
941
|
+
_v$20 = theme().muted;
|
|
942
|
+
_v$16 !== _p$.e && (_p$.e = _$setProp(_el$30, "fg", _v$16, _p$.e));
|
|
943
|
+
_v$17 !== _p$.t && (_p$.t = _$setProp(_el$33, "fg", _v$17, _p$.t));
|
|
944
|
+
_v$18 !== _p$.a && (_p$.a = _$setProp(_el$64, "fg", _v$18, _p$.a));
|
|
945
|
+
_v$19 !== _p$.o && (_p$.o = _$setProp(_el$66, "fg", _v$19, _p$.o));
|
|
946
|
+
_v$20 !== _p$.i && (_p$.i = _$setProp(_el$68, "fg", _v$20, _p$.i));
|
|
916
947
|
return _p$;
|
|
917
948
|
}, {
|
|
918
949
|
e: undefined,
|
|
@@ -930,6 +961,15 @@ export default Plugin.define({
|
|
|
930
961
|
const performance = new PerformanceMonitor(listener => context.data.listen(({
|
|
931
962
|
details
|
|
932
963
|
}) => listener(details)));
|
|
964
|
+
const runtime = new RuntimeMonitor(listener => context.data.listen(({
|
|
965
|
+
details
|
|
966
|
+
}) => listener(details)));
|
|
967
|
+
const synchronizeRuntime = () => void runtime.synchronize(signal => context.client.rpc(ContextSourceRpc).clock({}, {
|
|
968
|
+
location: context.location ?? context.data.location.default(),
|
|
969
|
+
signal
|
|
970
|
+
}));
|
|
971
|
+
synchronizeRuntime();
|
|
972
|
+
const stopClockSync = context.data.on("server.connected", synchronizeRuntime);
|
|
933
973
|
const controllers = new Set();
|
|
934
974
|
const register = controller => {
|
|
935
975
|
controllers.add(controller);
|
|
@@ -937,6 +977,19 @@ export default Plugin.define({
|
|
|
937
977
|
controllers.delete(controller);
|
|
938
978
|
};
|
|
939
979
|
};
|
|
980
|
+
const openUsage = sessionID => {
|
|
981
|
+
context.ui.dialog.show(() => _$createComponent(UsageDialog, {
|
|
982
|
+
context: context,
|
|
983
|
+
sessionID: sessionID,
|
|
984
|
+
performance: performance,
|
|
985
|
+
runtime: runtime,
|
|
986
|
+
register: register
|
|
987
|
+
}));
|
|
988
|
+
context.ui.dialog.set({
|
|
989
|
+
size: "large",
|
|
990
|
+
centered: true
|
|
991
|
+
});
|
|
992
|
+
};
|
|
940
993
|
const remove = context.ui.slot({
|
|
941
994
|
append: "sidebar.content",
|
|
942
995
|
render: props => _$createComponent(UsagePanel, {
|
|
@@ -945,10 +998,12 @@ export default Plugin.define({
|
|
|
945
998
|
return props.sessionID;
|
|
946
999
|
},
|
|
947
1000
|
performance: performance,
|
|
948
|
-
|
|
1001
|
+
runtime: runtime,
|
|
1002
|
+
register: register,
|
|
1003
|
+
open: openUsage
|
|
949
1004
|
})
|
|
950
1005
|
});
|
|
951
|
-
const openChildUsage =
|
|
1006
|
+
const openChildUsage = state => {
|
|
952
1007
|
context.ui.dialog.show(() => _$createComponent(ChildUsageDialog, {
|
|
953
1008
|
context: context,
|
|
954
1009
|
state: state
|
|
@@ -972,6 +1027,7 @@ export default Plugin.define({
|
|
|
972
1027
|
return props.sessionID;
|
|
973
1028
|
},
|
|
974
1029
|
performance: performance,
|
|
1030
|
+
runtime: runtime,
|
|
975
1031
|
register: register,
|
|
976
1032
|
open: openChildUsage
|
|
977
1033
|
});
|
|
@@ -995,18 +1051,7 @@ export default Plugin.define({
|
|
|
995
1051
|
run: () => {
|
|
996
1052
|
const route = context.ui.router.current();
|
|
997
1053
|
if (route.type !== "session") return;
|
|
998
|
-
|
|
999
|
-
context: context,
|
|
1000
|
-
get sessionID() {
|
|
1001
|
-
return route.sessionID;
|
|
1002
|
-
},
|
|
1003
|
-
performance: performance,
|
|
1004
|
-
register: register
|
|
1005
|
-
}));
|
|
1006
|
-
context.ui.dialog.set({
|
|
1007
|
-
size: "large",
|
|
1008
|
-
centered: true
|
|
1009
|
-
});
|
|
1054
|
+
openUsage(route.sessionID);
|
|
1010
1055
|
}
|
|
1011
1056
|
}]
|
|
1012
1057
|
}));
|
|
@@ -1020,6 +1065,8 @@ export default Plugin.define({
|
|
|
1020
1065
|
removeChild();
|
|
1021
1066
|
removeCommand();
|
|
1022
1067
|
performance.dispose();
|
|
1068
|
+
runtime.dispose();
|
|
1069
|
+
stopClockSync();
|
|
1023
1070
|
};
|
|
1024
1071
|
}
|
|
1025
1072
|
});
|