Spaces:
Runtime error
Runtime error
File size: 2,569 Bytes
077865a | 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 | import { getDb } from './server.mjs';
export interface TodayStats {
requests: number;
tokens: number;
lastModel: string;
}
// Direct SQL on the server bundle's own connection β no HTTP, no auth, no
// second better-sqlite3 handle (avoids WAL writer contention). `created_at`
// is stored as UTC text; compare in localtime so "today" matches the menu
// bar's wall clock.
export function todayStats(): TodayStats {
try {
const db = getDb();
const row = db.prepare(`
SELECT COUNT(*) AS requests,
COALESCE(SUM(COALESCE(input_tokens, 0) + COALESCE(output_tokens, 0)), 0) AS tokens
FROM requests
WHERE datetime(created_at, 'localtime') >= datetime('now', 'localtime', 'start of day')
`).get() as { requests: number; tokens: number };
const last = db.prepare(
'SELECT model_id FROM requests ORDER BY id DESC LIMIT 1',
).get() as { model_id?: string } | undefined;
return { requests: row.requests, tokens: row.tokens, lastModel: last?.model_id ?? 'β' };
} catch {
return { requests: 0, tokens: 0, lastModel: 'β' };
}
}
export function formatTokens(n: number): string {
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`;
return String(n);
}
// 24 hourly buckets, oldest β newest, for the popover chart. created_at is
// UTC "YYYY-MM-DD HH:MM:SS" text β parse with an explicit Z.
export function hourlyRequests(): number[] {
const buckets = new Array<number>(24).fill(0);
try {
const rows = getDb().prepare(
"SELECT created_at FROM requests WHERE created_at >= datetime('now', '-24 hours')",
).all() as { created_at: string }[];
const now = Date.now();
for (const r of rows) {
const t = Date.parse(r.created_at.replace(' ', 'T') + 'Z');
if (Number.isNaN(t)) continue;
const hoursAgo = Math.floor((now - t) / 3_600_000);
if (hoursAgo >= 0 && hoursAgo < 24) buckets[23 - hoursAgo]++;
}
} catch {
// fresh DB / no requests table content β all zeros is fine
}
return buckets;
}
export function successRateToday(): number | null {
try {
const row = getDb().prepare(`
SELECT COUNT(*) AS total,
SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS ok
FROM requests
WHERE datetime(created_at, 'localtime') >= datetime('now', 'localtime', 'start of day')
`).get() as { total: number; ok: number };
if (!row.total) return null;
return Math.round((row.ok / row.total) * 100);
} catch {
return null;
}
}
|