tokmon 0.21.0 → 0.22.0

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.
@@ -13,12 +13,13 @@ import {
13
13
  cursorModelSpend,
14
14
  detectProviders,
15
15
  fetchPeak,
16
+ modelColor,
16
17
  resolveTimezone,
17
18
  shortDate,
18
19
  systemTimezone,
19
20
  time,
20
21
  tokens
21
- } from "./chunk-YCIUMAKK.js";
22
+ } from "./chunk-2PIYMU6W.js";
22
23
  import {
23
24
  COLOR_PALETTE,
24
25
  DEFAULTS,
@@ -1086,7 +1087,7 @@ var TableProviderBar = memo4(function TableProviderBar2({ providers, active, onS
1086
1087
  /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: " p/P switch" })
1087
1088
  ] });
1088
1089
  });
1089
- var ControlBar = memo4(function ControlBar2({ views, period, sort, search, searchCaret, searching, showPeriod }) {
1090
+ var ControlBar = memo4(function ControlBar2({ views, period, sort, model, search, searchCaret, searching, showPeriod, showModel }) {
1090
1091
  return /* @__PURE__ */ jsxs4(Box4, { children: [
1091
1092
  showPeriod && /* @__PURE__ */ jsxs4(Fragment3, { children: [
1092
1093
  views.map((v, i) => /* @__PURE__ */ jsx4(Box4, { marginRight: 2, children: i === period ? /* @__PURE__ */ jsxs4(Text4, { bold: true, color: "cyan", children: [
@@ -1103,6 +1104,15 @@ var ControlBar = memo4(function ControlBar2({ views, period, sort, search, searc
1103
1104
  glyphs().middot,
1104
1105
  " "
1105
1106
  ] }),
1107
+ showModel && /* @__PURE__ */ jsxs4(Fragment3, { children: [
1108
+ /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "model " }),
1109
+ /* @__PURE__ */ jsx4(Text4, { bold: true, color: model ? modelColor(model) : "cyan", children: model ?? "all" }),
1110
+ /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
1111
+ " m model ",
1112
+ glyphs().middot,
1113
+ " "
1114
+ ] })
1115
+ ] }),
1106
1116
  searching ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
1107
1117
  /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "/" }),
1108
1118
  /* @__PURE__ */ jsx4(CaretText, { value: search, caret: searchCaret, color: "cyan" })
@@ -2038,6 +2048,45 @@ function sortRows(rows, sortIdx) {
2038
2048
  return sorted;
2039
2049
  }
2040
2050
  }
2051
+ function tableModelOptions(rows) {
2052
+ const models = /* @__PURE__ */ new Set();
2053
+ for (const row of rows) for (const model of row.breakdown) models.add(model.name);
2054
+ return [...models].sort();
2055
+ }
2056
+ function cycleTableModel(current, models, dir) {
2057
+ if (models.length === 0) return null;
2058
+ const idx = current ? models.indexOf(current) : -1;
2059
+ if (dir === 1) {
2060
+ if (idx < 0) return models[0];
2061
+ return idx === models.length - 1 ? null : models[idx + 1];
2062
+ }
2063
+ if (idx < 0) return models[models.length - 1];
2064
+ return idx === 0 ? null : models[idx - 1];
2065
+ }
2066
+ function filterRowsByModel(rows, model) {
2067
+ if (!model) return rows;
2068
+ return rows.flatMap((row) => {
2069
+ const detail = row.breakdown.find((m) => m.name === model);
2070
+ if (!detail) return [];
2071
+ const input = detail.input;
2072
+ const output = detail.output;
2073
+ const cacheCreate = detail.cacheCreate;
2074
+ const cacheRead = detail.cacheRead;
2075
+ return [{
2076
+ label: row.label,
2077
+ models: [model],
2078
+ input,
2079
+ output,
2080
+ cacheCreate,
2081
+ cacheRead,
2082
+ cacheSavings: detail.cacheSavings,
2083
+ total: input + output + cacheCreate + cacheRead,
2084
+ cost: detail.cost,
2085
+ count: detail.count,
2086
+ breakdown: [{ ...detail }]
2087
+ }];
2088
+ });
2089
+ }
2041
2090
  function filterTokenRows(rows, q) {
2042
2091
  if (!q) return rows;
2043
2092
  const s = q.toLowerCase();
@@ -2122,6 +2171,7 @@ function handleKey(input, key, ctx) {
2122
2171
  setSort,
2123
2172
  SORTS_FOR,
2124
2173
  tableIsCursor,
2174
+ cycleTableModel: cycleTableModel2,
2125
2175
  setView,
2126
2176
  cursor,
2127
2177
  rowCountRef,
@@ -2550,8 +2600,11 @@ function handleKey(input, key, ctx) {
2550
2600
  return;
2551
2601
  }
2552
2602
  if (input === "m") {
2553
- setView(2);
2554
- resetView();
2603
+ cycleTableModel2(1);
2604
+ return;
2605
+ }
2606
+ if (input === "M") {
2607
+ cycleTableModel2(-1);
2555
2608
  return;
2556
2609
  }
2557
2610
  if (key.leftArrow) {
@@ -2977,6 +3030,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
2977
3030
  const [expanded, setExpanded] = useState8(-1);
2978
3031
  const [sort, setSort] = useState8(1);
2979
3032
  const [tableProvider, setTableProvider] = useState8(null);
3033
+ const [tableModel, setTableModel] = useState8(null);
2980
3034
  const [search, setSearch] = useState8("");
2981
3035
  const [searchMode, setSearchMode] = useState8(false);
2982
3036
  const [cursorRowsLocal, setCursorRows] = useState8(null);
@@ -3163,6 +3217,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
3163
3217
  setCursorRows(null);
3164
3218
  setCursor(0);
3165
3219
  setExpanded(-1);
3220
+ setTableModel(null);
3166
3221
  setSort(tableIsCursor ? 0 : 1);
3167
3222
  setTableLoading(false);
3168
3223
  }, [tableKey]);
@@ -3202,7 +3257,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
3202
3257
  useEffect7(() => {
3203
3258
  setCursor(0);
3204
3259
  setExpanded(-1);
3205
- }, [search]);
3260
+ }, [search, tableModel]);
3206
3261
  useEffect7(() => {
3207
3262
  setDashPage((p) => Math.min(p, dashPageCount - 1));
3208
3263
  }, [dashPageCount]);
@@ -3319,6 +3374,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
3319
3374
  setSort(nextIsCursor ? 0 : 1);
3320
3375
  setCursor(0);
3321
3376
  setExpanded(-1);
3377
+ setTableModel(null);
3322
3378
  setSearch("");
3323
3379
  setSearchCaret(0);
3324
3380
  setSearchMode(false);
@@ -3348,7 +3404,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
3348
3404
  if (webStartingRef.current) return;
3349
3405
  webStartingRef.current = true;
3350
3406
  try {
3351
- const { startWebServer } = await import("./server-F7CUK4ZM.js");
3407
+ const { startWebServer } = await import("./server-GEGTLRUW.js");
3352
3408
  const ctrl = await startWebServer({ config: cfg, log: false });
3353
3409
  webRef.current = ctrl;
3354
3410
  openUrl(ctrl.url);
@@ -3369,6 +3425,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
3369
3425
  setTableProvider(p);
3370
3426
  setCursor(0);
3371
3427
  setExpanded(-1);
3428
+ setTableModel(null);
3372
3429
  setSearch("");
3373
3430
  setSearchCaret(0);
3374
3431
  setSearchMode(false);
@@ -3378,9 +3435,22 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
3378
3435
  else setCursor(idx);
3379
3436
  }, [cursor]);
3380
3437
  const onRowClickCursor = useCallback4((idx) => setCursor(idx), []);
3438
+ const rawTokenRows = useMemo2(
3439
+ () => tab === 1 && !tableIsCursor ? table ? [table.daily, table.weekly, table.monthly][view] : [] : [],
3440
+ [tab, tableIsCursor, table, view]
3441
+ );
3442
+ const tokenModelOptions = useMemo2(() => tableModelOptions(rawTokenRows), [rawTokenRows]);
3443
+ useEffect7(() => {
3444
+ if (tableModel && !tokenModelOptions.includes(tableModel)) setTableModel(null);
3445
+ }, [tableModel, tokenModelOptions]);
3446
+ const cycleTableModelFilter = useCallback4((dir) => {
3447
+ setTableModel((cur) => cycleTableModel(cur, tokenModelOptions, dir));
3448
+ resetView();
3449
+ }, [tokenModelOptions, resetView]);
3450
+ const activeTableModel = tableModel && tokenModelOptions.includes(tableModel) ? tableModel : null;
3381
3451
  const tokenRows = useMemo2(
3382
- () => tab === 1 && !tableIsCursor ? sortRows(filterTokenRows(table ? [table.daily, table.weekly, table.monthly][view] : [], search), sort) : [],
3383
- [tab, tableIsCursor, table, view, search, sort]
3452
+ () => tab === 1 && !tableIsCursor ? sortRows(filterTokenRows(filterRowsByModel(rawTokenRows, activeTableModel), search), sort) : [],
3453
+ [tab, tableIsCursor, rawTokenRows, activeTableModel, search, sort]
3384
3454
  );
3385
3455
  const cursorTableRows = useMemo2(
3386
3456
  () => tab === 1 && tableIsCursor ? sortCursorRows(filterCursorRows(cursorRows ?? [], search), sort) : [],
@@ -3446,6 +3516,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
3446
3516
  setSort,
3447
3517
  SORTS_FOR,
3448
3518
  tableIsCursor,
3519
+ cycleTableModel: cycleTableModelFilter,
3449
3520
  setView,
3450
3521
  cursor,
3451
3522
  rowCountRef,
@@ -3563,10 +3634,12 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
3563
3634
  views: VIEWS,
3564
3635
  period: view,
3565
3636
  sort: sortLabel(SORTS_FOR[sort % SORTS_FOR.length]),
3637
+ model: activeTableModel,
3566
3638
  search,
3567
3639
  searchCaret,
3568
3640
  searching: searchMode,
3569
- showPeriod: !tableIsCursor
3641
+ showPeriod: !tableIsCursor,
3642
+ showModel: !tableIsCursor
3570
3643
  }
3571
3644
  ),
3572
3645
  /* @__PURE__ */ jsx11(Box11, { height: 1 }),