34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import { type LlamaSwapConfig } from "./util";
|
|
|
|
export interface UsageStats {
|
|
totalRequests: number;
|
|
totalInputTokens: number;
|
|
totalOutputTokens: number;
|
|
genP95: number;
|
|
}
|
|
|
|
export function parseStats(json: unknown): UsageStats | null {
|
|
if (!json || typeof json !== "object") return null;
|
|
const obj = json as Record<string, unknown>;
|
|
const genHist = (obj.gen_histogram ?? {}) as Record<string, unknown>;
|
|
const num = (v: unknown): number => (typeof v === "number" && Number.isFinite(v) ? v : 0);
|
|
return {
|
|
totalRequests: num(obj.total_requests),
|
|
totalInputTokens: num(obj.total_input_tokens),
|
|
totalOutputTokens: num(obj.total_output_tokens),
|
|
genP95: num(genHist.p95),
|
|
};
|
|
}
|
|
|
|
export async function fetchStats(cfg: LlamaSwapConfig, modelId: string): Promise<UsageStats | null> {
|
|
const query = modelId === "all" ? "" : `?model=${encodeURIComponent(modelId)}`;
|
|
const headers: Record<string, string> = {};
|
|
if (cfg.apiKey) headers["Authorization"] = `Bearer ${cfg.apiKey}`;
|
|
const res = await fetch(`${cfg.baseUrl}/api/metrics/stats${query}`, {
|
|
headers,
|
|
signal: AbortSignal.timeout(5000),
|
|
});
|
|
if (!res.ok) return null;
|
|
return parseStats(await res.json());
|
|
}
|