@linxiraos/pi-stats 1.1.0 → 1.1.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/CHANGELOG.md +12 -0
- package/README.md +3 -3
- package/THIRD-PARTY-NOTICES.txt +22909 -0
- package/dist/client/index.css +1 -0
- package/dist/client/index.html +24 -0
- package/dist/client/index.js +257 -0
- package/dist/client/styles.css +1692 -0
- package/dist/types/aggregator.d.ts +103 -0
- package/dist/types/client/App.d.ts +1 -0
- package/dist/types/client/api.d.ts +22 -0
- package/dist/types/client/app/AppLayout.d.ts +16 -0
- package/dist/types/client/app/NavRail.d.ts +7 -0
- package/dist/types/client/app/RangeControl.d.ts +7 -0
- package/dist/types/client/app/SyncButton.d.ts +14 -0
- package/dist/types/client/app/ThemeToggle.d.ts +1 -0
- package/dist/types/client/app/TopBar.d.ts +15 -0
- package/dist/types/client/app/routes.d.ts +12 -0
- package/dist/types/client/components/AgentTokenShare.d.ts +5 -0
- package/dist/types/client/components/chart-shared.d.ts +173 -0
- package/dist/types/client/components/models-table-shared.d.ts +175 -0
- package/dist/types/client/components/range-meta.d.ts +21 -0
- package/dist/types/client/data/charts.d.ts +1 -0
- package/dist/types/client/data/formatters.d.ts +13 -0
- package/dist/types/client/data/useHashRoute.d.ts +8 -0
- package/dist/types/client/data/useResource.d.ts +13 -0
- package/dist/types/client/data/view-models.d.ts +75 -0
- package/dist/types/client/index.d.ts +2 -0
- package/dist/types/client/routes/BehaviorRoute.d.ts +7 -0
- package/dist/types/client/routes/CostsRoute.d.ts +7 -0
- package/dist/types/client/routes/ErrorsRoute.d.ts +8 -0
- package/dist/types/client/routes/GainRoute.d.ts +7 -0
- package/dist/types/client/routes/ModelsRoute.d.ts +7 -0
- package/dist/types/client/routes/OverviewRoute.d.ts +8 -0
- package/dist/types/client/routes/ProjectsRoute.d.ts +7 -0
- package/dist/types/client/routes/ProvidersRoute.d.ts +7 -0
- package/dist/types/client/routes/RequestsRoute.d.ts +8 -0
- package/dist/types/client/routes/ToolsRoute.d.ts +7 -0
- package/dist/types/client/routes/index.d.ts +10 -0
- package/dist/types/client/types.d.ts +63 -0
- package/dist/types/client/ui/AsyncBoundary.d.ts +12 -0
- package/dist/types/client/ui/DataTable.d.ts +17 -0
- package/dist/types/client/ui/EmptyState.d.ts +7 -0
- package/dist/types/client/ui/ErrorState.d.ts +6 -0
- package/dist/types/client/ui/JsonBlock.d.ts +7 -0
- package/dist/types/client/ui/MetricCluster.d.ts +5 -0
- package/dist/types/client/ui/Panel.d.ts +7 -0
- package/dist/types/client/ui/RequestDrawer.d.ts +5 -0
- package/dist/types/client/ui/SegmentedControl.d.ts +12 -0
- package/dist/types/client/ui/Skeleton.d.ts +8 -0
- package/dist/types/client/ui/StatusPill.d.ts +7 -0
- package/dist/types/client/ui/index.d.ts +11 -0
- package/dist/types/client/useSystemTheme.d.ts +11 -0
- package/dist/types/db.d.ts +160 -0
- package/dist/types/embedded-client.d.ts +18 -0
- package/dist/types/gain-aggregator.d.ts +26 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/parser.d.ts +53 -0
- package/dist/types/port-conflict.d.ts +16 -0
- package/dist/types/server.d.ts +14 -0
- package/dist/types/shared-types.d.ts +421 -0
- package/dist/types/sync-worker.d.ts +31 -0
- package/dist/types/types.d.ts +164 -0
- package/dist/types/usage-windows.d.ts +72 -0
- package/dist/types/user-metrics.d.ts +81 -0
- package/package.json +95 -91
- package/src/aggregator.ts +1 -1
- package/src/index.ts +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ClientUsageClientSummary } from "@linxiraos/pi-ai/usage";
|
|
2
|
+
import type { ProviderWindowInsight, UsageWindowSeries } from "./shared-types.js";
|
|
3
|
+
/** Subset of a `usage_history` row consumed by the window analytics. */
|
|
4
|
+
export interface UsageSnapshotRow {
|
|
5
|
+
/** Epoch ms the report was fetched. */
|
|
6
|
+
recordedAt: number;
|
|
7
|
+
provider: string;
|
|
8
|
+
/** Stable credential identity key. */
|
|
9
|
+
accountKey: string;
|
|
10
|
+
email: string | null;
|
|
11
|
+
accountId: string | null;
|
|
12
|
+
limitId: string;
|
|
13
|
+
label: string;
|
|
14
|
+
windowLabel: string | null;
|
|
15
|
+
/** Used fraction (0..1, >1 = overage) when the provider reported one. */
|
|
16
|
+
usedFraction: number | null;
|
|
17
|
+
status: string | null;
|
|
18
|
+
}
|
|
19
|
+
/** Utilization series + derived insights for every provider window in range. */
|
|
20
|
+
export interface UsageWindowStats {
|
|
21
|
+
usageSeries: UsageWindowSeries[];
|
|
22
|
+
windowInsights: ProviderWindowInsight[];
|
|
23
|
+
}
|
|
24
|
+
/** Usage snapshots plus, in broker mode, fleet-wide token burn per provider. */
|
|
25
|
+
export interface UsageDataSnapshot {
|
|
26
|
+
rows: UsageSnapshotRow[];
|
|
27
|
+
/**
|
|
28
|
+
* Total tokens (input + output + cache read/write) per provider summed
|
|
29
|
+
* across every install reporting to the auth broker, or `null` when no
|
|
30
|
+
* broker is configured or no client reports exist for the range. Matches
|
|
31
|
+
* the fleet-wide window fractions in `rows`, unlike local message stats
|
|
32
|
+
* which only see this install's burn.
|
|
33
|
+
*/
|
|
34
|
+
fleetTokensByProvider: Map<string, number> | null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Read usage-limit snapshots recorded at or after `sinceMs`, oldest first.
|
|
38
|
+
* Opens the agent DB read-only; returns `[]` when the DB or table is absent.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readUsageSnapshots(sinceMs: number, dbPath?: string): UsageSnapshotRow[];
|
|
41
|
+
/**
|
|
42
|
+
* Fetch usage data from wherever it actually accumulates: the auth broker's
|
|
43
|
+
* durable history plus per-client observed-usage reports when a broker is
|
|
44
|
+
* configured (the broker performs every upstream usage fetch in that mode, so
|
|
45
|
+
* the local `usage_history` stays frozen), else the local agent DB. Broker
|
|
46
|
+
* errors fall back to the local read so the dashboard degrades to
|
|
47
|
+
* stale-but-present data instead of failing.
|
|
48
|
+
*/
|
|
49
|
+
export declare function fetchUsageData(sinceMs: number): Promise<UsageDataSnapshot>;
|
|
50
|
+
/**
|
|
51
|
+
* Fold per-client provider aggregates into total tokens per provider
|
|
52
|
+
* (input + output + cache read/write, matching message-stat `totalTokens`).
|
|
53
|
+
* Returns `null` when no client reported anything, signalling "no data"
|
|
54
|
+
* rather than "zero burn".
|
|
55
|
+
*/
|
|
56
|
+
export declare function sumFleetTokens(clients: ClientUsageClientSummary[]): Map<string, number> | null;
|
|
57
|
+
/**
|
|
58
|
+
* Derive utilization series and per-window insights from raw snapshots.
|
|
59
|
+
*
|
|
60
|
+
* Windows are grouped by `(provider, limitId)` — never by display label.
|
|
61
|
+
* Distinct limits can share a duration label (Anthropic's overall and
|
|
62
|
+
* model-scoped 7-day windows, Codex's base and Spark weeklies); merging them
|
|
63
|
+
* interleaves unrelated fractions per account and wildly inflates consumption.
|
|
64
|
+
*
|
|
65
|
+
* `tokensByProvider` supplies each provider's token burn over the same time
|
|
66
|
+
* range (fleet-wide broker client reports when available, else local message
|
|
67
|
+
* stats); it converts consumed window fraction into an estimated token
|
|
68
|
+
* capacity per window. Attribution note: tokens are per provider, not per
|
|
69
|
+
* account, so the estimate treats the account fleet as one pooled
|
|
70
|
+
* subscription — which is exactly how round-robin auth uses it.
|
|
71
|
+
*/
|
|
72
|
+
export declare function computeUsageWindowStats(rows: UsageSnapshotRow[], tokensByProvider: ReadonlyMap<string, number>): UsageWindowStats;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavioral metrics extracted from a single user message.
|
|
3
|
+
*
|
|
4
|
+
* Pure, side-effect free. Designed for batch use during session ingestion
|
|
5
|
+
* and standalone testing.
|
|
6
|
+
*/
|
|
7
|
+
export interface UserMessageMetrics {
|
|
8
|
+
/** Total characters of analyzed text. */
|
|
9
|
+
chars: number;
|
|
10
|
+
/** Whitespace-delimited word count. */
|
|
11
|
+
words: number;
|
|
12
|
+
/**
|
|
13
|
+
* Number of "yelling" sentences: sentences where more than half of the
|
|
14
|
+
* alphabetic characters are uppercase (and there are enough letters to
|
|
15
|
+
* make the ratio meaningful - short acronyms like "OK" don't count).
|
|
16
|
+
* A sentence also needs either two uppercase runs ("WHAT THE HELL") or
|
|
17
|
+
* one elongated run ("CMOOON") so a lone acronym/env var ("use JSON",
|
|
18
|
+
* "HOME=/tmp") doesn't register.
|
|
19
|
+
*/
|
|
20
|
+
yelling: number;
|
|
21
|
+
/** Profanity hits (word-boundary, case-insensitive). */
|
|
22
|
+
profanity: number;
|
|
23
|
+
/**
|
|
24
|
+
* Catch-all "obviously upset" signal computed on a *prose-only* body
|
|
25
|
+
* (code fences, XML/HTML tags, URLs, file mentions, and quoted lines
|
|
26
|
+
* are stripped first; messages whose remaining prose is >=3 lines score
|
|
27
|
+
* zero because formatted prompts aren't tantrums).
|
|
28
|
+
*
|
|
29
|
+
* Sum of:
|
|
30
|
+
* - drama runs: 3+ `!` / `?` (with `1`-mishit fallout)
|
|
31
|
+
* - interjections, elongated where the short form is ambiguous:
|
|
32
|
+
* `noooo`, `ahhh`, `ugh(h)`, `argh`, `grr`, `stooop`, `whyyy`,
|
|
33
|
+
* `fuuu(ck)`, `wtfff`, `omggg`, `yesss`, `goddd`, `bruhh`
|
|
34
|
+
* - standalone `dude`
|
|
35
|
+
* - sad emoticons: `:(`, `;(`, `:-(((`
|
|
36
|
+
*/
|
|
37
|
+
anguish: number;
|
|
38
|
+
/**
|
|
39
|
+
* Corrective negation: the user is telling us we got it wrong.
|
|
40
|
+
*
|
|
41
|
+
* Counted on the same prose-only body as {@link anguish}.
|
|
42
|
+
*
|
|
43
|
+
* - line-leading `nope` / `nah` / `nvm` / `wrong` / `incorrect`
|
|
44
|
+
* (word-bounded, so `now`, `nobody`, `north` don't match)
|
|
45
|
+
* - line-leading `no` when used as an interjection - followed by
|
|
46
|
+
* punctuation, end-of-text, or a discourse word (`no i meant`,
|
|
47
|
+
* `no, wait`). Determiner `no` (`no extensions to the page`,
|
|
48
|
+
* `no auto start`) doesn't count.
|
|
49
|
+
* - `that(?:'s)? not (what|right|it)` and `not what i (meant|asked|said|wanted)`
|
|
50
|
+
* - `makes (no|zero) sense`
|
|
51
|
+
*/
|
|
52
|
+
negation: number;
|
|
53
|
+
/**
|
|
54
|
+
* The user is repeating themselves - strong signal the previous turn
|
|
55
|
+
* missed the ask. Counts hits for:
|
|
56
|
+
*
|
|
57
|
+
* - `i (meant|said|asked|told you|already (said|told|did|asked|wrote))`
|
|
58
|
+
* - `(like|as) i (said|told you|asked)`
|
|
59
|
+
* - `still (doesn't|isn't|not|broken|wrong|fails|failing|the same|same)`
|
|
60
|
+
*
|
|
61
|
+
* Bare `still` / `again` are too ambiguous to count alone (they show up
|
|
62
|
+
* in normal speech like "try again" or "still works").
|
|
63
|
+
*/
|
|
64
|
+
repetition: number;
|
|
65
|
+
/**
|
|
66
|
+
* Direct second-person reproach pinned on the agent:
|
|
67
|
+
*
|
|
68
|
+
* - `you (didn't|did not|broke|missed|forgot|keep|always|never|still|ignored)`
|
|
69
|
+
* - `why (would|did) (you|u)`
|
|
70
|
+
* - sentence-leading `stop <verb>ing` imperatives
|
|
71
|
+
*/
|
|
72
|
+
blame: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Compute behavioral metrics for a user message.
|
|
76
|
+
*
|
|
77
|
+
* `text` may be empty or whitespace; in that case every metric is 0.
|
|
78
|
+
*/
|
|
79
|
+
export declare function computeUserMessageMetrics(text: string): UserMessageMetrics;
|
|
80
|
+
/** Empty metrics constant for callers that need a default. */
|
|
81
|
+
export declare const EMPTY_USER_METRICS: UserMessageMetrics;
|
package/package.json
CHANGED
|
@@ -1,92 +1,96 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
2
|
+
"type": "module",
|
|
3
|
+
"name": "@linxiraos/pi-stats",
|
|
4
|
+
"version": "1.1.2",
|
|
5
|
+
"description": "Local observability dashboard for pi AI usage statistics",
|
|
6
|
+
"homepage": "https://linxira-os.github.io/zeta/",
|
|
7
|
+
"author": "Can Boluk",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Linxira-OS/linxira-zeta.git",
|
|
12
|
+
"directory": "packages/stats"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/Linxira-OS/linxira-zeta/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"ai",
|
|
19
|
+
"observability",
|
|
20
|
+
"metrics",
|
|
21
|
+
"dashboard",
|
|
22
|
+
"llm",
|
|
23
|
+
"statistics"
|
|
24
|
+
],
|
|
25
|
+
"main": "./src/index.ts",
|
|
26
|
+
"types": "./dist/types/index.d.ts",
|
|
27
|
+
"bin": {
|
|
28
|
+
"zeta-stats": "./src/index.ts"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"gen:stats": "bun scripts/generate-client-bundle.ts --generate",
|
|
32
|
+
"gen:stats:reset": "bun scripts/generate-client-bundle.ts --reset",
|
|
33
|
+
"build": "bun run build.ts",
|
|
34
|
+
"dev": "bun run src/index.ts",
|
|
35
|
+
"check": "biome check . && bun run check:types",
|
|
36
|
+
"check:types": "tsgo -p tsconfig.json --noEmit && tsgo -p tsconfig.client.json --noEmit",
|
|
37
|
+
"lint": "biome lint .",
|
|
38
|
+
"fix": "biome check --write --unsafe .",
|
|
39
|
+
"fmt": "biome format --write ."
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@linxiraos/pi-ai": "1.1.2",
|
|
43
|
+
"@linxiraos/pi-catalog": "1.1.2",
|
|
44
|
+
"@linxiraos/pi-utils": "1.1.2",
|
|
45
|
+
"@tailwindcss/node": "^4.3.2",
|
|
46
|
+
"chart.js": "^4.5.1",
|
|
47
|
+
"lucide-react": "^1.24.0",
|
|
48
|
+
"react": "19.2.7",
|
|
49
|
+
"react-chartjs-2": "^5.3.1",
|
|
50
|
+
"react-dom": "19.2.7",
|
|
51
|
+
"tailwindcss": "^4.3.2"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/bun": "^1.3.14",
|
|
55
|
+
"@types/react": "^19.2.17",
|
|
56
|
+
"@types/react-dom": "^19.2.3",
|
|
57
|
+
"postcss": "^8.5.16"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"bun": ">=1.3.14"
|
|
61
|
+
},
|
|
62
|
+
"files": [
|
|
63
|
+
"src",
|
|
64
|
+
"build.ts",
|
|
65
|
+
"tailwind.config.js",
|
|
66
|
+
"README.md",
|
|
67
|
+
"CHANGELOG.md",
|
|
68
|
+
"LICENSE",
|
|
69
|
+
"THIRD-PARTY-NOTICES.txt",
|
|
70
|
+
"dist/types",
|
|
71
|
+
"dist/client"
|
|
72
|
+
],
|
|
73
|
+
"exports": {
|
|
74
|
+
".": {
|
|
75
|
+
"types": "./dist/types/index.d.ts",
|
|
76
|
+
"import": "./src/index.ts"
|
|
77
|
+
},
|
|
78
|
+
"./*": {
|
|
79
|
+
"types": "./dist/types/*.d.ts",
|
|
80
|
+
"import": "./src/*.ts"
|
|
81
|
+
},
|
|
82
|
+
"./client": {
|
|
83
|
+
"types": "./dist/types/client/index.d.ts",
|
|
84
|
+
"import": "./src/client/index.tsx"
|
|
85
|
+
},
|
|
86
|
+
"./client/*": {
|
|
87
|
+
"types": "./dist/types/client/*.d.ts",
|
|
88
|
+
"import": "./src/client/*.ts"
|
|
89
|
+
},
|
|
90
|
+
"./client/components/*": {
|
|
91
|
+
"types": "./dist/types/client/components/*.d.ts",
|
|
92
|
+
"import": "./src/client/components/*.ts"
|
|
93
|
+
},
|
|
94
|
+
"./*.js": "./src/*.ts"
|
|
95
|
+
}
|
|
96
|
+
}
|
package/src/aggregator.ts
CHANGED
|
@@ -37,7 +37,7 @@ import { getSessionEntry, listAllSessionFiles, type ParseSessionResult, parseSes
|
|
|
37
37
|
import type { SyncWorkerRequest, SyncWorkerResponse } from "./sync-worker";
|
|
38
38
|
// Coding-agent binary/bundle workers route through the CLI entrypoint with a
|
|
39
39
|
// hidden argv mode, so the compiled binary and npm bundle only need one
|
|
40
|
-
// JavaScript entry. Standalone source `
|
|
40
|
+
// JavaScript entry. Standalone source `zeta-stats` keeps using this package's
|
|
41
41
|
// own sync-worker source file.
|
|
42
42
|
import type {
|
|
43
43
|
BehaviorDashboardStats,
|
package/src/index.ts
CHANGED
|
File without changes
|