import { readFile, readdir, stat } from "node:fs/promises"; import { join, resolve } from "node:path"; export interface SessionMetrics { sessions: number; requests: number; failedRequests: number; failureRate: number; totalTokens: number; cost: number; } export type TaskSuccess = "equal" | "better" | "worse"; export interface BenchmarkComparison { costReductionPercent: number; tokenReductionPercent: number; gates: { cost: boolean; tokens: boolean; failureRate: boolean; taskSuccess: boolean; }; passed: boolean; } interface UsageLike { totalTokens?: unknown; cost?: { total?: unknown }; } async function sessionFiles(paths: string[]): Promise { const files = new Set(); const visit = async (path: string): Promise => { const absolute = resolve(path); const metadata = await stat(absolute); if (metadata.isFile()) { if (absolute.endsWith(".jsonl")) files.add(absolute); return; } if (!metadata.isDirectory()) return; for (const entry of await readdir(absolute, { withFileTypes: true })) { const child = join(absolute, entry.name); if (entry.isDirectory()) await visit(child); else if (entry.isFile() && entry.name.endsWith(".jsonl")) files.add(child); } }; for (const path of paths) await visit(path); return [...files].sort(); } function round(value: number, digits = 8): number { const factor = 10 ** digits; return Math.round((value + Number.EPSILON) * factor) / factor; } export async function analyzeSessions(paths: string[]): Promise { const files = await sessionFiles(paths); let requests = 0; let failedRequests = 0; let totalTokens = 0; let cost = 0; for (const file of files) { const lines = (await readFile(file, "utf8")).split("\n"); for (let index = 0; index < lines.length; index++) { const line = lines[index].trim(); if (!line) continue; let entry: any; try { entry = JSON.parse(line); } catch (error) { throw new Error(`Invalid JSON in ${file}:${index + 1}`, { cause: error }); } const usage: UsageLike | undefined = entry.type === "message" ? entry.message?.usage : entry.usage; if (!usage) continue; requests += 1; totalTokens += typeof usage.totalTokens === "number" ? usage.totalTokens : 0; cost += typeof usage.cost?.total === "number" ? usage.cost.total : 0; if ( entry.type === "message" && entry.message?.role === "assistant" && entry.message.stopReason === "error" ) { failedRequests += 1; } } } return { sessions: files.length, requests, failedRequests, failureRate: requests === 0 ? 0 : round((failedRequests / requests) * 100), totalTokens, cost: round(cost), }; } export function compareBenchmark(input: { baseline: SessionMetrics; candidate: SessionMetrics; taskSuccess: TaskSuccess; }): BenchmarkComparison { const costReductionPercent = input.baseline.cost === 0 ? 0 : round((1 - input.candidate.cost / input.baseline.cost) * 100); const tokenReductionPercent = input.baseline.totalTokens === 0 ? 0 : round( (1 - input.candidate.totalTokens / input.baseline.totalTokens) * 100, ); const gates = { cost: costReductionPercent >= 25, tokens: tokenReductionPercent >= 40, failureRate: input.candidate.failureRate <= input.baseline.failureRate, taskSuccess: input.taskSuccess !== "worse", }; return { costReductionPercent, tokenReductionPercent, gates, passed: Object.values(gates).every(Boolean), }; }