@f5-sales-demo/xcsh-stats 19.51.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -0
- package/build.ts +84 -0
- package/package.json +89 -0
- package/src/aggregator.ts +129 -0
- package/src/client/App.tsx +116 -0
- package/src/client/api.ts +33 -0
- package/src/client/components/ChartsContainer.tsx +219 -0
- package/src/client/components/Header.tsx +48 -0
- package/src/client/components/ModelsTable.tsx +370 -0
- package/src/client/components/RequestDetail.tsx +174 -0
- package/src/client/components/RequestList.tsx +73 -0
- package/src/client/components/StatsGrid.tsx +97 -0
- package/src/client/css.d.ts +1 -0
- package/src/client/index.tsx +6 -0
- package/src/client/styles.css +306 -0
- package/src/client/types.ts +102 -0
- package/src/client/useSystemTheme.ts +31 -0
- package/src/db.ts +482 -0
- package/src/embedded-client.generated.txt +7 -0
- package/src/index.ts +153 -0
- package/src/parser.ts +169 -0
- package/src/server.ts +300 -0
- package/src/types.ts +175 -0
- package/tailwind.config.js +40 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { AssistantMessage, StopReason, Usage } from "@f5xc-salesdemos/pi-ai";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extracted stats from an assistant message.
|
|
5
|
+
*/
|
|
6
|
+
export interface MessageStats {
|
|
7
|
+
/** Database ID */
|
|
8
|
+
id?: number;
|
|
9
|
+
/** Session file path */
|
|
10
|
+
sessionFile: string;
|
|
11
|
+
/** Entry ID within the session */
|
|
12
|
+
entryId: string;
|
|
13
|
+
/** Folder/project path (extracted from session filename) */
|
|
14
|
+
folder: string;
|
|
15
|
+
/** Model ID */
|
|
16
|
+
model: string;
|
|
17
|
+
/** Provider name */
|
|
18
|
+
provider: string;
|
|
19
|
+
/** API type */
|
|
20
|
+
api: string;
|
|
21
|
+
/** Unix timestamp in milliseconds */
|
|
22
|
+
timestamp: number;
|
|
23
|
+
/** Request duration in milliseconds */
|
|
24
|
+
duration: number | null;
|
|
25
|
+
/** Time to first token in milliseconds */
|
|
26
|
+
ttft: number | null;
|
|
27
|
+
/** Stop reason */
|
|
28
|
+
stopReason: StopReason;
|
|
29
|
+
/** Error message if stopReason is error */
|
|
30
|
+
errorMessage: string | null;
|
|
31
|
+
/** Token usage */
|
|
32
|
+
usage: Usage;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Full details of a request, including content.
|
|
37
|
+
*/
|
|
38
|
+
export interface RequestDetails extends MessageStats {
|
|
39
|
+
messages: any[]; // The full conversation history or just the last turn
|
|
40
|
+
output: any; // The model's response
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Aggregated stats for a model or folder.
|
|
45
|
+
*/
|
|
46
|
+
export interface AggregatedStats {
|
|
47
|
+
/** Total number of requests */
|
|
48
|
+
totalRequests: number;
|
|
49
|
+
/** Number of successful requests */
|
|
50
|
+
successfulRequests: number;
|
|
51
|
+
/** Number of failed requests */
|
|
52
|
+
failedRequests: number;
|
|
53
|
+
/** Error rate (0-1) */
|
|
54
|
+
errorRate: number;
|
|
55
|
+
/** Total input tokens */
|
|
56
|
+
totalInputTokens: number;
|
|
57
|
+
/** Total output tokens */
|
|
58
|
+
totalOutputTokens: number;
|
|
59
|
+
/** Total cache read tokens */
|
|
60
|
+
totalCacheReadTokens: number;
|
|
61
|
+
/** Total cache write tokens */
|
|
62
|
+
totalCacheWriteTokens: number;
|
|
63
|
+
/** Cache hit rate (0-1) */
|
|
64
|
+
cacheRate: number;
|
|
65
|
+
/** Total cost */
|
|
66
|
+
totalCost: number;
|
|
67
|
+
/** Total premium requests */
|
|
68
|
+
totalPremiumRequests: number;
|
|
69
|
+
/** Average duration in ms */
|
|
70
|
+
avgDuration: number | null;
|
|
71
|
+
/** Average TTFT in ms */
|
|
72
|
+
avgTtft: number | null;
|
|
73
|
+
/** Average tokens per second (output tokens / duration) */
|
|
74
|
+
avgTokensPerSecond: number | null;
|
|
75
|
+
/** Time range */
|
|
76
|
+
firstTimestamp: number;
|
|
77
|
+
lastTimestamp: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Stats grouped by model.
|
|
82
|
+
*/
|
|
83
|
+
export interface ModelStats extends AggregatedStats {
|
|
84
|
+
model: string;
|
|
85
|
+
provider: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Stats grouped by folder.
|
|
90
|
+
*/
|
|
91
|
+
export interface FolderStats extends AggregatedStats {
|
|
92
|
+
folder: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Time series data point.
|
|
97
|
+
*/
|
|
98
|
+
export interface TimeSeriesPoint {
|
|
99
|
+
/** Bucket timestamp (start of hour/day) */
|
|
100
|
+
timestamp: number;
|
|
101
|
+
/** Request count */
|
|
102
|
+
requests: number;
|
|
103
|
+
/** Error count */
|
|
104
|
+
errors: number;
|
|
105
|
+
/** Total tokens */
|
|
106
|
+
tokens: number;
|
|
107
|
+
/** Total cost */
|
|
108
|
+
cost: number;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Model usage time series data point (daily buckets).
|
|
113
|
+
*/
|
|
114
|
+
export interface ModelTimeSeriesPoint {
|
|
115
|
+
/** Bucket timestamp (start of day) */
|
|
116
|
+
timestamp: number;
|
|
117
|
+
/** Model name */
|
|
118
|
+
model: string;
|
|
119
|
+
/** Provider name */
|
|
120
|
+
provider: string;
|
|
121
|
+
/** Request count */
|
|
122
|
+
requests: number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Model performance time series data point (daily buckets).
|
|
127
|
+
*/
|
|
128
|
+
export interface ModelPerformancePoint {
|
|
129
|
+
/** Bucket timestamp (start of day) */
|
|
130
|
+
timestamp: number;
|
|
131
|
+
/** Model name */
|
|
132
|
+
model: string;
|
|
133
|
+
/** Provider name */
|
|
134
|
+
provider: string;
|
|
135
|
+
/** Request count */
|
|
136
|
+
requests: number;
|
|
137
|
+
/** Average TTFT in ms */
|
|
138
|
+
avgTtft: number | null;
|
|
139
|
+
/** Average tokens per second */
|
|
140
|
+
avgTokensPerSecond: number | null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Overall dashboard stats.
|
|
145
|
+
*/
|
|
146
|
+
export interface DashboardStats {
|
|
147
|
+
overall: AggregatedStats;
|
|
148
|
+
byModel: ModelStats[];
|
|
149
|
+
byFolder: FolderStats[];
|
|
150
|
+
timeSeries: TimeSeriesPoint[];
|
|
151
|
+
modelSeries: ModelTimeSeriesPoint[];
|
|
152
|
+
modelPerformanceSeries: ModelPerformancePoint[];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Session log entry types.
|
|
157
|
+
*/
|
|
158
|
+
export interface SessionHeader {
|
|
159
|
+
type: "session";
|
|
160
|
+
version: number;
|
|
161
|
+
id: string;
|
|
162
|
+
timestamp: string;
|
|
163
|
+
cwd: string;
|
|
164
|
+
title?: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface SessionMessageEntry {
|
|
168
|
+
type: "message";
|
|
169
|
+
id: string;
|
|
170
|
+
parentId: string | null;
|
|
171
|
+
timestamp: string;
|
|
172
|
+
message: AssistantMessage | { role: "user" | "toolResult" };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export type SessionEntry = SessionHeader | SessionMessageEntry | { type: string };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
export default {
|
|
4
|
+
content: [path.join(import.meta.dir, "src", "client", "**/*.{js,jsx,ts,tsx}")],
|
|
5
|
+
darkMode: "class",
|
|
6
|
+
theme: {
|
|
7
|
+
extend: {
|
|
8
|
+
colors: {
|
|
9
|
+
page: "var(--bg-page)",
|
|
10
|
+
surface: "var(--bg-surface)",
|
|
11
|
+
elevated: "var(--bg-elevated)",
|
|
12
|
+
"border-subtle": "var(--border-subtle)",
|
|
13
|
+
"border-default": "var(--border-default)",
|
|
14
|
+
"text-primary": "var(--text-primary)",
|
|
15
|
+
"text-secondary": "var(--text-secondary)",
|
|
16
|
+
"text-muted": "var(--text-muted)",
|
|
17
|
+
pink: "var(--accent-pink)",
|
|
18
|
+
cyan: "var(--accent-cyan)",
|
|
19
|
+
violet: "var(--accent-violet)",
|
|
20
|
+
},
|
|
21
|
+
fontFamily: {
|
|
22
|
+
sans: [
|
|
23
|
+
"-apple-system",
|
|
24
|
+
"BlinkMacSystemFont",
|
|
25
|
+
'"Segoe UI"',
|
|
26
|
+
"Roboto",
|
|
27
|
+
"Helvetica",
|
|
28
|
+
"Arial",
|
|
29
|
+
"sans-serif",
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
borderRadius: {
|
|
33
|
+
sm: "var(--radius-sm)",
|
|
34
|
+
md: "var(--radius-md)",
|
|
35
|
+
lg: "var(--radius-lg)",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
plugins: [],
|
|
40
|
+
};
|