codex-devtools 0.1.11 → 0.2.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/dist-electron/main/chunks/{CodexServiceContext-CRkTP14W.cjs → CodexServiceContext-DaxLI918.cjs} +804 -71
- package/dist-electron/main/index.cjs +45 -2
- package/dist-electron/main/standalone.cjs +76 -15
- package/dist-electron/preload/index.cjs +2 -0
- package/out/renderer/assets/{index-BEzdp8iI.js → index-5ydAmpDO.js} +712 -26
- package/out/renderer/assets/{index-BTmVA30y.css → index-Cgat1ue6.css} +387 -16
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
|
@@ -7055,6 +7055,14 @@ class HttpApiClient {
|
|
|
7055
7055
|
async getSessionChunks(sessionId) {
|
|
7056
7056
|
return this.get(`/sessions/${encodeURIComponent(sessionId)}/chunks`);
|
|
7057
7057
|
}
|
|
7058
|
+
async getStats(scope = { type: "all" }) {
|
|
7059
|
+
if (scope.type === "project") {
|
|
7060
|
+
return this.get(
|
|
7061
|
+
`/stats?scope=project&cwd=${encodeURIComponent(scope.cwd)}`
|
|
7062
|
+
);
|
|
7063
|
+
}
|
|
7064
|
+
return this.get("/stats?scope=all");
|
|
7065
|
+
}
|
|
7058
7066
|
async searchSessions(query) {
|
|
7059
7067
|
return this.get(`/search?q=${encodeURIComponent(query)}`);
|
|
7060
7068
|
}
|
|
@@ -7642,8 +7650,57 @@ const createSessionSlice = (client2) => (set, get) => ({
|
|
|
7642
7650
|
});
|
|
7643
7651
|
}
|
|
7644
7652
|
});
|
|
7653
|
+
function normalizeScope$1(scope) {
|
|
7654
|
+
var _a;
|
|
7655
|
+
if (!scope || scope.type === "all") {
|
|
7656
|
+
return { type: "all" };
|
|
7657
|
+
}
|
|
7658
|
+
const cwd = (_a = scope.cwd) == null ? void 0 : _a.trim();
|
|
7659
|
+
if (!cwd) {
|
|
7660
|
+
return { type: "all" };
|
|
7661
|
+
}
|
|
7662
|
+
return {
|
|
7663
|
+
type: "project",
|
|
7664
|
+
cwd
|
|
7665
|
+
};
|
|
7666
|
+
}
|
|
7667
|
+
const createStatsSlice = (client2) => (set, get) => ({
|
|
7668
|
+
statsData: null,
|
|
7669
|
+
statsScope: { type: "all" },
|
|
7670
|
+
statsLoading: false,
|
|
7671
|
+
statsError: null,
|
|
7672
|
+
fetchStats: async (scope, options) => {
|
|
7673
|
+
var _a;
|
|
7674
|
+
const resolvedScope = normalizeScope$1(scope != null ? scope : get().statsScope);
|
|
7675
|
+
const background = (_a = options == null ? void 0 : options.background) != null ? _a : false;
|
|
7676
|
+
if (!background) {
|
|
7677
|
+
set({ statsLoading: true, statsError: null });
|
|
7678
|
+
}
|
|
7679
|
+
try {
|
|
7680
|
+
const statsData = await client2.getStats(resolvedScope);
|
|
7681
|
+
set((state) => ({
|
|
7682
|
+
statsData,
|
|
7683
|
+
statsScope: resolvedScope,
|
|
7684
|
+
statsLoading: background ? state.statsLoading : false,
|
|
7685
|
+
statsError: null
|
|
7686
|
+
}));
|
|
7687
|
+
} catch (error) {
|
|
7688
|
+
set((state) => ({
|
|
7689
|
+
statsScope: resolvedScope,
|
|
7690
|
+
statsLoading: background ? state.statsLoading : false,
|
|
7691
|
+
statsError: error instanceof Error ? error.message : "Failed to fetch stats"
|
|
7692
|
+
}));
|
|
7693
|
+
}
|
|
7694
|
+
},
|
|
7695
|
+
setStatsScope: async (scope) => {
|
|
7696
|
+
const resolvedScope = normalizeScope$1(scope);
|
|
7697
|
+
set({ statsScope: resolvedScope });
|
|
7698
|
+
await get().fetchStats(resolvedScope);
|
|
7699
|
+
}
|
|
7700
|
+
});
|
|
7645
7701
|
const DASHBOARD_TAB_ID$2 = "dashboard";
|
|
7646
7702
|
const SETTINGS_TAB_ID$2 = "settings";
|
|
7703
|
+
const STATS_TAB_ID$3 = "stats";
|
|
7647
7704
|
function createSessionTabId(sessionId) {
|
|
7648
7705
|
return `session:${sessionId}`;
|
|
7649
7706
|
}
|
|
@@ -7674,6 +7731,10 @@ const createTabSlice = (_client) => (set, get) => ({
|
|
|
7674
7731
|
openDashboardTab: () => {
|
|
7675
7732
|
set({ activeTabId: DASHBOARD_TAB_ID$2, activeSessionId: null });
|
|
7676
7733
|
},
|
|
7734
|
+
openStatsTab: () => {
|
|
7735
|
+
set({ activeTabId: STATS_TAB_ID$3, activeSessionId: null });
|
|
7736
|
+
void get().fetchStats(get().statsScope);
|
|
7737
|
+
},
|
|
7677
7738
|
openSettingsTab: () => {
|
|
7678
7739
|
set({ activeTabId: SETTINGS_TAB_ID$2, activeSessionId: null });
|
|
7679
7740
|
},
|
|
@@ -7690,6 +7751,9 @@ const createTabSlice = (_client) => (set, get) => ({
|
|
|
7690
7751
|
if (tab.type === "session" && tab.sessionId) {
|
|
7691
7752
|
void get().fetchChunks(tab.sessionId);
|
|
7692
7753
|
}
|
|
7754
|
+
if (tab.type === "stats") {
|
|
7755
|
+
void get().fetchStats(get().statsScope);
|
|
7756
|
+
}
|
|
7693
7757
|
},
|
|
7694
7758
|
closeTab: (tabId) => {
|
|
7695
7759
|
set((state) => {
|
|
@@ -7728,6 +7792,7 @@ const createUISlice = (_client) => (set) => ({
|
|
|
7728
7792
|
const createAppStore = (client2 = api) => create()((...args) => ({
|
|
7729
7793
|
...createProjectSlice(client2)(...args),
|
|
7730
7794
|
...createSessionSlice(client2)(...args),
|
|
7795
|
+
...createStatsSlice(client2)(...args),
|
|
7731
7796
|
...createConversationSlice(client2)(...args),
|
|
7732
7797
|
...createConfigSlice(client2)(...args),
|
|
7733
7798
|
...createTabSlice()(...args),
|
|
@@ -7737,6 +7802,7 @@ const createAppStore = (client2 = api) => create()((...args) => ({
|
|
|
7737
7802
|
const useAppStore = createAppStore();
|
|
7738
7803
|
const REFRESH_DEBOUNCE_MS = 120;
|
|
7739
7804
|
const FALLBACK_POLL_INTERVAL_MS = 5e3;
|
|
7805
|
+
const STATS_TAB_ID$2 = "stats";
|
|
7740
7806
|
function initializeEventListeners(store = useAppStore, client2 = api) {
|
|
7741
7807
|
let refreshTimer = null;
|
|
7742
7808
|
let pollTimer = null;
|
|
@@ -7760,6 +7826,9 @@ function initializeEventListeners(store = useAppStore, client2 = api) {
|
|
|
7760
7826
|
if (state.activeSessionId) {
|
|
7761
7827
|
void state.fetchChunks(state.activeSessionId);
|
|
7762
7828
|
}
|
|
7829
|
+
if (state.activeTabId === STATS_TAB_ID$2) {
|
|
7830
|
+
void state.fetchStats(state.statsScope, { background: true });
|
|
7831
|
+
}
|
|
7763
7832
|
}, REFRESH_DEBOUNCE_MS);
|
|
7764
7833
|
});
|
|
7765
7834
|
const runFallbackRefresh = () => {
|
|
@@ -7782,7 +7851,8 @@ function initializeEventListeners(store = useAppStore, client2 = api) {
|
|
|
7782
7851
|
prefetchPreviews: false,
|
|
7783
7852
|
background: true
|
|
7784
7853
|
}) : Promise.resolve(),
|
|
7785
|
-
state.activeSessionId ? state.fetchChunks(state.activeSessionId) : Promise.resolve()
|
|
7854
|
+
state.activeSessionId ? state.fetchChunks(state.activeSessionId) : Promise.resolve(),
|
|
7855
|
+
state.activeTabId === STATS_TAB_ID$2 ? state.fetchStats(state.statsScope, { background: true }) : Promise.resolve()
|
|
7786
7856
|
]).finally(() => {
|
|
7787
7857
|
polling = false;
|
|
7788
7858
|
});
|
|
@@ -9353,6 +9423,491 @@ const DashboardView = () => {
|
|
|
9353
9423
|
] })
|
|
9354
9424
|
] });
|
|
9355
9425
|
};
|
|
9426
|
+
const CONTRIBUTION_WEEKDAY_LABELS = ["", "Mon", "", "Wed", "", "Fri", ""];
|
|
9427
|
+
const CALENDAR_METRIC_OPTIONS = [
|
|
9428
|
+
{ value: "totalTokens", label: "Total tokens", tooltipLabel: "total tokens" },
|
|
9429
|
+
{ value: "inputTokens", label: "Input tokens", tooltipLabel: "input tokens" },
|
|
9430
|
+
{ value: "outputTokens", label: "Output tokens", tooltipLabel: "output tokens" },
|
|
9431
|
+
{ value: "eventCount", label: "Events", tooltipLabel: "events" },
|
|
9432
|
+
{ value: "sessionCount", label: "Sessions", tooltipLabel: "sessions" }
|
|
9433
|
+
];
|
|
9434
|
+
function normalizeScope(scope) {
|
|
9435
|
+
if (scope.type === "project" && scope.cwd.trim().length > 0) {
|
|
9436
|
+
return { type: "project", cwd: scope.cwd.trim() };
|
|
9437
|
+
}
|
|
9438
|
+
return { type: "all" };
|
|
9439
|
+
}
|
|
9440
|
+
function parseDateKey(value) {
|
|
9441
|
+
return /* @__PURE__ */ new Date(`${value}T00:00:00`);
|
|
9442
|
+
}
|
|
9443
|
+
function formatDateKey(date) {
|
|
9444
|
+
const year = date.getFullYear();
|
|
9445
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
9446
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
9447
|
+
return `${year}-${month}-${day}`;
|
|
9448
|
+
}
|
|
9449
|
+
function getContributionLevel(outputTokens, maxOutputTokens) {
|
|
9450
|
+
if (!Number.isFinite(outputTokens) || outputTokens <= 0 || maxOutputTokens <= 0) {
|
|
9451
|
+
return 0;
|
|
9452
|
+
}
|
|
9453
|
+
const normalized = Math.log(outputTokens + 1) / Math.log(maxOutputTokens + 1);
|
|
9454
|
+
if (normalized < 0.25) {
|
|
9455
|
+
return 1;
|
|
9456
|
+
}
|
|
9457
|
+
if (normalized < 0.5) {
|
|
9458
|
+
return 2;
|
|
9459
|
+
}
|
|
9460
|
+
if (normalized < 0.75) {
|
|
9461
|
+
return 3;
|
|
9462
|
+
}
|
|
9463
|
+
return 4;
|
|
9464
|
+
}
|
|
9465
|
+
function getDailyMetricValue(point, metric) {
|
|
9466
|
+
if (!point) {
|
|
9467
|
+
return 0;
|
|
9468
|
+
}
|
|
9469
|
+
switch (metric) {
|
|
9470
|
+
case "totalTokens":
|
|
9471
|
+
return point.totalTokens;
|
|
9472
|
+
case "inputTokens":
|
|
9473
|
+
return point.inputTokens;
|
|
9474
|
+
case "outputTokens":
|
|
9475
|
+
return point.outputTokens;
|
|
9476
|
+
case "eventCount":
|
|
9477
|
+
return point.eventCount;
|
|
9478
|
+
case "sessionCount":
|
|
9479
|
+
return point.sessionCount;
|
|
9480
|
+
default:
|
|
9481
|
+
return 0;
|
|
9482
|
+
}
|
|
9483
|
+
}
|
|
9484
|
+
function buildDailyContributionGrid(daily, metric) {
|
|
9485
|
+
if (daily.length === 0) {
|
|
9486
|
+
return {
|
|
9487
|
+
weeks: [],
|
|
9488
|
+
months: []
|
|
9489
|
+
};
|
|
9490
|
+
}
|
|
9491
|
+
const sorted = [...daily].sort((left, right) => left.date.localeCompare(right.date));
|
|
9492
|
+
const valuesByDate = new Map(sorted.map((point) => [point.date, point]));
|
|
9493
|
+
const maxMetricValue = Math.max(...sorted.map((point) => getDailyMetricValue(point, metric)), 0);
|
|
9494
|
+
const firstDate = parseDateKey(sorted[0].date);
|
|
9495
|
+
const lastDate = parseDateKey(sorted[sorted.length - 1].date);
|
|
9496
|
+
const paddedStart = new Date(firstDate);
|
|
9497
|
+
paddedStart.setDate(paddedStart.getDate() - paddedStart.getDay());
|
|
9498
|
+
const paddedEnd = new Date(lastDate);
|
|
9499
|
+
paddedEnd.setDate(paddedEnd.getDate() + (6 - paddedEnd.getDay()));
|
|
9500
|
+
const weeks = [];
|
|
9501
|
+
const cursor = new Date(paddedStart);
|
|
9502
|
+
while (cursor <= paddedEnd) {
|
|
9503
|
+
const week = [];
|
|
9504
|
+
for (let offset = 0; offset < 7; offset += 1) {
|
|
9505
|
+
const date = formatDateKey(cursor);
|
|
9506
|
+
const point = valuesByDate.get(date);
|
|
9507
|
+
const inRange = cursor >= firstDate && cursor <= lastDate;
|
|
9508
|
+
const metricValue = getDailyMetricValue(point, metric);
|
|
9509
|
+
week.push({
|
|
9510
|
+
date,
|
|
9511
|
+
metricValue,
|
|
9512
|
+
level: getContributionLevel(metricValue, maxMetricValue),
|
|
9513
|
+
inRange
|
|
9514
|
+
});
|
|
9515
|
+
cursor.setDate(cursor.getDate() + 1);
|
|
9516
|
+
}
|
|
9517
|
+
weeks.push(week);
|
|
9518
|
+
}
|
|
9519
|
+
const months = [];
|
|
9520
|
+
let previousMonthKey = "";
|
|
9521
|
+
weeks.forEach((week, weekIndex) => {
|
|
9522
|
+
const monthStartCell = week.find((cell) => cell.inRange && cell.date.endsWith("-01"));
|
|
9523
|
+
const anchor = monthStartCell != null ? monthStartCell : week.find((cell) => cell.inRange);
|
|
9524
|
+
if (!anchor) {
|
|
9525
|
+
return;
|
|
9526
|
+
}
|
|
9527
|
+
const monthDate = parseDateKey(anchor.date);
|
|
9528
|
+
const monthKey = `${monthDate.getFullYear()}-${String(monthDate.getMonth() + 1).padStart(2, "0")}`;
|
|
9529
|
+
if (monthKey === previousMonthKey) {
|
|
9530
|
+
return;
|
|
9531
|
+
}
|
|
9532
|
+
months.push({
|
|
9533
|
+
key: monthKey,
|
|
9534
|
+
label: monthDate.toLocaleString(void 0, { month: "short" }),
|
|
9535
|
+
weekIndex
|
|
9536
|
+
});
|
|
9537
|
+
previousMonthKey = monthKey;
|
|
9538
|
+
});
|
|
9539
|
+
return {
|
|
9540
|
+
weeks,
|
|
9541
|
+
months
|
|
9542
|
+
};
|
|
9543
|
+
}
|
|
9544
|
+
const StatsView = () => {
|
|
9545
|
+
const {
|
|
9546
|
+
projects,
|
|
9547
|
+
statsData,
|
|
9548
|
+
statsScope,
|
|
9549
|
+
statsLoading,
|
|
9550
|
+
statsError,
|
|
9551
|
+
fetchStats,
|
|
9552
|
+
setStatsScope
|
|
9553
|
+
} = useAppStore((state) => ({
|
|
9554
|
+
projects: state.projects,
|
|
9555
|
+
statsData: state.statsData,
|
|
9556
|
+
statsScope: state.statsScope,
|
|
9557
|
+
statsLoading: state.statsLoading,
|
|
9558
|
+
statsError: state.statsError,
|
|
9559
|
+
fetchStats: state.fetchStats,
|
|
9560
|
+
setStatsScope: state.setStatsScope
|
|
9561
|
+
}));
|
|
9562
|
+
const [calendarMetric, setCalendarMetric] = reactExports.useState("outputTokens");
|
|
9563
|
+
const [contributionTooltip, setContributionTooltip] = reactExports.useState(null);
|
|
9564
|
+
reactExports.useEffect(() => {
|
|
9565
|
+
if (!statsData && !statsLoading) {
|
|
9566
|
+
void fetchStats(statsScope);
|
|
9567
|
+
}
|
|
9568
|
+
}, [statsData, statsLoading, fetchStats, statsScope]);
|
|
9569
|
+
const dailyMaxOutput = reactExports.useMemo(
|
|
9570
|
+
() => {
|
|
9571
|
+
var _a;
|
|
9572
|
+
return Math.max(...(_a = statsData == null ? void 0 : statsData.daily.map((point) => point.outputTokens)) != null ? _a : [0]);
|
|
9573
|
+
},
|
|
9574
|
+
[statsData]
|
|
9575
|
+
);
|
|
9576
|
+
const hourlyMaxEvents = reactExports.useMemo(
|
|
9577
|
+
() => {
|
|
9578
|
+
var _a;
|
|
9579
|
+
return Math.max(...(_a = statsData == null ? void 0 : statsData.hourly.map((point) => point.eventCount)) != null ? _a : [1]);
|
|
9580
|
+
},
|
|
9581
|
+
[statsData]
|
|
9582
|
+
);
|
|
9583
|
+
const dailyContributionGrid = reactExports.useMemo(
|
|
9584
|
+
() => {
|
|
9585
|
+
var _a;
|
|
9586
|
+
return buildDailyContributionGrid((_a = statsData == null ? void 0 : statsData.daily) != null ? _a : [], calendarMetric);
|
|
9587
|
+
},
|
|
9588
|
+
[statsData, calendarMetric]
|
|
9589
|
+
);
|
|
9590
|
+
const selectedCalendarMetricOption = reactExports.useMemo(
|
|
9591
|
+
() => {
|
|
9592
|
+
var _a;
|
|
9593
|
+
return (_a = CALENDAR_METRIC_OPTIONS.find((option) => option.value === calendarMetric)) != null ? _a : CALENDAR_METRIC_OPTIONS[2];
|
|
9594
|
+
},
|
|
9595
|
+
[calendarMetric]
|
|
9596
|
+
);
|
|
9597
|
+
reactExports.useEffect(() => {
|
|
9598
|
+
setContributionTooltip(null);
|
|
9599
|
+
}, [calendarMetric, statsData]);
|
|
9600
|
+
const uncachedInputTokens = reactExports.useMemo(
|
|
9601
|
+
() => {
|
|
9602
|
+
var _a, _b;
|
|
9603
|
+
return Math.max(((_a = statsData == null ? void 0 : statsData.totals.inputTokens) != null ? _a : 0) - ((_b = statsData == null ? void 0 : statsData.totals.cachedTokens) != null ? _b : 0), 0);
|
|
9604
|
+
},
|
|
9605
|
+
[statsData]
|
|
9606
|
+
);
|
|
9607
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-shell", children: [
|
|
9608
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("header", { className: "stats-header", children: [
|
|
9609
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: "Stats" }),
|
|
9610
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Token volume, activity patterns, model usage, and reasoning effort." })
|
|
9611
|
+
] }),
|
|
9612
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "stats-controls", children: [
|
|
9613
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "sidebar-label", htmlFor: "stats-scope", children: "Scope" }),
|
|
9614
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9615
|
+
"select",
|
|
9616
|
+
{
|
|
9617
|
+
id: "stats-scope",
|
|
9618
|
+
className: "app-select",
|
|
9619
|
+
value: statsScope.type,
|
|
9620
|
+
onChange: (event) => {
|
|
9621
|
+
var _a, _b;
|
|
9622
|
+
if (event.target.value === "project") {
|
|
9623
|
+
const defaultProject = (_b = (_a = projects[0]) == null ? void 0 : _a.cwd) != null ? _b : "";
|
|
9624
|
+
void setStatsScope({ type: "project", cwd: defaultProject });
|
|
9625
|
+
return;
|
|
9626
|
+
}
|
|
9627
|
+
void setStatsScope({ type: "all" });
|
|
9628
|
+
},
|
|
9629
|
+
children: [
|
|
9630
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "all", children: "All projects" }),
|
|
9631
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "project", children: "Single project" })
|
|
9632
|
+
]
|
|
9633
|
+
}
|
|
9634
|
+
),
|
|
9635
|
+
statsScope.type === "project" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
9636
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "sidebar-label", htmlFor: "stats-project", children: "Project" }),
|
|
9637
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9638
|
+
"select",
|
|
9639
|
+
{
|
|
9640
|
+
id: "stats-project",
|
|
9641
|
+
className: "app-select",
|
|
9642
|
+
value: statsScope.cwd,
|
|
9643
|
+
onChange: (event) => {
|
|
9644
|
+
void setStatsScope({ type: "project", cwd: event.target.value });
|
|
9645
|
+
},
|
|
9646
|
+
children: [
|
|
9647
|
+
projects.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "No projects available" }) : null,
|
|
9648
|
+
projects.map((project) => /* @__PURE__ */ jsxRuntimeExports.jsxs("option", { value: project.cwd, children: [
|
|
9649
|
+
project.name,
|
|
9650
|
+
" - ",
|
|
9651
|
+
project.cwd
|
|
9652
|
+
] }, project.cwd))
|
|
9653
|
+
]
|
|
9654
|
+
}
|
|
9655
|
+
)
|
|
9656
|
+
] }) : null,
|
|
9657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9658
|
+
"button",
|
|
9659
|
+
{
|
|
9660
|
+
type: "button",
|
|
9661
|
+
className: "tabbar-action",
|
|
9662
|
+
onClick: () => {
|
|
9663
|
+
void fetchStats(normalizeScope(statsScope));
|
|
9664
|
+
},
|
|
9665
|
+
children: "Refresh"
|
|
9666
|
+
}
|
|
9667
|
+
)
|
|
9668
|
+
] }),
|
|
9669
|
+
statsError ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "stats-error", children: statsError }) : null,
|
|
9670
|
+
!statsData ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "empty-view", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "empty-title", children: statsLoading ? "Loading stats..." : "No stats available yet" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
9671
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "stats-kpi-grid", children: [
|
|
9672
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "stat-card", children: [
|
|
9673
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stat-label", children: "Total tokens" }),
|
|
9674
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "stat-value", children: statsData.totals.totalTokens.toLocaleString() })
|
|
9675
|
+
] }),
|
|
9676
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9677
|
+
"article",
|
|
9678
|
+
{
|
|
9679
|
+
className: "stat-card",
|
|
9680
|
+
title: `Cached: ${statsData.totals.cachedTokens.toLocaleString()} | Uncached: ${uncachedInputTokens.toLocaleString()}`,
|
|
9681
|
+
children: [
|
|
9682
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stat-label", children: "In" }),
|
|
9683
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "stat-value", children: statsData.totals.inputTokens.toLocaleString() })
|
|
9684
|
+
]
|
|
9685
|
+
}
|
|
9686
|
+
),
|
|
9687
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "stat-card", children: [
|
|
9688
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stat-label", children: "Out" }),
|
|
9689
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "stat-value", children: statsData.totals.outputTokens.toLocaleString() })
|
|
9690
|
+
] })
|
|
9691
|
+
] }),
|
|
9692
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "stats-section", children: [
|
|
9693
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-section-header", children: [
|
|
9694
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Generated tokens by day" }),
|
|
9695
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stats-section-subtle", children: "Output tokens" })
|
|
9696
|
+
] }),
|
|
9697
|
+
statsData.daily.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "empty-copy", children: "No daily token data yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "stats-day-list", children: statsData.daily.map((point) => {
|
|
9698
|
+
const rawWidthPercent = dailyMaxOutput > 0 ? point.outputTokens / dailyMaxOutput * 100 : 0;
|
|
9699
|
+
const widthPercent = Number.isFinite(rawWidthPercent) ? Math.max(0, Math.min(100, rawWidthPercent)) : 0;
|
|
9700
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "stats-day-row", children: [
|
|
9701
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stats-day-label", children: point.date }),
|
|
9702
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "stats-day-bar-wrap", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "stats-day-bar", style: { width: `${widthPercent}%` } }) }),
|
|
9703
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stats-day-value", children: point.outputTokens.toLocaleString() })
|
|
9704
|
+
] }, point.date);
|
|
9705
|
+
}) })
|
|
9706
|
+
] }),
|
|
9707
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "stats-section", children: [
|
|
9708
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-section-header", children: [
|
|
9709
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Output calendar" }),
|
|
9710
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-section-header-actions", children: [
|
|
9711
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "sidebar-label", htmlFor: "stats-calendar-metric", children: "Type" }),
|
|
9712
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9713
|
+
"select",
|
|
9714
|
+
{
|
|
9715
|
+
id: "stats-calendar-metric",
|
|
9716
|
+
className: "app-select stats-contrib-select",
|
|
9717
|
+
value: calendarMetric,
|
|
9718
|
+
onChange: (event) => {
|
|
9719
|
+
setCalendarMetric(event.target.value);
|
|
9720
|
+
},
|
|
9721
|
+
children: CALENDAR_METRIC_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: option.value, children: option.label }, option.value))
|
|
9722
|
+
}
|
|
9723
|
+
)
|
|
9724
|
+
] })
|
|
9725
|
+
] }),
|
|
9726
|
+
dailyContributionGrid.weeks.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "empty-copy", children: "No daily token data yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-contrib-frame", children: [
|
|
9727
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "stats-contrib-weekdays", children: CONTRIBUTION_WEEKDAY_LABELS.map((label, index) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: label }, `contrib-weekday-${index}`)) }),
|
|
9728
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-contrib-scroll", children: [
|
|
9729
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9730
|
+
"div",
|
|
9731
|
+
{
|
|
9732
|
+
className: "stats-contrib-months",
|
|
9733
|
+
style: { gridTemplateColumns: `repeat(${dailyContributionGrid.weeks.length}, 12px)` },
|
|
9734
|
+
children: dailyContributionGrid.months.map((month) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9735
|
+
"span",
|
|
9736
|
+
{
|
|
9737
|
+
className: "stats-contrib-month",
|
|
9738
|
+
style: { gridColumn: String(month.weekIndex + 1) },
|
|
9739
|
+
children: month.label
|
|
9740
|
+
},
|
|
9741
|
+
month.key
|
|
9742
|
+
))
|
|
9743
|
+
}
|
|
9744
|
+
),
|
|
9745
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9746
|
+
"div",
|
|
9747
|
+
{
|
|
9748
|
+
className: "stats-contrib-weeks",
|
|
9749
|
+
role: "img",
|
|
9750
|
+
"aria-label": "Daily output tokens calendar heatmap",
|
|
9751
|
+
children: dailyContributionGrid.weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "stats-contrib-week", children: week.map((cell) => {
|
|
9752
|
+
const tooltipText = `${cell.date} • ${cell.metricValue.toLocaleString()} ${selectedCalendarMetricOption.tooltipLabel}`;
|
|
9753
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9754
|
+
"div",
|
|
9755
|
+
{
|
|
9756
|
+
className: `stats-contrib-cell level-${cell.level}${!cell.inRange ? " is-padding" : ""}${cell.inRange && cell.level === 0 ? " is-empty" : ""}`,
|
|
9757
|
+
title: cell.inRange ? tooltipText : void 0,
|
|
9758
|
+
"aria-label": cell.inRange ? tooltipText : void 0,
|
|
9759
|
+
tabIndex: cell.inRange ? 0 : -1,
|
|
9760
|
+
onMouseEnter: (event) => {
|
|
9761
|
+
if (!cell.inRange) {
|
|
9762
|
+
return;
|
|
9763
|
+
}
|
|
9764
|
+
setContributionTooltip({
|
|
9765
|
+
text: tooltipText,
|
|
9766
|
+
x: event.clientX,
|
|
9767
|
+
y: event.clientY
|
|
9768
|
+
});
|
|
9769
|
+
},
|
|
9770
|
+
onMouseMove: (event) => {
|
|
9771
|
+
if (!cell.inRange) {
|
|
9772
|
+
return;
|
|
9773
|
+
}
|
|
9774
|
+
setContributionTooltip({
|
|
9775
|
+
text: tooltipText,
|
|
9776
|
+
x: event.clientX,
|
|
9777
|
+
y: event.clientY
|
|
9778
|
+
});
|
|
9779
|
+
},
|
|
9780
|
+
onMouseLeave: () => {
|
|
9781
|
+
setContributionTooltip(null);
|
|
9782
|
+
},
|
|
9783
|
+
onFocus: (event) => {
|
|
9784
|
+
if (!cell.inRange) {
|
|
9785
|
+
return;
|
|
9786
|
+
}
|
|
9787
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
9788
|
+
setContributionTooltip({
|
|
9789
|
+
text: tooltipText,
|
|
9790
|
+
x: rect.left + rect.width / 2,
|
|
9791
|
+
y: rect.bottom + 4
|
|
9792
|
+
});
|
|
9793
|
+
},
|
|
9794
|
+
onBlur: () => {
|
|
9795
|
+
setContributionTooltip(null);
|
|
9796
|
+
}
|
|
9797
|
+
},
|
|
9798
|
+
cell.date
|
|
9799
|
+
);
|
|
9800
|
+
}) }, `week-${weekIndex}`))
|
|
9801
|
+
}
|
|
9802
|
+
)
|
|
9803
|
+
] })
|
|
9804
|
+
] }),
|
|
9805
|
+
contributionTooltip ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9806
|
+
"div",
|
|
9807
|
+
{
|
|
9808
|
+
className: "stats-contrib-tooltip",
|
|
9809
|
+
role: "tooltip",
|
|
9810
|
+
style: {
|
|
9811
|
+
left: `${contributionTooltip.x + 12}px`,
|
|
9812
|
+
top: `${contributionTooltip.y + 12}px`
|
|
9813
|
+
},
|
|
9814
|
+
children: contributionTooltip.text
|
|
9815
|
+
}
|
|
9816
|
+
) : null
|
|
9817
|
+
] }),
|
|
9818
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "stats-grid-2", children: [
|
|
9819
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "stats-section", children: [
|
|
9820
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-section-header", children: [
|
|
9821
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Most active days" }),
|
|
9822
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stats-section-subtle", children: "By event count" })
|
|
9823
|
+
] }),
|
|
9824
|
+
statsData.topDays.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "empty-copy", children: "No activity data yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "stats-top-list", children: statsData.topDays.map((day) => /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "stats-top-item", children: [
|
|
9825
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: day.date }),
|
|
9826
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
9827
|
+
day.eventCount.toLocaleString(),
|
|
9828
|
+
" events"
|
|
9829
|
+
] })
|
|
9830
|
+
] }, day.date)) })
|
|
9831
|
+
] }),
|
|
9832
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "stats-section", children: [
|
|
9833
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-section-header", children: [
|
|
9834
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Most active hours" }),
|
|
9835
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stats-section-subtle", children: "By event count" })
|
|
9836
|
+
] }),
|
|
9837
|
+
statsData.topHours.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "empty-copy", children: "No activity data yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "stats-top-list", children: statsData.topHours.map((hour) => /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "stats-top-item", children: [
|
|
9838
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
9839
|
+
String(hour.hour).padStart(2, "0"),
|
|
9840
|
+
":00"
|
|
9841
|
+
] }),
|
|
9842
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
9843
|
+
hour.eventCount.toLocaleString(),
|
|
9844
|
+
" events"
|
|
9845
|
+
] })
|
|
9846
|
+
] }, hour.hour)) })
|
|
9847
|
+
] })
|
|
9848
|
+
] }),
|
|
9849
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "stats-section", children: [
|
|
9850
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-section-header", children: [
|
|
9851
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Hourly activity heatmap" }),
|
|
9852
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stats-section-subtle", children: "Event count + token volume + session presence" })
|
|
9853
|
+
] }),
|
|
9854
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "stats-heatmap-grid", children: statsData.hourly.map((point) => {
|
|
9855
|
+
const intensity = point.eventCount <= 0 ? 0 : point.eventCount / hourlyMaxEvents;
|
|
9856
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9857
|
+
"div",
|
|
9858
|
+
{
|
|
9859
|
+
className: "stats-heat-cell",
|
|
9860
|
+
style: {
|
|
9861
|
+
backgroundColor: intensity === 0 ? "rgba(59, 130, 246, 0.08)" : `rgba(59, 130, 246, ${0.16 + intensity * 0.66})`
|
|
9862
|
+
},
|
|
9863
|
+
title: `${String(point.hour).padStart(2, "0")}:00 • ${point.eventCount.toLocaleString()} events • ${point.totalTokens.toLocaleString()} tokens • ${point.sessionCount.toLocaleString()} sessions`,
|
|
9864
|
+
children: [
|
|
9865
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: String(point.hour).padStart(2, "0") }),
|
|
9866
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: point.eventCount.toLocaleString() })
|
|
9867
|
+
]
|
|
9868
|
+
},
|
|
9869
|
+
point.hour
|
|
9870
|
+
);
|
|
9871
|
+
}) })
|
|
9872
|
+
] }),
|
|
9873
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "stats-grid-2", children: [
|
|
9874
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "stats-section", children: [
|
|
9875
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-section-header", children: [
|
|
9876
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Models and reasoning effort" }),
|
|
9877
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stats-section-subtle", children: "Token distribution" })
|
|
9878
|
+
] }),
|
|
9879
|
+
statsData.models.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "empty-copy", children: "No model usage data yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "stats-table-wrap", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "stats-table", children: [
|
|
9880
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [
|
|
9881
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { children: "Model" }),
|
|
9882
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { children: "Effort" }),
|
|
9883
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { children: "Tokens" }),
|
|
9884
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { children: "Sessions" })
|
|
9885
|
+
] }) }),
|
|
9886
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: statsData.models.map((model) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [
|
|
9887
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { children: model.model }),
|
|
9888
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { children: model.reasoningEffort }),
|
|
9889
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { children: model.totalTokens.toLocaleString() }),
|
|
9890
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { children: model.sessionCount.toLocaleString() })
|
|
9891
|
+
] }, `${model.model}::${model.reasoningEffort}`)) })
|
|
9892
|
+
] }) })
|
|
9893
|
+
] }),
|
|
9894
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "stats-section", children: [
|
|
9895
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "stats-section-header", children: [
|
|
9896
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Reasoning effort mix" }),
|
|
9897
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "stats-section-subtle", children: "Across all models" })
|
|
9898
|
+
] }),
|
|
9899
|
+
statsData.reasoningEfforts.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "empty-copy", children: "No reasoning effort data yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "stats-top-list", children: statsData.reasoningEfforts.map((effort) => /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "stats-top-item", children: [
|
|
9900
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: effort.reasoningEffort }),
|
|
9901
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
9902
|
+
effort.totalTokens.toLocaleString(),
|
|
9903
|
+
" tokens"
|
|
9904
|
+
] })
|
|
9905
|
+
] }, effort.reasoningEffort)) })
|
|
9906
|
+
] })
|
|
9907
|
+
] })
|
|
9908
|
+
] })
|
|
9909
|
+
] });
|
|
9910
|
+
};
|
|
9356
9911
|
const SettingsView = () => {
|
|
9357
9912
|
const { appConfig, configLoading, fetchConfig, updateConfig } = useAppStore((state) => ({
|
|
9358
9913
|
appConfig: state.appConfig,
|
|
@@ -10829,12 +11384,15 @@ function parseCommandPreview(execution) {
|
|
|
10829
11384
|
return null;
|
|
10830
11385
|
}
|
|
10831
11386
|
const ExecutionTrace = ({ execution }) => {
|
|
10832
|
-
var _a, _b, _c;
|
|
11387
|
+
var _a, _b, _c, _d, _e;
|
|
10833
11388
|
const [expanded, setExpanded] = reactExports.useState(false);
|
|
10834
11389
|
const output = (_b = (_a = execution.functionOutput) == null ? void 0 : _a.output) != null ? _b : "";
|
|
10835
11390
|
const commandPreview = reactExports.useMemo(() => parseCommandPreview(execution), [execution]);
|
|
10836
11391
|
const isTerminalCommand = reactExports.useMemo(() => isTerminalCommandExecution(execution), [execution]);
|
|
10837
|
-
const tokenUsageLabel = execution.tokenUsage ? `${execution.tokenUsage.inputTokens.toLocaleString()} in
|
|
11392
|
+
const tokenUsageLabel = execution.tokenUsage ? `${execution.tokenUsage.inputTokens.toLocaleString()} in (${((_c = execution.tokenUsage.cachedInputTokens) != null ? _c : 0).toLocaleString()} cached + ${Math.max(
|
|
11393
|
+
execution.tokenUsage.inputTokens - ((_d = execution.tokenUsage.cachedInputTokens) != null ? _d : 0),
|
|
11394
|
+
0
|
|
11395
|
+
).toLocaleString()} uncached) • ${execution.tokenUsage.outputTokens.toLocaleString()} out` : null;
|
|
10838
11396
|
const formattedArguments = reactExports.useMemo(
|
|
10839
11397
|
() => prettyPrintJson(execution.functionCall.arguments),
|
|
10840
11398
|
[execution.functionCall.arguments]
|
|
@@ -10843,7 +11401,7 @@ const ExecutionTrace = ({ execution }) => {
|
|
|
10843
11401
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10844
11402
|
"section",
|
|
10845
11403
|
{
|
|
10846
|
-
className: `trace-card ${((
|
|
11404
|
+
className: `trace-card ${((_e = execution.functionOutput) == null ? void 0 : _e.isError) ? "error" : ""} ${isTerminalCommand ? "terminal" : ""}`,
|
|
10847
11405
|
children: [
|
|
10848
11406
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10849
11407
|
"button",
|
|
@@ -10891,7 +11449,9 @@ const ExecutionTraceGroup = ({
|
|
|
10891
11449
|
}) => {
|
|
10892
11450
|
const [expanded, setExpanded] = reactExports.useState(false);
|
|
10893
11451
|
const tokenTotals = reactExports.useMemo(() => {
|
|
11452
|
+
var _a;
|
|
10894
11453
|
let inputTokens = 0;
|
|
11454
|
+
let cachedInputTokens = 0;
|
|
10895
11455
|
let outputTokens = 0;
|
|
10896
11456
|
let hasTokenUsage = false;
|
|
10897
11457
|
for (const execution of executions) {
|
|
@@ -10900,15 +11460,19 @@ const ExecutionTraceGroup = ({
|
|
|
10900
11460
|
}
|
|
10901
11461
|
hasTokenUsage = true;
|
|
10902
11462
|
inputTokens += execution.tokenUsage.inputTokens;
|
|
11463
|
+
cachedInputTokens += (_a = execution.tokenUsage.cachedInputTokens) != null ? _a : 0;
|
|
10903
11464
|
outputTokens += execution.tokenUsage.outputTokens;
|
|
10904
11465
|
}
|
|
10905
|
-
return { hasTokenUsage, inputTokens, outputTokens };
|
|
11466
|
+
return { hasTokenUsage, inputTokens, cachedInputTokens, outputTokens };
|
|
10906
11467
|
}, [executions]);
|
|
10907
11468
|
if (executions.length === 0) {
|
|
10908
11469
|
return null;
|
|
10909
11470
|
}
|
|
10910
11471
|
const countLabel = `${executions.length} command${executions.length === 1 ? "" : "s"}`;
|
|
10911
|
-
const tokenUsageLabel = tokenTotals.hasTokenUsage ? `${tokenTotals.inputTokens.toLocaleString()} in
|
|
11472
|
+
const tokenUsageLabel = tokenTotals.hasTokenUsage ? `${tokenTotals.inputTokens.toLocaleString()} in (${tokenTotals.cachedInputTokens.toLocaleString()} cached + ${Math.max(
|
|
11473
|
+
tokenTotals.inputTokens - tokenTotals.cachedInputTokens,
|
|
11474
|
+
0
|
|
11475
|
+
).toLocaleString()} uncached) • ${tokenTotals.outputTokens.toLocaleString()} out` : null;
|
|
10912
11476
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "trace-group-card", children: [
|
|
10913
11477
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10914
11478
|
"button",
|
|
@@ -11320,6 +11884,16 @@ function getPreludeHint(kind) {
|
|
|
11320
11884
|
return "System prelude";
|
|
11321
11885
|
}
|
|
11322
11886
|
}
|
|
11887
|
+
function buildSessionTokenStats() {
|
|
11888
|
+
return {
|
|
11889
|
+
totalTokens: 0,
|
|
11890
|
+
inputTokens: 0,
|
|
11891
|
+
outputTokens: 0
|
|
11892
|
+
};
|
|
11893
|
+
}
|
|
11894
|
+
function buildSystemPreludeKey(timestamp, rowIndex) {
|
|
11895
|
+
return `${timestamp}-${rowIndex}`;
|
|
11896
|
+
}
|
|
11323
11897
|
const ChatHistory = ({ sessionId }) => {
|
|
11324
11898
|
const { chunks, chunksLoading, chunksSessionId, sessions } = useAppStore((state) => ({
|
|
11325
11899
|
chunks: state.chunks,
|
|
@@ -11334,7 +11908,40 @@ const ChatHistory = ({ sessionId }) => {
|
|
|
11334
11908
|
estimateSize: () => 168,
|
|
11335
11909
|
overscan: 6
|
|
11336
11910
|
});
|
|
11911
|
+
const [expandedPreludeKeys, setExpandedPreludeKeys] = reactExports.useState(
|
|
11912
|
+
() => /* @__PURE__ */ new Set()
|
|
11913
|
+
);
|
|
11337
11914
|
const virtualRows = rowVirtualizer.getVirtualItems();
|
|
11915
|
+
const remeasureVisibleRows = reactExports.useCallback(() => {
|
|
11916
|
+
rowVirtualizer.measure();
|
|
11917
|
+
const parent = parentRef.current;
|
|
11918
|
+
if (!parent) {
|
|
11919
|
+
return;
|
|
11920
|
+
}
|
|
11921
|
+
for (const row of rowVirtualizer.getVirtualItems()) {
|
|
11922
|
+
const element = parent.querySelector(`[data-index="${row.index}"]`);
|
|
11923
|
+
if (!element) {
|
|
11924
|
+
continue;
|
|
11925
|
+
}
|
|
11926
|
+
rowVirtualizer.measureElement(element);
|
|
11927
|
+
}
|
|
11928
|
+
}, [rowVirtualizer]);
|
|
11929
|
+
const toggleSystemPrelude = reactExports.useCallback((preludeKey) => {
|
|
11930
|
+
setExpandedPreludeKeys((current) => {
|
|
11931
|
+
const next = new Set(current);
|
|
11932
|
+
if (next.has(preludeKey)) {
|
|
11933
|
+
next.delete(preludeKey);
|
|
11934
|
+
} else {
|
|
11935
|
+
next.add(preludeKey);
|
|
11936
|
+
}
|
|
11937
|
+
return next;
|
|
11938
|
+
});
|
|
11939
|
+
remeasureVisibleRows();
|
|
11940
|
+
notifyChatLayoutInvalidated();
|
|
11941
|
+
}, [remeasureVisibleRows]);
|
|
11942
|
+
reactExports.useEffect(() => {
|
|
11943
|
+
setExpandedPreludeKeys(/* @__PURE__ */ new Set());
|
|
11944
|
+
}, [sessionId]);
|
|
11338
11945
|
reactExports.useEffect(() => {
|
|
11339
11946
|
const container = parentRef.current;
|
|
11340
11947
|
if (!container) {
|
|
@@ -11350,15 +11957,37 @@ const ChatHistory = ({ sessionId }) => {
|
|
|
11350
11957
|
return;
|
|
11351
11958
|
}
|
|
11352
11959
|
const handleLayoutInvalidation = () => {
|
|
11353
|
-
|
|
11960
|
+
remeasureVisibleRows();
|
|
11961
|
+
requestAnimationFrame(() => {
|
|
11962
|
+
remeasureVisibleRows();
|
|
11963
|
+
});
|
|
11354
11964
|
};
|
|
11355
11965
|
window.addEventListener(CHAT_LAYOUT_INVALIDATED_EVENT, handleLayoutInvalidation);
|
|
11356
11966
|
return () => {
|
|
11357
11967
|
window.removeEventListener(CHAT_LAYOUT_INVALIDATED_EVENT, handleLayoutInvalidation);
|
|
11358
11968
|
};
|
|
11359
|
-
}, [
|
|
11969
|
+
}, [remeasureVisibleRows]);
|
|
11970
|
+
reactExports.useEffect(() => {
|
|
11971
|
+
remeasureVisibleRows();
|
|
11972
|
+
const raf = requestAnimationFrame(() => {
|
|
11973
|
+
remeasureVisibleRows();
|
|
11974
|
+
});
|
|
11975
|
+
return () => cancelAnimationFrame(raf);
|
|
11976
|
+
}, [chunks, expandedPreludeKeys, remeasureVisibleRows]);
|
|
11360
11977
|
const hasChunks = chunks.length > 0;
|
|
11361
11978
|
const isLoading = chunksLoading && chunksSessionId === sessionId;
|
|
11979
|
+
const sessionTokenStats = reactExports.useMemo(() => {
|
|
11980
|
+
return chunks.reduce((totals, chunk) => {
|
|
11981
|
+
var _a, _b, _c;
|
|
11982
|
+
if (chunk.type !== "ai") {
|
|
11983
|
+
return totals;
|
|
11984
|
+
}
|
|
11985
|
+
totals.totalTokens += (_a = chunk.metrics.totalTokens) != null ? _a : 0;
|
|
11986
|
+
totals.inputTokens += (_b = chunk.metrics.inputTokens) != null ? _b : 0;
|
|
11987
|
+
totals.outputTokens += (_c = chunk.metrics.outputTokens) != null ? _c : 0;
|
|
11988
|
+
return totals;
|
|
11989
|
+
}, buildSessionTokenStats());
|
|
11990
|
+
}, [chunks]);
|
|
11362
11991
|
const initialModelUsage = reactExports.useMemo(() => {
|
|
11363
11992
|
if (!sessionId) {
|
|
11364
11993
|
return null;
|
|
@@ -11386,14 +12015,27 @@ const ChatHistory = ({ sessionId }) => {
|
|
|
11386
12015
|
] });
|
|
11387
12016
|
}
|
|
11388
12017
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
11389
|
-
|
|
11390
|
-
"
|
|
11391
|
-
|
|
11392
|
-
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
|
|
11396
|
-
|
|
12018
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "chat-session-token-sticky", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "chat-session-token-strip", "aria-label": "Session token totals and initial model", children: [
|
|
12019
|
+
initialModelUsage ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "chat-session-token-pair", children: [
|
|
12020
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "chat-session-token-key", children: "Model:" }),
|
|
12021
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "chat-session-token-value", children: [
|
|
12022
|
+
initialModelUsage.model,
|
|
12023
|
+
initialModelUsage.reasoningEffort !== "unknown" ? ` (${initialModelUsage.reasoningEffort})` : ""
|
|
12024
|
+
] })
|
|
12025
|
+
] }) : null,
|
|
12026
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "chat-session-token-pair", children: [
|
|
12027
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "chat-session-token-key", children: "In:" }),
|
|
12028
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "chat-session-token-value", children: sessionTokenStats.inputTokens.toLocaleString() })
|
|
12029
|
+
] }),
|
|
12030
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "chat-session-token-pair", children: [
|
|
12031
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "chat-session-token-key", children: "Out:" }),
|
|
12032
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "chat-session-token-value", children: sessionTokenStats.outputTokens.toLocaleString() })
|
|
12033
|
+
] }),
|
|
12034
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "chat-session-token-pair", children: [
|
|
12035
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "chat-session-token-key", children: "Total:" }),
|
|
12036
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "chat-session-token-value", children: sessionTokenStats.totalTokens.toLocaleString() })
|
|
12037
|
+
] })
|
|
12038
|
+
] }) }),
|
|
11397
12039
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11398
12040
|
"div",
|
|
11399
12041
|
{
|
|
@@ -11408,6 +12050,8 @@ const ChatHistory = ({ sessionId }) => {
|
|
|
11408
12050
|
return null;
|
|
11409
12051
|
}
|
|
11410
12052
|
const systemPreludeKind = chunk.type === "system" ? classifyCodexBootstrapMessage(chunk.content) : null;
|
|
12053
|
+
const systemPreludeKey = chunk.type === "system" && systemPreludeKind && systemPreludeKind !== "collaboration_mode" ? buildSystemPreludeKey(chunk.timestamp, virtualRow.index) : null;
|
|
12054
|
+
const isSystemPreludeExpanded = systemPreludeKey !== null && expandedPreludeKeys.has(systemPreludeKey);
|
|
11411
12055
|
const key = `${chunk.type}-${chunk.timestamp}-${virtualRow.index}`;
|
|
11412
12056
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11413
12057
|
"div",
|
|
@@ -11429,16 +12073,28 @@ const ChatHistory = ({ sessionId }) => {
|
|
|
11429
12073
|
"Collaboration mode: ",
|
|
11430
12074
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: extractCollaborationModeLabel(chunk.content) })
|
|
11431
12075
|
] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11432
|
-
"
|
|
12076
|
+
"section",
|
|
11433
12077
|
{
|
|
11434
|
-
className: `chat-system-prelude ${systemPreludeKind}`,
|
|
11435
|
-
onToggle: notifyChatLayoutInvalidated,
|
|
12078
|
+
className: `chat-system-prelude ${systemPreludeKind}${isSystemPreludeExpanded ? " open" : ""}`,
|
|
11436
12079
|
children: [
|
|
11437
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11438
|
-
|
|
11439
|
-
|
|
11440
|
-
|
|
11441
|
-
|
|
12080
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12081
|
+
"button",
|
|
12082
|
+
{
|
|
12083
|
+
type: "button",
|
|
12084
|
+
className: "chat-system-prelude-summary",
|
|
12085
|
+
"aria-expanded": isSystemPreludeExpanded,
|
|
12086
|
+
onClick: () => {
|
|
12087
|
+
if (systemPreludeKey) {
|
|
12088
|
+
toggleSystemPrelude(systemPreludeKey);
|
|
12089
|
+
}
|
|
12090
|
+
},
|
|
12091
|
+
children: [
|
|
12092
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: getPreludeLabel(systemPreludeKind) }),
|
|
12093
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "chat-system-prelude-summary-hint", children: getPreludeHint(systemPreludeKind) })
|
|
12094
|
+
]
|
|
12095
|
+
}
|
|
12096
|
+
),
|
|
12097
|
+
isSystemPreludeExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "chat-system-prelude-content", children: chunk.content }) : null
|
|
11442
12098
|
]
|
|
11443
12099
|
}
|
|
11444
12100
|
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "chat-system-message", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: chunk.content }) }) : null,
|
|
@@ -11471,7 +12127,20 @@ const ChatHistory = ({ sessionId }) => {
|
|
|
11471
12127
|
}
|
|
11472
12128
|
)
|
|
11473
12129
|
] });
|
|
11474
|
-
}, [
|
|
12130
|
+
}, [
|
|
12131
|
+
chunks,
|
|
12132
|
+
hasChunks,
|
|
12133
|
+
initialModelUsage,
|
|
12134
|
+
isLoading,
|
|
12135
|
+
rowVirtualizer,
|
|
12136
|
+
sessionTokenStats.inputTokens,
|
|
12137
|
+
sessionTokenStats.outputTokens,
|
|
12138
|
+
sessionTokenStats.totalTokens,
|
|
12139
|
+
expandedPreludeKeys,
|
|
12140
|
+
remeasureVisibleRows,
|
|
12141
|
+
toggleSystemPrelude,
|
|
12142
|
+
virtualRows
|
|
12143
|
+
]);
|
|
11475
12144
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "chat-shell", ref: parentRef, children: content });
|
|
11476
12145
|
};
|
|
11477
12146
|
const SessionTabContent = ({ tab }) => {
|
|
@@ -11695,6 +12364,7 @@ const Sidebar = () => {
|
|
|
11695
12364
|
] });
|
|
11696
12365
|
};
|
|
11697
12366
|
const DASHBOARD_TAB_ID$1 = "dashboard";
|
|
12367
|
+
const STATS_TAB_ID$1 = "stats";
|
|
11698
12368
|
const SETTINGS_TAB_ID$1 = "settings";
|
|
11699
12369
|
const TabBar = () => {
|
|
11700
12370
|
const {
|
|
@@ -11703,6 +12373,7 @@ const TabBar = () => {
|
|
|
11703
12373
|
setActiveTab,
|
|
11704
12374
|
closeTab,
|
|
11705
12375
|
openDashboardTab,
|
|
12376
|
+
openStatsTab,
|
|
11706
12377
|
openSettingsTab,
|
|
11707
12378
|
toggleSidebarCollapsed,
|
|
11708
12379
|
sidebarCollapsed
|
|
@@ -11712,6 +12383,7 @@ const TabBar = () => {
|
|
|
11712
12383
|
setActiveTab: state.setActiveTab,
|
|
11713
12384
|
closeTab: state.closeTab,
|
|
11714
12385
|
openDashboardTab: state.openDashboardTab,
|
|
12386
|
+
openStatsTab: state.openStatsTab,
|
|
11715
12387
|
openSettingsTab: state.openSettingsTab,
|
|
11716
12388
|
toggleSidebarCollapsed: state.toggleSidebarCollapsed,
|
|
11717
12389
|
sidebarCollapsed: state.sidebarCollapsed
|
|
@@ -11743,6 +12415,17 @@ const TabBar = () => {
|
|
|
11743
12415
|
children: "Dashboard"
|
|
11744
12416
|
}
|
|
11745
12417
|
),
|
|
12418
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12419
|
+
"button",
|
|
12420
|
+
{
|
|
12421
|
+
className: `tabbar-action ${activeTabId === STATS_TAB_ID$1 ? "active" : ""}`,
|
|
12422
|
+
onClick: openStatsTab,
|
|
12423
|
+
type: "button",
|
|
12424
|
+
role: "tab",
|
|
12425
|
+
"aria-selected": activeTabId === STATS_TAB_ID$1,
|
|
12426
|
+
children: "Stats"
|
|
12427
|
+
}
|
|
12428
|
+
),
|
|
11746
12429
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11747
12430
|
"button",
|
|
11748
12431
|
{
|
|
@@ -11786,6 +12469,7 @@ const TabBar = () => {
|
|
|
11786
12469
|
};
|
|
11787
12470
|
const DASHBOARD_TAB_ID = "dashboard";
|
|
11788
12471
|
const SETTINGS_TAB_ID = "settings";
|
|
12472
|
+
const STATS_TAB_ID = "stats";
|
|
11789
12473
|
const TabbedLayout = () => {
|
|
11790
12474
|
const { openTabs, activeTabId, sidebarCollapsed } = useAppStore((state) => ({
|
|
11791
12475
|
openTabs: state.openTabs,
|
|
@@ -11797,13 +12481,15 @@ const TabbedLayout = () => {
|
|
|
11797
12481
|
return (activeTab == null ? void 0 : activeTab.type) === "session" ? activeTab : null;
|
|
11798
12482
|
}, [openTabs, activeTabId]);
|
|
11799
12483
|
const settingsActive = activeTabId === SETTINGS_TAB_ID;
|
|
11800
|
-
const
|
|
12484
|
+
const statsActive = activeTabId === STATS_TAB_ID;
|
|
12485
|
+
const dashboardActive = activeTabId === DASHBOARD_TAB_ID || !settingsActive && !statsActive && !activeSessionTab;
|
|
11801
12486
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "layout-shell", children: [
|
|
11802
12487
|
!sidebarCollapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(Sidebar, {}) : null,
|
|
11803
12488
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "content-shell", children: [
|
|
11804
12489
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TabBar, {}),
|
|
11805
12490
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "content-body", children: [
|
|
11806
12491
|
activeSessionTab ? /* @__PURE__ */ jsxRuntimeExports.jsx(SessionTabContent, { tab: activeSessionTab }) : null,
|
|
12492
|
+
statsActive ? /* @__PURE__ */ jsxRuntimeExports.jsx(StatsView, {}) : null,
|
|
11807
12493
|
dashboardActive ? /* @__PURE__ */ jsxRuntimeExports.jsx(DashboardView, {}) : null,
|
|
11808
12494
|
settingsActive ? /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsView, {}) : null
|
|
11809
12495
|
] })
|