@oh-my-pi/omp-stats 18.3.5 → 18.4.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.
- package/CHANGELOG.md +16 -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 +123 -40
- 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,4 +1,4 @@
|
|
|
1
|
-
import type { AgentType, AgentTypeStats,
|
|
1
|
+
import type { AgentType, AgentTypeStats, CostTimeSeriesPoint, FolderStats, MessageStats, ModelPerformancePoint, ToolUsageStats } from "../types.js";
|
|
2
2
|
export interface ConversationTokenStats {
|
|
3
3
|
totalInputTokens: number;
|
|
4
4
|
totalOutputTokens: number;
|
|
@@ -28,12 +28,37 @@ export interface AgentTokenShareView {
|
|
|
28
28
|
* conversation-token buckets as the overview total so the two views reconcile.
|
|
29
29
|
*/
|
|
30
30
|
export declare function buildAgentTokenShare(stats: AgentTypeStats[]): AgentTokenShareView;
|
|
31
|
-
|
|
31
|
+
/** API-equivalent cost split by billing component. */
|
|
32
|
+
export interface CostComponents {
|
|
33
|
+
costInput: number;
|
|
34
|
+
costOutput: number;
|
|
35
|
+
costCacheRead: number;
|
|
36
|
+
costCacheWrite: number;
|
|
37
|
+
}
|
|
38
|
+
/** One model's (model + provider) totals across the cost series. */
|
|
39
|
+
export interface CostModelRow extends CostComponents {
|
|
40
|
+
/** `model::provider` (see `modelKey`). */
|
|
41
|
+
key: string;
|
|
42
|
+
model: string;
|
|
43
|
+
provider: string;
|
|
44
|
+
cost: number;
|
|
45
|
+
requests: number;
|
|
46
|
+
unpricedRequests: number;
|
|
47
|
+
/** Fraction (0-1) of the total estimate. */
|
|
48
|
+
share: number;
|
|
49
|
+
}
|
|
50
|
+
export interface CostSummaryView extends CostComponents {
|
|
32
51
|
totalCost: number;
|
|
52
|
+
requests: number;
|
|
33
53
|
unpricedRequests: number;
|
|
54
|
+
/** Day buckets that carry any usage. */
|
|
55
|
+
activeDays: number;
|
|
56
|
+
/** Total estimate ÷ active days. */
|
|
34
57
|
avgDailyCost: number;
|
|
35
|
-
|
|
36
|
-
|
|
58
|
+
/** Ranked by estimate, then requests, then key. */
|
|
59
|
+
models: CostModelRow[];
|
|
60
|
+
/** Highest-estimate model; `null` when nothing is priced. */
|
|
61
|
+
topModel: CostModelRow | null;
|
|
37
62
|
}
|
|
38
63
|
export interface ModelPerformanceDataPoint {
|
|
39
64
|
timestamp: number;
|
|
@@ -41,35 +66,93 @@ export interface ModelPerformanceDataPoint {
|
|
|
41
66
|
avgTokensPerSecond: number | null;
|
|
42
67
|
requests: number;
|
|
43
68
|
}
|
|
44
|
-
export interface ModelPerformanceSeries {
|
|
45
|
-
label: string;
|
|
46
|
-
data: ModelPerformanceDataPoint[];
|
|
47
|
-
}
|
|
48
|
-
export interface BehaviorSummaryView {
|
|
49
|
-
totalMessages: number;
|
|
50
|
-
totalYelling: number;
|
|
51
|
-
totalProfanity: number;
|
|
52
|
-
totalAnguish: number;
|
|
53
|
-
totalFrustration: number;
|
|
54
|
-
highestFrictionModel: {
|
|
55
|
-
model: string;
|
|
56
|
-
provider: string;
|
|
57
|
-
score: number;
|
|
58
|
-
} | null;
|
|
59
|
-
}
|
|
60
69
|
export interface FolderRowView extends FolderStats {
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
/** Uncached input + cache reads + cache writes + output. */
|
|
71
|
+
conversationTokens: number;
|
|
72
|
+
/** Share of every folder's requests in range (0-1). */
|
|
73
|
+
requestShare: number;
|
|
74
|
+
/** Share of every folder's API-equivalent cost in range (0-1). */
|
|
75
|
+
costShare: number;
|
|
76
|
+
/** Session directory under a system temp location (`/tmp`, `/var/folders`, …). */
|
|
77
|
+
temporary: boolean;
|
|
78
|
+
}
|
|
79
|
+
export interface FolderTableView {
|
|
80
|
+
rows: FolderRowView[];
|
|
81
|
+
totalRequests: number;
|
|
82
|
+
failedRequests: number;
|
|
83
|
+
totalCost: number;
|
|
84
|
+
unpricedRequests: number;
|
|
85
|
+
conversationTokens: number;
|
|
86
|
+
/** Cache reads ÷ (uncached input + cache reads) across every folder. */
|
|
87
|
+
cacheRate: number;
|
|
88
|
+
/** Largest single-folder request count / cost, for meter scales. */
|
|
89
|
+
maxRequests: number;
|
|
90
|
+
maxCost: number;
|
|
91
|
+
temporaryCount: number;
|
|
63
92
|
}
|
|
64
|
-
|
|
65
|
-
export declare function
|
|
66
|
-
|
|
67
|
-
|
|
93
|
+
/** Totals, per-model breakdown and component split for the Costs page. */
|
|
94
|
+
export declare function buildCostSummary(costSeries: readonly CostTimeSeriesPoint[]): CostSummaryView;
|
|
95
|
+
/**
|
|
96
|
+
* Per-model (`model::provider`) performance points in ascending time order,
|
|
97
|
+
* with TTFT converted to seconds. Only buckets where the model served
|
|
98
|
+
* requests are present, so sparse history (all time) keeps every point.
|
|
99
|
+
*/
|
|
100
|
+
export declare function buildModelPerformanceLookup(points: readonly ModelPerformancePoint[]): Map<string, ModelPerformanceDataPoint[]>;
|
|
101
|
+
/** Table rows plus range totals for the Projects page; linear in the (possibly tens of thousands of) folders. */
|
|
102
|
+
export declare function buildFolderRows(folders: readonly FolderStats[]): FolderTableView;
|
|
68
103
|
/** Table row for the Tools route: usage stats plus derived rates/shares. */
|
|
69
104
|
export interface ToolRowView extends ToolUsageStats {
|
|
70
105
|
/** errors / calls (0 for zero calls). */
|
|
71
106
|
errorRate: number;
|
|
72
|
-
/**
|
|
73
|
-
|
|
107
|
+
/** This tool's fraction (0..1) of all calls in range. */
|
|
108
|
+
callFraction: number;
|
|
109
|
+
/** This tool's fraction (0..1) of all attributed tokens in range. */
|
|
110
|
+
tokenFraction: number;
|
|
111
|
+
/** This tool's fraction (0..1) of all attributed cost in range. */
|
|
112
|
+
costFraction: number;
|
|
113
|
+
/** Mean result characters fed back into context per call. */
|
|
114
|
+
avgResultChars: number;
|
|
74
115
|
}
|
|
75
116
|
export declare function buildToolRows(tools: ToolUsageStats[]): ToolRowView[];
|
|
117
|
+
export type RequestStatus = "ok" | "aborted" | "failed";
|
|
118
|
+
/** Outcome of one request: cancellations abort; provider/transport errors fail. */
|
|
119
|
+
export declare function requestStatus(row: Pick<MessageStats, "stopReason" | "errorMessage">): RequestStatus;
|
|
120
|
+
export interface RequestLogSummary {
|
|
121
|
+
requests: number;
|
|
122
|
+
failed: number;
|
|
123
|
+
aborted: number;
|
|
124
|
+
tokens: number;
|
|
125
|
+
cost: number;
|
|
126
|
+
/** Requests with tokens but no price (see `isUnpricedMessage`). */
|
|
127
|
+
unpriced: number;
|
|
128
|
+
medianDuration: number | null;
|
|
129
|
+
p95Duration: number | null;
|
|
130
|
+
medianTtft: number | null;
|
|
131
|
+
oldest: number | null;
|
|
132
|
+
newest: number | null;
|
|
133
|
+
}
|
|
134
|
+
/** Totals and latency quantiles over a list of requests. */
|
|
135
|
+
export declare function summarizeRequests(rows: readonly MessageStats[]): RequestLogSummary;
|
|
136
|
+
/**
|
|
137
|
+
* Normalized error message used to group failures: whitespace collapsed,
|
|
138
|
+
* request ids / hashes / counters replaced with placeholders (HTTP status
|
|
139
|
+
* codes kept), truncated.
|
|
140
|
+
*/
|
|
141
|
+
export declare function errorSignature(message: string | null): string;
|
|
142
|
+
export interface ErrorGroupModel {
|
|
143
|
+
model: string;
|
|
144
|
+
provider: string;
|
|
145
|
+
count: number;
|
|
146
|
+
}
|
|
147
|
+
export interface ErrorGroupView {
|
|
148
|
+
signature: string;
|
|
149
|
+
count: number;
|
|
150
|
+
firstSeen: number;
|
|
151
|
+
lastSeen: number;
|
|
152
|
+
/** Most recent occurrence (full message, drawer target). */
|
|
153
|
+
latest: MessageStats;
|
|
154
|
+
/** Affected models, most failures first. */
|
|
155
|
+
models: ErrorGroupModel[];
|
|
156
|
+
}
|
|
157
|
+
/** Group failures by `errorSignature`; most frequent first, then most recent. */
|
|
158
|
+
export declare function groupErrorsBySignature(rows: readonly MessageStats[]): ErrorGroupView[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import "./costs.css";
|
|
1
2
|
import type { TimeRange } from "../types.js";
|
|
2
3
|
export interface CostsRouteProps {
|
|
3
4
|
active: boolean;
|
|
4
5
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
6
|
}
|
|
7
|
-
export declare function CostsRoute({ active, range
|
|
7
|
+
export declare function CostsRoute({ active, range }: CostsRouteProps): import("react").JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { TimeRange } from "../types.js";
|
|
2
|
+
import "./errors.css";
|
|
2
3
|
export interface ErrorsRouteProps {
|
|
3
4
|
active: boolean;
|
|
4
5
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
6
|
onRequestClick: (id: number) => void;
|
|
7
7
|
}
|
|
8
|
-
export declare function ErrorsRoute({ active, range,
|
|
8
|
+
export declare function ErrorsRoute({ active, range, onRequestClick }: ErrorsRouteProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TimeRange } from "../types.js";
|
|
2
|
+
import "./frustration.css";
|
|
3
|
+
export interface FrustrationRouteProps {
|
|
4
|
+
active: boolean;
|
|
5
|
+
range: TimeRange;
|
|
6
|
+
}
|
|
7
|
+
export declare function FrustrationRoute({ active, range }: FrustrationRouteProps): import("react").JSX.Element;
|
|
@@ -2,6 +2,5 @@ import type { TimeRange } from "../types.js";
|
|
|
2
2
|
export interface GainRouteProps {
|
|
3
3
|
active: boolean;
|
|
4
4
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
5
|
}
|
|
7
|
-
export declare function GainRoute({ active, range
|
|
6
|
+
export declare function GainRoute({ active, range }: GainRouteProps): import("react").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import "./models.css";
|
|
1
2
|
import type { TimeRange } from "../types.js";
|
|
2
3
|
export interface ModelsRouteProps {
|
|
3
4
|
active: boolean;
|
|
4
5
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
6
|
}
|
|
7
|
-
export declare function ModelsRoute({ active, range
|
|
7
|
+
export declare function ModelsRoute({ active, range }: ModelsRouteProps): import("react").JSX.Element;
|
|
@@ -2,7 +2,6 @@ import type { TimeRange } from "../types.js";
|
|
|
2
2
|
export interface OverviewRouteProps {
|
|
3
3
|
active: boolean;
|
|
4
4
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
5
|
onRequestClick: (id: number) => void;
|
|
7
6
|
}
|
|
8
|
-
export declare function OverviewRoute({ active, range,
|
|
7
|
+
export declare function OverviewRoute({ active, range, onRequestClick }: OverviewRouteProps): import("react").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TimeRange } from "../types.js";
|
|
2
|
+
import "./projects.css";
|
|
2
3
|
export interface ProjectsRouteProps {
|
|
3
4
|
active: boolean;
|
|
4
5
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
6
|
}
|
|
7
|
-
export declare function ProjectsRoute({ active, range
|
|
7
|
+
export declare function ProjectsRoute({ active, range }: ProjectsRouteProps): import("react").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TimeRange } from "../types.js";
|
|
2
|
+
import "./providers.css";
|
|
2
3
|
export interface ProvidersRouteProps {
|
|
3
4
|
active: boolean;
|
|
4
5
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
6
|
}
|
|
7
|
-
export declare function ProvidersRoute({ active, range
|
|
7
|
+
export declare function ProvidersRoute({ active, range }: ProvidersRouteProps): import("react").JSX.Element;
|
|
@@ -2,7 +2,6 @@ import type { TimeRange } from "../types.js";
|
|
|
2
2
|
export interface RequestsRouteProps {
|
|
3
3
|
active: boolean;
|
|
4
4
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
5
|
onRequestClick: (id: number) => void;
|
|
7
6
|
}
|
|
8
|
-
export declare function RequestsRoute({ active,
|
|
7
|
+
export declare function RequestsRoute({ active, range, onRequestClick }: RequestsRouteProps): import("react").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TimeRange } from "../types.js";
|
|
2
|
+
import "./tools.css";
|
|
2
3
|
export interface ToolsRouteProps {
|
|
3
4
|
active: boolean;
|
|
4
5
|
range: TimeRange;
|
|
5
|
-
refreshTrigger: number;
|
|
6
6
|
}
|
|
7
|
-
export declare function ToolsRoute({ active, range
|
|
7
|
+
export declare function ToolsRoute({ active, range }: ToolsRouteProps): import("react").JSX.Element;
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Traces section: root-session list (subagents folded in) that opens the
|
|
3
3
|
* flamegraph trace viewer for a selected session.
|
|
4
4
|
*/
|
|
5
|
+
import "../traces/traces.css";
|
|
5
6
|
export interface TracesRouteProps {
|
|
6
7
|
active: boolean;
|
|
7
8
|
session: string | null;
|
|
8
9
|
onOpenSession: (file: string | null) => void;
|
|
9
|
-
refreshTrigger: number;
|
|
10
10
|
}
|
|
11
|
-
export declare function TracesRoute({ active, session, onOpenSession
|
|
11
|
+
export declare function TracesRoute({ active, session, onOpenSession }: TracesRouteProps): import("react").JSX.Element;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* time descending
|
|
2
|
+
* Per-tool duration aggregates for one trace (sortable; server order is total
|
|
3
|
+
* time descending).
|
|
4
4
|
*/
|
|
5
5
|
import type { TraceToolStat } from "../types.js";
|
|
6
6
|
export interface AggregatesPanelProps {
|
|
7
7
|
toolStats: TraceToolStat[];
|
|
8
|
+
index?: number;
|
|
8
9
|
}
|
|
9
|
-
export declare function AggregatesPanel({ toolStats }: AggregatesPanelProps): import("react").JSX.Element | null;
|
|
10
|
+
export declare function AggregatesPanel({ toolStats, index }: AggregatesPanelProps): import("react").JSX.Element | null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Headline
|
|
3
|
-
* tool calls, agents, tokens, cost.
|
|
2
|
+
* Headline tiles for one trace: wall time split into model/tool/idle, then
|
|
3
|
+
* turns, requests, tool calls, agents, tokens, cost.
|
|
4
4
|
*/
|
|
5
5
|
import type { TraceSummary } from "../types.js";
|
|
6
6
|
export interface SummaryStripProps {
|
|
@@ -1,31 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* mirror `CHART_THEMES` so the canvas matches the chart.js surfaces.
|
|
2
|
+
* Canvas palette for the trace flamegraph, resolved from the dashboard's CSS
|
|
3
|
+
* design tokens so canvas drawing follows the active theme.
|
|
5
4
|
*/
|
|
6
5
|
import type { TraceSpanKind } from "../types.js";
|
|
7
6
|
export interface TraceTheme {
|
|
8
7
|
/** Span fill per category. */
|
|
9
8
|
category: Record<TraceSpanKind, string>;
|
|
10
|
-
/** Error
|
|
9
|
+
/** Error left-edge accent. */
|
|
11
10
|
error: string;
|
|
11
|
+
/** Error fill tint. */
|
|
12
|
+
errorSoft: string;
|
|
12
13
|
/** Marker diamond fill. */
|
|
13
14
|
marker: string;
|
|
14
15
|
/** Alternating turn-band fill. */
|
|
15
16
|
turnBand: string;
|
|
16
|
-
/** Canvas background. */
|
|
17
|
-
surface: string;
|
|
18
17
|
/** Ruler/lane hairlines. */
|
|
19
18
|
grid: string;
|
|
20
19
|
/** Ruler tick labels. */
|
|
21
20
|
tick: string;
|
|
22
21
|
/** Span label text drawn inside blocks. */
|
|
23
22
|
spanText: string;
|
|
24
|
-
/** Selection outline
|
|
23
|
+
/** Selection outline / minimap brush. */
|
|
25
24
|
selection: string;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
/** Minimap brush fill. */
|
|
26
|
+
brush: string;
|
|
27
|
+
/** Canvas font stacks. */
|
|
28
|
+
fontSans: string;
|
|
29
|
+
fontMono: string;
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
/** CSS custom property backing each category (also used by DOM chips). */
|
|
32
|
+
export declare const CATEGORY_VARS: Record<TraceSpanKind, string>;
|
|
33
|
+
/**
|
|
34
|
+
* Current trace palette. Re-reads the tokens whenever the resolved theme
|
|
35
|
+
* changes (store or a direct `data-theme` attribute write).
|
|
36
|
+
*/
|
|
37
|
+
export declare function useTraceTheme(): TraceTheme;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type Tone = "neutral" | "ok" | "warn" | "bad" | "accent";
|
|
3
|
+
/** Pill label; status badges always carry a word, never color alone. */
|
|
4
|
+
export declare function Badge({ tone, mono, children }: {
|
|
5
|
+
tone?: Tone;
|
|
6
|
+
mono?: boolean;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
9
|
+
/** Round status dot; `pulse` for things happening right now. */
|
|
10
|
+
export declare function Dot({ tone, pulse }: {
|
|
11
|
+
tone?: Tone | "live";
|
|
12
|
+
pulse?: boolean;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
/** Color square matching a chart series. */
|
|
15
|
+
export declare function Swatch({ color }: {
|
|
16
|
+
color: string;
|
|
17
|
+
}): import("react").JSX.Element;
|
|
18
|
+
/** Badge tone for an error rate (fraction). */
|
|
19
|
+
export declare function errorRateTone(rate: number): Tone;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface CardProps {
|
|
3
|
+
title?: ReactNode;
|
|
4
|
+
description?: ReactNode;
|
|
5
|
+
/** Right-aligned header controls (segmented toggles, selects, buttons). */
|
|
6
|
+
actions?: ReactNode;
|
|
7
|
+
/** Body without padding — for full-bleed tables and lists. */
|
|
8
|
+
flush?: boolean;
|
|
9
|
+
footer?: ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
/** Stagger index for the entrance animation. */
|
|
12
|
+
index?: number;
|
|
13
|
+
/** Dim the body while previous data is on screen (see `useQuery().stale`). */
|
|
14
|
+
stale?: boolean;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/** The dashboard's container: top-lit hairline edge, optional header and footer. */
|
|
18
|
+
export declare function Card({ title, description, actions, flush, footer, className, index, stale, children }: CardProps): import("react").JSX.Element;
|
|
19
|
+
export interface PageHeaderProps {
|
|
20
|
+
title: ReactNode;
|
|
21
|
+
description?: ReactNode;
|
|
22
|
+
actions?: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
/** Title band at the top of every page. */
|
|
25
|
+
export declare function PageHeader({ title, description, actions }: PageHeaderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface DrawerProps {
|
|
3
|
+
open: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
title: ReactNode;
|
|
6
|
+
subtitle?: ReactNode;
|
|
7
|
+
/** Header controls left of the close button. */
|
|
8
|
+
actions?: ReactNode;
|
|
9
|
+
/** Sheet width in px. Default 560. */
|
|
10
|
+
width?: number;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Right-side glass sheet over a scrim, portalled to `document.body`. Esc and
|
|
15
|
+
* scrim clicks close it; focus returns to the opener.
|
|
16
|
+
*/
|
|
17
|
+
export declare function Drawer({ open, onClose, title, subtitle, actions, width, children }: DrawerProps): import("react").ReactPortal | null;
|
|
18
|
+
/** Label/value grid for detail panels. */
|
|
19
|
+
export declare function KeyValues({ items }: {
|
|
20
|
+
items: readonly {
|
|
21
|
+
key: string;
|
|
22
|
+
label: ReactNode;
|
|
23
|
+
value: ReactNode;
|
|
24
|
+
}[];
|
|
25
|
+
}): import("react").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type React from "react";
|
|
2
1
|
export interface JsonBlockProps {
|
|
3
2
|
data: unknown;
|
|
4
3
|
title?: string;
|
|
5
4
|
initialCollapsed?: boolean;
|
|
6
5
|
}
|
|
7
|
-
|
|
6
|
+
/** Collapsible, copyable pretty-printed JSON. */
|
|
7
|
+
export declare function JsonBlock({ data, title, initialCollapsed }: JsonBlockProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import "./modal.css";
|
|
3
|
+
export interface ModalAction {
|
|
4
|
+
label: string;
|
|
5
|
+
onClick: () => void;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ModalProps {
|
|
9
|
+
open: boolean;
|
|
10
|
+
title: React.ReactNode;
|
|
11
|
+
/** Called on Esc, overlay click, the close icon, and the cancel button. */
|
|
12
|
+
onClose: () => void;
|
|
13
|
+
/** Confirming action; receives focus whenever it is present and enabled. */
|
|
14
|
+
primaryAction?: ModalAction;
|
|
15
|
+
cancelLabel?: string;
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Centered dialog over a dimmed overlay, portalled to `document.body` so route
|
|
20
|
+
* containers cannot clip it. Focus lands on the primary action (or the cancel
|
|
21
|
+
* button when there is none) and returns to the opener on close.
|
|
22
|
+
*/
|
|
23
|
+
export declare function Modal({ open, title, onClose, primaryAction, cancelLabel, children }: ModalProps): React.ReactPortal | null;
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import { type RequestStatus } from "../data/view-models.js";
|
|
2
|
+
import { type Tone } from "./Badge.js";
|
|
3
|
+
import "./request-drawer.css";
|
|
4
|
+
/** Label and tone for each request outcome; shared by the request tables. */
|
|
5
|
+
export declare const REQUEST_STATUS: Record<RequestStatus, {
|
|
6
|
+
label: string;
|
|
7
|
+
tone: Tone;
|
|
8
|
+
}>;
|
|
1
9
|
export interface RequestDrawerProps {
|
|
2
10
|
id: number | null;
|
|
3
11
|
onClose: () => void;
|
|
4
12
|
}
|
|
5
|
-
|
|
13
|
+
/** Full detail sheet for one model request: timing, tokens, cost, ids, error, and the raw session entry. */
|
|
14
|
+
export declare function RequestDrawer({ id, onClose }: RequestDrawerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SearchInputProps {
|
|
2
|
+
value: string;
|
|
3
|
+
onChange: (value: string) => void;
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
width?: number;
|
|
6
|
+
}
|
|
7
|
+
/** Text filter with a leading search glyph. */
|
|
8
|
+
export declare function SearchInput({ value, onChange, placeholder, width }: SearchInputProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface SegmentedOption<T extends string> {
|
|
3
|
+
value: T;
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
title?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SegmentedProps<T extends string> {
|
|
8
|
+
options: readonly SegmentedOption<T>[];
|
|
9
|
+
value: T;
|
|
10
|
+
onChange: (value: T) => void;
|
|
11
|
+
size?: "md" | "sm";
|
|
12
|
+
"aria-label"?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Pill toggle with a measured sliding thumb. */
|
|
15
|
+
export declare function Segmented<T extends string>({ options, value, onChange, size, "aria-label": ariaLabel, }: SegmentedProps<T>): import("react").JSX.Element;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface StatDelta {
|
|
3
|
+
/** Relative change vs the previous period (0.12 = +12%). `null` when there is no baseline. */
|
|
4
|
+
change: number | null;
|
|
5
|
+
/** Which direction is good news. Default `"up"`. */
|
|
6
|
+
good?: "up" | "down";
|
|
7
|
+
}
|
|
8
|
+
export interface StatProps {
|
|
9
|
+
label: ReactNode;
|
|
10
|
+
value: ReactNode;
|
|
11
|
+
/** Small print under the value. */
|
|
12
|
+
hint?: ReactNode;
|
|
13
|
+
delta?: StatDelta;
|
|
14
|
+
/** Trend under the value. */
|
|
15
|
+
spark?: readonly number[];
|
|
16
|
+
sparkColor?: string;
|
|
17
|
+
size?: "md" | "sm";
|
|
18
|
+
/** Title tooltip explaining the metric. */
|
|
19
|
+
title?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* One metric tile. The value flashes briefly when it changes after mount, so
|
|
23
|
+
* live updates are noticeable without being loud.
|
|
24
|
+
*/
|
|
25
|
+
export declare function Stat({ label, value, hint, delta, spark, sparkColor, size, title }: StatProps): import("react").JSX.Element;
|
|
26
|
+
export interface StatGridProps {
|
|
27
|
+
/** Minimum tile width before wrapping. Default 170px. */
|
|
28
|
+
min?: number;
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/** Tiles sharing one card, separated by hairlines. */
|
|
32
|
+
export declare function StatGrid({ min, children }: StatGridProps): import("react").JSX.Element;
|
|
33
|
+
/** Signed percentage change pill, green when the move is good news. */
|
|
34
|
+
export declare function Delta({ change, good }: StatDelta): import("react").JSX.Element;
|
|
35
|
+
/** Relative change from `previous` to `current`; `null` when there is no baseline. */
|
|
36
|
+
export declare function relativeChange(current: number, previous: number): number | null;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
export declare function EmptyState({ title, hint }: {
|
|
3
|
+
title?: ReactNode;
|
|
4
|
+
hint?: ReactNode;
|
|
5
|
+
}): import("react").JSX.Element;
|
|
6
|
+
export declare function ErrorState({ error, onRetry }: {
|
|
7
|
+
error: Error | string;
|
|
8
|
+
onRetry?: () => void;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
export declare function Skeleton({ width, height, style, }: {
|
|
11
|
+
width?: number | string;
|
|
12
|
+
height?: number | string;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
}): import("react").JSX.Element;
|
|
15
|
+
/** Placeholder block matching a chart's footprint. */
|
|
16
|
+
export declare function ChartSkeleton({ height }: {
|
|
17
|
+
height?: number;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
19
|
+
/** Placeholder rows matching a table's footprint. */
|
|
20
|
+
export declare function TableSkeleton({ rows }: {
|
|
21
|
+
rows?: number;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
|
+
export interface QueryViewProps<T> {
|
|
24
|
+
query: {
|
|
25
|
+
data: T | null;
|
|
26
|
+
error: Error | null;
|
|
27
|
+
loading: boolean;
|
|
28
|
+
refetch: () => void;
|
|
29
|
+
};
|
|
30
|
+
/** Rendered on first load. */
|
|
31
|
+
skeleton: ReactNode;
|
|
32
|
+
/** Treat loaded data as empty (renders `empty`). */
|
|
33
|
+
isEmpty?: (data: T) => boolean;
|
|
34
|
+
empty?: ReactNode;
|
|
35
|
+
children: (data: T) => ReactNode;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Standard load/error/empty switch for one `useQuery` result. Errors with
|
|
39
|
+
* data already on screen keep the data and show the error above it.
|
|
40
|
+
*/
|
|
41
|
+
export declare function QueryView<T>({ query, skeleton, isEmpty, empty, children }: QueryViewProps<T>): import("react").JSX.Element;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface Column<T> {
|
|
3
|
+
key: string;
|
|
4
|
+
header: ReactNode;
|
|
5
|
+
render: (row: T) => ReactNode;
|
|
6
|
+
/** Sort key; the column header becomes clickable when present. */
|
|
7
|
+
sort?: (row: T) => number | string;
|
|
8
|
+
align?: "left" | "right" | "center";
|
|
9
|
+
width?: number | string;
|
|
10
|
+
/** Allow the cell to wrap (cells are single-line by default). */
|
|
11
|
+
wrap?: boolean;
|
|
12
|
+
/** Header tooltip. */
|
|
13
|
+
title?: string;
|
|
14
|
+
}
|
|
15
|
+
export type SortDir = "asc" | "desc";
|
|
16
|
+
export interface TableProps<T> {
|
|
17
|
+
columns: readonly Column<T>[];
|
|
18
|
+
rows: readonly T[];
|
|
19
|
+
rowKey: (row: T) => string | number;
|
|
20
|
+
onRowClick?: (row: T) => void;
|
|
21
|
+
selectedKey?: string | number | null;
|
|
22
|
+
/** Initial sort; numeric columns usually start `desc`. */
|
|
23
|
+
initialSort?: {
|
|
24
|
+
key: string;
|
|
25
|
+
dir: SortDir;
|
|
26
|
+
};
|
|
27
|
+
/** Show the first `limit` rows; "Show more" reveals `limit` × 4 more at a time (rendering stays cheap for huge tables). */
|
|
28
|
+
limit?: number;
|
|
29
|
+
dense?: boolean;
|
|
30
|
+
empty?: ReactNode;
|
|
31
|
+
/** Detail row rendered below a row (return `null` for collapsed rows). */
|
|
32
|
+
expanded?: (row: T) => ReactNode | null;
|
|
33
|
+
}
|
|
34
|
+
/** Sortable data table. Clicking a sorted header flips its direction. */
|
|
35
|
+
export declare function Table<T>({ columns, rows, rowKey, onRowClick, selectedKey, initialSort, limit, dense, empty, expanded, }: TableProps<T>): import("react").JSX.Element;
|
|
36
|
+
/** Right-aligned value with a proportional bar, for ranked numeric columns. */
|
|
37
|
+
export declare function MeterCell({ value, max, display, color, }: {
|
|
38
|
+
value: number;
|
|
39
|
+
max: number;
|
|
40
|
+
display: ReactNode;
|
|
41
|
+
color?: string;
|
|
42
|
+
}): import("react").JSX.Element;
|
|
43
|
+
/** Two-line cell: primary label and a dim secondary line. */
|
|
44
|
+
export declare function LabelCell({ primary, secondary, lead, }: {
|
|
45
|
+
primary: ReactNode;
|
|
46
|
+
secondary?: ReactNode;
|
|
47
|
+
lead?: ReactNode;
|
|
48
|
+
}): import("react").JSX.Element;
|