// ModelLedgerEntry — aggregate per-task-type-per-model performance. // Built by aggregating mode_experiments.jsonl + model_trust.jsonl. // Updated rather than appended — one row per (model_name, task_type) // representing latest aggregates. import { ValidationResult, requireString, requireNumber, requireIsoTimestamp, requireStringArray, } from "./types"; export const MODEL_LEDGER_SCHEMA_VERSION = 1; export interface ModelLedgerEntry { schema_version: number; model_name: string; model_provider: string; task_type: string; success_rate: number; // [0, 1] failure_modes: string[]; // top failure mode tags best_partner_model?: string; // pairs well with X (consensus / tie-break) escalation_role?: string; // when this model gets escalated TO (or FROM) cost_usd_p50?: number; latency_ms_p50?: number; latency_ms_p95?: number; context_window?: number; sample_count: number; last_updated: string; // ISO 8601 notes?: string; } export function validateModelLedgerEntry(input: unknown): ValidationResult { const errors: string[] = []; if (typeof input !== "object" || input === null) return { valid: false, errors: ["expected object"] }; const r = input as Record; let ok = true; if (r.schema_version !== MODEL_LEDGER_SCHEMA_VERSION) { errors.push(`schema_version: expected ${MODEL_LEDGER_SCHEMA_VERSION}, got ${JSON.stringify(r.schema_version)}`); ok = false; } ok = requireString(r.model_name, "model_name", errors) && ok; ok = requireString(r.model_provider, "model_provider", errors) && ok; ok = requireString(r.task_type, "task_type", errors) && ok; ok = requireIsoTimestamp(r.last_updated, "last_updated", errors) && ok; ok = requireStringArray(r.failure_modes, "failure_modes", errors) && ok; if (!requireNumber(r.success_rate, "success_rate", errors)) ok = false; else if ((r.success_rate as number) < 0 || (r.success_rate as number) > 1) { errors.push("success_rate: must be in [0, 1]"); ok = false; } if (!requireNumber(r.sample_count, "sample_count", errors)) ok = false; else if ((r.sample_count as number) < 1 || !Number.isInteger(r.sample_count)) { errors.push("sample_count: must be positive integer (no aggregate from zero samples)"); ok = false; } if (!ok) return { valid: false, errors }; return { valid: true, value: r as unknown as ModelLedgerEntry }; }