@oh-my-pi/omp-stats 18.3.5 → 18.4.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/CHANGELOG.md +22 -0
- package/README.md +13 -11
- package/build.ts +5 -49
- package/dist/client/index.css +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/index.js +105 -126
- package/dist/types/aggregator.d.ts +25 -22
- package/dist/types/client/api.d.ts +11 -7
- package/dist/types/client/app/LiveChip.d.ts +2 -0
- package/dist/types/client/app/Shell.d.ts +16 -0
- package/dist/types/client/app/ThemeToggle.d.ts +1 -0
- package/dist/types/client/app/nav.d.ts +18 -0
- package/dist/types/client/charts/BarList.d.ts +17 -0
- package/dist/types/client/charts/Chart.d.ts +49 -0
- package/dist/types/client/charts/Legend.d.ts +16 -0
- package/dist/types/client/charts/ShareBar.d.ts +11 -0
- package/dist/types/client/charts/Sparkline.d.ts +11 -0
- package/dist/types/client/charts/TimeChart.d.ts +9 -0
- package/dist/types/client/charts/index.d.ts +7 -0
- package/dist/types/client/charts/types.d.ts +25 -0
- package/dist/types/client/charts/useWidth.d.ts +3 -0
- package/dist/types/client/data/colors.d.ts +25 -0
- package/dist/types/client/data/formatters.d.ts +9 -1
- package/dist/types/client/data/live.d.ts +29 -0
- package/dist/types/client/data/query.d.ts +35 -0
- package/dist/types/client/data/range.d.ts +31 -0
- package/dist/types/client/data/series.d.ts +28 -0
- package/dist/types/client/data/useHashRoute.d.ts +18 -4
- package/dist/types/client/data/view-models.d.ts +111 -28
- package/dist/types/client/index.d.ts +0 -1
- package/dist/types/client/routes/CostsRoute.d.ts +2 -2
- package/dist/types/client/routes/ErrorsRoute.d.ts +2 -2
- package/dist/types/client/routes/FrustrationRoute.d.ts +7 -0
- package/dist/types/client/routes/GainRoute.d.ts +1 -2
- package/dist/types/client/routes/ModelsRoute.d.ts +2 -2
- package/dist/types/client/routes/OverviewRoute.d.ts +1 -2
- package/dist/types/client/routes/ProjectsRoute.d.ts +2 -2
- package/dist/types/client/routes/ProvidersRoute.d.ts +2 -2
- package/dist/types/client/routes/RequestsRoute.d.ts +1 -2
- package/dist/types/client/routes/ToolsRoute.d.ts +2 -2
- package/dist/types/client/routes/TracesRoute.d.ts +2 -2
- package/dist/types/client/routes/index.d.ts +1 -1
- package/dist/types/client/traces/AggregatesPanel.d.ts +4 -3
- package/dist/types/client/traces/SummaryStrip.d.ts +2 -2
- package/dist/types/client/traces/trace-colors.d.ts +18 -12
- package/dist/types/client/ui/Badge.d.ts +19 -0
- package/dist/types/client/ui/Card.d.ts +25 -0
- package/dist/types/client/ui/Drawer.d.ts +25 -0
- package/dist/types/client/ui/JsonBlock.d.ts +2 -2
- package/dist/types/client/ui/Modal.d.ts +23 -0
- package/dist/types/client/ui/RequestDrawer.d.ts +10 -1
- package/dist/types/client/ui/SearchInput.d.ts +8 -0
- package/dist/types/client/ui/Segmented.d.ts +15 -0
- package/dist/types/client/ui/Stat.d.ts +36 -0
- package/dist/types/client/ui/States.d.ts +41 -0
- package/dist/types/client/ui/Table.d.ts +48 -0
- package/dist/types/client/ui/index.d.ts +9 -10
- package/dist/types/db.d.ts +90 -106
- package/dist/types/frustration.d.ts +70 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/live.d.ts +30 -0
- package/dist/types/rollup.d.ts +115 -0
- package/dist/types/server.d.ts +6 -1
- package/dist/types/shared-types.d.ts +116 -56
- package/dist/types/types.d.ts +4 -0
- package/dist/types/user-metrics.d.ts +8 -0
- package/package.json +7 -13
- package/src/aggregator.ts +276 -211
- package/src/client/App.tsx +38 -80
- package/src/client/api.ts +65 -7
- package/src/client/app/LiveChip.tsx +97 -0
- package/src/client/app/Shell.tsx +181 -0
- package/src/client/app/ThemeToggle.tsx +5 -2
- package/src/client/app/nav.ts +78 -0
- package/src/client/charts/BarList.tsx +48 -0
- package/src/client/charts/Chart.tsx +388 -0
- package/src/client/charts/Legend.tsx +61 -0
- package/src/client/charts/ShareBar.tsx +26 -0
- package/src/client/charts/Sparkline.tsx +38 -0
- package/src/client/charts/TimeChart.tsx +22 -0
- package/src/client/charts/index.ts +7 -0
- package/src/client/charts/types.ts +27 -0
- package/src/client/charts/useWidth.ts +19 -0
- package/src/client/data/colors.ts +45 -0
- package/src/client/data/formatters.ts +30 -9
- package/src/client/data/live.tsx +85 -0
- package/src/client/data/query.ts +166 -0
- package/src/client/data/range.ts +82 -0
- package/src/client/data/series.ts +85 -0
- package/src/client/data/useHashRoute.ts +41 -83
- package/src/client/data/view-models.ts +347 -140
- package/src/client/index.tsx +3 -6
- package/src/client/routes/CostsRoute.tsx +394 -222
- package/src/client/routes/ErrorsRoute.tsx +401 -98
- package/src/client/routes/FrustrationRoute.tsx +924 -0
- package/src/client/routes/GainRoute.tsx +209 -206
- package/src/client/routes/ModelsRoute.tsx +540 -431
- package/src/client/routes/OverviewRoute.tsx +283 -311
- package/src/client/routes/ProjectsRoute.tsx +298 -156
- package/src/client/routes/ProvidersRoute.tsx +948 -416
- package/src/client/routes/RequestsRoute.tsx +295 -107
- package/src/client/routes/ToolsRoute.tsx +495 -398
- package/src/client/routes/TracesRoute.tsx +136 -117
- package/src/client/routes/costs.css +24 -0
- package/src/client/routes/errors.css +60 -0
- package/src/client/routes/frustration.css +123 -0
- package/src/client/routes/index.ts +1 -1
- package/src/client/routes/models.css +43 -0
- package/src/client/routes/projects.css +6 -0
- package/src/client/routes/providers.css +28 -0
- package/src/client/routes/tools.css +14 -0
- package/src/client/styles.css +1396 -1299
- package/src/client/traces/AggregatesPanel.tsx +55 -74
- package/src/client/traces/Minimap.tsx +6 -15
- package/src/client/traces/SpanDrawer.tsx +128 -194
- package/src/client/traces/SummaryStrip.tsx +21 -24
- package/src/client/traces/TimelineCanvas.tsx +27 -44
- package/src/client/traces/TraceView.tsx +175 -130
- package/src/client/traces/TranscriptList.tsx +13 -41
- package/src/client/traces/trace-colors.ts +60 -53
- package/src/client/traces/traces.css +279 -0
- package/src/client/ui/Badge.tsx +29 -0
- package/src/client/ui/Card.tsx +61 -0
- package/src/client/ui/Drawer.tsx +93 -0
- package/src/client/ui/JsonBlock.tsx +26 -44
- package/src/client/ui/Modal.tsx +106 -0
- package/src/client/ui/RequestDrawer.tsx +163 -188
- package/src/client/ui/SearchInput.tsx +25 -0
- package/src/client/ui/Segmented.tsx +61 -0
- package/src/client/ui/Stat.tsx +104 -0
- package/src/client/ui/States.tsx +81 -0
- package/src/client/ui/Table.tsx +229 -0
- package/src/client/ui/index.ts +9 -10
- package/src/client/ui/modal.css +54 -0
- package/src/client/ui/request-drawer.css +40 -0
- package/src/db.ts +379 -983
- package/src/frustration.ts +473 -0
- package/src/index.ts +22 -22
- package/src/live.ts +259 -0
- package/src/parser.ts +55 -66
- package/src/rollup.ts +951 -0
- package/src/server.ts +143 -87
- package/src/shared-types.ts +120 -56
- package/src/trace.ts +14 -7
- package/src/types.ts +4 -0
- package/src/user-metrics.ts +13 -0
- package/dist/client/styles.css +0 -1976
- package/dist/types/client/app/AppLayout.d.ts +0 -16
- package/dist/types/client/app/NavRail.d.ts +0 -7
- package/dist/types/client/app/RangeControl.d.ts +0 -7
- package/dist/types/client/app/SyncButton.d.ts +0 -14
- package/dist/types/client/app/TopBar.d.ts +0 -15
- package/dist/types/client/app/routes.d.ts +0 -12
- package/dist/types/client/components/AgentTokenShare.d.ts +0 -5
- package/dist/types/client/components/chart-shared.d.ts +0 -178
- package/dist/types/client/components/models-table-shared.d.ts +0 -175
- package/dist/types/client/components/range-meta.d.ts +0 -21
- package/dist/types/client/data/charts.d.ts +0 -1
- package/dist/types/client/data/useResource.d.ts +0 -13
- package/dist/types/client/routes/BehaviorRoute.d.ts +0 -7
- package/dist/types/client/ui/AsyncBoundary.d.ts +0 -12
- package/dist/types/client/ui/DataTable.d.ts +0 -17
- package/dist/types/client/ui/EmptyState.d.ts +0 -7
- package/dist/types/client/ui/ErrorState.d.ts +0 -6
- package/dist/types/client/ui/MetricCluster.d.ts +0 -5
- package/dist/types/client/ui/Panel.d.ts +0 -7
- package/dist/types/client/ui/SegmentedControl.d.ts +0 -12
- package/dist/types/client/ui/Skeleton.d.ts +0 -8
- package/dist/types/client/ui/StatusPill.d.ts +0 -7
- package/src/client/app/AppLayout.tsx +0 -93
- package/src/client/app/NavRail.tsx +0 -44
- package/src/client/app/RangeControl.tsx +0 -39
- package/src/client/app/SyncButton.tsx +0 -75
- package/src/client/app/TopBar.tsx +0 -73
- package/src/client/app/routes.ts +0 -93
- package/src/client/components/AgentTokenShare.tsx +0 -68
- package/src/client/components/chart-shared.tsx +0 -273
- package/src/client/components/models-table-shared.tsx +0 -255
- package/src/client/components/range-meta.ts +0 -73
- package/src/client/data/charts.ts +0 -14
- package/src/client/data/useResource.ts +0 -154
- package/src/client/routes/BehaviorRoute.tsx +0 -623
- package/src/client/ui/AsyncBoundary.tsx +0 -54
- package/src/client/ui/DataTable.tsx +0 -122
- package/src/client/ui/EmptyState.tsx +0 -16
- package/src/client/ui/ErrorState.tsx +0 -25
- package/src/client/ui/MetricCluster.tsx +0 -92
- package/src/client/ui/Panel.tsx +0 -24
- package/src/client/ui/SegmentedControl.tsx +0 -36
- package/src/client/ui/Skeleton.tsx +0 -17
- package/src/client/ui/StatusPill.tsx +0 -15
- package/tailwind.config.js +0 -40
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type React from "react";
|
|
2
|
-
import type { TimeRange } from "../types.js";
|
|
3
|
-
import type { DashboardSection } from "./routes.js";
|
|
4
|
-
export interface AppLayoutProps {
|
|
5
|
-
activeSection: DashboardSection;
|
|
6
|
-
onSectionChange: (section: DashboardSection) => void;
|
|
7
|
-
range: TimeRange;
|
|
8
|
-
onRangeChange: (range: TimeRange) => void;
|
|
9
|
-
updatedAt: number | null;
|
|
10
|
-
onSyncStart?: () => void;
|
|
11
|
-
onSyncComplete?: (result: {
|
|
12
|
-
success: boolean;
|
|
13
|
-
}) => void;
|
|
14
|
-
children: React.ReactNode;
|
|
15
|
-
}
|
|
16
|
-
export declare function AppLayout({ activeSection, onSectionChange, range, onRangeChange, updatedAt, onSyncStart, onSyncComplete, children, }: AppLayoutProps): React.JSX.Element;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type DashboardSection } from "./routes.js";
|
|
2
|
-
export interface NavRailProps {
|
|
3
|
-
activeSection: DashboardSection;
|
|
4
|
-
onSectionChange: (section: DashboardSection) => void;
|
|
5
|
-
className?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function NavRail({ activeSection, onSectionChange, className }: NavRailProps): import("react").JSX.Element;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { TimeRange } from "../types.js";
|
|
2
|
-
export interface RangeControlProps {
|
|
3
|
-
value: TimeRange;
|
|
4
|
-
onChange: (value: TimeRange) => void;
|
|
5
|
-
className?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function RangeControl({ value, onChange, className }: RangeControlProps): import("react").JSX.Element;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export interface SyncButtonProps {
|
|
2
|
-
onSyncStart?: () => void;
|
|
3
|
-
onSyncComplete?: (result: {
|
|
4
|
-
success: boolean;
|
|
5
|
-
data?: {
|
|
6
|
-
processed: number;
|
|
7
|
-
files: number;
|
|
8
|
-
totalMessages: number;
|
|
9
|
-
};
|
|
10
|
-
error?: string;
|
|
11
|
-
}) => void;
|
|
12
|
-
className?: string;
|
|
13
|
-
}
|
|
14
|
-
export declare function SyncButton({ onSyncStart, onSyncComplete, className }: SyncButtonProps): import("react").JSX.Element;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { TimeRange } from "../types.js";
|
|
2
|
-
import type { DashboardSection } from "./routes.js";
|
|
3
|
-
export interface TopBarProps {
|
|
4
|
-
activeSection: DashboardSection;
|
|
5
|
-
range: TimeRange;
|
|
6
|
-
onRangeChange: (range: TimeRange) => void;
|
|
7
|
-
updatedAt: number | null;
|
|
8
|
-
onSyncStart?: () => void;
|
|
9
|
-
onSyncComplete?: (result: {
|
|
10
|
-
success: boolean;
|
|
11
|
-
}) => void;
|
|
12
|
-
onMenuToggle?: () => void;
|
|
13
|
-
className?: string;
|
|
14
|
-
}
|
|
15
|
-
export declare function TopBar({ activeSection, range, onRangeChange, updatedAt, onSyncStart, onSyncComplete, onMenuToggle, className, }: TopBarProps): import("react").JSX.Element;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type React from "react";
|
|
2
|
-
export type DashboardSection = "overview" | "requests" | "traces" | "errors" | "models" | "providers" | "tools" | "costs" | "behavior" | "projects" | "gain";
|
|
3
|
-
export interface DashboardRoute {
|
|
4
|
-
id: DashboardSection;
|
|
5
|
-
label: string;
|
|
6
|
-
shortLabel?: string;
|
|
7
|
-
icon: React.ComponentType<{
|
|
8
|
-
size?: number;
|
|
9
|
-
className?: string;
|
|
10
|
-
}>;
|
|
11
|
-
}
|
|
12
|
-
export declare const routes: DashboardRoute[];
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared chart primitives for the dashboard timeline charts: the OMP color
|
|
3
|
-
* palette, light/dark chart chrome, legend/tooltip + scale plumbing, dataset
|
|
4
|
-
* styling, and the top-N-by-model / aggregate bucketing used by the cost and
|
|
5
|
-
* behavior series.
|
|
6
|
-
*/
|
|
7
|
-
export declare const MODEL_COLORS: string[];
|
|
8
|
-
export declare function buildModelColorLookup(records: readonly {
|
|
9
|
-
model: string;
|
|
10
|
-
provider: string;
|
|
11
|
-
totalRequests: number;
|
|
12
|
-
}[]): Map<string, string>;
|
|
13
|
-
export declare const CHART_THEMES: {
|
|
14
|
-
readonly dark: {
|
|
15
|
-
readonly legendLabel: "#a89fb3";
|
|
16
|
-
readonly tooltipBackground: "#241a2e";
|
|
17
|
-
readonly tooltipTitle: "#eae5ef";
|
|
18
|
-
readonly tooltipBody: "#a89fb3";
|
|
19
|
-
readonly tooltipBorder: "rgba(255, 255, 255, 0.12)";
|
|
20
|
-
readonly grid: "rgba(255, 255, 255, 0.06)";
|
|
21
|
-
readonly tick: "#867a93";
|
|
22
|
-
};
|
|
23
|
-
readonly light: {
|
|
24
|
-
readonly legendLabel: "#5a5462";
|
|
25
|
-
readonly tooltipBackground: "#ffffff";
|
|
26
|
-
readonly tooltipTitle: "#241a2e";
|
|
27
|
-
readonly tooltipBody: "#5a5462";
|
|
28
|
-
readonly tooltipBorder: "rgba(20, 12, 28, 0.15)";
|
|
29
|
-
readonly grid: "rgba(20, 12, 28, 0.08)";
|
|
30
|
-
readonly tick: "#6a6275";
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
export type ChartTheme = (typeof CHART_THEMES)[keyof typeof CHART_THEMES];
|
|
34
|
-
export interface ChartSeries {
|
|
35
|
-
labels: string[];
|
|
36
|
-
datasets: Array<{
|
|
37
|
-
label: string;
|
|
38
|
-
data: number[];
|
|
39
|
-
}>;
|
|
40
|
-
}
|
|
41
|
-
interface TooltipItem {
|
|
42
|
-
parsed: {
|
|
43
|
-
y: number | null;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
/** Tooltip + legend config common to bar and line variants of the time charts. */
|
|
47
|
-
export declare function buildSharedPlugins(opts: {
|
|
48
|
-
chartTheme: ChartTheme;
|
|
49
|
-
showLegend: boolean;
|
|
50
|
-
defaultLabel: string;
|
|
51
|
-
formatValue: (n: number) => string;
|
|
52
|
-
footer?: (items: TooltipItem[]) => string | undefined;
|
|
53
|
-
}): {
|
|
54
|
-
legend: {
|
|
55
|
-
display: boolean;
|
|
56
|
-
position: "top";
|
|
57
|
-
align: "start";
|
|
58
|
-
labels: {
|
|
59
|
-
color: "#5a5462" | "#a89fb3";
|
|
60
|
-
usePointStyle: boolean;
|
|
61
|
-
padding: number;
|
|
62
|
-
font: {
|
|
63
|
-
size: number;
|
|
64
|
-
};
|
|
65
|
-
boxWidth: number;
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
tooltip: {
|
|
69
|
-
backgroundColor: "#241a2e" | "#ffffff";
|
|
70
|
-
titleColor: "#241a2e" | "#eae5ef";
|
|
71
|
-
bodyColor: "#5a5462" | "#a89fb3";
|
|
72
|
-
borderColor: "rgba(20, 12, 28, 0.15)" | "rgba(255, 255, 255, 0.12)";
|
|
73
|
-
borderWidth: number;
|
|
74
|
-
padding: number;
|
|
75
|
-
cornerRadius: number;
|
|
76
|
-
callbacks: {
|
|
77
|
-
label: (ctx: {
|
|
78
|
-
dataset: {
|
|
79
|
-
label?: string;
|
|
80
|
-
};
|
|
81
|
-
parsed: {
|
|
82
|
-
y: number | null;
|
|
83
|
-
};
|
|
84
|
-
}) => string;
|
|
85
|
-
footer?: ((items: TooltipItem[]) => string | undefined) | undefined;
|
|
86
|
-
};
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
/** Y-axis tick formatter + grid/tick styling shared by both charts. */
|
|
90
|
-
export declare function buildSharedScales(opts: {
|
|
91
|
-
chartTheme: ChartTheme;
|
|
92
|
-
formatY: (n: number) => string;
|
|
93
|
-
}): {
|
|
94
|
-
sharedScaleBase: {
|
|
95
|
-
grid: {
|
|
96
|
-
color: "rgba(20, 12, 28, 0.08)" | "rgba(255, 255, 255, 0.06)";
|
|
97
|
-
drawBorder: boolean;
|
|
98
|
-
};
|
|
99
|
-
ticks: {
|
|
100
|
-
color: "#6a6275" | "#867a93";
|
|
101
|
-
font: {
|
|
102
|
-
size: number;
|
|
103
|
-
};
|
|
104
|
-
};
|
|
105
|
-
};
|
|
106
|
-
yScale: {
|
|
107
|
-
grid: {
|
|
108
|
-
color: "rgba(20, 12, 28, 0.08)" | "rgba(255, 255, 255, 0.06)";
|
|
109
|
-
drawBorder: boolean;
|
|
110
|
-
};
|
|
111
|
-
ticks: {
|
|
112
|
-
color: "#6a6275" | "#867a93";
|
|
113
|
-
font: {
|
|
114
|
-
size: number;
|
|
115
|
-
};
|
|
116
|
-
callback: (value: number | string) => string;
|
|
117
|
-
};
|
|
118
|
-
min: number;
|
|
119
|
-
};
|
|
120
|
-
};
|
|
121
|
-
/** Stylistic defaults for a single line dataset in a stacked/by-model chart. */
|
|
122
|
-
export declare function lineDatasetStyle(color: string): {
|
|
123
|
-
borderColor: string;
|
|
124
|
-
backgroundColor: string;
|
|
125
|
-
fill: boolean;
|
|
126
|
-
tension: number;
|
|
127
|
-
pointRadius: number;
|
|
128
|
-
pointHoverRadius: number;
|
|
129
|
-
borderWidth: number;
|
|
130
|
-
};
|
|
131
|
-
/** Stylistic defaults for a single bar dataset in a stacked chart. */
|
|
132
|
-
export declare function barDatasetStyle(color: string): {
|
|
133
|
-
backgroundColor: string;
|
|
134
|
-
borderColor: string;
|
|
135
|
-
borderWidth: number;
|
|
136
|
-
borderRadius: number;
|
|
137
|
-
maxBarThickness: number;
|
|
138
|
-
};
|
|
139
|
-
/**
|
|
140
|
-
* Map a generic ChartSeries' datasets through a per-index style function so
|
|
141
|
-
* callers can supply line or bar styling without repeating the label/data
|
|
142
|
-
* spread at every chart site.
|
|
143
|
-
*/
|
|
144
|
-
export declare function styleDatasets(series: ChartSeries, styleFor: (index: number) => Record<string, unknown>): {
|
|
145
|
-
label: string;
|
|
146
|
-
data: number[];
|
|
147
|
-
}[];
|
|
148
|
-
/**
|
|
149
|
-
* Bucket points by day into a single aggregate series. Caller supplies the
|
|
150
|
-
* per-bucket accumulator + final value extractor; mirrors the shape of
|
|
151
|
-
* `buildTopNByModelSeries` for the non-by-model variant of each time chart.
|
|
152
|
-
*/
|
|
153
|
-
export declare function buildAggregateTimeSeries<T extends {
|
|
154
|
-
timestamp: number;
|
|
155
|
-
}, B>(points: T[], label: string, opts: {
|
|
156
|
-
initBucket: () => B;
|
|
157
|
-
accumulate: (bucket: B, point: T) => void;
|
|
158
|
-
bucketToValue: (bucket: B) => number;
|
|
159
|
-
}): ChartSeries;
|
|
160
|
-
interface ModelKeyedPoint {
|
|
161
|
-
timestamp: number;
|
|
162
|
-
model: string;
|
|
163
|
-
provider: string;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Bucket points by day and by top-N model (with an "Other" rollup), producing
|
|
167
|
-
* a ChartSeries. Caller controls how points contribute to ranking and to each
|
|
168
|
-
* day-bucket value via the `rankWeight`/`accumulate`/`bucketToValue` callbacks
|
|
169
|
-
* — keeps the behavior chart's rate math separate from the cost chart's sum.
|
|
170
|
-
*/
|
|
171
|
-
export declare function buildTopNByModelSeries<T extends ModelKeyedPoint, B>(points: T[], opts: {
|
|
172
|
-
topN?: number;
|
|
173
|
-
rankWeight: (point: T) => number;
|
|
174
|
-
initBucket: () => B;
|
|
175
|
-
accumulate: (bucket: B, point: T) => void;
|
|
176
|
-
bucketToValue: (bucket: B) => number;
|
|
177
|
-
}): ChartSeries;
|
|
178
|
-
export {};
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared primitives for the per-model breakdown tables. Each table owns its
|
|
3
|
-
* column definitions, sort order, and chart type — this module owns the
|
|
4
|
-
* surface chrome, expand-row plumbing, theme palette, the mini-sparkline, and
|
|
5
|
-
* the shared plugin/scale config consumed by multi-line detail charts.
|
|
6
|
-
*/
|
|
7
|
-
import type { ChartTheme } from "./chart-shared.js";
|
|
8
|
-
export { CHART_THEMES as TABLE_CHART_THEMES, MODEL_COLORS } from "./chart-shared.js";
|
|
9
|
-
export type TableChartTheme = ChartTheme;
|
|
10
|
-
/** Style defaults for one line in a non-stacked detail chart. */
|
|
11
|
-
export declare function lineSeriesStyle(color: string): {
|
|
12
|
-
borderColor: string;
|
|
13
|
-
backgroundColor: string;
|
|
14
|
-
tension: number;
|
|
15
|
-
pointRadius: number;
|
|
16
|
-
borderWidth: number;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* No-axis, no-legend single-series sparkline used in the trend cell of every
|
|
20
|
-
* model row. Caller supplies the already-extracted numeric series so this
|
|
21
|
-
* stays agnostic of the row's underlying data shape.
|
|
22
|
-
*/
|
|
23
|
-
export declare function MiniSparkline({ timestamps, values, color, }: {
|
|
24
|
-
timestamps: number[];
|
|
25
|
-
values: number[];
|
|
26
|
-
color: string;
|
|
27
|
-
}): import("react").JSX.Element;
|
|
28
|
-
/**
|
|
29
|
-
* Plugin block (legend + tooltip) shared by every multi-series detail chart
|
|
30
|
-
* in the table expanded views.
|
|
31
|
-
*/
|
|
32
|
-
export declare function detailChartPlugins(chartTheme: TableChartTheme): {
|
|
33
|
-
legend: {
|
|
34
|
-
display: boolean;
|
|
35
|
-
position: "top";
|
|
36
|
-
labels: {
|
|
37
|
-
color: "#5a5462" | "#a89fb3";
|
|
38
|
-
usePointStyle: boolean;
|
|
39
|
-
padding: number;
|
|
40
|
-
font: {
|
|
41
|
-
size: number;
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
tooltip: {
|
|
46
|
-
backgroundColor: "#241a2e" | "#ffffff";
|
|
47
|
-
titleColor: "#241a2e" | "#eae5ef";
|
|
48
|
-
bodyColor: "#5a5462" | "#a89fb3";
|
|
49
|
-
borderColor: "rgba(20, 12, 28, 0.15)" | "rgba(255, 255, 255, 0.12)";
|
|
50
|
-
borderWidth: number;
|
|
51
|
-
cornerRadius: number;
|
|
52
|
-
};
|
|
53
|
-
};
|
|
54
|
-
/**
|
|
55
|
-
* Single-Y-axis scales for a detail chart (used when every series shares a
|
|
56
|
-
* unit, e.g. behavior counts). Min anchored at 0.
|
|
57
|
-
*/
|
|
58
|
-
export declare function detailChartScalesSingleAxis(chartTheme: TableChartTheme): {
|
|
59
|
-
x: {
|
|
60
|
-
grid: {
|
|
61
|
-
color: "rgba(20, 12, 28, 0.08)" | "rgba(255, 255, 255, 0.06)";
|
|
62
|
-
};
|
|
63
|
-
ticks: {
|
|
64
|
-
color: "#6a6275" | "#867a93";
|
|
65
|
-
font: {
|
|
66
|
-
size: number;
|
|
67
|
-
};
|
|
68
|
-
};
|
|
69
|
-
};
|
|
70
|
-
y: {
|
|
71
|
-
grid: {
|
|
72
|
-
color: "rgba(20, 12, 28, 0.08)" | "rgba(255, 255, 255, 0.06)";
|
|
73
|
-
};
|
|
74
|
-
ticks: {
|
|
75
|
-
color: "#6a6275" | "#867a93";
|
|
76
|
-
font: {
|
|
77
|
-
size: number;
|
|
78
|
-
};
|
|
79
|
-
};
|
|
80
|
-
min: number;
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
/**
|
|
84
|
-
* Dual-Y-axis scales for a detail chart with mixed units (e.g. TTFT seconds
|
|
85
|
-
* on left, tokens/s on right). Right-axis grid is suppressed so it doesn't
|
|
86
|
-
* collide with the left.
|
|
87
|
-
*/
|
|
88
|
-
export declare function detailChartScalesDualAxis(chartTheme: TableChartTheme): {
|
|
89
|
-
x: {
|
|
90
|
-
grid: {
|
|
91
|
-
color: "rgba(20, 12, 28, 0.08)" | "rgba(255, 255, 255, 0.06)";
|
|
92
|
-
};
|
|
93
|
-
ticks: {
|
|
94
|
-
color: "#6a6275" | "#867a93";
|
|
95
|
-
font: {
|
|
96
|
-
size: number;
|
|
97
|
-
};
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
y: {
|
|
101
|
-
type: "linear";
|
|
102
|
-
display: boolean;
|
|
103
|
-
position: "left";
|
|
104
|
-
grid: {
|
|
105
|
-
color: "rgba(20, 12, 28, 0.08)" | "rgba(255, 255, 255, 0.06)";
|
|
106
|
-
};
|
|
107
|
-
ticks: {
|
|
108
|
-
color: "#6a6275" | "#867a93";
|
|
109
|
-
font: {
|
|
110
|
-
size: number;
|
|
111
|
-
};
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
y1: {
|
|
115
|
-
type: "linear";
|
|
116
|
-
display: boolean;
|
|
117
|
-
position: "right";
|
|
118
|
-
grid: {
|
|
119
|
-
drawOnChartArea: boolean;
|
|
120
|
-
};
|
|
121
|
-
ticks: {
|
|
122
|
-
color: "#6a6275" | "#867a93";
|
|
123
|
-
font: {
|
|
124
|
-
size: number;
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
export interface TableColumn {
|
|
130
|
-
label: string;
|
|
131
|
-
align?: "left" | "right" | "center";
|
|
132
|
-
}
|
|
133
|
-
/** Outer card + section title used by every model table. */
|
|
134
|
-
export declare function ModelTableShell({ title, subtitle, children, }: {
|
|
135
|
-
title: string;
|
|
136
|
-
subtitle?: string;
|
|
137
|
-
children: React.ReactNode;
|
|
138
|
-
}): import("react").JSX.Element;
|
|
139
|
-
/** Sticky column-header row for a model table. */
|
|
140
|
-
export declare function ModelTableHeader({ columns, gridTemplate }: {
|
|
141
|
-
columns: TableColumn[];
|
|
142
|
-
gridTemplate: string;
|
|
143
|
-
}): import("react").JSX.Element;
|
|
144
|
-
/** Scroll wrapper for the row stack — capped to fit the dashboard viewport. */
|
|
145
|
-
export declare function ModelTableBody({ children }: {
|
|
146
|
-
children: React.ReactNode;
|
|
147
|
-
}): import("react").JSX.Element;
|
|
148
|
-
/**
|
|
149
|
-
* Two-line model identity cell (model name + provider) shared by every
|
|
150
|
-
* per-model table. Kept as a stable named contract so callers don't restate
|
|
151
|
-
* the same two divs and font-utility classes.
|
|
152
|
-
*/
|
|
153
|
-
export declare function ModelNameCell({ model, provider }: {
|
|
154
|
-
model: string;
|
|
155
|
-
provider: string;
|
|
156
|
-
}): import("react").JSX.Element;
|
|
157
|
-
/**
|
|
158
|
-
* One expandable model row. `cells` matches the column order from
|
|
159
|
-
* `ModelTableHeader` plus the trend cell at the end (caller controls the
|
|
160
|
-
* sparkline / placeholder). `expandedContent` is the panel revealed on toggle.
|
|
161
|
-
*/
|
|
162
|
-
export declare function ExpandableModelRow({ gridTemplate, cells, trendCell, isExpanded, onToggle, expandedContent, }: {
|
|
163
|
-
gridTemplate: string;
|
|
164
|
-
cells: React.ReactNode[];
|
|
165
|
-
trendCell: React.ReactNode;
|
|
166
|
-
isExpanded: boolean;
|
|
167
|
-
onToggle: () => void;
|
|
168
|
-
expandedContent: React.ReactNode;
|
|
169
|
-
}): import("react").JSX.Element;
|
|
170
|
-
/** Placeholder shown in the trend cell when a model has no time-series data. */
|
|
171
|
-
export declare function TrendEmpty(): import("react").JSX.Element;
|
|
172
|
-
/** Placeholder shown in the expanded detail-chart slot when data is missing. */
|
|
173
|
-
export declare function DetailChartEmpty({ message }: {
|
|
174
|
-
message?: string;
|
|
175
|
-
}): import("react").JSX.Element;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Display metadata for a `TimeRange` — keeps chart labels, sparkline bucket
|
|
3
|
-
* counts, and x-axis date formatting in sync with the server-side bucketing
|
|
4
|
-
* defined in `aggregator.ts`.
|
|
5
|
-
*/
|
|
6
|
-
import type { TimeRange } from "../types.js";
|
|
7
|
-
export interface RangeMeta {
|
|
8
|
-
/** Human label used in chart subtitles ("the last 24 hours"). */
|
|
9
|
-
windowLabel: string;
|
|
10
|
-
/** Short prefix used in compact column headers ("24h Trend"). */
|
|
11
|
-
trendLabel: string;
|
|
12
|
-
/** Bucket size matching the server query for this range. */
|
|
13
|
-
bucketMs: number;
|
|
14
|
-
/** Number of buckets the server is expected to return for this range. */
|
|
15
|
-
bucketCount: number;
|
|
16
|
-
/** Date format string for x-axis labels and tooltip headings. */
|
|
17
|
-
tickFormat: string;
|
|
18
|
-
}
|
|
19
|
-
export declare function rangeMeta(range: TimeRange): RangeMeta;
|
|
20
|
-
/** Format a bucket timestamp using the active range's tick format. */
|
|
21
|
-
export declare function formatRangeTick(timestamp: number, range: TimeRange): string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export interface ResourceResult<T> {
|
|
2
|
-
data: T | null;
|
|
3
|
-
error: Error | null;
|
|
4
|
-
loading: boolean;
|
|
5
|
-
refreshing: boolean;
|
|
6
|
-
refetch: () => Promise<void>;
|
|
7
|
-
updatedAt: number | null;
|
|
8
|
-
}
|
|
9
|
-
export interface ResourceOptions {
|
|
10
|
-
pollMs?: number;
|
|
11
|
-
enabled?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export declare function useResource<T>(key: readonly unknown[], fetcher: (signal: AbortSignal) => Promise<T>, options?: ResourceOptions): ResourceResult<T>;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { TimeRange } from "../types.js";
|
|
2
|
-
export interface BehaviorRouteProps {
|
|
3
|
-
active: boolean;
|
|
4
|
-
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
|
-
}
|
|
7
|
-
export declare function BehaviorRoute({ active, range, refreshTrigger }: BehaviorRouteProps): import("react").JSX.Element;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type React from "react";
|
|
2
|
-
export interface AsyncBoundaryProps {
|
|
3
|
-
loading: boolean;
|
|
4
|
-
error: Error | null;
|
|
5
|
-
data: unknown | null;
|
|
6
|
-
empty?: boolean;
|
|
7
|
-
emptyText?: string;
|
|
8
|
-
fallback?: React.ReactNode;
|
|
9
|
-
onRetry?: () => void;
|
|
10
|
-
children: React.ReactNode;
|
|
11
|
-
}
|
|
12
|
-
export declare function AsyncBoundary({ loading, error, data, empty, emptyText, fallback, onRetry, children, }: AsyncBoundaryProps): React.JSX.Element;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type React from "react";
|
|
2
|
-
export interface DataTableColumn<T> {
|
|
3
|
-
key: string;
|
|
4
|
-
header: React.ReactNode;
|
|
5
|
-
render?: (item: T) => React.ReactNode;
|
|
6
|
-
className?: string;
|
|
7
|
-
numeric?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface DataTableProps<T> {
|
|
10
|
-
columns: DataTableColumn<T>[];
|
|
11
|
-
data: T[];
|
|
12
|
-
keyExtractor: (item: T) => string | number;
|
|
13
|
-
onRowClick?: (item: T) => void;
|
|
14
|
-
renderMobileCard?: (item: T, onClick?: () => void) => React.ReactNode;
|
|
15
|
-
emptyText?: string;
|
|
16
|
-
}
|
|
17
|
-
export declare function DataTable<T>({ columns, data, keyExtractor, onRowClick, renderMobileCard, emptyText, }: DataTableProps<T>): React.JSX.Element;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type LucideIcon } from "lucide-react";
|
|
2
|
-
export interface EmptyStateProps {
|
|
3
|
-
message?: string;
|
|
4
|
-
icon?: LucideIcon;
|
|
5
|
-
className?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function EmptyState({ message, icon: Icon, className }: EmptyStateProps): import("react").JSX.Element;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type React from "react";
|
|
2
|
-
export interface PanelProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
|
|
3
|
-
title?: React.ReactNode;
|
|
4
|
-
subtitle?: React.ReactNode;
|
|
5
|
-
actions?: React.ReactNode;
|
|
6
|
-
}
|
|
7
|
-
export declare function Panel({ title, subtitle, actions, children, className, ...props }: PanelProps): React.JSX.Element;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface SegmentedControlOption<T> {
|
|
2
|
-
value: T;
|
|
3
|
-
label: string;
|
|
4
|
-
title?: string;
|
|
5
|
-
}
|
|
6
|
-
export interface SegmentedControlProps<T> {
|
|
7
|
-
options: SegmentedControlOption<T>[];
|
|
8
|
-
value: T;
|
|
9
|
-
onChange: (value: T) => void;
|
|
10
|
-
className?: string;
|
|
11
|
-
}
|
|
12
|
-
export declare function SegmentedControl<T>({ options, value, onChange, className }: SegmentedControlProps<T>): import("react").JSX.Element;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type React from "react";
|
|
2
|
-
export interface SkeletonProps {
|
|
3
|
-
variant?: "text" | "rect" | "circle";
|
|
4
|
-
width?: string | number;
|
|
5
|
-
height?: string | number;
|
|
6
|
-
className?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function Skeleton({ variant, width, height, className }: SkeletonProps): React.JSX.Element;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type React from "react";
|
|
2
|
-
export interface StatusPillProps {
|
|
3
|
-
variant: "success" | "danger" | "warning" | "info" | "default";
|
|
4
|
-
children: React.ReactNode;
|
|
5
|
-
className?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function StatusPill({ variant, children, className }: StatusPillProps): React.JSX.Element;
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { X } from "lucide-react";
|
|
2
|
-
import type React from "react";
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import type { TimeRange } from "../types";
|
|
5
|
-
import { NavRail } from "./NavRail";
|
|
6
|
-
import type { DashboardSection } from "./routes";
|
|
7
|
-
import { TopBar } from "./TopBar";
|
|
8
|
-
|
|
9
|
-
export interface AppLayoutProps {
|
|
10
|
-
activeSection: DashboardSection;
|
|
11
|
-
onSectionChange: (section: DashboardSection) => void;
|
|
12
|
-
range: TimeRange;
|
|
13
|
-
onRangeChange: (range: TimeRange) => void;
|
|
14
|
-
updatedAt: number | null;
|
|
15
|
-
onSyncStart?: () => void;
|
|
16
|
-
onSyncComplete?: (result: { success: boolean }) => void;
|
|
17
|
-
children: React.ReactNode;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function AppLayout({
|
|
21
|
-
activeSection,
|
|
22
|
-
onSectionChange,
|
|
23
|
-
range,
|
|
24
|
-
onRangeChange,
|
|
25
|
-
updatedAt,
|
|
26
|
-
onSyncStart,
|
|
27
|
-
onSyncComplete,
|
|
28
|
-
children,
|
|
29
|
-
}: AppLayoutProps) {
|
|
30
|
-
const [menuOpen, setMenuOpen] = useState(false);
|
|
31
|
-
|
|
32
|
-
const handleSectionChange = (section: DashboardSection) => {
|
|
33
|
-
onSectionChange(section);
|
|
34
|
-
setMenuOpen(false);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div className="stats-app-container">
|
|
39
|
-
{/* Desktop Rail */}
|
|
40
|
-
<NavRail activeSection={activeSection} onSectionChange={handleSectionChange} className="stats-desktop-nav" />
|
|
41
|
-
|
|
42
|
-
{/* Mobile Nav Drawer */}
|
|
43
|
-
{menuOpen && (
|
|
44
|
-
<div className="stats-mobile-drawer-overlay" onClick={() => setMenuOpen(false)} role="presentation">
|
|
45
|
-
<div
|
|
46
|
-
className="stats-mobile-drawer"
|
|
47
|
-
onClick={e => e.stopPropagation()}
|
|
48
|
-
role="dialog"
|
|
49
|
-
aria-modal="true"
|
|
50
|
-
aria-label="Navigation menu"
|
|
51
|
-
>
|
|
52
|
-
<div className="stats-mobile-drawer-header">
|
|
53
|
-
<div className="stats-logo-container">
|
|
54
|
-
<span className="stats-logo-text">OH MY PI</span>
|
|
55
|
-
<span className="stats-logo-subtext">Observability</span>
|
|
56
|
-
</div>
|
|
57
|
-
<button
|
|
58
|
-
type="button"
|
|
59
|
-
onClick={() => setMenuOpen(false)}
|
|
60
|
-
className="stats-drawer-close-btn"
|
|
61
|
-
aria-label="Close navigation menu"
|
|
62
|
-
>
|
|
63
|
-
<X size={18} />
|
|
64
|
-
</button>
|
|
65
|
-
</div>
|
|
66
|
-
<NavRail
|
|
67
|
-
activeSection={activeSection}
|
|
68
|
-
onSectionChange={handleSectionChange}
|
|
69
|
-
className="stats-mobile-nav"
|
|
70
|
-
/>
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
)}
|
|
74
|
-
|
|
75
|
-
{/* Main Layout Pane */}
|
|
76
|
-
<div className="stats-main-pane">
|
|
77
|
-
<TopBar
|
|
78
|
-
activeSection={activeSection}
|
|
79
|
-
range={range}
|
|
80
|
-
onRangeChange={onRangeChange}
|
|
81
|
-
updatedAt={updatedAt}
|
|
82
|
-
onSyncStart={onSyncStart}
|
|
83
|
-
onSyncComplete={onSyncComplete}
|
|
84
|
-
onMenuToggle={() => setMenuOpen(true)}
|
|
85
|
-
/>
|
|
86
|
-
|
|
87
|
-
<main className="stats-content-area">
|
|
88
|
-
<div className="stats-content-inner">{children}</div>
|
|
89
|
-
</main>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
}
|