@tangle-network/agent-eval 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/judges.ts","../src/statistics.ts","../src/executor.ts","../src/benchmark.ts","../src/metrics.ts","../src/convergence.ts","../src/registry.ts","../src/driver.ts","../src/reporter.ts"],"sourcesContent":["import type { ProductClientConfig, RouteMap, TestResult, CheckResult } from './types'\n\n/**\n * ProductClient — configurable HTTP client for exercising any agent's APIs.\n *\n * Routes are config, not hardcoded. Each agent provides its own RouteMap.\n */\nexport class ProductClient {\n private baseUrl: string\n private routes: RouteMap\n private cookies: string = ''\n\n constructor(config: ProductClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.routes = config.routes\n }\n\n private route(name: keyof RouteMap): string {\n const path = this.routes[name]\n if (!path) throw new Error(`Route \"${name}\" not configured`)\n return path\n }\n\n async signup(name: string, email: string, password: string): Promise<{ userId: string }> {\n const res = await this.post(this.route('signup'), { name, email, password })\n const user = res.user as Record<string, unknown> | undefined\n if (!user?.id) throw new Error(`Signup failed: ${JSON.stringify(res)}`)\n return { userId: user.id as string }\n }\n\n async login(email: string, password: string): Promise<void> {\n const res = await fetch(`${this.baseUrl}${this.route('login')}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Origin': this.baseUrl },\n body: JSON.stringify({ email, password }),\n redirect: 'manual',\n })\n const setCookie = res.headers.get('set-cookie')\n if (setCookie) {\n this.cookies = setCookie.split(';')[0]\n }\n const body = await res.json() as Record<string, unknown>\n if (!body.user) throw new Error(`Login failed: ${JSON.stringify(body)}`)\n }\n\n async createWorkspace(name: string, type = 'project'): Promise<string> {\n const res = await this.post(this.route('workspaces'), { name, type })\n const ws = res.workspace as Record<string, unknown> | undefined\n if (!ws?.id) throw new Error(`Workspace creation failed: ${JSON.stringify(res)}`)\n return ws.id as string\n }\n\n async createThread(workspaceId: string): Promise<string> {\n const res = await this.post(this.route('threads'), { workspaceId })\n const thread = res.thread as Record<string, unknown> | undefined\n if (!thread?.id) throw new Error(`Thread creation failed: ${JSON.stringify(res)}`)\n return thread.id as string\n }\n\n async chat(\n workspaceId: string,\n threadId: string,\n content: string,\n _opts?: { blockPatterns?: RegExp[] },\n ): Promise<{ text: string; blocks: { type: string; title: string }[] }> {\n const res = await fetch(`${this.baseUrl}${this.route('chat')}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Origin': this.baseUrl,\n 'Cookie': this.cookies,\n },\n body: JSON.stringify({ workspaceId, threadId, content }),\n })\n\n if (!res.ok || !res.body) throw new Error(`Chat failed: ${res.status}`)\n\n // Parse NDJSON stream\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n let text = ''\n const blocks: { type: string; title: string }[] = []\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split('\\n')\n buf = lines.pop() ?? ''\n for (const line of lines) {\n if (!line.trim()) continue\n try {\n const event = JSON.parse(line) as { type?: string; data?: { delta?: string } }\n if (event.type === 'message.part.updated' && event.data?.delta) {\n text += event.data.delta\n }\n } catch { /* skip non-JSON lines */ }\n }\n }\n\n // Extract :::blocks from text\n const blockRe = /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n let match\n while ((match = blockRe.exec(text)) !== null) {\n const fields: Record<string, string> = {}\n for (const line of match[2].split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n blocks.push({ type: match[1], title: fields.title ?? '' })\n }\n\n return { text, blocks }\n }\n\n async getTasks(workspaceId: string): Promise<{ id: string; title: string; status: string; priority: string }[]> {\n const res = await this.get(`${this.route('tasks')}?workspaceId=${workspaceId}`)\n return (res.tasks ?? []) as { id: string; title: string; status: string; priority: string }[]\n }\n\n async getEvents(workspaceId: string): Promise<{ id: string; title: string; type: string }[]> {\n const res = await this.get(`${this.route('events')}?workspaceId=${workspaceId}`)\n return (res.events ?? []) as { id: string; title: string; type: string }[]\n }\n\n async getApprovals(workspaceId: string): Promise<{ id: string; title: string; status: string; type: string }[]> {\n const res = await this.get(`${this.route('approvals')}?workspaceId=${workspaceId}`)\n return (res.actions ?? []) as { id: string; title: string; status: string; type: string }[]\n }\n\n async getVaultTree(workspaceId: string): Promise<string[]> {\n const res = await this.get(`${this.route('vault')}?workspaceId=${workspaceId}`)\n const paths: string[] = []\n function extract(nodes: unknown[]) {\n for (const n of nodes) {\n const node = n as { path?: string; type?: string; children?: unknown[] }\n if (node.type === 'file' && node.path) paths.push(node.path)\n if (node.children) extract(node.children)\n }\n }\n extract((res.tree ?? []) as unknown[])\n return paths\n }\n\n async approveAction(workspaceId: string, id: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'approved' })\n }\n\n async rejectAction(workspaceId: string, id: string, reason: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'rejected', reason })\n }\n\n async getGenerations(workspaceId: string): Promise<{ id: string; type: string; prompt: string }[]> {\n const res = await this.get(`${this.route('generations')}?workspaceId=${workspaceId}`)\n return (res.generations ?? []) as { id: string; type: string; prompt: string }[]\n }\n\n /** Generic GET for custom routes */\n async get(path: string): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n headers: { 'Cookie': this.cookies },\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /** Generic POST for custom routes */\n async post(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Origin': this.baseUrl,\n 'Cookie': this.cookies,\n },\n body: JSON.stringify(body),\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /** Generic PATCH for custom routes */\n async patch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n 'Origin': this.baseUrl,\n 'Cookie': this.cookies,\n },\n body: JSON.stringify(body),\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n}\n\n/**\n * Run a full e2e workflow test against a live product.\n *\n * The `workflow` callback receives a ProductClient and returns CheckResults.\n * This is the generic harness — each agent defines its own workflow steps.\n */\nexport async function runE2EWorkflow(\n client: ProductClient,\n name: string,\n workflow: (client: ProductClient) => Promise<CheckResult[]>,\n): Promise<TestResult> {\n const start = Date.now()\n const checks: CheckResult[] = []\n\n try {\n const results = await workflow(client)\n checks.push(...results)\n } catch (err) {\n checks.push({\n name: 'fatal_error',\n passed: false,\n expected: 'no crash',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n return {\n name,\n passed: checks.every(c => c.passed),\n duration: Date.now() - start,\n detail: `${checks.filter(c => c.passed).length}/${checks.length} checks passed`,\n checks,\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\n/**\n * Create a domain expert judge with a configurable domain.\n *\n * The judge evaluates professional accuracy and depth.\n */\nexport function createDomainExpertJudge(domain: string): JudgeFn {\n return async (tc: TCloud, { scenario, turns }: Pick<JudgeInput, 'scenario' | 'turns'>): Promise<JudgeScore[]> => {\n const conversation = turns.map((t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 2000)}`\n ).join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [{\n role: 'system',\n content: `You are a senior ${domain} professional with 20+ years of experience. You are evaluating an AI agent's responses for professional accuracy and depth.\n\nScore STRICTLY. A 5 means \"a junior professional could do this.\" An 8 means \"solid mid-career work.\" A 10 means \"I would hire this agent.\"\n\nEvaluate:\n1. **domain_accuracy** (0-10): Are the technical terms correct? Are the recommendations what you'd actually do? Would this advice cause problems if followed?\n2. **professional_depth** (0-10): Does it go beyond surface-level? Does it consider practical constraints, edge cases, industry standards? Or is it generic textbook advice?\n\nRespond with JSON only: [{\"dimension\":\"domain_accuracy\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"quote from response\"},{\"dimension\":\"professional_depth\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"quote\"}]`\n }, {\n role: 'user',\n content: `Persona: ${scenario.persona} (${scenario.label})\\nScenario: ${scenario.thesis}\\n\\n${conversation}`\n }],\n temperature: 0.1,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('domain_expert', resp)\n }\n}\n\n/**\n * Code execution judge — evaluates whether code blocks are valid and runnable.\n */\nexport const codeExecutionJudge: JudgeFn = async (tc, { scenario, artifacts }) => {\n const codeBlocks = artifacts.codeBlocks\n if (codeBlocks.length === 0) {\n return [{\n judgeName: 'code_execution',\n dimension: 'code_execution',\n score: 0,\n reasoning: 'No code blocks found in agent response.',\n }]\n }\n\n const codeText = codeBlocks.map((b, i) =>\n `Block ${i + 1} (${b.language}):\\n\\`\\`\\`${b.language}\\n${b.code.slice(0, 3000)}\\n\\`\\`\\``\n ).join('\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [{\n role: 'system',\n content: `You are a principal software engineer reviewing code written by an AI agent.\n\nScore STRICTLY:\n1. **executability** (0-10): Would this code run without errors? Check: import errors, undefined variables, missing deps, syntax errors. A 5 means \"would run with minor fixes.\" A 10 means \"copy-paste and it works.\"\n2. **completeness** (0-10): Does it handle the FULL task, or just the happy path? A 5 means \"handles the main case.\" A 10 means \"production-ready.\"\n3. **reusability** (0-10): Could this be saved as a tool and reused? A 5 means \"works for this case.\" A 10 means \"general-purpose tool.\"\n\nRespond with JSON only: [{\"dimension\":\"executability\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"specific line/issue\"},{\"dimension\":\"completeness\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"},{\"dimension\":\"reusability\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"}]`\n }, {\n role: 'user',\n content: `Task: ${scenario.thesis}\\n\\n${codeText}`\n }],\n temperature: 0.1,\n maxTokens: 1000,\n })\n\n return parseJudgeResponse('code_execution', resp)\n}\n\n/**\n * Coherence judge — evaluates multi-turn consistency and progression.\n */\nexport const coherenceJudge: JudgeFn = async (tc, { scenario, turns }) => {\n if (turns.length < 2) {\n return [{\n judgeName: 'coherence',\n dimension: 'coherence',\n score: 5,\n reasoning: 'Single-turn scenario — coherence not fully testable.',\n }]\n }\n\n const conversation = turns.map((t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent (${t.agentResponse.length} chars): ${t.agentResponse.slice(0, 1500)}`\n ).join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [{\n role: 'system',\n content: `You evaluate whether an AI agent maintains coherence across a multi-turn conversation.\n\nScore STRICTLY:\n1. **consistency** (0-10): Does the agent contradict itself across turns? Does it remember what it said/built earlier?\n2. **progression** (0-10): Does each turn BUILD on the previous? Or does it start fresh? A 5 means \"vaguely related.\" A 10 means \"each turn clearly advances the work.\"\n3. **feedback_integration** (0-10): When the user gives feedback, does the agent demonstrate it HEARD the feedback?\n\nRespond with JSON only: [{\"dimension\":\"consistency\",\"score\":N,\"reasoning\":\"...\"},{\"dimension\":\"progression\",\"score\":N,\"reasoning\":\"...\"},{\"dimension\":\"feedback_integration\",\"score\":N,\"reasoning\":\"...\"}]`\n }, {\n role: 'user',\n content: `Scenario: ${scenario.thesis}\\n\\n${conversation}`\n }],\n temperature: 0.1,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('coherence', resp)\n}\n\n/**\n * Adversarial judge — red-teams agent responses.\n */\nexport const adversarialJudge: JudgeFn = async (tc, { scenario, turns }) => {\n const conversation = turns.map((t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 1500)}`\n ).join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [{\n role: 'system',\n content: `You are a red-team evaluator. Find the WEAKEST point in the AI agent's responses. Be adversarial.\n\n1. **hallucination** (0-10, inverted — 10 means NO hallucination): Did the agent make up facts, cite nonexistent tools, invent standards?\n2. **false_confidence** (0-10, inverted — 10 means appropriate uncertainty): Did the agent present uncertain information as fact?\n3. **worst_failure** (0-10, inverted — 10 means no critical failures): What is the single worst thing in the response?\n\nBe harsh. If everything is genuinely good, say so — but look hard first.\n\nRespond with JSON only: [{\"dimension\":\"hallucination\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"specific quote\"},{\"dimension\":\"false_confidence\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"},{\"dimension\":\"worst_failure\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"}]`\n }, {\n role: 'user',\n content: `Persona: ${scenario.persona}\\nScenario: ${scenario.thesis}\\n\\n${conversation}`\n }],\n temperature: 0.2,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('adversarial', resp)\n}\n\n/**\n * Create a custom judge with a fully custom prompt.\n */\nexport function createCustomJudge(\n name: string,\n systemPrompt: string,\n opts?: { model?: string; temperature?: number; maxTokens?: number },\n): JudgeFn {\n return async (tc, { scenario, turns }) => {\n const conversation = turns.map((t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 2000)}`\n ).join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: opts?.model ?? 'gpt-4o',\n messages: [{\n role: 'system',\n content: systemPrompt,\n }, {\n role: 'user',\n content: `Persona: ${scenario.persona} (${scenario.label})\\nScenario: ${scenario.thesis}\\n\\n${conversation}`\n }],\n temperature: opts?.temperature ?? 0.1,\n maxTokens: opts?.maxTokens ?? 1000,\n })\n\n return parseJudgeResponse(name, resp)\n }\n}\n\n/** Default judge set (domain must be provided for domain expert) */\nexport function defaultJudges(domain: string): JudgeFn[] {\n return [\n createDomainExpertJudge(domain),\n codeExecutionJudge,\n coherenceJudge,\n adversarialJudge,\n ]\n}\n\n// ── Helpers ──\n\nfunction parseJudgeResponse(judgeName: string, resp: unknown): JudgeScore[] {\n try {\n const content = (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ?? ''\n let cleaned = content.replace(/```json\\n?|\\n?```/g, '').trim()\n const arrayMatch = cleaned.match(/\\[[\\s\\S]*\\]/)\n if (arrayMatch) cleaned = arrayMatch[0]\n const parsed = JSON.parse(cleaned) as { dimension: string; score: number; reasoning: string; evidence?: string }[]\n return parsed.map((p) => ({\n judgeName,\n dimension: p.dimension,\n score: Math.max(0, Math.min(10, p.score)),\n reasoning: p.reasoning ?? '',\n evidence: p.evidence,\n }))\n } catch (err) {\n const content = (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ?? ''\n console.log(` [parse_error] ${judgeName}: ${(err as Error).message?.slice(0, 50)} | response: ${content.slice(0, 100)}`)\n return [{\n judgeName,\n dimension: 'parse_error',\n score: 0,\n reasoning: `Parse failed: ${(err as Error).message?.slice(0, 100)}. Raw: ${content.slice(0, 200)}`,\n }]\n }\n}\n","import type { JudgeScore } from './types'\n\n/** Dimensions where lower raw score = better outcome (inverted semantics) */\nconst INVERTED_DIMENSIONS = new Set([\n 'hallucination',\n 'false_confidence',\n 'worst_failure',\n])\n\n/**\n * Normalize scores so all dimensions follow \"higher = better\".\n * Inverted dimensions (hallucination, false_confidence, worst_failure)\n * already use inverted scoring in the prompt (10 = no hallucination),\n * but this function ensures consistency if raw scores leak through.\n */\nexport function normalizeScores(scores: JudgeScore[]): JudgeScore[] {\n return scores.map((s) => {\n if (INVERTED_DIMENSIONS.has(s.dimension)) {\n return s\n }\n return s\n })\n}\n\n/** Weighted mean — falls back to uniform weights when omitted */\nexport function weightedMean(scores: { score: number; weight?: number }[]): number {\n if (scores.length === 0) return 0\n let totalWeight = 0\n let weightedSum = 0\n for (const { score, weight } of scores) {\n const w = weight ?? 1\n weightedSum += score * w\n totalWeight += w\n }\n return totalWeight > 0 ? weightedSum / totalWeight : 0\n}\n\n/** Bootstrap confidence interval */\nexport function confidenceInterval(\n scores: number[],\n confidence = 0.95,\n): { mean: number; lower: number; upper: number } {\n if (scores.length === 0) return { mean: 0, lower: 0, upper: 0 }\n if (scores.length === 1) return { mean: scores[0], lower: scores[0], upper: scores[0] }\n\n const n = scores.length\n const mean = scores.reduce((a, b) => a + b, 0) / n\n\n const B = 1000\n const bootstrapMeans: number[] = []\n\n for (let i = 0; i < B; i++) {\n let sum = 0\n for (let j = 0; j < n; j++) {\n sum += scores[Math.floor(Math.random() * n)]\n }\n bootstrapMeans.push(sum / n)\n }\n\n bootstrapMeans.sort((a, b) => a - b)\n\n const alpha = 1 - confidence\n const lowerIdx = Math.floor((alpha / 2) * B)\n const upperIdx = Math.floor((1 - alpha / 2) * B) - 1\n\n return {\n mean,\n lower: bootstrapMeans[lowerIdx],\n upper: bootstrapMeans[Math.min(upperIdx, B - 1)],\n }\n}\n\n/**\n * Inter-rater reliability — simplified Krippendorff's alpha.\n *\n * Each inner array is one judge's scores for all items.\n * All arrays must have the same length (same items scored).\n */\nexport function interRaterReliability(judgeScores: JudgeScore[][]): number {\n if (judgeScores.length < 2) return 1\n\n // Group scores by dimension across judges\n const dimensionMap = new Map<string, number[][]>()\n for (const judgeSet of judgeScores) {\n for (const s of judgeSet) {\n if (!dimensionMap.has(s.dimension)) dimensionMap.set(s.dimension, [])\n const arr = dimensionMap.get(s.dimension)!\n if (arr.length === 0 || arr[arr.length - 1].length >= judgeScores.length) {\n arr.push([s.score])\n } else {\n arr[arr.length - 1].push(s.score)\n }\n }\n }\n\n // Collect all paired ratings\n const allValues: number[] = []\n const pairDiffs: number[] = []\n\n for (const items of dimensionMap.values()) {\n for (const ratings of items) {\n if (ratings.length < 2) continue\n for (const v of ratings) allValues.push(v)\n for (let i = 0; i < ratings.length; i++) {\n for (let j = i + 1; j < ratings.length; j++) {\n pairDiffs.push((ratings[i] - ratings[j]) ** 2)\n }\n }\n }\n }\n\n if (pairDiffs.length === 0 || allValues.length < 2) return 1\n\n const observedDisagreement = pairDiffs.reduce((a, b) => a + b, 0) / pairDiffs.length\n\n // Expected disagreement from all possible pairings of values\n let expectedDisagreement = 0\n let expectedCount = 0\n for (let i = 0; i < allValues.length; i++) {\n for (let j = i + 1; j < allValues.length; j++) {\n expectedDisagreement += (allValues[i] - allValues[j]) ** 2\n expectedCount++\n }\n }\n expectedDisagreement = expectedCount > 0 ? expectedDisagreement / expectedCount : 0\n\n if (expectedDisagreement === 0) return 1\n return 1 - observedDisagreement / expectedDisagreement\n}\n\n/**\n * Mann-Whitney U test for comparing two independent groups.\n * Returns U statistic and approximate p-value (normal approximation).\n */\nexport function mannWhitneyU(a: number[], b: number[]): { u: number; p: number } {\n if (a.length === 0 || b.length === 0) return { u: 0, p: 1 }\n\n const n1 = a.length\n const n2 = b.length\n\n // Rank all values together\n const combined = [\n ...a.map((v) => ({ v, group: 'a' as const })),\n ...b.map((v) => ({ v, group: 'b' as const })),\n ].sort((x, y) => x.v - y.v)\n\n // Assign ranks with tie handling\n const ranks: number[] = new Array(combined.length)\n let i = 0\n while (i < combined.length) {\n let j = i\n while (j < combined.length && combined[j].v === combined[i].v) j++\n const avgRank = (i + 1 + j) / 2\n for (let k = i; k < j; k++) ranks[k] = avgRank\n i = j\n }\n\n // Sum ranks for group a\n let r1 = 0\n for (let k = 0; k < combined.length; k++) {\n if (combined[k].group === 'a') r1 += ranks[k]\n }\n\n const u1 = r1 - (n1 * (n1 + 1)) / 2\n const u2 = n1 * n2 - u1\n const u = Math.min(u1, u2)\n\n // Normal approximation for p-value\n const mu = (n1 * n2) / 2\n const sigma = Math.sqrt((n1 * n2 * (n1 + n2 + 1)) / 12)\n\n if (sigma === 0) return { u, p: 1 }\n\n const z = Math.abs(u - mu) / sigma\n // Two-tailed p-value from z-score (approximation)\n const p = 2 * (1 - normalCdf(z))\n\n return { u, p }\n}\n\n/** Partial credit: returns 0-1 ratio of current toward target */\nexport function partialCredit(current: number, target: number): number {\n if (target <= 0) return 1\n return Math.min(1, Math.max(0, current / target))\n}\n\n// Standard normal CDF approximation (Abramowitz and Stegun)\nfunction normalCdf(x: number): number {\n const a1 = 0.254829592\n const a2 = -0.284496736\n const a3 = 1.421413741\n const a4 = -1.453152027\n const a5 = 1.061405429\n const p = 0.3275911\n\n const sign = x < 0 ? -1 : 1\n const absX = Math.abs(x)\n const t = 1 / (1 + p * absX)\n const y = 1 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-absX * absX / 2)\n\n return 0.5 * (1 + sign * y)\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type {\n Scenario, TurnResult, CollectedArtifacts,\n ScenarioResult, JudgeScore, JudgeFn,\n} from './types'\nimport { normalizeScores, weightedMean } from './statistics'\n\ninterface ChatMessage {\n role: 'system' | 'user' | 'assistant'\n content: string\n}\n\nexport interface ExecutorConfig {\n /** System prompt for the agent under test */\n systemPrompt: string\n /** Model to use for the agent */\n model?: string\n /** Judges to run after execution */\n judges: JudgeFn[]\n /** Regex patterns for detecting tool/API calls in responses */\n toolCallPatterns?: RegExp[]\n /** Block delimiter pattern (default: :::type\\n...\\n:::) */\n blockPattern?: RegExp\n /** Custom artifact checker for domain-specific checks */\n artifactChecker?: (check: Scenario['artifactChecks'][0], artifacts: CollectedArtifacts) => { passed: boolean; detail: string } | null\n}\n\n/**\n * Execute a scenario against an LLM via tcloud.\n *\n * Runs multi-turn conversation, extracts artifacts, runs judges.\n */\nexport async function executeScenario(\n tc: TCloud,\n scenario: Scenario,\n config: ExecutorConfig,\n): Promise<ScenarioResult> {\n const startTime = Date.now()\n const model = config.model ?? 'gpt-4o'\n\n const systemPrompt = [\n config.systemPrompt,\n scenario.systemPromptAppend ?? '',\n ].filter(Boolean).join('\\n\\n')\n\n const messages: ChatMessage[] = [\n { role: 'system', content: systemPrompt },\n ]\n\n const turns: TurnResult[] = []\n const allCodeBlocks: { language: string; code: string }[] = []\n const allBlocks: { type: string; fields: Record<string, string> }[] = []\n const allToolCalls: string[] = []\n\n const blockRe = config.blockPattern ?? /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n\n for (let i = 0; i < scenario.turns.length; i++) {\n const turn = scenario.turns[i]\n const turnStart = Date.now()\n\n messages.push({ role: 'user', content: turn.user })\n\n const resp = await tc.chat({\n model,\n messages,\n temperature: 0.4,\n maxTokens: 3000,\n })\n\n const content = (resp as { choices?: { message?: { content?: string } }[] })\n .choices?.[0]?.message?.content ?? ''\n\n messages.push({ role: 'assistant', content })\n\n // Extract code blocks\n const codeRe = /```(\\w+)?\\n([\\s\\S]*?)```/g\n let codeMatch\n while ((codeMatch = codeRe.exec(content)) !== null) {\n allCodeBlocks.push({ language: codeMatch[1] ?? 'text', code: codeMatch[2] })\n }\n\n // Extract structured blocks\n const turnBlocks: { type: string; title: string }[] = []\n let blockMatch\n const blockReLocal = new RegExp(blockRe.source, blockRe.flags)\n while ((blockMatch = blockReLocal.exec(content)) !== null) {\n const fields: Record<string, string> = {}\n for (const line of blockMatch[2].split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n allBlocks.push({ type: blockMatch[1], fields })\n turnBlocks.push({ type: blockMatch[1], title: fields.title ?? '' })\n }\n\n // Detect tool calls via configurable patterns\n let hasToolCall = false\n if (config.toolCallPatterns) {\n for (const pattern of config.toolCallPatterns) {\n const re = new RegExp(pattern.source, pattern.flags)\n let toolMatch\n while ((toolMatch = re.exec(content)) !== null) {\n allToolCalls.push(toolMatch[0])\n hasToolCall = true\n }\n }\n }\n\n turns.push({\n turnIndex: i,\n userMessage: turn.user,\n agentResponse: content,\n durationMs: Date.now() - turnStart,\n blocksExtracted: turnBlocks,\n containsCode: allCodeBlocks.length > 0,\n containsToolCall: hasToolCall,\n })\n }\n\n const artifacts: CollectedArtifacts = {\n vaultFiles: [],\n blocksExtracted: allBlocks,\n codeBlocks: allCodeBlocks,\n toolCalls: allToolCalls,\n }\n\n // Run artifact checks\n const artifactResults = scenario.artifactChecks.map((check) => {\n // Try custom checker first\n if (config.artifactChecker) {\n const custom = config.artifactChecker(check, artifacts)\n if (custom) return { check, ...custom }\n }\n\n switch (check.type) {\n case 'block_extracted': {\n const count = allBlocks.filter(b => b.type === check.target).length\n return {\n check,\n passed: count >= (check.minCount ?? 1),\n detail: `Found ${count} ${check.target} blocks (need ${check.minCount ?? 1})`,\n }\n }\n case 'code_valid': {\n const hasCode = allCodeBlocks.some(b =>\n b.language === check.target || b.code.includes(check.target)\n )\n return { check, passed: hasCode, detail: hasCode ? 'Code block found' : 'No matching code' }\n }\n default:\n return { check, passed: false, detail: `Check type \"${check.type}\" requires live environment` }\n }\n })\n\n // Run judges sequentially with retry\n const judgeInput = { scenario, turns, artifacts }\n const judgeResults: JudgeScore[][] = []\n\n for (const judge of config.judges) {\n let lastErr = ''\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n if (attempt > 0) {\n const wait = attempt * 10_000\n console.log(` judge retry ${attempt}/2 (waiting ${wait / 1000}s)`)\n await new Promise(r => setTimeout(r, wait))\n }\n const scores = await judge(tc, judgeInput)\n judgeResults.push(scores)\n await new Promise(r => setTimeout(r, 3000))\n break\n } catch (err) {\n lastErr = err instanceof Error ? err.message : String(err)\n if (attempt === 2) {\n judgeResults.push([{\n judgeName: 'unknown',\n dimension: 'error',\n score: 0,\n reasoning: `Judge failed after 3 attempts: ${lastErr.slice(0, 200)}`,\n }])\n }\n }\n }\n }\n\n const allScores = judgeResults.flat()\n const errorScores = allScores.filter(s => s.dimension === 'parse_error' || s.dimension === 'error')\n const validScores = allScores.filter(s => s.dimension !== 'parse_error' && s.dimension !== 'error')\n const normalized = normalizeScores(validScores)\n\n // Build weight map from scenario rubric dimensions\n const weightMap = new Map<string, number>()\n for (const dim of scenario.dimensions) {\n weightMap.set(dim, 1)\n }\n\n const overallScore = weightedMean(\n normalized.map((s) => ({\n score: s.score,\n weight: weightMap.get(s.dimension) ?? 1,\n })),\n )\n\n return {\n scenarioId: scenario.id,\n persona: scenario.persona,\n turns,\n artifactResults,\n judgeScores: allScores,\n judgeErrors: errorScores.length,\n overallScore,\n totalDurationMs: Date.now() - startTime,\n artifacts,\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { Scenario, ScenarioResult, BenchmarkReport, BenchmarkRunnerConfig } from './types'\nimport { executeScenario } from './executor'\n\n/**\n * BenchmarkRunner — orchestrates scenarios, executor, judges, and scoring.\n *\n * Domain-agnostic. Each agent provides its own scenarios, judges, and system prompt.\n */\nexport class BenchmarkRunner {\n private tc: TCloud\n private config: BenchmarkRunnerConfig\n\n constructor(tc: TCloud, config: BenchmarkRunnerConfig) {\n this.tc = tc\n this.config = config\n }\n\n async run(scenarios?: Scenario[]): Promise<BenchmarkReport> {\n const toRun = scenarios ?? this.config.scenarios\n const passThreshold = this.config.passThreshold ?? 6.0\n\n console.log('='.repeat(70))\n console.log(' AGENT EVAL — BENCHMARK')\n console.log(' Multi-turn scenarios x Multi-judge panel')\n console.log('='.repeat(70))\n console.log(`Scenarios: ${toRun.length}`)\n console.log(`Judges: ${this.config.judges.length}`)\n console.log(`Model: ${this.config.model ?? 'gpt-4o'}`)\n console.log()\n\n const results: ScenarioResult[] = []\n\n for (let i = 0; i < toRun.length; i++) {\n const scenario = toRun[i]\n console.log(`[${i + 1}/${toRun.length}] ${scenario.id} (${scenario.persona})`)\n console.log(` thesis: ${scenario.thesis}`)\n console.log(` turns: ${scenario.turns.length}`)\n\n const result = await executeScenario(this.tc, scenario, {\n systemPrompt: this.config.systemPrompt,\n model: this.config.model,\n judges: this.config.judges,\n })\n results.push(result)\n\n // Print turn summaries\n for (const turn of result.turns) {\n const codeIcon = turn.containsCode ? '[code]' : ''\n const toolIcon = turn.containsToolCall ? '[tool]' : ''\n const blockCount = turn.blocksExtracted.length\n const blockIcon = blockCount > 0 ? `[blocks:${blockCount}]` : ''\n console.log(` turn ${turn.turnIndex + 1}: ${(turn.durationMs / 1000).toFixed(1)}s ${codeIcon} ${toolIcon} ${blockIcon} (${turn.agentResponse.length} chars)`)\n }\n\n // Print artifact results\n for (const ar of result.artifactResults) {\n const icon = ar.passed ? '+' : 'X'\n console.log(` artifact: [${icon}] ${ar.check.description} — ${ar.detail}`)\n }\n\n // Print judge scores\n console.log(` judges:`)\n const byJudge: Record<string, { scores: number[]; dimensions: string[] }> = {}\n for (const js of result.judgeScores) {\n if (!byJudge[js.judgeName]) byJudge[js.judgeName] = { scores: [], dimensions: [] }\n byJudge[js.judgeName].scores.push(js.score)\n byJudge[js.judgeName].dimensions.push(`${js.dimension}=${js.score}`)\n }\n for (const [name, data] of Object.entries(byJudge)) {\n const avg = (data.scores.reduce((a, b) => a + b, 0) / data.scores.length).toFixed(1)\n console.log(` ${name.padEnd(16)} avg=${avg} [${data.dimensions.join(', ')}]`)\n }\n\n console.log(` OVERALL: ${result.overallScore.toFixed(1)}/10 (${(result.totalDurationMs / 1000).toFixed(0)}s)`)\n console.log()\n }\n\n // Build summary\n const byPersona: Record<string, { avg: number; passed: number; total: number }> = {}\n const byDimension: Record<string, { avg: number; scores: number[] }> = {}\n\n for (const r of results) {\n if (!byPersona[r.persona]) byPersona[r.persona] = { avg: 0, passed: 0, total: 0 }\n byPersona[r.persona].total++\n byPersona[r.persona].avg += r.overallScore\n if (r.overallScore >= passThreshold) byPersona[r.persona].passed++\n\n for (const js of r.judgeScores) {\n if (!byDimension[js.dimension]) byDimension[js.dimension] = { avg: 0, scores: [] }\n byDimension[js.dimension].scores.push(js.score)\n }\n }\n\n for (const p of Object.values(byPersona)) {\n p.avg = p.total > 0 ? p.avg / p.total : 0\n }\n for (const d of Object.values(byDimension)) {\n d.avg = d.scores.length > 0 ? d.scores.reduce((a, b) => a + b, 0) / d.scores.length : 0\n }\n\n const sorted = [...results].sort((a, b) => a.overallScore - b.overallScore)\n const weakest = sorted.slice(0, 3).map(r => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason: r.judgeScores.filter(s => s.score < passThreshold).map(s => `${s.dimension}=${s.score}`).join(', ') || 'close to threshold',\n }))\n const strongest = sorted.slice(-3).reverse().map(r => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason: r.judgeScores.filter(s => s.score >= 9).map(s => `${s.dimension}=${s.score}`).join(', ') || 'consistently strong',\n }))\n\n // Print final summary\n console.log('='.repeat(70))\n console.log(' RESULTS')\n console.log('='.repeat(70))\n\n const overallAvg = results.length > 0\n ? results.reduce((s, r) => s + r.overallScore, 0) / results.length\n : 0\n\n console.log(`Overall: ${overallAvg.toFixed(1)}/10`)\n console.log()\n\n console.log('By persona:')\n for (const [name, data] of Object.entries(byPersona)) {\n console.log(` ${name.padEnd(20)} ${data.avg.toFixed(1)}/10 (${data.passed}/${data.total} passed)`)\n }\n console.log()\n\n console.log('By dimension:')\n const dimEntries = Object.entries(byDimension).sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n console.log(` ${name.padEnd(24)} avg=${data.avg.toFixed(1)} range=[${min}-${max}] n=${data.scores.length}`)\n }\n console.log()\n\n if (weakest.length > 0) {\n console.log('Weakest:')\n for (const w of weakest) {\n console.log(` ${w.scenario}: ${w.score.toFixed(1)} — ${w.reason}`)\n }\n console.log()\n }\n\n return {\n timestamp: new Date().toISOString(),\n generation: this.config.generation ?? 1,\n promptVersion: this.config.promptVersion ?? 'v1',\n scenarioCount: toRun.length,\n results,\n summary: { overallAvg, byPersona, byDimension, weakest, strongest },\n }\n }\n}\n","import type { TurnMetrics, DriverState } from './types'\nimport type { ProductClient } from './client'\n\n/** Per-1K token pricing for common models */\nexport const MODEL_PRICING: Record<string, { input: number; output: number }> = {\n 'gpt-4o': { input: 0.0025, output: 0.01 },\n 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },\n 'gpt-4-turbo': { input: 0.01, output: 0.03 },\n 'claude-sonnet-4-20250514': { input: 0.003, output: 0.015 },\n 'claude-opus-4-20250514': { input: 0.015, output: 0.075 },\n 'claude-3-haiku-20240307': { input: 0.00025, output: 0.00125 },\n}\n\n/** Estimate token count from string length (chars / 4 approximation) */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\n/** Calculate cost in USD from token counts and model */\nexport function estimateCost(\n inputTokens: number,\n outputTokens: number,\n model: string,\n): number {\n const pricing = MODEL_PRICING[model]\n if (!pricing) return 0\n return (inputTokens / 1000) * pricing.input + (outputTokens / 1000) * pricing.output\n}\n\n/**\n * TokenCounter — accumulates token usage and cost across turns.\n */\nexport class TokenCounter {\n private totalInput = 0\n private totalOutput = 0\n private totalCost = 0\n private model: string\n\n constructor(model = 'gpt-4o') {\n this.model = model\n }\n\n /** Record tokens for a turn, returns per-turn cost */\n record(inputTokens: number, outputTokens: number): number {\n this.totalInput += inputTokens\n this.totalOutput += outputTokens\n const cost = estimateCost(inputTokens, outputTokens, this.model)\n this.totalCost += cost\n return cost\n }\n\n /** Estimate and record from raw text */\n recordFromText(inputText: string, outputText: string): { inputTokens: number; outputTokens: number; cost: number } {\n const inputTokens = estimateTokens(inputText)\n const outputTokens = estimateTokens(outputText)\n const cost = this.record(inputTokens, outputTokens)\n return { inputTokens, outputTokens, cost }\n }\n\n getTotalInput(): number { return this.totalInput }\n getTotalOutput(): number { return this.totalOutput }\n getTotalCost(): number { return this.totalCost }\n}\n\n/**\n * MetricsCollector — collects per-turn metrics from the product.\n *\n * After each turn, queries the product's APIs to measure state changes.\n */\nexport class MetricsCollector {\n private client: ProductClient\n private workspaceId: string\n private metrics: TurnMetrics[] = []\n constructor(client: ProductClient, workspaceId: string) {\n this.client = client\n this.workspaceId = workspaceId\n }\n\n /** Collect metrics after a turn completes */\n async collect(\n turn: number,\n responseLatencyMs: number,\n responseChars: number,\n codeBlocksProduced: number,\n blocksExtracted: number,\n completionCriteriaMet: number,\n completionCriteriaTotal: number,\n qualityScore?: number,\n inputTokens = 0,\n outputTokens = 0,\n estimatedCostUsd = 0,\n ): Promise<TurnMetrics> {\n const state = await this.getState()\n\n const m: TurnMetrics = {\n turn,\n timestamp: new Date().toISOString(),\n tasks: state.tasks,\n events: state.events,\n proposals: state.proposals,\n vaultFiles: state.vaultFiles.length,\n responseLatencyMs,\n responseChars,\n codeBlocksProduced,\n blocksExtracted,\n qualityScore,\n inputTokens,\n outputTokens,\n estimatedCostUsd,\n totalCostUsd: estimatedCostUsd,\n completionPercent: completionCriteriaTotal > 0\n ? (completionCriteriaMet / completionCriteriaTotal) * 100\n : 0,\n }\n\n this.metrics.push(m)\n return m\n }\n\n /** Get current product state */\n async getState(): Promise<DriverState> {\n const [tasks, events, approvals, vaultFiles] = await Promise.all([\n this.client.getTasks(this.workspaceId),\n this.client.getEvents(this.workspaceId),\n this.client.getApprovals(this.workspaceId),\n this.client.getVaultTree(this.workspaceId),\n ])\n\n return {\n tasks: tasks.length,\n events: events.length,\n proposals: {\n pending: approvals.filter(a => a.status === 'pending').length,\n approved: approvals.filter(a => a.status === 'approved').length,\n rejected: approvals.filter(a => a.status === 'rejected').length,\n },\n vaultFiles,\n codeBlocks: 0,\n generations: 0,\n }\n }\n\n /** Get all collected metrics */\n getMetrics(): TurnMetrics[] {\n return [...this.metrics]\n }\n\n /** Get convergence curve (completion% over turns) */\n getConvergenceCurve(): number[] {\n return this.metrics.map(m => m.completionPercent)\n }\n}\n","import type { CompletionCriterion, DriverState } from './types'\n\n/**\n * ConvergenceTracker — tracks completion percentage over turns.\n *\n * Produces convergence curves showing how quickly the agent reaches\n * completion criteria.\n */\nexport class ConvergenceTracker {\n private criteria: CompletionCriterion[]\n private history: { turn: number; completionPercent: number; criteriaStatus: Record<string, boolean | number> }[] = []\n\n constructor(criteria: CompletionCriterion[]) {\n this.criteria = criteria\n }\n\n /** Evaluate criteria against current state, record result */\n record(turn: number, state: DriverState): { completionPercent: number; complete: boolean; criteriaStatus: Record<string, boolean | number> } {\n const criteriaStatus: Record<string, boolean | number> = {}\n let totalCredit = 0\n\n for (const criterion of this.criteria) {\n if (criterion.progress) {\n const credit = Math.min(1, Math.max(0, criterion.progress(state)))\n criteriaStatus[criterion.name] = credit\n totalCredit += credit\n } else {\n const passed = criterion.check(state)\n criteriaStatus[criterion.name] = passed\n totalCredit += passed ? 1 : 0\n }\n }\n\n const completionPercent = this.criteria.length > 0\n ? (totalCredit / this.criteria.length) * 100\n : 100\n\n this.history.push({ turn, completionPercent, criteriaStatus })\n\n return {\n completionPercent,\n complete: totalCredit >= this.criteria.length,\n criteriaStatus,\n }\n }\n\n /** Get convergence curve */\n getCurve(): number[] {\n return this.history.map(h => h.completionPercent)\n }\n\n /** Get full history with per-criterion status */\n getHistory() {\n return [...this.history]\n }\n\n /** Find the turn where completion first reached 100% (or null) */\n getTurnToCompletion(): number | null {\n const entry = this.history.find(h => h.completionPercent === 100)\n return entry?.turn ?? null\n }\n}\n","import type { Scenario, ScenarioFile } from './types'\n\n/**\n * ScenarioRegistry — manages scenario discovery and filtering.\n *\n * Each agent registers its scenarios. The registry handles conversion\n * from ScenarioFile format to the framework's Scenario type.\n */\nexport class ScenarioRegistry {\n private scenarios: Scenario[] = []\n private scenarioFiles: ScenarioFile[] = []\n\n /** Register scenarios from ScenarioFile format */\n registerFiles(files: ScenarioFile[]): void {\n this.scenarioFiles.push(...files)\n this.scenarios.push(...files.map(toScenario))\n }\n\n /** Register pre-built Scenario objects directly */\n register(scenarios: Scenario[]): void {\n this.scenarios.push(...scenarios)\n }\n\n /** Get all scenarios */\n all(): Scenario[] {\n return [...this.scenarios]\n }\n\n /** Get scenarios filtered by category */\n byCategory(category: string): Scenario[] {\n const fromFiles = this.scenarioFiles\n .filter(sf => sf.category === category)\n .map(toScenario)\n return fromFiles\n }\n\n /** List all categories with counts */\n listCategories(): { category: string; count: number }[] {\n const counts: Record<string, number> = {}\n for (const sf of this.scenarioFiles) {\n counts[sf.category] = (counts[sf.category] ?? 0) + 1\n }\n return Object.entries(counts).map(([category, count]) => ({ category, count }))\n }\n\n /** Get scenarios filtered by persona */\n byPersona(persona: string): Scenario[] {\n return this.scenarios.filter(s => s.persona === persona)\n }\n\n /** Get a single scenario by ID */\n byId(id: string): Scenario | undefined {\n return this.scenarios.find(s => s.id === id)\n }\n\n /** Count total scenarios */\n get count(): number {\n return this.scenarios.length\n }\n}\n\n/** Convert ScenarioFile to the framework's Scenario type */\nfunction toScenario(sf: ScenarioFile): Scenario {\n return {\n id: sf.id,\n persona: sf.persona,\n label: sf.label,\n thesis: sf.thesis,\n dimensions: [],\n turns: sf.turns,\n artifactChecks: sf.artifactChecks,\n systemPromptAppend: sf.isControl ? 'You are a helpful AI assistant.' : undefined,\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { PersonaConfig, DriverResult, DriverState, TurnMetrics } from './types'\nimport { ProductClient } from './client'\nimport { MetricsCollector } from './metrics'\nimport { ConvergenceTracker } from './convergence'\n\nexport interface AgentDriverConfig {\n client: ProductClient\n driverModel?: string\n /** System prompt context for the driver LLM to understand the product */\n productContext?: string\n}\n\n/**\n * AgentDriver — meta-agent that plays a persona against the real product.\n *\n * Uses a driver LLM (Claude/GPT-4o) to decide what to say each turn.\n * Not scripted — the driver gets the current product state and decides\n * the next realistic user message.\n */\nexport class AgentDriver {\n private tc: TCloud\n private client: ProductClient\n private driverModel: string\n private productContext: string\n\n constructor(tc: TCloud, config: AgentDriverConfig) {\n this.tc = tc\n this.client = config.client\n this.driverModel = config.driverModel ?? 'claude-sonnet-4-6'\n this.productContext = config.productContext ?? ''\n }\n\n /**\n * Run a persona through the product.\n *\n * Returns metrics on how many turns to completion, cost curve,\n * quality curve, and convergence curve.\n */\n async run(persona: PersonaConfig): Promise<DriverResult> {\n // Setup: create workspace + thread\n const email = `eval-driver-${Date.now()}@test.agent-eval.local`\n await this.client.signup(`Driver ${persona.role}`, email, 'eval-driver-pass')\n await this.client.login(email, 'eval-driver-pass')\n const workspaceId = await this.client.createWorkspace(`${persona.role} Eval`)\n const threadId = await this.client.createThread(workspaceId)\n\n const metrics = new MetricsCollector(this.client, workspaceId)\n const convergence = new ConvergenceTracker(persona.completionCriteria)\n const turnMetrics: TurnMetrics[] = []\n const conversationHistory: { role: string; content: string }[] = []\n\n let completed = false\n let turnsToCompletion: number | null = null\n\n for (let turn = 1; turn <= persona.maxTurns; turn++) {\n // Get current product state\n const state = await metrics.getState()\n\n // Ask driver LLM what to say\n const userMessage = await this.decideNextMessage(persona, state, conversationHistory)\n\n if (userMessage === 'DONE') {\n completed = true\n turnsToCompletion = turn - 1\n break\n }\n\n // Send to product\n const turnStart = Date.now()\n const response = await this.client.chat(workspaceId, threadId, userMessage)\n const latency = Date.now() - turnStart\n\n conversationHistory.push(\n { role: 'user', content: userMessage },\n { role: 'assistant', content: response.text },\n )\n\n // Wait for post-processor\n await new Promise(r => setTimeout(r, 2000))\n\n // Handle pending approvals\n await this.handleApprovals(persona, workspaceId, state)\n\n // Check convergence\n const postState = await metrics.getState()\n const conv = convergence.record(turn, postState)\n\n // Collect metrics\n const codeBlockCount = (response.text.match(/```\\w+\\n/g) || []).length\n const m = await metrics.collect(\n turn,\n latency,\n response.text.length,\n codeBlockCount,\n response.blocks.length,\n Object.values(conv.criteriaStatus).filter(Boolean).length,\n persona.completionCriteria.length,\n )\n turnMetrics.push(m)\n\n // Print turn status\n const criteriaStr = Object.entries(conv.criteriaStatus)\n .map(([k, v]) => `${k}:${v ? '+' : '-'}`)\n .join(' ')\n console.log(` [turn ${turn}] ${conv.completionPercent.toFixed(0)}% — ${criteriaStr} (${(latency / 1000).toFixed(1)}s)`)\n\n if (conv.complete) {\n completed = true\n turnsToCompletion = turn\n console.log(` COMPLETE at turn ${turn}`)\n break\n }\n }\n\n const finalState = await metrics.getState()\n\n return {\n personaId: persona.id,\n completed,\n turnsToCompletion,\n totalTurns: turnMetrics.length,\n metrics: turnMetrics,\n finalState,\n convergenceCurve: convergence.getCurve(),\n totalCostUsd: 0,\n finalQualityScore: null,\n }\n }\n\n /** Use the driver LLM to decide what the \"user\" says next */\n private async decideNextMessage(\n persona: PersonaConfig,\n state: DriverState,\n history: { role: string; content: string }[],\n ): Promise<string> {\n const lastResponse = history.length > 0\n ? history[history.length - 1].content.slice(0, 2000)\n : '(no conversation yet — this is the first message)'\n\n const recentHistory = history.slice(-6).map(h =>\n `${h.role}: ${h.content.slice(0, 500)}`\n ).join('\\n\\n')\n\n const resp = await this.tc.chat({\n model: this.driverModel,\n messages: [{\n role: 'system',\n content: `You are playing the role of a ${persona.role} testing an AI agent.\nYour goal: ${persona.goal}\n\n${this.productContext ? `Product context:\\n${this.productContext}\\n` : ''}\nCurrent state:\n- Tasks: ${state.tasks}\n- Events: ${state.events}\n- Proposals: pending=${state.proposals.pending}, approved=${state.proposals.approved}, rejected=${state.proposals.rejected}\n- Vault files: ${state.vaultFiles.length} (${state.vaultFiles.slice(0, 10).join(', ')}${state.vaultFiles.length > 10 ? '...' : ''})\n\nCompletion criteria met: ${this.describeCompletion(persona, state)}\n\nDecide what to do next:\n1. If completion is 100% — respond with exactly \"DONE\"\n2. If a proposal is pending — approve or reject it (with reason)\n3. If the agent is on track — push for the next deliverable\n4. If the agent is off track — give specific corrective feedback\n5. If this is the first message — start with a clear, actionable request\n\nOutput ONLY your next message to the agent. Be specific. Be realistic.\nDon't be patient — a real ${persona.role} wouldn't accept vague answers.`\n }, {\n role: 'user',\n content: recentHistory\n ? `Recent conversation:\\n${recentHistory}\\n\\nThe agent just said:\\n${lastResponse}`\n : 'No conversation yet. Send your opening message.',\n }],\n temperature: 0.5,\n maxTokens: 500,\n })\n\n const content = (resp as { choices?: { message?: { content?: string } }[] })\n .choices?.[0]?.message?.content ?? ''\n\n return content.trim()\n }\n\n /** Handle pending approvals based on persona feedback patterns */\n private async handleApprovals(\n persona: PersonaConfig,\n workspaceId: string,\n _state: DriverState,\n ): Promise<void> {\n const approvals = await this.client.getApprovals(workspaceId)\n const pending = approvals.filter(a => a.status === 'pending')\n\n for (const action of pending) {\n // Check if any feedback pattern triggers a rejection\n const rejection = persona.feedbackPatterns?.find(fp => {\n const title = action.title.toLowerCase()\n return title.includes(fp.trigger.toLowerCase())\n })\n\n if (rejection) {\n await this.client.rejectAction(workspaceId, action.id, rejection.response)\n console.log(` rejected: ${action.title} — ${rejection.response.slice(0, 60)}`)\n } else {\n await this.client.approveAction(workspaceId, action.id)\n console.log(` approved: ${action.title}`)\n }\n }\n }\n\n /** Describe which completion criteria are met */\n private describeCompletion(persona: PersonaConfig, state: DriverState): string {\n const results = persona.completionCriteria.map(c => {\n const met = c.check(state)\n return `${c.name}: ${met ? 'MET' : 'NOT MET'}`\n })\n const metCount = results.filter(r => r.includes('MET') && !r.includes('NOT')).length\n return `${metCount}/${persona.completionCriteria.length} — ${results.join(', ')}`\n }\n}\n","import type { BenchmarkReport, DriverResult } from './types'\n\n/**\n * Report generation utilities.\n *\n * Outputs convergence curves, cost curves, quality curves,\n * and per-persona summaries in markdown format.\n */\n\n/** Generate a markdown report from benchmark results */\nexport function formatBenchmarkReport(report: BenchmarkReport): string {\n const lines: string[] = []\n\n lines.push(`# Benchmark Report`)\n lines.push(``)\n lines.push(`**Date:** ${report.timestamp}`)\n lines.push(`**Generation:** ${report.generation}`)\n lines.push(`**Prompt Version:** ${report.promptVersion}`)\n lines.push(`**Scenarios:** ${report.scenarioCount}`)\n lines.push(`**Overall Score:** ${report.summary.overallAvg.toFixed(1)}/10`)\n lines.push(``)\n\n // By persona\n lines.push(`## By Persona`)\n lines.push(``)\n lines.push(`| Persona | Avg | Passed | Total |`)\n lines.push(`|---------|-----|--------|-------|`)\n for (const [name, data] of Object.entries(report.summary.byPersona)) {\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${data.passed} | ${data.total} |`)\n }\n lines.push(``)\n\n // By dimension\n lines.push(`## By Dimension`)\n lines.push(``)\n lines.push(`| Dimension | Avg | Range | N |`)\n lines.push(`|-----------|-----|-------|---|`)\n const dimEntries = Object.entries(report.summary.byDimension)\n .sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${min}-${max} | ${data.scores.length} |`)\n }\n lines.push(``)\n\n // Weakest\n if (report.summary.weakest.length > 0) {\n lines.push(`## Weakest Scenarios`)\n lines.push(``)\n for (const w of report.summary.weakest) {\n lines.push(`- **${w.scenario}** (${w.score.toFixed(1)}): ${w.reason}`)\n }\n lines.push(``)\n }\n\n // Strongest\n if (report.summary.strongest.length > 0) {\n lines.push(`## Strongest Scenarios`)\n lines.push(``)\n for (const s of report.summary.strongest) {\n lines.push(`- **${s.scenario}** (${s.score.toFixed(1)}): ${s.reason}`)\n }\n lines.push(``)\n }\n\n return lines.join('\\n')\n}\n\n/** Generate a markdown report from agent driver results */\nexport function formatDriverReport(results: DriverResult[]): string {\n const lines: string[] = []\n\n lines.push(`# Agent Driver Report`)\n lines.push(``)\n\n for (const r of results) {\n lines.push(`## Persona: ${r.personaId}`)\n lines.push(``)\n lines.push(`- **Completed:** ${r.completed ? 'Yes' : 'No'}`)\n lines.push(`- **Turns to completion:** ${r.turnsToCompletion ?? 'N/A'}`)\n lines.push(`- **Total turns:** ${r.totalTurns}`)\n lines.push(`- **Final state:** ${r.finalState.tasks} tasks, ${r.finalState.events} events, ${r.finalState.vaultFiles.length} vault files`)\n lines.push(``)\n\n // Convergence curve (ASCII)\n lines.push(`### Convergence`)\n lines.push(``)\n lines.push('```')\n for (let i = 0; i < r.convergenceCurve.length; i++) {\n const pct = r.convergenceCurve[i]\n const bar = '#'.repeat(Math.round(pct / 2))\n lines.push(` turn ${String(i + 1).padStart(2)}: ${bar} ${pct.toFixed(0)}%`)\n }\n lines.push('```')\n lines.push(``)\n\n // Per-turn metrics table\n if (r.metrics.length > 0) {\n lines.push(`### Per-Turn Metrics`)\n lines.push(``)\n lines.push(`| Turn | Tasks | Events | Vault | Latency | Completion |`)\n lines.push(`|------|-------|--------|-------|---------|------------|`)\n for (const m of r.metrics) {\n lines.push(`| ${m.turn} | ${m.tasks} | ${m.events} | ${m.vaultFiles} | ${(m.responseLatencyMs / 1000).toFixed(1)}s | ${m.completionPercent.toFixed(0)}% |`)\n }\n lines.push(``)\n }\n }\n\n return lines.join('\\n')\n}\n\n/** Print a compact summary to console */\nexport function printDriverSummary(results: DriverResult[]): void {\n console.log('='.repeat(70))\n console.log(' AGENT DRIVER — RESULTS')\n console.log('='.repeat(70))\n\n for (const r of results) {\n const status = r.completed ? 'COMPLETE' : 'INCOMPLETE'\n const turns = r.turnsToCompletion ?? r.totalTurns\n console.log(` ${r.personaId.padEnd(20)} ${status.padEnd(12)} turns=${turns} tasks=${r.finalState.tasks} events=${r.finalState.events} vault=${r.finalState.vaultFiles.length}`)\n }\n\n console.log()\n const completedCount = results.filter(r => r.completed).length\n console.log(`${completedCount}/${results.length} personas completed`)\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/judges.ts","../src/statistics.ts","../src/executor.ts","../src/benchmark.ts","../src/metrics.ts","../src/convergence.ts","../src/registry.ts","../src/driver.ts","../src/reporter.ts","../src/prompt-registry.ts","../src/trace-store.ts","../src/anti-slop.ts","../src/artifact-validator.ts","../src/workspace-inspector.ts","../src/experiment-tracker.ts","../src/prompt-optimizer.ts","../src/dual-agent-bench.ts"],"sourcesContent":["import type { ProductClientConfig, RouteMap, TestResult, CheckResult } from './types'\n\n/**\n * ProductClient — configurable HTTP client for exercising any agent's APIs.\n *\n * Routes are config, not hardcoded. Each agent provides its own RouteMap.\n */\nexport class ProductClient {\n private baseUrl: string\n private routes: RouteMap\n private cookies: string = ''\n\n constructor(config: ProductClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.routes = config.routes\n }\n\n private route(name: keyof RouteMap): string {\n const path = this.routes[name]\n if (!path) throw new Error(`Route \"${name}\" not configured`)\n return path\n }\n\n async signup(name: string, email: string, password: string): Promise<{ userId: string }> {\n const res = await this.post(this.route('signup'), { name, email, password })\n const user = res.user as Record<string, unknown> | undefined\n if (!user?.id) throw new Error(`Signup failed: ${JSON.stringify(res)}`)\n return { userId: user.id as string }\n }\n\n async login(email: string, password: string): Promise<void> {\n const res = await fetch(`${this.baseUrl}${this.route('login')}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Origin': this.baseUrl },\n body: JSON.stringify({ email, password }),\n redirect: 'manual',\n })\n const setCookie = res.headers.get('set-cookie')\n if (setCookie) {\n this.cookies = setCookie.split(';')[0]\n }\n const body = await res.json() as Record<string, unknown>\n if (!body.user) throw new Error(`Login failed: ${JSON.stringify(body)}`)\n }\n\n async createWorkspace(name: string, type = 'project'): Promise<string> {\n const res = await this.post(this.route('workspaces'), { name, type })\n const ws = res.workspace as Record<string, unknown> | undefined\n if (!ws?.id) throw new Error(`Workspace creation failed: ${JSON.stringify(res)}`)\n return ws.id as string\n }\n\n async createThread(workspaceId: string): Promise<string> {\n const res = await this.post(this.route('threads'), { workspaceId })\n const thread = res.thread as Record<string, unknown> | undefined\n if (!thread?.id) throw new Error(`Thread creation failed: ${JSON.stringify(res)}`)\n return thread.id as string\n }\n\n async chat(\n workspaceId: string,\n threadId: string,\n content: string,\n _opts?: { blockPatterns?: RegExp[] },\n ): Promise<{ text: string; blocks: { type: string; title: string }[] }> {\n const res = await fetch(`${this.baseUrl}${this.route('chat')}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Origin': this.baseUrl,\n 'Cookie': this.cookies,\n },\n body: JSON.stringify({ workspaceId, threadId, content }),\n })\n\n if (!res.ok || !res.body) throw new Error(`Chat failed: ${res.status}`)\n\n // Parse NDJSON stream\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n let text = ''\n const blocks: { type: string; title: string }[] = []\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split('\\n')\n buf = lines.pop() ?? ''\n for (const line of lines) {\n if (!line.trim()) continue\n try {\n const event = JSON.parse(line) as { type?: string; data?: { delta?: string } }\n if (event.type === 'message.part.updated' && event.data?.delta) {\n text += event.data.delta\n }\n } catch { /* skip non-JSON lines */ }\n }\n }\n\n // Extract :::blocks from text\n const blockRe = /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n let match\n while ((match = blockRe.exec(text)) !== null) {\n const fields: Record<string, string> = {}\n for (const line of match[2].split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n blocks.push({ type: match[1], title: fields.title ?? '' })\n }\n\n return { text, blocks }\n }\n\n async getTasks(workspaceId: string): Promise<{ id: string; title: string; status: string; priority: string }[]> {\n const res = await this.get(`${this.route('tasks')}?workspaceId=${workspaceId}`)\n return (res.tasks ?? []) as { id: string; title: string; status: string; priority: string }[]\n }\n\n async getEvents(workspaceId: string): Promise<{ id: string; title: string; type: string }[]> {\n const res = await this.get(`${this.route('events')}?workspaceId=${workspaceId}`)\n return (res.events ?? []) as { id: string; title: string; type: string }[]\n }\n\n async getApprovals(workspaceId: string): Promise<{ id: string; title: string; status: string; type: string }[]> {\n const res = await this.get(`${this.route('approvals')}?workspaceId=${workspaceId}`)\n return (res.actions ?? []) as { id: string; title: string; status: string; type: string }[]\n }\n\n async getVaultTree(workspaceId: string): Promise<string[]> {\n const res = await this.get(`${this.route('vault')}?workspaceId=${workspaceId}`)\n const paths: string[] = []\n function extract(nodes: unknown[]) {\n for (const n of nodes) {\n const node = n as { path?: string; type?: string; children?: unknown[] }\n if (node.type === 'file' && node.path) paths.push(node.path)\n if (node.children) extract(node.children)\n }\n }\n extract((res.tree ?? []) as unknown[])\n return paths\n }\n\n async approveAction(workspaceId: string, id: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'approved' })\n }\n\n async rejectAction(workspaceId: string, id: string, reason: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'rejected', reason })\n }\n\n async getGenerations(workspaceId: string): Promise<{ id: string; type: string; prompt: string }[]> {\n const res = await this.get(`${this.route('generations')}?workspaceId=${workspaceId}`)\n return (res.generations ?? []) as { id: string; type: string; prompt: string }[]\n }\n\n /** Generic GET for custom routes */\n async get(path: string): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n headers: { 'Cookie': this.cookies },\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /** Generic POST for custom routes */\n async post(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Origin': this.baseUrl,\n 'Cookie': this.cookies,\n },\n body: JSON.stringify(body),\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /** Generic PATCH for custom routes */\n async patch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n 'Origin': this.baseUrl,\n 'Cookie': this.cookies,\n },\n body: JSON.stringify(body),\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n}\n\n/**\n * Run a full e2e workflow test against a live product.\n *\n * The `workflow` callback receives a ProductClient and returns CheckResults.\n * This is the generic harness — each agent defines its own workflow steps.\n */\nexport async function runE2EWorkflow(\n client: ProductClient,\n name: string,\n workflow: (client: ProductClient) => Promise<CheckResult[]>,\n): Promise<TestResult> {\n const start = Date.now()\n const checks: CheckResult[] = []\n\n try {\n const results = await workflow(client)\n checks.push(...results)\n } catch (err) {\n checks.push({\n name: 'fatal_error',\n passed: false,\n expected: 'no crash',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n return {\n name,\n passed: checks.every(c => c.passed),\n duration: Date.now() - start,\n detail: `${checks.filter(c => c.passed).length}/${checks.length} checks passed`,\n checks,\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\n/**\n * Create a domain expert judge with a configurable domain.\n *\n * The judge evaluates professional accuracy and depth.\n */\nexport function createDomainExpertJudge(domain: string): JudgeFn {\n return async (tc: TCloud, { scenario, turns }: Pick<JudgeInput, 'scenario' | 'turns'>): Promise<JudgeScore[]> => {\n const conversation = turns.map((t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 2000)}`\n ).join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [{\n role: 'system',\n content: `You are a senior ${domain} professional with 20+ years of experience. You are evaluating an AI agent's responses for professional accuracy and depth.\n\nScore STRICTLY. A 5 means \"a junior professional could do this.\" An 8 means \"solid mid-career work.\" A 10 means \"I would hire this agent.\"\n\nEvaluate:\n1. **domain_accuracy** (0-10): Are the technical terms correct? Are the recommendations what you'd actually do? Would this advice cause problems if followed?\n2. **professional_depth** (0-10): Does it go beyond surface-level? Does it consider practical constraints, edge cases, industry standards? Or is it generic textbook advice?\n\nRespond with JSON only: [{\"dimension\":\"domain_accuracy\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"quote from response\"},{\"dimension\":\"professional_depth\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"quote\"}]`\n }, {\n role: 'user',\n content: `Persona: ${scenario.persona} (${scenario.label})\\nScenario: ${scenario.thesis}\\n\\n${conversation}`\n }],\n temperature: 0.1,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('domain_expert', resp)\n }\n}\n\n/**\n * Code execution judge — evaluates whether code blocks are valid and runnable.\n */\nexport const codeExecutionJudge: JudgeFn = async (tc, { scenario, artifacts }) => {\n const codeBlocks = artifacts.codeBlocks\n if (codeBlocks.length === 0) {\n return [{\n judgeName: 'code_execution',\n dimension: 'code_execution',\n score: 0,\n reasoning: 'No code blocks found in agent response.',\n }]\n }\n\n const codeText = codeBlocks.map((b, i) =>\n `Block ${i + 1} (${b.language}):\\n\\`\\`\\`${b.language}\\n${b.code.slice(0, 3000)}\\n\\`\\`\\``\n ).join('\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [{\n role: 'system',\n content: `You are a principal software engineer reviewing code written by an AI agent.\n\nScore STRICTLY:\n1. **executability** (0-10): Would this code run without errors? Check: import errors, undefined variables, missing deps, syntax errors. A 5 means \"would run with minor fixes.\" A 10 means \"copy-paste and it works.\"\n2. **completeness** (0-10): Does it handle the FULL task, or just the happy path? A 5 means \"handles the main case.\" A 10 means \"production-ready.\"\n3. **reusability** (0-10): Could this be saved as a tool and reused? A 5 means \"works for this case.\" A 10 means \"general-purpose tool.\"\n\nRespond with JSON only: [{\"dimension\":\"executability\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"specific line/issue\"},{\"dimension\":\"completeness\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"},{\"dimension\":\"reusability\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"}]`\n }, {\n role: 'user',\n content: `Task: ${scenario.thesis}\\n\\n${codeText}`\n }],\n temperature: 0.1,\n maxTokens: 1000,\n })\n\n return parseJudgeResponse('code_execution', resp)\n}\n\n/**\n * Coherence judge — evaluates multi-turn consistency and progression.\n */\nexport const coherenceJudge: JudgeFn = async (tc, { scenario, turns }) => {\n if (turns.length < 2) {\n return [{\n judgeName: 'coherence',\n dimension: 'coherence',\n score: 5,\n reasoning: 'Single-turn scenario — coherence not fully testable.',\n }]\n }\n\n const conversation = turns.map((t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent (${t.agentResponse.length} chars): ${t.agentResponse.slice(0, 1500)}`\n ).join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [{\n role: 'system',\n content: `You evaluate whether an AI agent maintains coherence across a multi-turn conversation.\n\nScore STRICTLY:\n1. **consistency** (0-10): Does the agent contradict itself across turns? Does it remember what it said/built earlier?\n2. **progression** (0-10): Does each turn BUILD on the previous? Or does it start fresh? A 5 means \"vaguely related.\" A 10 means \"each turn clearly advances the work.\"\n3. **feedback_integration** (0-10): When the user gives feedback, does the agent demonstrate it HEARD the feedback?\n\nRespond with JSON only: [{\"dimension\":\"consistency\",\"score\":N,\"reasoning\":\"...\"},{\"dimension\":\"progression\",\"score\":N,\"reasoning\":\"...\"},{\"dimension\":\"feedback_integration\",\"score\":N,\"reasoning\":\"...\"}]`\n }, {\n role: 'user',\n content: `Scenario: ${scenario.thesis}\\n\\n${conversation}`\n }],\n temperature: 0.1,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('coherence', resp)\n}\n\n/**\n * Adversarial judge — red-teams agent responses.\n */\nexport const adversarialJudge: JudgeFn = async (tc, { scenario, turns }) => {\n const conversation = turns.map((t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 1500)}`\n ).join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [{\n role: 'system',\n content: `You are a red-team evaluator. Find the WEAKEST point in the AI agent's responses. Be adversarial.\n\n1. **hallucination** (0-10, inverted — 10 means NO hallucination): Did the agent make up facts, cite nonexistent tools, invent standards?\n2. **false_confidence** (0-10, inverted — 10 means appropriate uncertainty): Did the agent present uncertain information as fact?\n3. **worst_failure** (0-10, inverted — 10 means no critical failures): What is the single worst thing in the response?\n\nBe harsh. If everything is genuinely good, say so — but look hard first.\n\nRespond with JSON only: [{\"dimension\":\"hallucination\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"specific quote\"},{\"dimension\":\"false_confidence\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"},{\"dimension\":\"worst_failure\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"}]`\n }, {\n role: 'user',\n content: `Persona: ${scenario.persona}\\nScenario: ${scenario.thesis}\\n\\n${conversation}`\n }],\n temperature: 0.2,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('adversarial', resp)\n}\n\n/**\n * Create a custom judge with a fully custom prompt.\n */\nexport function createCustomJudge(\n name: string,\n systemPrompt: string,\n opts?: { model?: string; temperature?: number; maxTokens?: number },\n): JudgeFn {\n return async (tc, { scenario, turns }) => {\n const conversation = turns.map((t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 2000)}`\n ).join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: opts?.model ?? 'gpt-4o',\n messages: [{\n role: 'system',\n content: systemPrompt,\n }, {\n role: 'user',\n content: `Persona: ${scenario.persona} (${scenario.label})\\nScenario: ${scenario.thesis}\\n\\n${conversation}`\n }],\n temperature: opts?.temperature ?? 0.1,\n maxTokens: opts?.maxTokens ?? 1000,\n })\n\n return parseJudgeResponse(name, resp)\n }\n}\n\n/** Default judge set (domain must be provided for domain expert) */\nexport function defaultJudges(domain: string): JudgeFn[] {\n return [\n createDomainExpertJudge(domain),\n codeExecutionJudge,\n coherenceJudge,\n adversarialJudge,\n ]\n}\n\n// ── Helpers ──\n\nfunction parseJudgeResponse(judgeName: string, resp: unknown): JudgeScore[] {\n try {\n const content = (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ?? ''\n let cleaned = content.replace(/```json\\n?|\\n?```/g, '').trim()\n const arrayMatch = cleaned.match(/\\[[\\s\\S]*\\]/)\n if (arrayMatch) cleaned = arrayMatch[0]\n const parsed = JSON.parse(cleaned) as { dimension: string; score: number; reasoning: string; evidence?: string }[]\n return parsed.map((p) => ({\n judgeName,\n dimension: p.dimension,\n score: Math.max(0, Math.min(10, p.score)),\n reasoning: p.reasoning ?? '',\n evidence: p.evidence,\n }))\n } catch (err) {\n const content = (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ?? ''\n console.log(` [parse_error] ${judgeName}: ${(err as Error).message?.slice(0, 50)} | response: ${content.slice(0, 100)}`)\n return [{\n judgeName,\n dimension: 'parse_error',\n score: 0,\n reasoning: `Parse failed: ${(err as Error).message?.slice(0, 100)}. Raw: ${content.slice(0, 200)}`,\n }]\n }\n}\n","import type { JudgeScore } from './types'\n\n/** Dimensions where lower raw score = better outcome (inverted semantics) */\nconst INVERTED_DIMENSIONS = new Set([\n 'hallucination',\n 'false_confidence',\n 'worst_failure',\n])\n\n/**\n * Normalize scores so all dimensions follow \"higher = better\".\n * Inverted dimensions (hallucination, false_confidence, worst_failure)\n * already use inverted scoring in the prompt (10 = no hallucination),\n * but this function ensures consistency if raw scores leak through.\n */\nexport function normalizeScores(scores: JudgeScore[]): JudgeScore[] {\n return scores.map((s) => {\n if (INVERTED_DIMENSIONS.has(s.dimension)) {\n return s\n }\n return s\n })\n}\n\n/** Weighted mean — falls back to uniform weights when omitted */\nexport function weightedMean(scores: { score: number; weight?: number }[]): number {\n if (scores.length === 0) return 0\n let totalWeight = 0\n let weightedSum = 0\n for (const { score, weight } of scores) {\n const w = weight ?? 1\n weightedSum += score * w\n totalWeight += w\n }\n return totalWeight > 0 ? weightedSum / totalWeight : 0\n}\n\n/** Bootstrap confidence interval */\nexport function confidenceInterval(\n scores: number[],\n confidence = 0.95,\n): { mean: number; lower: number; upper: number } {\n if (scores.length === 0) return { mean: 0, lower: 0, upper: 0 }\n if (scores.length === 1) return { mean: scores[0], lower: scores[0], upper: scores[0] }\n\n const n = scores.length\n const mean = scores.reduce((a, b) => a + b, 0) / n\n\n const B = 1000\n const bootstrapMeans: number[] = []\n\n for (let i = 0; i < B; i++) {\n let sum = 0\n for (let j = 0; j < n; j++) {\n sum += scores[Math.floor(Math.random() * n)]\n }\n bootstrapMeans.push(sum / n)\n }\n\n bootstrapMeans.sort((a, b) => a - b)\n\n const alpha = 1 - confidence\n const lowerIdx = Math.floor((alpha / 2) * B)\n const upperIdx = Math.floor((1 - alpha / 2) * B) - 1\n\n return {\n mean,\n lower: bootstrapMeans[lowerIdx],\n upper: bootstrapMeans[Math.min(upperIdx, B - 1)],\n }\n}\n\n/**\n * Inter-rater reliability — simplified Krippendorff's alpha.\n *\n * Each inner array is one judge's scores for all items.\n * All arrays must have the same length (same items scored).\n */\nexport function interRaterReliability(judgeScores: JudgeScore[][]): number {\n if (judgeScores.length < 2) return 1\n\n // Group scores by dimension across judges\n const dimensionMap = new Map<string, number[][]>()\n for (const judgeSet of judgeScores) {\n for (const s of judgeSet) {\n if (!dimensionMap.has(s.dimension)) dimensionMap.set(s.dimension, [])\n const arr = dimensionMap.get(s.dimension)!\n if (arr.length === 0 || arr[arr.length - 1].length >= judgeScores.length) {\n arr.push([s.score])\n } else {\n arr[arr.length - 1].push(s.score)\n }\n }\n }\n\n // Collect all paired ratings\n const allValues: number[] = []\n const pairDiffs: number[] = []\n\n for (const items of dimensionMap.values()) {\n for (const ratings of items) {\n if (ratings.length < 2) continue\n for (const v of ratings) allValues.push(v)\n for (let i = 0; i < ratings.length; i++) {\n for (let j = i + 1; j < ratings.length; j++) {\n pairDiffs.push((ratings[i] - ratings[j]) ** 2)\n }\n }\n }\n }\n\n if (pairDiffs.length === 0 || allValues.length < 2) return 1\n\n const observedDisagreement = pairDiffs.reduce((a, b) => a + b, 0) / pairDiffs.length\n\n // Expected disagreement from all possible pairings of values\n let expectedDisagreement = 0\n let expectedCount = 0\n for (let i = 0; i < allValues.length; i++) {\n for (let j = i + 1; j < allValues.length; j++) {\n expectedDisagreement += (allValues[i] - allValues[j]) ** 2\n expectedCount++\n }\n }\n expectedDisagreement = expectedCount > 0 ? expectedDisagreement / expectedCount : 0\n\n if (expectedDisagreement === 0) return 1\n return 1 - observedDisagreement / expectedDisagreement\n}\n\n/**\n * Mann-Whitney U test for comparing two independent groups.\n * Returns U statistic and approximate p-value (normal approximation).\n */\nexport function mannWhitneyU(a: number[], b: number[]): { u: number; p: number } {\n if (a.length === 0 || b.length === 0) return { u: 0, p: 1 }\n\n const n1 = a.length\n const n2 = b.length\n\n // Rank all values together\n const combined = [\n ...a.map((v) => ({ v, group: 'a' as const })),\n ...b.map((v) => ({ v, group: 'b' as const })),\n ].sort((x, y) => x.v - y.v)\n\n // Assign ranks with tie handling\n const ranks: number[] = new Array(combined.length)\n let i = 0\n while (i < combined.length) {\n let j = i\n while (j < combined.length && combined[j].v === combined[i].v) j++\n const avgRank = (i + 1 + j) / 2\n for (let k = i; k < j; k++) ranks[k] = avgRank\n i = j\n }\n\n // Sum ranks for group a\n let r1 = 0\n for (let k = 0; k < combined.length; k++) {\n if (combined[k].group === 'a') r1 += ranks[k]\n }\n\n const u1 = r1 - (n1 * (n1 + 1)) / 2\n const u2 = n1 * n2 - u1\n const u = Math.min(u1, u2)\n\n // Normal approximation for p-value\n const mu = (n1 * n2) / 2\n const sigma = Math.sqrt((n1 * n2 * (n1 + n2 + 1)) / 12)\n\n if (sigma === 0) return { u, p: 1 }\n\n const z = Math.abs(u - mu) / sigma\n // Two-tailed p-value from z-score (approximation)\n const p = 2 * (1 - normalCdf(z))\n\n return { u, p }\n}\n\n/** Partial credit: returns 0-1 ratio of current toward target */\nexport function partialCredit(current: number, target: number): number {\n if (target <= 0) return 1\n return Math.min(1, Math.max(0, current / target))\n}\n\n/**\n * Paired t-test — before/after measurements on the SAME items.\n * Pairing removes inter-item variance, giving tighter significance than\n * an unpaired test when comparing prompt v1 vs prompt v2 on identical\n * scenarios.\n */\nexport function pairedTTest(before: number[], after: number[]): { t: number; df: number; p: number } {\n if (before.length !== after.length) {\n throw new Error(`pairedTTest: unequal sample sizes (${before.length} vs ${after.length})`)\n }\n const n = before.length\n if (n < 2) return { t: 0, df: 0, p: 1 }\n\n const diffs = before.map((b, i) => after[i] - b)\n const mean = diffs.reduce((a, b) => a + b, 0) / n\n const variance = diffs.reduce((acc, d) => acc + (d - mean) ** 2, 0) / (n - 1)\n const se = Math.sqrt(variance / n)\n if (se === 0) return { t: mean === 0 ? 0 : Infinity, df: n - 1, p: mean === 0 ? 1 : 0 }\n\n const t = mean / se\n const df = n - 1\n const p = 2 * (1 - studentTCdf(Math.abs(t), df))\n return { t, df, p }\n}\n\n/**\n * Wilcoxon signed-rank test — paired non-parametric alternative.\n * Use when the differences aren't normally distributed.\n */\nexport function wilcoxonSignedRank(before: number[], after: number[]): { w: number; p: number } {\n if (before.length !== after.length) {\n throw new Error(`wilcoxonSignedRank: unequal sample sizes (${before.length} vs ${after.length})`)\n }\n const diffs = before.map((b, i) => after[i] - b).filter((d) => d !== 0)\n const n = diffs.length\n if (n < 6) return { w: 0, p: 1 }\n\n const absRanks = diffs\n .map((d, i) => ({ abs: Math.abs(d), sign: Math.sign(d), i }))\n .sort((a, b) => a.abs - b.abs)\n const ranks: number[] = new Array(n)\n let i = 0\n while (i < n) {\n let j = i\n while (j < n && absRanks[j].abs === absRanks[i].abs) j++\n const avg = (i + 1 + j) / 2\n for (let k = i; k < j; k++) ranks[absRanks[k].i] = avg\n i = j\n }\n let wPlus = 0\n for (let k = 0; k < n; k++) if (diffs[k] > 0) wPlus += ranks[k]\n\n const mean = (n * (n + 1)) / 4\n const variance = (n * (n + 1) * (2 * n + 1)) / 24\n const z = (wPlus - mean) / Math.sqrt(variance)\n const p = 2 * (1 - normalCdf(Math.abs(z)))\n return { w: wPlus, p }\n}\n\n/**\n * Cohen's d — standardized effect size for two independent groups.\n * Positive d means group b has higher mean than group a.\n * Rule of thumb: |d| < 0.2 negligible, 0.2–0.5 small, 0.5–0.8 medium, > 0.8 large.\n */\nexport function cohensD(a: number[], b: number[]): number {\n if (a.length < 2 || b.length < 2) return 0\n const meanA = a.reduce((x, y) => x + y, 0) / a.length\n const meanB = b.reduce((x, y) => x + y, 0) / b.length\n const varA = a.reduce((acc, x) => acc + (x - meanA) ** 2, 0) / (a.length - 1)\n const varB = b.reduce((acc, x) => acc + (x - meanB) ** 2, 0) / (b.length - 1)\n const pooled = Math.sqrt(\n ((a.length - 1) * varA + (b.length - 1) * varB) / (a.length + b.length - 2),\n )\n if (pooled === 0) return 0\n return (meanB - meanA) / pooled\n}\n\n/** Student-t CDF approximation via Abramowitz-Stegun series. */\nfunction studentTCdf(t: number, df: number): number {\n if (df <= 0) return 0.5\n if (df > 100) return normalCdf(t)\n const x = df / (df + t * t)\n const a = df / 2\n const b = 0.5\n const ib = incompleteBeta(x, a, b)\n return t >= 0 ? 1 - 0.5 * ib : 0.5 * ib\n}\n\n/** Regularized incomplete beta function via continued fraction (Lentz). */\nfunction incompleteBeta(x: number, a: number, b: number): number {\n if (x <= 0) return 0\n if (x >= 1) return 1\n const lnBeta = lnGamma(a) + lnGamma(b) - lnGamma(a + b)\n const front = Math.exp(Math.log(x) * a + Math.log(1 - x) * b - lnBeta) / a\n const maxIter = 200\n const eps = 3e-7\n let c = 1\n let d = 1 - ((a + b) * x) / (a + 1)\n if (Math.abs(d) < 1e-30) d = 1e-30\n d = 1 / d\n let f = d\n for (let m = 1; m <= maxIter; m++) {\n const m2 = 2 * m\n let num = (m * (b - m) * x) / ((a + m2 - 1) * (a + m2))\n d = 1 + num * d\n if (Math.abs(d) < 1e-30) d = 1e-30\n c = 1 + num / c\n if (Math.abs(c) < 1e-30) c = 1e-30\n d = 1 / d\n f *= d * c\n num = -((a + m) * (a + b + m) * x) / ((a + m2) * (a + m2 + 1))\n d = 1 + num * d\n if (Math.abs(d) < 1e-30) d = 1e-30\n c = 1 + num / c\n if (Math.abs(c) < 1e-30) c = 1e-30\n d = 1 / d\n const delta = d * c\n f *= delta\n if (Math.abs(delta - 1) < eps) break\n }\n return front * f\n}\n\n/** Lanczos approximation to ln Γ(z). */\nfunction lnGamma(z: number): number {\n const g = 7\n const coefs = [\n 0.99999999999980993, 676.5203681218851, -1259.1392167224028,\n 771.32342877765313, -176.61502916214059, 12.507343278686905,\n -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7,\n ]\n if (z < 0.5) {\n return Math.log(Math.PI / Math.sin(Math.PI * z)) - lnGamma(1 - z)\n }\n z -= 1\n let x = coefs[0]\n for (let i = 1; i < g + 2; i++) x += coefs[i] / (z + i)\n const t = z + g + 0.5\n return 0.5 * Math.log(2 * Math.PI) + (z + 0.5) * Math.log(t) - t + Math.log(x)\n}\n\n// Standard normal CDF approximation (Abramowitz and Stegun)\nfunction normalCdf(x: number): number {\n const a1 = 0.254829592\n const a2 = -0.284496736\n const a3 = 1.421413741\n const a4 = -1.453152027\n const a5 = 1.061405429\n const p = 0.3275911\n\n const sign = x < 0 ? -1 : 1\n const absX = Math.abs(x)\n const t = 1 / (1 + p * absX)\n const y = 1 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-absX * absX / 2)\n\n return 0.5 * (1 + sign * y)\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type {\n Scenario, TurnResult, CollectedArtifacts,\n ScenarioResult, JudgeScore, JudgeFn,\n} from './types'\nimport { normalizeScores, weightedMean } from './statistics'\n\ninterface ChatMessage {\n role: 'system' | 'user' | 'assistant'\n content: string\n}\n\nexport interface ExecutorConfig {\n /** System prompt for the agent under test */\n systemPrompt: string\n /** Model to use for the agent */\n model?: string\n /** Judges to run after execution */\n judges: JudgeFn[]\n /** Regex patterns for detecting tool/API calls in responses */\n toolCallPatterns?: RegExp[]\n /** Block delimiter pattern (default: :::type\\n...\\n:::) */\n blockPattern?: RegExp\n /** Custom artifact checker for domain-specific checks */\n artifactChecker?: (check: Scenario['artifactChecks'][0], artifacts: CollectedArtifacts) => { passed: boolean; detail: string } | null\n}\n\n/**\n * Execute a scenario against an LLM via tcloud.\n *\n * Runs multi-turn conversation, extracts artifacts, runs judges.\n */\nexport async function executeScenario(\n tc: TCloud,\n scenario: Scenario,\n config: ExecutorConfig,\n): Promise<ScenarioResult> {\n const startTime = Date.now()\n const model = config.model ?? 'gpt-4o'\n\n const systemPrompt = [\n config.systemPrompt,\n scenario.systemPromptAppend ?? '',\n ].filter(Boolean).join('\\n\\n')\n\n const messages: ChatMessage[] = [\n { role: 'system', content: systemPrompt },\n ]\n\n const turns: TurnResult[] = []\n const allCodeBlocks: { language: string; code: string }[] = []\n const allBlocks: { type: string; fields: Record<string, string> }[] = []\n const allToolCalls: string[] = []\n\n const blockRe = config.blockPattern ?? /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n\n for (let i = 0; i < scenario.turns.length; i++) {\n const turn = scenario.turns[i]\n const turnStart = Date.now()\n\n messages.push({ role: 'user', content: turn.user })\n\n const resp = await tc.chat({\n model,\n messages,\n temperature: 0.4,\n maxTokens: 3000,\n })\n\n const content = (resp as { choices?: { message?: { content?: string } }[] })\n .choices?.[0]?.message?.content ?? ''\n\n messages.push({ role: 'assistant', content })\n\n // Extract code blocks\n const codeRe = /```(\\w+)?\\n([\\s\\S]*?)```/g\n let codeMatch\n while ((codeMatch = codeRe.exec(content)) !== null) {\n allCodeBlocks.push({ language: codeMatch[1] ?? 'text', code: codeMatch[2] })\n }\n\n // Extract structured blocks\n const turnBlocks: { type: string; title: string }[] = []\n let blockMatch\n const blockReLocal = new RegExp(blockRe.source, blockRe.flags)\n while ((blockMatch = blockReLocal.exec(content)) !== null) {\n const fields: Record<string, string> = {}\n for (const line of blockMatch[2].split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n allBlocks.push({ type: blockMatch[1], fields })\n turnBlocks.push({ type: blockMatch[1], title: fields.title ?? '' })\n }\n\n // Detect tool calls via configurable patterns\n let hasToolCall = false\n if (config.toolCallPatterns) {\n for (const pattern of config.toolCallPatterns) {\n const re = new RegExp(pattern.source, pattern.flags)\n let toolMatch\n while ((toolMatch = re.exec(content)) !== null) {\n allToolCalls.push(toolMatch[0])\n hasToolCall = true\n }\n }\n }\n\n turns.push({\n turnIndex: i,\n userMessage: turn.user,\n agentResponse: content,\n durationMs: Date.now() - turnStart,\n blocksExtracted: turnBlocks,\n containsCode: allCodeBlocks.length > 0,\n containsToolCall: hasToolCall,\n })\n }\n\n const artifacts: CollectedArtifacts = {\n vaultFiles: [],\n blocksExtracted: allBlocks,\n codeBlocks: allCodeBlocks,\n toolCalls: allToolCalls,\n }\n\n // Run artifact checks\n const artifactResults = scenario.artifactChecks.map((check) => {\n // Try custom checker first\n if (config.artifactChecker) {\n const custom = config.artifactChecker(check, artifacts)\n if (custom) return { check, ...custom }\n }\n\n switch (check.type) {\n case 'block_extracted': {\n const count = allBlocks.filter(b => b.type === check.target).length\n return {\n check,\n passed: count >= (check.minCount ?? 1),\n detail: `Found ${count} ${check.target} blocks (need ${check.minCount ?? 1})`,\n }\n }\n case 'code_valid': {\n const hasCode = allCodeBlocks.some(b =>\n b.language === check.target || b.code.includes(check.target)\n )\n return { check, passed: hasCode, detail: hasCode ? 'Code block found' : 'No matching code' }\n }\n default:\n return { check, passed: false, detail: `Check type \"${check.type}\" requires live environment` }\n }\n })\n\n // Run judges sequentially with retry\n const judgeInput = { scenario, turns, artifacts }\n const judgeResults: JudgeScore[][] = []\n\n for (const judge of config.judges) {\n let lastErr = ''\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n if (attempt > 0) {\n const wait = attempt * 10_000\n console.log(` judge retry ${attempt}/2 (waiting ${wait / 1000}s)`)\n await new Promise(r => setTimeout(r, wait))\n }\n const scores = await judge(tc, judgeInput)\n judgeResults.push(scores)\n await new Promise(r => setTimeout(r, 3000))\n break\n } catch (err) {\n lastErr = err instanceof Error ? err.message : String(err)\n if (attempt === 2) {\n judgeResults.push([{\n judgeName: 'unknown',\n dimension: 'error',\n score: 0,\n reasoning: `Judge failed after 3 attempts: ${lastErr.slice(0, 200)}`,\n }])\n }\n }\n }\n }\n\n const allScores = judgeResults.flat()\n const errorScores = allScores.filter(s => s.dimension === 'parse_error' || s.dimension === 'error')\n const validScores = allScores.filter(s => s.dimension !== 'parse_error' && s.dimension !== 'error')\n const normalized = normalizeScores(validScores)\n\n // Build weight map from scenario rubric dimensions\n const weightMap = new Map<string, number>()\n for (const dim of scenario.dimensions) {\n weightMap.set(dim, 1)\n }\n\n const overallScore = weightedMean(\n normalized.map((s) => ({\n score: s.score,\n weight: weightMap.get(s.dimension) ?? 1,\n })),\n )\n\n return {\n scenarioId: scenario.id,\n persona: scenario.persona,\n turns,\n artifactResults,\n judgeScores: allScores,\n judgeErrors: errorScores.length,\n overallScore,\n totalDurationMs: Date.now() - startTime,\n artifacts,\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { Scenario, ScenarioResult, BenchmarkReport, BenchmarkRunnerConfig } from './types'\nimport { executeScenario } from './executor'\n\n/**\n * BenchmarkRunner — orchestrates scenarios, executor, judges, and scoring.\n *\n * Domain-agnostic. Each agent provides its own scenarios, judges, and system prompt.\n */\nexport class BenchmarkRunner {\n private tc: TCloud\n private config: BenchmarkRunnerConfig\n\n constructor(tc: TCloud, config: BenchmarkRunnerConfig) {\n this.tc = tc\n this.config = config\n }\n\n async run(scenarios?: Scenario[]): Promise<BenchmarkReport> {\n const toRun = scenarios ?? this.config.scenarios\n const passThreshold = this.config.passThreshold ?? 6.0\n\n console.log('='.repeat(70))\n console.log(' AGENT EVAL — BENCHMARK')\n console.log(' Multi-turn scenarios x Multi-judge panel')\n console.log('='.repeat(70))\n console.log(`Scenarios: ${toRun.length}`)\n console.log(`Judges: ${this.config.judges.length}`)\n console.log(`Model: ${this.config.model ?? 'gpt-4o'}`)\n console.log()\n\n const results: ScenarioResult[] = []\n\n for (let i = 0; i < toRun.length; i++) {\n const scenario = toRun[i]\n console.log(`[${i + 1}/${toRun.length}] ${scenario.id} (${scenario.persona})`)\n console.log(` thesis: ${scenario.thesis}`)\n console.log(` turns: ${scenario.turns.length}`)\n\n const result = await executeScenario(this.tc, scenario, {\n systemPrompt: this.config.systemPrompt,\n model: this.config.model,\n judges: this.config.judges,\n })\n results.push(result)\n\n // Print turn summaries\n for (const turn of result.turns) {\n const codeIcon = turn.containsCode ? '[code]' : ''\n const toolIcon = turn.containsToolCall ? '[tool]' : ''\n const blockCount = turn.blocksExtracted.length\n const blockIcon = blockCount > 0 ? `[blocks:${blockCount}]` : ''\n console.log(` turn ${turn.turnIndex + 1}: ${(turn.durationMs / 1000).toFixed(1)}s ${codeIcon} ${toolIcon} ${blockIcon} (${turn.agentResponse.length} chars)`)\n }\n\n // Print artifact results\n for (const ar of result.artifactResults) {\n const icon = ar.passed ? '+' : 'X'\n console.log(` artifact: [${icon}] ${ar.check.description} — ${ar.detail}`)\n }\n\n // Print judge scores\n console.log(` judges:`)\n const byJudge: Record<string, { scores: number[]; dimensions: string[] }> = {}\n for (const js of result.judgeScores) {\n if (!byJudge[js.judgeName]) byJudge[js.judgeName] = { scores: [], dimensions: [] }\n byJudge[js.judgeName].scores.push(js.score)\n byJudge[js.judgeName].dimensions.push(`${js.dimension}=${js.score}`)\n }\n for (const [name, data] of Object.entries(byJudge)) {\n const avg = (data.scores.reduce((a, b) => a + b, 0) / data.scores.length).toFixed(1)\n console.log(` ${name.padEnd(16)} avg=${avg} [${data.dimensions.join(', ')}]`)\n }\n\n console.log(` OVERALL: ${result.overallScore.toFixed(1)}/10 (${(result.totalDurationMs / 1000).toFixed(0)}s)`)\n console.log()\n }\n\n // Build summary\n const byPersona: Record<string, { avg: number; passed: number; total: number }> = {}\n const byDimension: Record<string, { avg: number; scores: number[] }> = {}\n\n for (const r of results) {\n if (!byPersona[r.persona]) byPersona[r.persona] = { avg: 0, passed: 0, total: 0 }\n byPersona[r.persona].total++\n byPersona[r.persona].avg += r.overallScore\n if (r.overallScore >= passThreshold) byPersona[r.persona].passed++\n\n for (const js of r.judgeScores) {\n if (!byDimension[js.dimension]) byDimension[js.dimension] = { avg: 0, scores: [] }\n byDimension[js.dimension].scores.push(js.score)\n }\n }\n\n for (const p of Object.values(byPersona)) {\n p.avg = p.total > 0 ? p.avg / p.total : 0\n }\n for (const d of Object.values(byDimension)) {\n d.avg = d.scores.length > 0 ? d.scores.reduce((a, b) => a + b, 0) / d.scores.length : 0\n }\n\n const sorted = [...results].sort((a, b) => a.overallScore - b.overallScore)\n const weakest = sorted.slice(0, 3).map(r => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason: r.judgeScores.filter(s => s.score < passThreshold).map(s => `${s.dimension}=${s.score}`).join(', ') || 'close to threshold',\n }))\n const strongest = sorted.slice(-3).reverse().map(r => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason: r.judgeScores.filter(s => s.score >= 9).map(s => `${s.dimension}=${s.score}`).join(', ') || 'consistently strong',\n }))\n\n // Print final summary\n console.log('='.repeat(70))\n console.log(' RESULTS')\n console.log('='.repeat(70))\n\n const overallAvg = results.length > 0\n ? results.reduce((s, r) => s + r.overallScore, 0) / results.length\n : 0\n\n console.log(`Overall: ${overallAvg.toFixed(1)}/10`)\n console.log()\n\n console.log('By persona:')\n for (const [name, data] of Object.entries(byPersona)) {\n console.log(` ${name.padEnd(20)} ${data.avg.toFixed(1)}/10 (${data.passed}/${data.total} passed)`)\n }\n console.log()\n\n console.log('By dimension:')\n const dimEntries = Object.entries(byDimension).sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n console.log(` ${name.padEnd(24)} avg=${data.avg.toFixed(1)} range=[${min}-${max}] n=${data.scores.length}`)\n }\n console.log()\n\n if (weakest.length > 0) {\n console.log('Weakest:')\n for (const w of weakest) {\n console.log(` ${w.scenario}: ${w.score.toFixed(1)} — ${w.reason}`)\n }\n console.log()\n }\n\n return {\n timestamp: new Date().toISOString(),\n generation: this.config.generation ?? 1,\n promptVersion: this.config.promptVersion ?? 'v1',\n scenarioCount: toRun.length,\n results,\n summary: { overallAvg, byPersona, byDimension, weakest, strongest },\n }\n }\n}\n","import type { TurnMetrics, DriverState } from './types'\nimport type { ProductClient } from './client'\n\n/** Per-1K token pricing for common models */\nexport const MODEL_PRICING: Record<string, { input: number; output: number }> = {\n 'gpt-4o': { input: 0.0025, output: 0.01 },\n 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },\n 'gpt-4-turbo': { input: 0.01, output: 0.03 },\n 'claude-sonnet-4-20250514': { input: 0.003, output: 0.015 },\n 'claude-opus-4-20250514': { input: 0.015, output: 0.075 },\n 'claude-3-haiku-20240307': { input: 0.00025, output: 0.00125 },\n}\n\n/** Estimate token count from string length (chars / 4 approximation) */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\n/** Calculate cost in USD from token counts and model */\nexport function estimateCost(\n inputTokens: number,\n outputTokens: number,\n model: string,\n): number {\n const pricing = MODEL_PRICING[model]\n if (!pricing) return 0\n return (inputTokens / 1000) * pricing.input + (outputTokens / 1000) * pricing.output\n}\n\n/**\n * TokenCounter — accumulates token usage and cost across turns.\n */\nexport class TokenCounter {\n private totalInput = 0\n private totalOutput = 0\n private totalCost = 0\n private model: string\n\n constructor(model = 'gpt-4o') {\n this.model = model\n }\n\n /** Record tokens for a turn, returns per-turn cost */\n record(inputTokens: number, outputTokens: number): number {\n this.totalInput += inputTokens\n this.totalOutput += outputTokens\n const cost = estimateCost(inputTokens, outputTokens, this.model)\n this.totalCost += cost\n return cost\n }\n\n /** Estimate and record from raw text */\n recordFromText(inputText: string, outputText: string): { inputTokens: number; outputTokens: number; cost: number } {\n const inputTokens = estimateTokens(inputText)\n const outputTokens = estimateTokens(outputText)\n const cost = this.record(inputTokens, outputTokens)\n return { inputTokens, outputTokens, cost }\n }\n\n getTotalInput(): number { return this.totalInput }\n getTotalOutput(): number { return this.totalOutput }\n getTotalCost(): number { return this.totalCost }\n}\n\n/**\n * MetricsCollector — collects per-turn metrics from the product.\n *\n * After each turn, queries the product's APIs to measure state changes.\n */\nexport class MetricsCollector {\n private client: ProductClient\n private workspaceId: string\n private metrics: TurnMetrics[] = []\n constructor(client: ProductClient, workspaceId: string) {\n this.client = client\n this.workspaceId = workspaceId\n }\n\n /** Collect metrics after a turn completes */\n async collect(\n turn: number,\n responseLatencyMs: number,\n responseChars: number,\n codeBlocksProduced: number,\n blocksExtracted: number,\n completionCriteriaMet: number,\n completionCriteriaTotal: number,\n qualityScore?: number,\n inputTokens = 0,\n outputTokens = 0,\n estimatedCostUsd = 0,\n ): Promise<TurnMetrics> {\n const state = await this.getState()\n\n const m: TurnMetrics = {\n turn,\n timestamp: new Date().toISOString(),\n tasks: state.tasks,\n events: state.events,\n proposals: state.proposals,\n vaultFiles: state.vaultFiles.length,\n responseLatencyMs,\n responseChars,\n codeBlocksProduced,\n blocksExtracted,\n qualityScore,\n inputTokens,\n outputTokens,\n estimatedCostUsd,\n totalCostUsd: estimatedCostUsd,\n completionPercent: completionCriteriaTotal > 0\n ? (completionCriteriaMet / completionCriteriaTotal) * 100\n : 0,\n }\n\n this.metrics.push(m)\n return m\n }\n\n /** Get current product state */\n async getState(): Promise<DriverState> {\n const [tasks, events, approvals, vaultFiles] = await Promise.all([\n this.client.getTasks(this.workspaceId),\n this.client.getEvents(this.workspaceId),\n this.client.getApprovals(this.workspaceId),\n this.client.getVaultTree(this.workspaceId),\n ])\n\n return {\n tasks: tasks.length,\n events: events.length,\n proposals: {\n pending: approvals.filter(a => a.status === 'pending').length,\n approved: approvals.filter(a => a.status === 'approved').length,\n rejected: approvals.filter(a => a.status === 'rejected').length,\n },\n vaultFiles,\n codeBlocks: 0,\n generations: 0,\n }\n }\n\n /** Get all collected metrics */\n getMetrics(): TurnMetrics[] {\n return [...this.metrics]\n }\n\n /** Get convergence curve (completion% over turns) */\n getConvergenceCurve(): number[] {\n return this.metrics.map(m => m.completionPercent)\n }\n}\n","import type { CompletionCriterion, DriverState } from './types'\n\n/**\n * ConvergenceTracker — tracks completion percentage over turns.\n *\n * Produces convergence curves showing how quickly the agent reaches\n * completion criteria.\n */\nexport class ConvergenceTracker {\n private criteria: CompletionCriterion[]\n private history: { turn: number; completionPercent: number; criteriaStatus: Record<string, boolean | number> }[] = []\n\n constructor(criteria: CompletionCriterion[]) {\n this.criteria = criteria\n }\n\n /** Evaluate criteria against current state, record result */\n record(turn: number, state: DriverState): { completionPercent: number; complete: boolean; criteriaStatus: Record<string, boolean | number> } {\n const criteriaStatus: Record<string, boolean | number> = {}\n let totalCredit = 0\n\n for (const criterion of this.criteria) {\n if (criterion.progress) {\n const credit = Math.min(1, Math.max(0, criterion.progress(state)))\n criteriaStatus[criterion.name] = credit\n totalCredit += credit\n } else {\n const passed = criterion.check(state)\n criteriaStatus[criterion.name] = passed\n totalCredit += passed ? 1 : 0\n }\n }\n\n const completionPercent = this.criteria.length > 0\n ? (totalCredit / this.criteria.length) * 100\n : 100\n\n this.history.push({ turn, completionPercent, criteriaStatus })\n\n return {\n completionPercent,\n complete: totalCredit >= this.criteria.length,\n criteriaStatus,\n }\n }\n\n /** Get convergence curve */\n getCurve(): number[] {\n return this.history.map(h => h.completionPercent)\n }\n\n /** Get full history with per-criterion status */\n getHistory() {\n return [...this.history]\n }\n\n /** Find the turn where completion first reached 100% (or null) */\n getTurnToCompletion(): number | null {\n const entry = this.history.find(h => h.completionPercent === 100)\n return entry?.turn ?? null\n }\n}\n","import type { Scenario, ScenarioFile } from './types'\n\n/**\n * ScenarioRegistry — manages scenario discovery and filtering.\n *\n * Each agent registers its scenarios. The registry handles conversion\n * from ScenarioFile format to the framework's Scenario type.\n */\nexport class ScenarioRegistry {\n private scenarios: Scenario[] = []\n private scenarioFiles: ScenarioFile[] = []\n\n /** Register scenarios from ScenarioFile format */\n registerFiles(files: ScenarioFile[]): void {\n this.scenarioFiles.push(...files)\n this.scenarios.push(...files.map(toScenario))\n }\n\n /** Register pre-built Scenario objects directly */\n register(scenarios: Scenario[]): void {\n this.scenarios.push(...scenarios)\n }\n\n /** Get all scenarios */\n all(): Scenario[] {\n return [...this.scenarios]\n }\n\n /** Get scenarios filtered by category */\n byCategory(category: string): Scenario[] {\n const fromFiles = this.scenarioFiles\n .filter(sf => sf.category === category)\n .map(toScenario)\n return fromFiles\n }\n\n /** List all categories with counts */\n listCategories(): { category: string; count: number }[] {\n const counts: Record<string, number> = {}\n for (const sf of this.scenarioFiles) {\n counts[sf.category] = (counts[sf.category] ?? 0) + 1\n }\n return Object.entries(counts).map(([category, count]) => ({ category, count }))\n }\n\n /** Get scenarios filtered by persona */\n byPersona(persona: string): Scenario[] {\n return this.scenarios.filter(s => s.persona === persona)\n }\n\n /** Get a single scenario by ID */\n byId(id: string): Scenario | undefined {\n return this.scenarios.find(s => s.id === id)\n }\n\n /** Count total scenarios */\n get count(): number {\n return this.scenarios.length\n }\n}\n\n/** Convert ScenarioFile to the framework's Scenario type */\nfunction toScenario(sf: ScenarioFile): Scenario {\n return {\n id: sf.id,\n persona: sf.persona,\n label: sf.label,\n thesis: sf.thesis,\n dimensions: [],\n turns: sf.turns,\n artifactChecks: sf.artifactChecks,\n systemPromptAppend: sf.isControl ? 'You are a helpful AI assistant.' : undefined,\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { PersonaConfig, DriverResult, DriverState, TurnMetrics } from './types'\nimport { ProductClient } from './client'\nimport { MetricsCollector } from './metrics'\nimport { ConvergenceTracker } from './convergence'\n\nexport interface AgentDriverConfig {\n client: ProductClient\n driverModel?: string\n /** System prompt context for the driver LLM to understand the product */\n productContext?: string\n}\n\n/**\n * AgentDriver — meta-agent that plays a persona against the real product.\n *\n * Uses a driver LLM (Claude/GPT-4o) to decide what to say each turn.\n * Not scripted — the driver gets the current product state and decides\n * the next realistic user message.\n */\nexport class AgentDriver {\n private tc: TCloud\n private client: ProductClient\n private driverModel: string\n private productContext: string\n\n constructor(tc: TCloud, config: AgentDriverConfig) {\n this.tc = tc\n this.client = config.client\n this.driverModel = config.driverModel ?? 'claude-sonnet-4-6'\n this.productContext = config.productContext ?? ''\n }\n\n /**\n * Run a persona through the product.\n *\n * Returns metrics on how many turns to completion, cost curve,\n * quality curve, and convergence curve.\n */\n async run(persona: PersonaConfig): Promise<DriverResult> {\n // Setup: create workspace + thread\n const email = `eval-driver-${Date.now()}@test.agent-eval.local`\n await this.client.signup(`Driver ${persona.role}`, email, 'eval-driver-pass')\n await this.client.login(email, 'eval-driver-pass')\n const workspaceId = await this.client.createWorkspace(`${persona.role} Eval`)\n const threadId = await this.client.createThread(workspaceId)\n\n const metrics = new MetricsCollector(this.client, workspaceId)\n const convergence = new ConvergenceTracker(persona.completionCriteria)\n const turnMetrics: TurnMetrics[] = []\n const conversationHistory: { role: string; content: string }[] = []\n\n let completed = false\n let turnsToCompletion: number | null = null\n\n for (let turn = 1; turn <= persona.maxTurns; turn++) {\n // Get current product state\n const state = await metrics.getState()\n\n // Ask driver LLM what to say\n const userMessage = await this.decideNextMessage(persona, state, conversationHistory)\n\n if (userMessage === 'DONE') {\n completed = true\n turnsToCompletion = turn - 1\n break\n }\n\n // Send to product\n const turnStart = Date.now()\n const response = await this.client.chat(workspaceId, threadId, userMessage)\n const latency = Date.now() - turnStart\n\n conversationHistory.push(\n { role: 'user', content: userMessage },\n { role: 'assistant', content: response.text },\n )\n\n // Wait for post-processor\n await new Promise(r => setTimeout(r, 2000))\n\n // Handle pending approvals\n await this.handleApprovals(persona, workspaceId, state)\n\n // Check convergence\n const postState = await metrics.getState()\n const conv = convergence.record(turn, postState)\n\n // Collect metrics\n const codeBlockCount = (response.text.match(/```\\w+\\n/g) || []).length\n const m = await metrics.collect(\n turn,\n latency,\n response.text.length,\n codeBlockCount,\n response.blocks.length,\n Object.values(conv.criteriaStatus).filter(Boolean).length,\n persona.completionCriteria.length,\n )\n turnMetrics.push(m)\n\n // Print turn status\n const criteriaStr = Object.entries(conv.criteriaStatus)\n .map(([k, v]) => `${k}:${v ? '+' : '-'}`)\n .join(' ')\n console.log(` [turn ${turn}] ${conv.completionPercent.toFixed(0)}% — ${criteriaStr} (${(latency / 1000).toFixed(1)}s)`)\n\n if (conv.complete) {\n completed = true\n turnsToCompletion = turn\n console.log(` COMPLETE at turn ${turn}`)\n break\n }\n }\n\n const finalState = await metrics.getState()\n\n return {\n personaId: persona.id,\n completed,\n turnsToCompletion,\n totalTurns: turnMetrics.length,\n metrics: turnMetrics,\n finalState,\n convergenceCurve: convergence.getCurve(),\n totalCostUsd: 0,\n finalQualityScore: null,\n }\n }\n\n /** Use the driver LLM to decide what the \"user\" says next */\n private async decideNextMessage(\n persona: PersonaConfig,\n state: DriverState,\n history: { role: string; content: string }[],\n ): Promise<string> {\n const lastResponse = history.length > 0\n ? history[history.length - 1].content.slice(0, 2000)\n : '(no conversation yet — this is the first message)'\n\n const recentHistory = history.slice(-6).map(h =>\n `${h.role}: ${h.content.slice(0, 500)}`\n ).join('\\n\\n')\n\n const resp = await this.tc.chat({\n model: this.driverModel,\n messages: [{\n role: 'system',\n content: `You are playing the role of a ${persona.role} testing an AI agent.\nYour goal: ${persona.goal}\n\n${this.productContext ? `Product context:\\n${this.productContext}\\n` : ''}\nCurrent state:\n- Tasks: ${state.tasks}\n- Events: ${state.events}\n- Proposals: pending=${state.proposals.pending}, approved=${state.proposals.approved}, rejected=${state.proposals.rejected}\n- Vault files: ${state.vaultFiles.length} (${state.vaultFiles.slice(0, 10).join(', ')}${state.vaultFiles.length > 10 ? '...' : ''})\n\nCompletion criteria met: ${this.describeCompletion(persona, state)}\n\nDecide what to do next:\n1. If completion is 100% — respond with exactly \"DONE\"\n2. If a proposal is pending — approve or reject it (with reason)\n3. If the agent is on track — push for the next deliverable\n4. If the agent is off track — give specific corrective feedback\n5. If this is the first message — start with a clear, actionable request\n\nOutput ONLY your next message to the agent. Be specific. Be realistic.\nDon't be patient — a real ${persona.role} wouldn't accept vague answers.`\n }, {\n role: 'user',\n content: recentHistory\n ? `Recent conversation:\\n${recentHistory}\\n\\nThe agent just said:\\n${lastResponse}`\n : 'No conversation yet. Send your opening message.',\n }],\n temperature: 0.5,\n maxTokens: 500,\n })\n\n const content = (resp as { choices?: { message?: { content?: string } }[] })\n .choices?.[0]?.message?.content ?? ''\n\n return content.trim()\n }\n\n /** Handle pending approvals based on persona feedback patterns */\n private async handleApprovals(\n persona: PersonaConfig,\n workspaceId: string,\n _state: DriverState,\n ): Promise<void> {\n const approvals = await this.client.getApprovals(workspaceId)\n const pending = approvals.filter(a => a.status === 'pending')\n\n for (const action of pending) {\n // Check if any feedback pattern triggers a rejection\n const rejection = persona.feedbackPatterns?.find(fp => {\n const title = action.title.toLowerCase()\n return title.includes(fp.trigger.toLowerCase())\n })\n\n if (rejection) {\n await this.client.rejectAction(workspaceId, action.id, rejection.response)\n console.log(` rejected: ${action.title} — ${rejection.response.slice(0, 60)}`)\n } else {\n await this.client.approveAction(workspaceId, action.id)\n console.log(` approved: ${action.title}`)\n }\n }\n }\n\n /** Describe which completion criteria are met */\n private describeCompletion(persona: PersonaConfig, state: DriverState): string {\n const results = persona.completionCriteria.map(c => {\n const met = c.check(state)\n return `${c.name}: ${met ? 'MET' : 'NOT MET'}`\n })\n const metCount = results.filter(r => r.includes('MET') && !r.includes('NOT')).length\n return `${metCount}/${persona.completionCriteria.length} — ${results.join(', ')}`\n }\n}\n","import type { BenchmarkReport, DriverResult } from './types'\n\n/**\n * Report generation utilities.\n *\n * Outputs convergence curves, cost curves, quality curves,\n * and per-persona summaries in markdown format.\n */\n\n/** Generate a markdown report from benchmark results */\nexport function formatBenchmarkReport(report: BenchmarkReport): string {\n const lines: string[] = []\n\n lines.push(`# Benchmark Report`)\n lines.push(``)\n lines.push(`**Date:** ${report.timestamp}`)\n lines.push(`**Generation:** ${report.generation}`)\n lines.push(`**Prompt Version:** ${report.promptVersion}`)\n lines.push(`**Scenarios:** ${report.scenarioCount}`)\n lines.push(`**Overall Score:** ${report.summary.overallAvg.toFixed(1)}/10`)\n lines.push(``)\n\n // By persona\n lines.push(`## By Persona`)\n lines.push(``)\n lines.push(`| Persona | Avg | Passed | Total |`)\n lines.push(`|---------|-----|--------|-------|`)\n for (const [name, data] of Object.entries(report.summary.byPersona)) {\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${data.passed} | ${data.total} |`)\n }\n lines.push(``)\n\n // By dimension\n lines.push(`## By Dimension`)\n lines.push(``)\n lines.push(`| Dimension | Avg | Range | N |`)\n lines.push(`|-----------|-----|-------|---|`)\n const dimEntries = Object.entries(report.summary.byDimension)\n .sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${min}-${max} | ${data.scores.length} |`)\n }\n lines.push(``)\n\n // Weakest\n if (report.summary.weakest.length > 0) {\n lines.push(`## Weakest Scenarios`)\n lines.push(``)\n for (const w of report.summary.weakest) {\n lines.push(`- **${w.scenario}** (${w.score.toFixed(1)}): ${w.reason}`)\n }\n lines.push(``)\n }\n\n // Strongest\n if (report.summary.strongest.length > 0) {\n lines.push(`## Strongest Scenarios`)\n lines.push(``)\n for (const s of report.summary.strongest) {\n lines.push(`- **${s.scenario}** (${s.score.toFixed(1)}): ${s.reason}`)\n }\n lines.push(``)\n }\n\n return lines.join('\\n')\n}\n\n/** Generate a markdown report from agent driver results */\nexport function formatDriverReport(results: DriverResult[]): string {\n const lines: string[] = []\n\n lines.push(`# Agent Driver Report`)\n lines.push(``)\n\n for (const r of results) {\n lines.push(`## Persona: ${r.personaId}`)\n lines.push(``)\n lines.push(`- **Completed:** ${r.completed ? 'Yes' : 'No'}`)\n lines.push(`- **Turns to completion:** ${r.turnsToCompletion ?? 'N/A'}`)\n lines.push(`- **Total turns:** ${r.totalTurns}`)\n lines.push(`- **Final state:** ${r.finalState.tasks} tasks, ${r.finalState.events} events, ${r.finalState.vaultFiles.length} vault files`)\n lines.push(``)\n\n // Convergence curve (ASCII)\n lines.push(`### Convergence`)\n lines.push(``)\n lines.push('```')\n for (let i = 0; i < r.convergenceCurve.length; i++) {\n const pct = r.convergenceCurve[i]\n const bar = '#'.repeat(Math.round(pct / 2))\n lines.push(` turn ${String(i + 1).padStart(2)}: ${bar} ${pct.toFixed(0)}%`)\n }\n lines.push('```')\n lines.push(``)\n\n // Per-turn metrics table\n if (r.metrics.length > 0) {\n lines.push(`### Per-Turn Metrics`)\n lines.push(``)\n lines.push(`| Turn | Tasks | Events | Vault | Latency | Completion |`)\n lines.push(`|------|-------|--------|-------|---------|------------|`)\n for (const m of r.metrics) {\n lines.push(`| ${m.turn} | ${m.tasks} | ${m.events} | ${m.vaultFiles} | ${(m.responseLatencyMs / 1000).toFixed(1)}s | ${m.completionPercent.toFixed(0)}% |`)\n }\n lines.push(``)\n }\n }\n\n return lines.join('\\n')\n}\n\n/** Print a compact summary to console */\nexport function printDriverSummary(results: DriverResult[]): void {\n console.log('='.repeat(70))\n console.log(' AGENT DRIVER — RESULTS')\n console.log('='.repeat(70))\n\n for (const r of results) {\n const status = r.completed ? 'COMPLETE' : 'INCOMPLETE'\n const turns = r.turnsToCompletion ?? r.totalTurns\n console.log(` ${r.personaId.padEnd(20)} ${status.padEnd(12)} turns=${turns} tasks=${r.finalState.tasks} events=${r.finalState.events} vault=${r.finalState.vaultFiles.length}`)\n }\n\n console.log()\n const completedCount = results.filter(r => r.completed).length\n console.log(`${completedCount}/${results.length} personas completed`)\n}\n","/**\n * Versioned prompt registry.\n *\n * Every prompt used in an eval run is registered with an explicit version.\n * Reports include the content hash so A/B compares are rigorous: if the\n * hash changes between two reports, the prompt actually changed; if it\n * matches, the variance is elsewhere.\n *\n * Hash is SHA-256(content), truncated to 12 hex chars for readability.\n * Uses the Web Crypto API (works in Workers, Node 22+, browsers).\n */\n\nexport interface PromptHandle {\n /** Stable human-readable id, e.g. 'legal.system' */\n id: string\n /** Caller-chosen version string, e.g. 'v3' or '2026-04-20' */\n version: string\n /** SHA-256 of content, 12-hex-char prefix */\n hash: string\n /** Full prompt body */\n content: string\n}\n\nexport class PromptRegistry {\n private readonly entries = new Map<string, PromptHandle>() // `${id}@${version}` → handle\n\n /**\n * Register a prompt. Re-registering the same id+version with DIFFERENT\n * content throws — versions are immutable. Re-registering with the SAME\n * content is a no-op (idempotent).\n */\n async register(id: string, version: string, content: string): Promise<PromptHandle> {\n validateId(id)\n validateVersion(version)\n\n const key = makeKey(id, version)\n const hash = await hashContent(content)\n const existing = this.entries.get(key)\n if (existing) {\n if (existing.hash !== hash) {\n throw new Error(\n `Prompt ${key} already registered with a different hash (${existing.hash} vs ${hash}). Bump the version.`,\n )\n }\n return existing\n }\n const handle: PromptHandle = { id, version, hash, content }\n this.entries.set(key, handle)\n return handle\n }\n\n /** Look up a registered prompt. Throws if unknown — no implicit defaults. */\n get(id: string, version: string): PromptHandle {\n const key = makeKey(id, version)\n const handle = this.entries.get(key)\n if (!handle) throw new Error(`Prompt ${key} not registered`)\n return handle\n }\n\n /** Return all versions of an id, newest-first (lex-descending on version). */\n listVersions(id: string): PromptHandle[] {\n return [...this.entries.values()]\n .filter((h) => h.id === id)\n .sort((a, b) => b.version.localeCompare(a.version))\n }\n\n /** Snapshot the whole registry — useful for including in reports. */\n list(): PromptHandle[] {\n return [...this.entries.values()]\n }\n\n /** Verify a hash against registered content. Returns null if not found. */\n verifyHash(id: string, version: string, expectedHash: string): boolean | null {\n const handle = this.entries.get(makeKey(id, version))\n if (!handle) return null\n return handle.hash === expectedHash\n }\n}\n\n/** SHA-256(content) → first 12 hex chars. Stable across runtimes. */\nexport async function hashContent(content: string): Promise<string> {\n const bytes = new TextEncoder().encode(content)\n const digest = await crypto.subtle.digest('SHA-256', bytes)\n const full = Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n return full.slice(0, 12)\n}\n\nfunction makeKey(id: string, version: string): string {\n return `${id}@${version}`\n}\n\nconst ID_RE = /^[a-z][a-z0-9._-]*$/i\nfunction validateId(id: string): void {\n if (!ID_RE.test(id)) {\n throw new Error(`Invalid prompt id \"${id}\": must match ${ID_RE}`)\n }\n}\n\nfunction validateVersion(version: string): void {\n if (!version || version.length > 64) {\n throw new Error(`Invalid version \"${version}\": must be 1–64 chars`)\n }\n}\n","/**\n * LLM trace store — one record per model call.\n *\n * Sink for the full eval data-plane: what got sent, what came back, what it\n * cost, how long it took. Replayable, queryable, diff-able.\n *\n * Two built-in stores:\n * - `MemoryTraceStore` — fast, ephemeral, useful in tests and short runs\n * - `FileSystemTraceStore` — NDJSON files per-run, grepable, committable\n *\n * Consumers plug in custom stores for Langfuse / OTEL / D1 / Postgres.\n */\n\nexport interface LlmTrace {\n id: string\n runId: string\n scenarioId?: string\n turnIndex?: number\n role: 'driver' | 'judge' | 'product' | 'optimizer' | string\n model: string\n prompt: string\n output: string\n inputTokens?: number\n outputTokens?: number\n costUsd?: number\n durationMs?: number\n timestamp: string\n metadata?: Record<string, unknown>\n}\n\nexport interface TraceQuery {\n runId?: string\n scenarioId?: string\n role?: string\n model?: string\n sinceMs?: number\n limit?: number\n}\n\nexport interface TraceStore {\n record(trace: LlmTrace): Promise<void>\n query(query: TraceQuery): Promise<LlmTrace[]>\n count(query?: TraceQuery): Promise<number>\n}\n\n// ---------------------------------------------------------------------------\n// In-memory implementation — O(1) record, O(n) query\n// ---------------------------------------------------------------------------\n\nexport class MemoryTraceStore implements TraceStore {\n private traces: LlmTrace[] = []\n\n async record(trace: LlmTrace): Promise<void> {\n this.traces.push(trace)\n }\n\n async query(query: TraceQuery): Promise<LlmTrace[]> {\n let result = this.filter(query)\n if (query.limit !== undefined) result = result.slice(0, query.limit)\n return result\n }\n\n async count(query?: TraceQuery): Promise<number> {\n return query ? this.filter(query).length : this.traces.length\n }\n\n /** Clear the store — test helper. */\n reset(): void {\n this.traces = []\n }\n\n private filter(query: TraceQuery): LlmTrace[] {\n return this.traces.filter((t) => {\n if (query.runId && t.runId !== query.runId) return false\n if (query.scenarioId && t.scenarioId !== query.scenarioId) return false\n if (query.role && t.role !== query.role) return false\n if (query.model && t.model !== query.model) return false\n if (query.sinceMs !== undefined) {\n const ts = Date.parse(t.timestamp)\n if (Number.isFinite(ts) && ts < query.sinceMs) return false\n }\n return true\n })\n }\n}\n\n// ---------------------------------------------------------------------------\n// NDJSON filesystem implementation — append-only, grepable\n// ---------------------------------------------------------------------------\n\nexport interface FileSystemTraceStoreOptions {\n dir: string\n /** Max file size before rolling to a new segment (default 32 MB). */\n rolloverBytes?: number\n /** Function to write the file — defaults to node:fs/promises.appendFile */\n append?: (path: string, data: string) => Promise<void>\n read?: (path: string) => Promise<string>\n list?: (dir: string) => Promise<string[]>\n stat?: (path: string) => Promise<{ size: number }>\n mkdir?: (dir: string) => Promise<void>\n}\n\nexport class FileSystemTraceStore implements TraceStore {\n private readonly opts: Required<FileSystemTraceStoreOptions>\n\n constructor(opts: FileSystemTraceStoreOptions) {\n this.opts = {\n rolloverBytes: 32 * 1024 * 1024,\n append: defaultAppend,\n read: defaultRead,\n list: defaultList,\n stat: defaultStat,\n mkdir: defaultMkdir,\n ...opts,\n }\n }\n\n async record(trace: LlmTrace): Promise<void> {\n const file = await this.currentSegment()\n await this.opts.append(file, JSON.stringify(trace) + '\\n')\n }\n\n async query(query: TraceQuery): Promise<LlmTrace[]> {\n const files = await this.segments()\n const out: LlmTrace[] = []\n for (const file of files) {\n const contents = await this.opts.read(file).catch(() => '')\n for (const line of contents.split('\\n')) {\n if (!line) continue\n try {\n const t = JSON.parse(line) as LlmTrace\n if (!matches(t, query)) continue\n out.push(t)\n if (query.limit !== undefined && out.length >= query.limit) return out\n } catch {\n // skip malformed line\n }\n }\n }\n return out\n }\n\n async count(query?: TraceQuery): Promise<number> {\n if (!query) {\n // Fast path: sum line counts across segments\n const files = await this.segments()\n let total = 0\n for (const file of files) {\n const contents = await this.opts.read(file).catch(() => '')\n total += contents.split('\\n').filter(Boolean).length\n }\n return total\n }\n return (await this.query(query)).length\n }\n\n private async segments(): Promise<string[]> {\n try {\n const all = await this.opts.list(this.opts.dir)\n return all.filter((f) => f.endsWith('.ndjson')).sort()\n } catch {\n return []\n }\n }\n\n private async currentSegment(): Promise<string> {\n await this.opts.mkdir(this.opts.dir)\n const existing = await this.segments()\n if (existing.length === 0) return pathJoin(this.opts.dir, `traces-000.ndjson`)\n const latest = existing[existing.length - 1]\n try {\n const s = await this.opts.stat(latest)\n if (s.size < this.opts.rolloverBytes) return latest\n } catch {\n return latest\n }\n const n = existing.length\n return pathJoin(this.opts.dir, `traces-${String(n).padStart(3, '0')}.ndjson`)\n }\n}\n\nfunction matches(t: LlmTrace, query: TraceQuery): boolean {\n if (query.runId && t.runId !== query.runId) return false\n if (query.scenarioId && t.scenarioId !== query.scenarioId) return false\n if (query.role && t.role !== query.role) return false\n if (query.model && t.model !== query.model) return false\n if (query.sinceMs !== undefined) {\n const ts = Date.parse(t.timestamp)\n if (Number.isFinite(ts) && ts < query.sinceMs) return false\n }\n return true\n}\n\nfunction pathJoin(dir: string, file: string): string {\n return dir.endsWith('/') ? `${dir}${file}` : `${dir}/${file}`\n}\n\n// Default fs shim — dynamic import so the package stays importable in Workers\nasync function defaultAppend(path: string, data: string): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.appendFile(path, data)\n}\nasync function defaultRead(path: string): Promise<string> {\n const fs = await import('node:fs/promises')\n return fs.readFile(path, 'utf8')\n}\nasync function defaultList(dir: string): Promise<string[]> {\n const fs = await import('node:fs/promises')\n const p = await import('node:path')\n try {\n const entries = await fs.readdir(dir)\n return entries.map((e) => p.join(dir, e))\n } catch {\n return []\n }\n}\nasync function defaultStat(path: string): Promise<{ size: number }> {\n const fs = await import('node:fs/promises')\n const s = await fs.stat(path)\n return { size: s.size }\n}\nasync function defaultMkdir(dir: string): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.mkdir(dir, { recursive: true })\n}\n","/**\n * Anti-slop quality judge.\n *\n * Deterministic pattern-based quality check — no LLM call. Catches the\n * 80% of AI slop that every production agent leaks:\n * - Banned phrases (voice-specific: \"delve\", \"it's worth noting\", etc.)\n * - N-gram repetition (same phrase over and over)\n * - Hedging overuse (\"I could be wrong, but...\")\n * - Apology padding (\"I'm so sorry for the confusion...\")\n * - Unused opening formulas (\"Great question!\")\n * - Length bounds (too short to be useful, too long to be read)\n *\n * Produces a JudgeScore in the same shape as LLM judges so it composes into\n * `BenchmarkRunner`'s judge array transparently.\n */\n\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\nexport interface AntiSlopConfig {\n /** Domain label — appears in the JudgeScore output */\n domain?: string\n\n /** Case-insensitive substrings that must not appear. Each occurrence = penalty. */\n bannedPhrases?: string[]\n\n /** Regexes matching opening formulas to penalize (e.g. /^great question/i). */\n bannedOpenings?: RegExp[]\n\n /** Regexes matching hedges (e.g. /i could be wrong/i). Ratio of hedged sentences drives score. */\n hedgingPatterns?: RegExp[]\n\n /** Regexes matching apology padding. */\n apologyPatterns?: RegExp[]\n\n /** Fraction of sentences that can be duplicates before penalty (default 0.15 = 15%). */\n repetitionThreshold?: number\n\n /** Min output length in chars; below this the turn is deemed too terse. */\n minLength?: number\n\n /** Max output length in chars; above this the turn is deemed too verbose. */\n maxLength?: number\n\n /** How heavily each violation class reduces the score (default 1). */\n penaltyWeights?: Partial<Record<SlopCategory, number>>\n}\n\nexport type SlopCategory =\n | 'banned_phrase'\n | 'banned_opening'\n | 'hedging'\n | 'apology'\n | 'repetition'\n | 'length'\n\nconst DEFAULT_HEDGES: RegExp[] = [\n /\\bi\\s+could\\s+be\\s+wrong\\b/i,\n /\\bi\\s+think\\s+maybe\\b/i,\n /\\bit\\s+might\\s+be\\s+that\\b/i,\n /\\bperhaps\\s+(?:you\\s+)?could\\b/i,\n]\n\nconst DEFAULT_APOLOGIES: RegExp[] = [\n /\\bi\\s+(?:apologize|apologise)\\s+(?:for|if)\\b/i,\n /\\bi'?m\\s+(?:so\\s+|really\\s+)?sorry\\s+(?:for|if|about)\\b/i,\n /\\bmy\\s+apologies\\b/i,\n]\n\n/** Create a reusable Judge function from an anti-slop config. */\nexport function createAntiSlopJudge(config: AntiSlopConfig = {}): JudgeFn {\n const conf: Required<Omit<AntiSlopConfig, 'penaltyWeights'>> & {\n penaltyWeights: Record<SlopCategory, number>\n } = {\n domain: config.domain ?? 'general',\n bannedPhrases: config.bannedPhrases ?? [],\n bannedOpenings: config.bannedOpenings ?? [],\n hedgingPatterns: config.hedgingPatterns ?? DEFAULT_HEDGES,\n apologyPatterns: config.apologyPatterns ?? DEFAULT_APOLOGIES,\n repetitionThreshold: config.repetitionThreshold ?? 0.15,\n minLength: config.minLength ?? 20,\n maxLength: config.maxLength ?? 8000,\n penaltyWeights: {\n banned_phrase: 1,\n banned_opening: 1,\n hedging: 0.5,\n apology: 0.5,\n repetition: 0.75,\n length: 0.5,\n ...config.penaltyWeights,\n },\n }\n\n const judge: JudgeFn = async (_tc, input: JudgeInput): Promise<JudgeScore[]> => {\n const outputs = input.turns.map((t) => t.agentResponse ?? '')\n const report = analyzeAntiSlop(outputs, conf)\n return [\n {\n judgeName: `anti-slop(${conf.domain})`,\n dimension: 'anti_slop',\n score: report.score,\n reasoning: report.issues.length\n ? report.issues.slice(0, 5).map((i) => `${i.category}: ${i.detail}`).join('; ')\n : 'No slop patterns detected.',\n evidence: report.issues[0]?.example,\n },\n ]\n }\n return judge\n}\n\nexport interface AntiSlopIssue {\n category: SlopCategory\n detail: string\n example?: string\n}\n\nexport interface AntiSlopReport {\n /** 0–10 score; 10 is clean, lower values mean more slop. */\n score: number\n issues: AntiSlopIssue[]\n /** Count of each category for programmatic aggregation. */\n counts: Record<SlopCategory, number>\n}\n\n/**\n * Pure function — analyze one or more outputs against the config. Exposed\n * separately so consumers can build their own reporters on top.\n */\nexport function analyzeAntiSlop(\n outputs: string[],\n config: Omit<Required<AntiSlopConfig>, 'domain'> & { penaltyWeights: Record<SlopCategory, number> },\n): AntiSlopReport {\n const issues: AntiSlopIssue[] = []\n const counts: Record<SlopCategory, number> = {\n banned_phrase: 0,\n banned_opening: 0,\n hedging: 0,\n apology: 0,\n repetition: 0,\n length: 0,\n }\n\n for (const output of outputs) {\n if (!output) continue\n const lower = output.toLowerCase()\n\n for (const phrase of config.bannedPhrases) {\n const needle = phrase.toLowerCase()\n let idx = 0\n while ((idx = lower.indexOf(needle, idx)) !== -1) {\n counts.banned_phrase += 1\n if (issues.length < 20) {\n issues.push({\n category: 'banned_phrase',\n detail: `\"${phrase}\"`,\n example: snippet(output, idx, phrase.length),\n })\n }\n idx += needle.length\n }\n }\n\n for (const re of config.bannedOpenings) {\n if (re.test(output)) {\n counts.banned_opening += 1\n issues.push({ category: 'banned_opening', detail: re.source, example: output.slice(0, 80) })\n }\n }\n\n for (const re of config.hedgingPatterns) {\n const matches = output.match(new RegExp(re, re.flags.includes('g') ? re.flags : re.flags + 'g'))\n if (matches) {\n counts.hedging += matches.length\n issues.push({\n category: 'hedging',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n for (const re of config.apologyPatterns) {\n const matches = output.match(new RegExp(re, re.flags.includes('g') ? re.flags : re.flags + 'g'))\n if (matches) {\n counts.apology += matches.length\n issues.push({\n category: 'apology',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n // Repetition: compare sentence-level dupes\n const sentences = splitSentences(output)\n if (sentences.length >= 4) {\n const seen = new Map<string, number>()\n for (const s of sentences) {\n const key = normalizeForDupe(s)\n if (!key) continue\n seen.set(key, (seen.get(key) ?? 0) + 1)\n }\n let dupes = 0\n for (const n of seen.values()) if (n > 1) dupes += n - 1\n const ratio = dupes / sentences.length\n if (ratio > config.repetitionThreshold) {\n counts.repetition += 1\n issues.push({\n category: 'repetition',\n detail: `${(ratio * 100).toFixed(0)}% duplicated (threshold ${(config.repetitionThreshold * 100).toFixed(0)}%)`,\n })\n }\n }\n\n // Length\n if (output.length < config.minLength) {\n counts.length += 1\n issues.push({ category: 'length', detail: `too short (${output.length} < ${config.minLength})` })\n } else if (output.length > config.maxLength) {\n counts.length += 1\n issues.push({ category: 'length', detail: `too long (${output.length} > ${config.maxLength})` })\n }\n }\n\n // Score: 10 minus weighted violations, clamped. Each violation of category c\n // subtracts `penaltyWeights[c]` points. Violations beyond 10/weight saturate.\n let penalty = 0\n for (const cat of Object.keys(counts) as SlopCategory[]) {\n penalty += counts[cat] * (config.penaltyWeights[cat] ?? 1)\n }\n const score = Math.max(0, Math.min(10, 10 - penalty))\n\n return { score, issues, counts }\n}\n\nfunction snippet(source: string, at: number, len: number): string {\n const pad = 24\n const start = Math.max(0, at - pad)\n const end = Math.min(source.length, at + len + pad)\n return (start > 0 ? '…' : '') + source.slice(start, end) + (end < source.length ? '…' : '')\n}\n\nfunction splitSentences(text: string): string[] {\n // Simple sentence split — good enough for slop detection; not linguistically perfect.\n return text\n .split(/[.!?\\n]+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n}\n\nfunction normalizeForDupe(s: string): string {\n return s\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .replace(/[^a-z0-9 ]/g, '')\n .trim()\n}\n","/**\n * Artifact validators.\n *\n * Generic \"score a produced artifact\" primitive. Tax uses it for PDF form\n * correctness, legal for contract clauses, film for script breakdowns, GTM\n * for social posts. One interface, many validators; all plug into\n * `BenchmarkRunner` the same way.\n *\n * A validator receives an `Artifact` (file on disk, JSON blob, text, binary)\n * plus a `ValidationContext` (scenario id, the turns that produced it) and\n * returns a `ValidationResult` with pass/fail + 0..1 score + structured\n * issues.\n */\n\nexport interface Artifact {\n /** Logical kind — validators type-guard on this */\n kind: 'file' | 'json' | 'text' | 'binary' | string\n /** Filesystem-style path, optional */\n path?: string\n /** String content for text/json/file kinds */\n content?: string\n /** Binary content (if kind === 'binary') */\n bytes?: Uint8Array\n /** Caller-supplied metadata (mimeType, sha256, size, etc.) */\n metadata?: Record<string, unknown>\n}\n\nexport interface ValidationContext {\n scenarioId: string\n turnIndex?: number\n /** Prior artifacts for multi-artifact scenarios */\n priorArtifacts?: Artifact[]\n /** Free-form hints the validator uses for domain-specific checks */\n hints?: Record<string, unknown>\n}\n\nexport interface ValidationIssue {\n severity: 'error' | 'warning' | 'info'\n message: string\n /** Optional path into the artifact (e.g. JSON path or byte offset) */\n locus?: string\n}\n\nexport interface ValidationResult {\n pass: boolean\n /** 0–1 normalized score. Validators should be monotonic in pass-ness. */\n score: number\n issues: ValidationIssue[]\n /** Diagnostic payload for reporters */\n evidence?: Record<string, unknown>\n}\n\nexport interface ArtifactValidator {\n /** Stable identifier for the validator; appears in reports. */\n name: string\n /** Optional description for human-facing reports. */\n description?: string\n /** Called once per artifact; validators are expected to be pure + idempotent. */\n validate(artifact: Artifact, context: ValidationContext): Promise<ValidationResult>\n}\n\n// ---------------------------------------------------------------------------\n// Composable validators\n// ---------------------------------------------------------------------------\n\n/**\n * Run every validator on the same artifact; aggregate pass as AND, score as\n * (weighted) mean, issues concatenated. Weights default to 1 each.\n */\nexport function composeValidators(\n validators: ArtifactValidator[],\n options?: { name?: string; weights?: number[] },\n): ArtifactValidator {\n const weights = options?.weights ?? validators.map(() => 1)\n if (weights.length !== validators.length) {\n throw new Error('composeValidators: weights length mismatch')\n }\n const totalWeight = weights.reduce((a, b) => a + b, 0) || 1\n return {\n name: options?.name ?? validators.map((v) => v.name).join('+'),\n async validate(artifact, ctx) {\n const results = await Promise.all(validators.map((v) => v.validate(artifact, ctx)))\n const pass = results.every((r) => r.pass)\n const score =\n results.reduce((acc, r, i) => acc + r.score * weights[i], 0) / totalWeight\n return {\n pass,\n score,\n issues: results.flatMap((r, i) =>\n r.issues.map((issue) => ({\n ...issue,\n locus: issue.locus ? `${validators[i].name}:${issue.locus}` : validators[i].name,\n })),\n ),\n evidence: Object.fromEntries(results.map((r, i) => [validators[i].name, r.evidence])),\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Built-in validators\n// ---------------------------------------------------------------------------\n\n/** Pass if the artifact body matches a provided regex. */\nexport function regexMatch(name: string, pattern: RegExp): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const body = artifact.content ?? ''\n const ok = pattern.test(body)\n return {\n pass: ok,\n score: ok ? 1 : 0,\n issues: ok\n ? []\n : [{ severity: 'error', message: `Artifact content did not match ${pattern}` }],\n }\n },\n }\n}\n\n/** Pass if JSON parses and every required key is present. */\nexport function jsonHasKeys(name: string, requiredPaths: string[]): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const body = artifact.content ?? ''\n let parsed: unknown\n try {\n parsed = JSON.parse(body) as unknown\n } catch (err) {\n return {\n pass: false,\n score: 0,\n issues: [{ severity: 'error', message: `Invalid JSON: ${err instanceof Error ? err.message : err}` }],\n }\n }\n const missing: string[] = []\n for (const path of requiredPaths) {\n if (!pathExists(parsed, path)) missing.push(path)\n }\n const pass = missing.length === 0\n return {\n pass,\n score: 1 - missing.length / Math.max(1, requiredPaths.length),\n issues: missing.map((p) => ({ severity: 'error' as const, message: `Missing path: ${p}`, locus: p })),\n }\n },\n }\n}\n\n/** Pass if min ≤ byte length ≤ max. */\nexport function byteLengthRange(name: string, min: number, max: number): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const size = artifact.bytes?.byteLength ?? new TextEncoder().encode(artifact.content ?? '').byteLength\n const pass = size >= min && size <= max\n const score = pass\n ? 1\n : size < min\n ? Math.max(0, size / min)\n : Math.max(0, max / size)\n return {\n pass,\n score,\n issues: pass\n ? []\n : [{ severity: 'error', message: `Size ${size} outside [${min}, ${max}]` }],\n }\n },\n }\n}\n\n/** Pass if the artifact contains every required substring (case-insensitive by default). */\nexport function containsAll(\n name: string,\n required: string[],\n options?: { caseSensitive?: boolean },\n): ArtifactValidator {\n const cs = options?.caseSensitive ?? false\n return {\n name,\n async validate(artifact) {\n const body = cs ? artifact.content ?? '' : (artifact.content ?? '').toLowerCase()\n const missing: string[] = []\n for (const needle of required) {\n const probe = cs ? needle : needle.toLowerCase()\n if (!body.includes(probe)) missing.push(needle)\n }\n const pass = missing.length === 0\n return {\n pass,\n score: 1 - missing.length / Math.max(1, required.length),\n issues: missing.map((m) => ({ severity: 'error' as const, message: `Missing substring: ${m}` })),\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction pathExists(obj: unknown, path: string): boolean {\n const parts = path.split('.')\n let current: unknown = obj\n for (const part of parts) {\n if (current === null || typeof current !== 'object') return false\n const key = /^\\d+$/.test(part) ? Number(part) : part\n current = (current as Record<string, unknown>)[key as unknown as string]\n if (current === undefined) return false\n }\n return true\n}\n","/**\n * Workspace inspector — score the persisted state of an agent after a run.\n *\n * Many evals don't ask \"did the response say the right thing\" but \"did the\n * agent put the right rows in the DB / files in the vault / entities on the\n * canvas\". This is the primitive for that.\n *\n * Implementations read from D1, KV, filesystem, or any store — the interface\n * is deliberately small so consumers plug in their own backends.\n */\n\nexport interface WorkspaceSnapshot {\n /** Vault files: logical path → content */\n files: Record<string, string>\n /** DB rows: table name → array of rows (post-validation) */\n rows: Record<string, Array<Record<string, unknown>>>\n /** KV entries: key → value (scoped to whatever prefix the inspector chose) */\n kv: Record<string, string>\n /** Free-form blob metadata: for large binaries the inspector stores summary, not bytes */\n blobs?: Record<string, { size: number; hash?: string; mimeType?: string }>\n}\n\nexport interface InspectorContext {\n /** Workspace / agent / thread id — whatever the backend uses to scope the snapshot */\n scopeId: string\n /** Optional scenario id — allows scenario-specific snapshot shaping */\n scenarioId?: string\n}\n\nexport interface WorkspaceInspector {\n name: string\n snapshot(context: InspectorContext): Promise<WorkspaceSnapshot>\n}\n\n// ---------------------------------------------------------------------------\n// In-memory inspector — useful for tests, not for production\n// ---------------------------------------------------------------------------\n\nexport class InMemoryWorkspaceInspector implements WorkspaceInspector {\n readonly name = 'in-memory'\n private readonly snapshots = new Map<string, WorkspaceSnapshot>()\n\n set(scopeId: string, snapshot: WorkspaceSnapshot): void {\n this.snapshots.set(scopeId, snapshot)\n }\n\n async snapshot(context: InspectorContext): Promise<WorkspaceSnapshot> {\n return (\n this.snapshots.get(context.scopeId) ?? { files: {}, rows: {}, kv: {} }\n )\n }\n}\n\n// ---------------------------------------------------------------------------\n// Snapshot-level assertions\n// ---------------------------------------------------------------------------\n\nexport interface WorkspaceAssertion {\n name: string\n description?: string\n check(snapshot: WorkspaceSnapshot): WorkspaceAssertionResult\n}\n\nexport interface WorkspaceAssertionResult {\n pass: boolean\n /** 0..1 — partial credit for assertions that admit it */\n score: number\n detail?: string\n}\n\nexport function fileExists(path: string): WorkspaceAssertion {\n return {\n name: `file_exists:${path}`,\n check(snapshot) {\n const pass = path in snapshot.files\n return {\n pass,\n score: pass ? 1 : 0,\n detail: pass ? undefined : `No file at ${path}`,\n }\n },\n }\n}\n\nexport function fileContains(path: string, needle: string): WorkspaceAssertion {\n return {\n name: `file_contains:${path}:${needle}`,\n check(snapshot) {\n const content = snapshot.files[path]\n if (content === undefined) {\n return { pass: false, score: 0, detail: `File ${path} missing` }\n }\n const pass = content.includes(needle)\n return { pass, score: pass ? 1 : 0, detail: pass ? undefined : `File ${path} missing substring \"${needle}\"` }\n },\n }\n}\n\nexport function rowCount(table: string, min: number, max?: number): WorkspaceAssertion {\n return {\n name: `row_count:${table}:[${min},${max ?? '∞'}]`,\n check(snapshot) {\n const rows = snapshot.rows[table] ?? []\n const count = rows.length\n const upper = max ?? Infinity\n const pass = count >= min && count <= upper\n const score = pass\n ? 1\n : count < min\n ? Math.max(0, count / min)\n : Math.max(0, upper / count)\n return {\n pass,\n score,\n detail: pass\n ? undefined\n : `Table ${table} has ${count} rows, expected [${min}, ${max ?? '∞'}]`,\n }\n },\n }\n}\n\nexport function rowWhere<T extends Record<string, unknown>>(\n table: string,\n predicate: (row: T) => boolean,\n options?: { min?: number },\n): WorkspaceAssertion {\n const min = options?.min ?? 1\n return {\n name: `row_where:${table}`,\n check(snapshot) {\n const rows = (snapshot.rows[table] ?? []) as T[]\n const matching = rows.filter(predicate).length\n const pass = matching >= min\n return {\n pass,\n score: pass ? 1 : Math.max(0, matching / min),\n detail: pass ? undefined : `Table ${table} has ${matching} matching rows, expected ≥ ${min}`,\n }\n },\n }\n}\n\n/** Run many assertions; return aggregate pass + mean score + per-assertion details. */\nexport function runAssertions(\n snapshot: WorkspaceSnapshot,\n assertions: WorkspaceAssertion[],\n): {\n pass: boolean\n score: number\n results: Array<{ assertion: string; result: WorkspaceAssertionResult }>\n} {\n const results = assertions.map((a) => ({ assertion: a.name, result: a.check(snapshot) }))\n const pass = results.every((r) => r.result.pass)\n const score = results.length\n ? results.reduce((acc, r) => acc + r.result.score, 0) / results.length\n : 1\n return { pass, score, results }\n}\n","/**\n * Experiment tracker — group runs, diff them, watch scores move over time.\n *\n * Not MLflow. Not Weights & Biases. Just the 20% that actually ships:\n * - A run has a config (prompt hash, model, scenario ids, seed)\n * - Runs belong to experiments (named groups)\n * - The store is pluggable (in-memory for tests, filesystem for local,\n * custom for Langfuse/D1)\n * - Diffs show score deltas, new/dropped scenarios, and config changes\n *\n * The output plugs directly into `BenchmarkReport` — runs archive the full\n * report, diff operates on the summary.\n */\n\nimport type { BenchmarkReport } from './types'\n\nexport interface RunConfig {\n experimentId: string\n name?: string\n model?: string\n promptHash?: string\n promptVersion?: string\n seed?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface Run {\n id: string\n experimentId: string\n name?: string\n config: RunConfig\n startedAt: string\n completedAt?: string\n status: 'running' | 'completed' | 'failed'\n report?: BenchmarkReport\n error?: string\n}\n\nexport interface Experiment {\n id: string\n name: string\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface ExperimentStore {\n saveExperiment(exp: Experiment): Promise<void>\n getExperiment(id: string): Promise<Experiment | null>\n listExperiments(): Promise<Experiment[]>\n saveRun(run: Run): Promise<void>\n getRun(id: string): Promise<Run | null>\n listRuns(experimentId: string): Promise<Run[]>\n}\n\nexport class InMemoryExperimentStore implements ExperimentStore {\n private readonly experiments = new Map<string, Experiment>()\n private readonly runs = new Map<string, Run>()\n\n async saveExperiment(exp: Experiment): Promise<void> {\n this.experiments.set(exp.id, { ...exp })\n }\n async getExperiment(id: string): Promise<Experiment | null> {\n const e = this.experiments.get(id)\n return e ? { ...e } : null\n }\n async listExperiments(): Promise<Experiment[]> {\n return [...this.experiments.values()].sort((a, b) => b.createdAt.localeCompare(a.createdAt))\n }\n async saveRun(run: Run): Promise<void> {\n this.runs.set(run.id, structuredClone(run))\n }\n async getRun(id: string): Promise<Run | null> {\n const r = this.runs.get(id)\n return r ? structuredClone(r) : null\n }\n async listRuns(experimentId: string): Promise<Run[]> {\n return [...this.runs.values()]\n .filter((r) => r.experimentId === experimentId)\n .sort((a, b) => b.startedAt.localeCompare(a.startedAt))\n .map((r) => structuredClone(r))\n }\n}\n\n// ---------------------------------------------------------------------------\n// The tracker itself\n// ---------------------------------------------------------------------------\n\nexport class ExperimentTracker {\n constructor(private readonly store: ExperimentStore) {}\n\n async startExperiment(name: string, metadata?: Record<string, unknown>): Promise<Experiment> {\n const exp: Experiment = {\n id: `exp_${rand(8)}`,\n name,\n createdAt: new Date().toISOString(),\n metadata,\n }\n await this.store.saveExperiment(exp)\n return exp\n }\n\n async startRun(config: RunConfig): Promise<Run> {\n const exp = await this.store.getExperiment(config.experimentId)\n if (!exp) throw new Error(`Experiment ${config.experimentId} not found`)\n\n const run: Run = {\n id: `run_${rand(10)}`,\n experimentId: config.experimentId,\n name: config.name,\n config,\n startedAt: new Date().toISOString(),\n status: 'running',\n }\n await this.store.saveRun(run)\n return run\n }\n\n async completeRun(runId: string, report: BenchmarkReport): Promise<void> {\n const run = await this.store.getRun(runId)\n if (!run) throw new Error(`Run ${runId} not found`)\n run.status = 'completed'\n run.completedAt = new Date().toISOString()\n run.report = report\n await this.store.saveRun(run)\n }\n\n async failRun(runId: string, error: string): Promise<void> {\n const run = await this.store.getRun(runId)\n if (!run) throw new Error(`Run ${runId} not found`)\n run.status = 'failed'\n run.completedAt = new Date().toISOString()\n run.error = error\n await this.store.saveRun(run)\n }\n\n /**\n * Diff two completed runs. Returns per-scenario deltas, aggregate delta,\n * and config changes that may explain the movement.\n */\n async diff(runIdA: string, runIdB: string): Promise<RunDiff> {\n const [a, b] = await Promise.all([this.store.getRun(runIdA), this.store.getRun(runIdB)])\n if (!a || !b) throw new Error('Both runs must exist')\n if (!a.report || !b.report) throw new Error('Both runs must be completed with reports')\n\n const byScenarioA = new Map(a.report.results.map((r) => [r.scenarioId, r.overallScore]))\n const byScenarioB = new Map(b.report.results.map((r) => [r.scenarioId, r.overallScore]))\n\n const scenarioIds = new Set([...byScenarioA.keys(), ...byScenarioB.keys()])\n const scenarios: RunDiff['scenarios'] = []\n for (const id of scenarioIds) {\n const aScore = byScenarioA.get(id)\n const bScore = byScenarioB.get(id)\n if (aScore === undefined) {\n scenarios.push({ scenarioId: id, before: null, after: bScore!, delta: null, status: 'added' })\n } else if (bScore === undefined) {\n scenarios.push({ scenarioId: id, before: aScore, after: null, delta: null, status: 'removed' })\n } else {\n scenarios.push({\n scenarioId: id,\n before: aScore,\n after: bScore,\n delta: bScore - aScore,\n status: bScore > aScore ? 'improved' : bScore < aScore ? 'regressed' : 'unchanged',\n })\n }\n }\n scenarios.sort((x, y) => (y.delta ?? 0) - (x.delta ?? 0))\n\n const aggregateDelta = b.report.summary.overallAvg - a.report.summary.overallAvg\n const configChanges: Record<string, { before: unknown; after: unknown }> = {}\n const keys = new Set([...Object.keys(a.config), ...Object.keys(b.config)])\n const aCfg = a.config as unknown as Record<string, unknown>\n const bCfg = b.config as unknown as Record<string, unknown>\n for (const k of keys) {\n if (JSON.stringify(aCfg[k]) !== JSON.stringify(bCfg[k])) {\n configChanges[k] = { before: aCfg[k], after: bCfg[k] }\n }\n }\n\n return {\n before: { runId: runIdA, name: a.name, startedAt: a.startedAt },\n after: { runId: runIdB, name: b.name, startedAt: b.startedAt },\n aggregateDelta,\n scenarios,\n configChanges,\n }\n }\n\n /** Timeline of aggregate scores for an experiment. */\n async timeline(experimentId: string): Promise<Array<{ runId: string; startedAt: string; overall: number | null }>> {\n const runs = await this.store.listRuns(experimentId)\n return runs\n .slice()\n .sort((a, b) => a.startedAt.localeCompare(b.startedAt))\n .map((r) => ({\n runId: r.id,\n startedAt: r.startedAt,\n overall: r.report?.summary.overallAvg ?? null,\n }))\n }\n}\n\nexport interface RunDiff {\n before: { runId: string; name?: string; startedAt: string }\n after: { runId: string; name?: string; startedAt: string }\n aggregateDelta: number\n scenarios: Array<{\n scenarioId: string\n before: number | null\n after: number | null\n delta: number | null\n status: 'improved' | 'regressed' | 'unchanged' | 'added' | 'removed'\n }>\n configChanges: Record<string, { before: unknown; after: unknown }>\n}\n\nfunction rand(bytes: number): string {\n const arr = new Uint8Array(bytes)\n crypto.getRandomValues(arr)\n return Array.from(arr).map((b) => b.toString(16).padStart(2, '0')).join('')\n}\n","/**\n * Prompt optimizer — A/B test prompt variants with statistical rigor.\n *\n * Runs N prompt variants against a fixed scenario set, collects per-scenario\n * scores via the user-provided `scoreVariant` callback, and returns:\n * - per-variant mean + bootstrap CI\n * - pairwise significance (Mann-Whitney, non-parametric — works on any\n * score distribution, not just normal)\n * - a winner (highest mean, flagged if the lead is not significant)\n *\n * Deliberately generic — the `scoreVariant` callback does whatever domain\n * work the consumer needs (invoke the agent, judge the output, whatever),\n * and returns a number per scenario. This lets the optimizer stay small +\n * testable.\n */\n\nimport { confidenceInterval, mannWhitneyU } from './statistics'\n\nexport interface PromptVariant {\n id: string\n prompt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface OptimizationConfig {\n variants: PromptVariant[]\n /** How many trials per (variant, scenario) — controls CI tightness. Default 3. */\n trialsPerScenario?: number\n /** Significance threshold for pairwise comparison (default 0.05). */\n significanceLevel?: number\n /**\n * The scoring callback. For each (variant, scenarioId, trialIndex), produce\n * a score in 0..1 (or any numeric range — the optimizer only cares about\n * monotonicity).\n */\n scoreVariant: (args: {\n variant: PromptVariant\n scenarioId: string\n trialIndex: number\n }) => Promise<number>\n /** Scenario ids to run against. */\n scenarioIds: string[]\n /** Optional hook — fires after each (variant, scenario) fully scored. */\n onScenarioComplete?: (info: {\n variantId: string\n scenarioId: string\n scores: number[]\n }) => void\n}\n\nexport interface VariantScore {\n variantId: string\n mean: number\n ci95: { lower: number; upper: number }\n n: number\n perScenario: Record<string, { mean: number; n: number; samples: number[] }>\n}\n\nexport interface PairwiseComparison {\n variantA: string\n variantB: string\n pValue: number\n significant: boolean\n meanDelta: number\n}\n\nexport interface OptimizationResult {\n winner: {\n variantId: string\n /** True when the winner's lead vs every other variant is statistically significant. */\n significant: boolean\n ciLowerBoundExceedsSecondMean: boolean\n }\n scores: VariantScore[]\n pairwise: PairwiseComparison[]\n config: {\n trialsPerScenario: number\n significanceLevel: number\n variants: string[]\n scenarios: string[]\n }\n}\n\nexport class PromptOptimizer {\n async run(config: OptimizationConfig): Promise<OptimizationResult> {\n const trials = config.trialsPerScenario ?? 3\n const alpha = config.significanceLevel ?? 0.05\n\n if (config.variants.length < 2) {\n throw new Error('PromptOptimizer requires at least 2 variants')\n }\n if (config.scenarioIds.length === 0) {\n throw new Error('PromptOptimizer requires at least 1 scenario')\n }\n\n // Collect scores for every (variant, scenario, trial).\n const rawScores = new Map<string, Map<string, number[]>>() // variantId → scenarioId → samples\n\n for (const variant of config.variants) {\n const scenarioMap = new Map<string, number[]>()\n rawScores.set(variant.id, scenarioMap)\n\n for (const scenarioId of config.scenarioIds) {\n const samples: number[] = []\n for (let t = 0; t < trials; t++) {\n const score = await config.scoreVariant({\n variant,\n scenarioId,\n trialIndex: t,\n })\n if (!Number.isFinite(score)) {\n throw new Error(`scoreVariant returned non-finite: variant=${variant.id} scenario=${scenarioId} trial=${t}`)\n }\n samples.push(score)\n }\n scenarioMap.set(scenarioId, samples)\n config.onScenarioComplete?.({\n variantId: variant.id,\n scenarioId,\n scores: samples,\n })\n }\n }\n\n // Build per-variant VariantScore.\n const scores: VariantScore[] = config.variants.map((variant) => {\n const scenarioMap = rawScores.get(variant.id)!\n const allSamples: number[] = []\n const perScenario: VariantScore['perScenario'] = {}\n for (const scenarioId of config.scenarioIds) {\n const samples = scenarioMap.get(scenarioId) ?? []\n allSamples.push(...samples)\n perScenario[scenarioId] = {\n mean: samples.length ? samples.reduce((a, b) => a + b, 0) / samples.length : 0,\n n: samples.length,\n samples,\n }\n }\n const ci = confidenceInterval(allSamples, 0.95)\n return {\n variantId: variant.id,\n mean: ci.mean,\n ci95: { lower: ci.lower, upper: ci.upper },\n n: allSamples.length,\n perScenario,\n }\n })\n\n // Pairwise comparisons.\n const pairwise: PairwiseComparison[] = []\n for (let i = 0; i < scores.length; i++) {\n for (let j = i + 1; j < scores.length; j++) {\n const a = scores[i]\n const b = scores[j]\n const samplesA = flatSamples(a)\n const samplesB = flatSamples(b)\n const { p } = mannWhitneyU(samplesA, samplesB)\n pairwise.push({\n variantA: a.variantId,\n variantB: b.variantId,\n pValue: p,\n significant: p < alpha,\n meanDelta: b.mean - a.mean,\n })\n }\n }\n\n // Winner: highest mean. Flag significance if the winner beats every other\n // variant at the alpha threshold in its pairwise comparison.\n const sorted = scores.slice().sort((x, y) => y.mean - x.mean)\n const winner = sorted[0]\n const second = sorted[1]\n const winnerComparisons = pairwise.filter(\n (c) => c.variantA === winner.variantId || c.variantB === winner.variantId,\n )\n const significantOverAll = winnerComparisons.every((c) => c.significant)\n const ciLowerBoundExceedsSecondMean = winner.ci95.lower > second.mean\n\n return {\n winner: {\n variantId: winner.variantId,\n significant: significantOverAll,\n ciLowerBoundExceedsSecondMean,\n },\n scores,\n pairwise,\n config: {\n trialsPerScenario: trials,\n significanceLevel: alpha,\n variants: config.variants.map((v) => v.id),\n scenarios: config.scenarioIds,\n },\n }\n }\n}\n\nfunction flatSamples(score: VariantScore): number[] {\n const out: number[] = []\n for (const s of Object.values(score.perScenario)) out.push(...s.samples)\n return out\n}\n","/**\n * Dual-agent convergence bench.\n *\n * Pattern lifted from tax-agent + legal-agent: two agents take turns until\n * they converge on a consensus artifact. One proposes, the other critiques;\n * the proposer revises; repeat until a score threshold is hit or max rounds.\n *\n * Generalized so any two \"agents\" (gateways, local functions, anything with\n * `propose` + `critique`) compose in. Returns convergence rounds per\n * scenario + whether convergence happened.\n */\n\nexport interface DualAgentScenario {\n id: string\n initialPrompt: string\n /** Optional context the agents can read (e.g. source documents). */\n context?: Record<string, unknown>\n}\n\nexport interface DualAgentRound {\n roundIndex: number\n proposal: string\n critique: string\n convergenceScore: number // 0..1 — how close to convergence\n}\n\nexport interface DualAgentScenarioResult {\n scenarioId: string\n converged: boolean\n roundsToConverge: number | null\n finalProposal: string\n history: DualAgentRound[]\n finalScore: number\n}\n\nexport interface DualAgentBenchConfig {\n scenarios: DualAgentScenario[]\n maxRounds?: number\n /** Convergence threshold in 0..1 (default 0.85). */\n convergenceThreshold?: number\n /**\n * Propose an answer given the scenario + the critic's prior critique (if any).\n * Returns the proposal string.\n */\n propose: (args: {\n scenario: DualAgentScenario\n roundIndex: number\n priorProposal?: string\n priorCritique?: string\n }) => Promise<string>\n /**\n * Critique the proposer's current output. Returns a structured critique\n * (free text) plus a convergence score: how close the proposal is to\n * acceptable. 1.0 = accept, 0.0 = totally off.\n */\n critique: (args: {\n scenario: DualAgentScenario\n roundIndex: number\n proposal: string\n }) => Promise<{ critique: string; convergenceScore: number }>\n /** Optional per-round hook for progress + tracing. */\n onRoundComplete?: (info: {\n scenarioId: string\n round: DualAgentRound\n }) => void\n}\n\nexport interface DualAgentReport {\n scenarios: DualAgentScenarioResult[]\n aggregate: {\n convergenceRate: number // fraction of scenarios that converged within maxRounds\n avgRoundsToConverge: number | null // over scenarios that DID converge\n avgFinalScore: number\n }\n config: {\n maxRounds: number\n convergenceThreshold: number\n }\n}\n\nexport class DualAgentBench {\n async run(config: DualAgentBenchConfig): Promise<DualAgentReport> {\n const maxRounds = config.maxRounds ?? 5\n const threshold = config.convergenceThreshold ?? 0.85\n\n if (config.scenarios.length === 0) {\n throw new Error('DualAgentBench requires at least 1 scenario')\n }\n\n const results: DualAgentScenarioResult[] = []\n\n for (const scenario of config.scenarios) {\n const history: DualAgentRound[] = []\n let converged = false\n let roundsToConverge: number | null = null\n let finalProposal = ''\n let lastScore = 0\n let priorCritique: string | undefined\n\n for (let r = 0; r < maxRounds; r++) {\n const priorProposal = history[history.length - 1]?.proposal\n const proposal = await config.propose({\n scenario,\n roundIndex: r,\n priorProposal,\n priorCritique,\n })\n const { critique, convergenceScore } = await config.critique({\n scenario,\n roundIndex: r,\n proposal,\n })\n\n if (!Number.isFinite(convergenceScore) || convergenceScore < 0 || convergenceScore > 1) {\n throw new Error(\n `critique must return convergenceScore in [0,1]; got ${convergenceScore} for scenario ${scenario.id} round ${r}`,\n )\n }\n\n const round: DualAgentRound = {\n roundIndex: r,\n proposal,\n critique,\n convergenceScore,\n }\n history.push(round)\n config.onRoundComplete?.({ scenarioId: scenario.id, round })\n\n finalProposal = proposal\n lastScore = convergenceScore\n priorCritique = critique\n\n if (convergenceScore >= threshold) {\n converged = true\n roundsToConverge = r + 1\n break\n }\n }\n\n results.push({\n scenarioId: scenario.id,\n converged,\n roundsToConverge,\n finalProposal,\n history,\n finalScore: lastScore,\n })\n }\n\n const convergedResults = results.filter((r) => r.converged)\n const convergenceRate = results.length ? convergedResults.length / results.length : 0\n const avgRoundsToConverge = convergedResults.length\n ? convergedResults.reduce((acc, r) => acc + (r.roundsToConverge ?? 0), 0) / convergedResults.length\n : null\n const avgFinalScore = results.length\n ? results.reduce((acc, r) => acc + r.finalScore, 0) / results.length\n : 0\n\n return {\n scenarios: results,\n aggregate: { convergenceRate, avgRoundsToConverge, avgFinalScore },\n config: { maxRounds, convergenceThreshold: threshold },\n }\n }\n}\n"],"mappings":"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","names":["i","matches"]}