UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

87 lines • 3.42 kB
/** Bucket key for a score whose run named no agent (mirrors the governance run breakdown). */ const DEFAULT_AGENT_BUCKET = '(default)'; /** Mean of a bucket. Every caller below builds its buckets by pushing, so none is ever empty. */ function mean(values) { let total = 0; for (const value of values) { total += value; } return total / values.length; } /** Rollup per scorer, worst mean first — the ordering that puts the problem at the top. */ export function summarizeByScorer(rows) { const byScorer = new Map(); for (const row of rows) { const bucket = byScorer.get(row.scorer) ?? { kind: row.kind, scores: [] }; bucket.scores.push(row.score); byScorer.set(row.scorer, bucket); } const result = []; for (const [scorer, bucket] of byScorer) { result.push({ scorer, kind: bucket.kind, samples: bucket.scores.length, meanScore: mean(bucket.scores), minScore: Math.min(...bucket.scores), maxScore: Math.max(...bucket.scores), }); } result.sort((left, right) => left.meanScore - right.meanScore || left.scorer.localeCompare(right.scorer)); return result; } /** Rollup per (agent, scorer) pair, worst mean first — which persona drags which signal down. */ export function summarizeByAgent(rows) { const byPair = new Map(); for (const row of rows) { const agentName = row.agentName ?? DEFAULT_AGENT_BUCKET; const key = `${agentName} ${row.scorer}`; const bucket = byPair.get(key) ?? { agentName, scorer: row.scorer, scores: [] }; bucket.scores.push(row.score); byPair.set(key, bucket); } const result = []; for (const bucket of byPair.values()) { result.push({ agentName: bucket.agentName, scorer: bucket.scorer, samples: bucket.scores.length, meanScore: mean(bucket.scores), }); } result.sort((left, right) => left.meanScore - right.meanScore || left.agentName.localeCompare(right.agentName) || left.scorer.localeCompare(right.scorer)); return result; } /** Daily mean per scorer, ascending by day then scorer — the "is it getting better" series. */ export function bucketScoreTrend(rows) { const byDay = new Map(); for (const row of rows) { const key = `${row.day} ${row.scorer}`; const bucket = byDay.get(key) ?? { day: row.day, scorer: row.scorer, scores: [] }; bucket.scores.push(row.score); byDay.set(key, bucket); } const result = []; for (const bucket of byDay.values()) { result.push({ day: bucket.day, scorer: bucket.scorer, samples: bucket.scores.length, meanScore: mean(bucket.scores), }); } result.sort((left, right) => left.day.localeCompare(right.day) || left.scorer.localeCompare(right.scorer)); return result; } /** * The lowest-scoring runs, worst first, capped at `limit` — the triage queue. Every scorer carries a * `reason`, so this is the one view that answers "show me what went wrong" without a second read. */ export function worstScoredRuns(rows, limit) { return [...rows] .sort((left, right) => left.score - right.score || left.runId.localeCompare(right.runId)) .slice(0, limit); } //# sourceMappingURL=summarize.js.map