singularity-forge/src/tests/cli-stats-models.test.ts
2026-05-05 14:31:16 +02:00

72 lines
1.7 KiB
TypeScript

import assert from "node:assert/strict";
import { test } from "vitest";
import {
formatModelStatsTable,
parseDurationSeconds,
queryModelStats,
} from "../cli-stats.js";
test("sf stats models formats ASCII table rows from SQLite aggregate data", () => {
const rows = [
{
model_id: "gpt-5.4",
provider: "openai",
unit_type: "execute-task",
attempts: 2,
successes: 1,
avg_ms: 1234.4,
avg_cost: 0.01234,
avg_retries: 1.5,
},
];
const output = formatModelStatsTable(rows);
assert.match(output, /^\+/);
assert.match(output, /\| model_id \| provider \| unit_type/);
assert.match(output, /\| gpt-5\.4\s+\| openai\s+\| execute-task/);
assert.match(
output,
/\|\s+2 \|\s+50\.0% \|\s+1234 \|\s+\$0\.0123 \|\s+1\.50 \|/,
);
});
test("sf stats models queries llm_task_outcomes with since and unit-type filters", () => {
let capturedSql = "";
let capturedParams: unknown[] = [];
const fakeDb = {
prepare(sql: string) {
capturedSql = sql;
return {
all(...params: unknown[]) {
capturedParams = params;
return [
{
model_id: "claude-sonnet",
provider: "anthropic",
unit_type: "plan-slice",
attempts: 4,
successes: 3,
avg_ms: 2000,
avg_cost: 0.02,
avg_retries: 0.25,
},
];
},
};
},
};
const rows = queryModelStats(fakeDb, {
sinceSeconds: parseDurationSeconds("24h"),
unitType: "plan-slice",
});
assert.equal(rows.length, 1);
assert.match(capturedSql, /FROM llm_task_outcomes/);
assert.match(capturedSql, /recorded_at > unixepoch\(\) - \?/);
assert.match(capturedSql, /unit_type = \?/);
assert.match(capturedSql, /GROUP BY model_id, unit_type/);
assert.deepEqual(capturedParams, [86_400, "plan-slice"]);
});