@tangle-network/agent-eval 0.71.0 → 0.72.3
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/CHANGELOG.md +63 -0
- package/dist/adapters/http.d.ts +1 -1
- package/dist/adapters/langchain.d.ts +1 -1
- package/dist/adapters/otel.d.ts +3 -2
- package/dist/agent-profile-DYRboYWu.d.ts +364 -0
- package/dist/analyst/index.d.ts +221 -0
- package/dist/analyst/index.js +371 -0
- package/dist/analyst/index.js.map +1 -0
- package/dist/analyst-t7zZS3TV.d.ts +88 -0
- package/dist/campaign/index.d.ts +485 -9
- package/dist/campaign/index.js +618 -30
- package/dist/campaign/index.js.map +1 -1
- package/dist/chunk-7W4SM7FD.js +1075 -0
- package/dist/chunk-7W4SM7FD.js.map +1 -0
- package/dist/{chunk-AIWHLG7J.js → chunk-GJJNJVIR.js} +11 -11
- package/dist/chunk-JHA3ZGSO.js +1496 -0
- package/dist/chunk-JHA3ZGSO.js.map +1 -0
- package/dist/{chunk-VMAYE3LM.js → chunk-JYE3WOTE.js} +57 -9
- package/dist/{chunk-VMAYE3LM.js.map → chunk-JYE3WOTE.js.map} +1 -1
- package/dist/chunk-LB2UOI5F.js +412 -0
- package/dist/chunk-LB2UOI5F.js.map +1 -0
- package/dist/{chunk-ODGETRTM.js → chunk-VUINJM5M.js} +234 -1415
- package/dist/chunk-VUINJM5M.js.map +1 -0
- package/dist/chunk-WYIHD6EB.js +1044 -0
- package/dist/chunk-WYIHD6EB.js.map +1 -0
- package/dist/{chunk-6QZUCFKM.js → chunk-XPILG2CA.js} +120 -3
- package/dist/chunk-XPILG2CA.js.map +1 -0
- package/dist/{chunk-6XQIEUQ2.js → chunk-ZPSKPT3V.js} +5 -3
- package/dist/{chunk-6XQIEUQ2.js.map → chunk-ZPSKPT3V.js.map} +1 -1
- package/dist/contract/index.d.ts +17 -13
- package/dist/contract/index.js +14 -8
- package/dist/contract/index.js.map +1 -1
- package/dist/{control-DxvZeV5X.d.ts → control-BgA6BYTm.d.ts} +1 -1
- package/dist/control.d.ts +2 -2
- package/dist/{feedback-trajectory-8hKC5EOb.d.ts → feedback-trajectory-B3rErRsh.d.ts} +1 -1
- package/dist/harness-optimizer-EnEnQPsr.d.ts +106 -0
- package/dist/hosted/index.d.ts +223 -2
- package/dist/index.d.ts +49 -1323
- package/dist/index.js +339 -2627
- package/dist/index.js.map +1 -1
- package/dist/{index-BGBrVS24.d.ts → insight-report-Df3lxYXM.d.ts} +1 -221
- package/dist/kind-factory-DW9XWPvM.d.ts +172 -0
- package/dist/multi-layer-verifier-DlWCXuxL.d.ts +141 -0
- package/dist/openapi.json +1 -1
- package/dist/pareto-E-pembql.d.ts +81 -0
- package/dist/{provenance-C69gLUXH.d.ts → provenance-B-TFszPW.d.ts} +131 -4
- package/dist/redact-B40YG2M_.d.ts +45 -0
- package/dist/registry-DuVYiTvw.d.ts +128 -0
- package/dist/{researcher-WJvIpX3L.d.ts → researcher-C_KJyIGg.d.ts} +1 -141
- package/dist/rl.d.ts +4 -3
- package/dist/rl.js +4 -4
- package/dist/{run-campaign-BVY3RGAZ.js → run-campaign-OVEZF24D.js} +2 -2
- package/dist/run-critic-BAIjX99r.d.ts +56 -0
- package/dist/{run-improvement-loop-Bzamo6GB.d.ts → run-improvement-loop-BqYH2vCR.d.ts} +25 -1
- package/dist/semantic-concept-judge-CV9Wlx4t.d.ts +650 -0
- package/dist/{store-jzKpMl16.d.ts → store-GmBE2pZZ.d.ts} +1 -1
- package/dist/traces.d.ts +371 -308
- package/dist/traces.js +43 -18
- package/dist/{types-CnmZ2bkP.d.ts → types-Bba0vl1V.d.ts} +1 -1
- package/dist/{registry-BGKyX6bw.d.ts → types-CRD68aH7.d.ts} +3 -128
- package/dist/wire/index.d.ts +1 -1
- package/dist/workflow/index.d.ts +494 -0
- package/dist/workflow/index.js +2177 -0
- package/dist/workflow/index.js.map +1 -0
- package/docs/design/self-improvement-roadmap.md +106 -0
- package/package.json +36 -12
- package/dist/agent-profile-DzcPHR1Z.d.ts +0 -114
- package/dist/chunk-6QZUCFKM.js.map +0 -1
- package/dist/chunk-ODGETRTM.js.map +0 -1
- package/dist/chunk-PQV2TKC3.js +0 -27
- package/dist/chunk-PQV2TKC3.js.map +0 -1
- /package/dist/{chunk-AIWHLG7J.js.map → chunk-GJJNJVIR.js.map} +0 -0
- /package/dist/{run-campaign-BVY3RGAZ.js.map → run-campaign-OVEZF24D.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/trace-analyst/hook.ts","../src/trace-analyst/insights.ts","../src/trace-analyst/otlp-flatten.ts","../src/trace-analyst/otlp-to-run-records.ts","../src/trace/store.ts","../src/trace/capture-fetch.ts","../src/trace/otel.ts","../src/trace/otel-bridge.ts","../src/trace/otel-export.ts","../src/replay.ts"],"sourcesContent":["/**\n * Trace-analyst auto-execution hook.\n *\n * Wires `analyzeTraces` into a `TraceEmitter`'s `onRunComplete` so a\n * direct matrix run produces an analysis artifact without an out-of-band\n * step. Designed for the case where the consumer reports \"the analyst\n * never ran\" — the cause is almost always orchestration, not the analyst.\n *\n * Usage:\n *\n * const emitter = new TraceEmitter(store, {\n * onRunComplete: [traceAnalystOnRunComplete({ analyze: opts, save })],\n * })\n *\n * Hooks are best-effort by default — they never crash the underlying run.\n * The caller decides whether to gate the run on the analysis result via\n * the `gateOn` callback.\n */\n\nimport type { RunCompleteHook, RunCompleteHookContext } from '../trace/emitter'\nimport { type AnalyzeTracesOptions, type AnalyzeTracesResult, analyzeTraces } from './analyst'\n\nexport interface TraceAnalystHookOptions {\n /**\n * Options forwarded to `analyzeTraces`. The hook supplies the question\n * if you don't pass one — defaulting to a launch-grade prompt that asks\n * for failure modes, surprising findings, and a recommendation.\n */\n analyze: Omit<AnalyzeTracesOptions, 'source'> & { source?: AnalyzeTracesOptions['source'] }\n /**\n * Override the question. The default is intentionally generic:\n * \"Summarise what happened in this run, surface any failure modes,\n * surprising findings, or evidence the verdict is wrong.\"\n */\n question?: string\n /**\n * Persist the result. The hook calls this with the analysis output and\n * the run context. Common implementations write to a TraceAnalysisStore\n * or append to a per-run JSONL.\n */\n save?: (result: AnalyzeTracesResult, ctx: RunCompleteHookContext) => Promise<void>\n /**\n * Predicate gating execution per run. Default: every completed run.\n * Use to skip aborted runs, debug runs, or runs without LLM activity.\n */\n shouldRun?: (ctx: RunCompleteHookContext) => boolean\n /**\n * Optional gate: if set and returns false, the hook records the failure\n * as a log event on the run instead of staying quiet. The caller can\n * then trigger downstream alerts off `analyst_gate_failed` log events.\n */\n gateOn?: (result: AnalyzeTracesResult, ctx: RunCompleteHookContext) => boolean\n}\n\nconst DEFAULT_QUESTION =\n \"Summarise what happened in this run. Surface any failure modes, surprising findings, or evidence that the run's verdict is wrong.\"\n\nexport function traceAnalystOnRunComplete(opts: TraceAnalystHookOptions): RunCompleteHook {\n return async (ctx: RunCompleteHookContext) => {\n if (opts.shouldRun && !opts.shouldRun(ctx)) return\n const source = opts.analyze.source\n if (source === undefined) {\n // The analyst needs a source. If the caller didn't supply one we don't\n // run — but we do leave a breadcrumb so the absence is visible.\n await ctx.store.appendEvent({\n eventId: `analyst-skip-${ctx.runId}`,\n runId: ctx.runId,\n kind: 'log',\n timestamp: Date.now(),\n payload: { source: 'trace_analyst_hook', reason: 'no source configured' },\n })\n return\n }\n const result = await analyzeTraces({ question: opts.question ?? DEFAULT_QUESTION }, {\n ...opts.analyze,\n source,\n } as AnalyzeTracesOptions)\n if (opts.save) await opts.save(result, ctx)\n if (opts.gateOn && !opts.gateOn(result, ctx)) {\n await ctx.store.appendEvent({\n eventId: `analyst-gate-${ctx.runId}`,\n runId: ctx.runId,\n kind: 'log',\n timestamp: Date.now(),\n payload: {\n source: 'trace_analyst_hook',\n reason: 'analyst_gate_failed',\n findings: result.findings,\n },\n })\n }\n }\n}\n","export interface TraceInsightTask {\n id: string\n name: string\n prompt?: string\n difficulty?: string\n tags?: string[]\n outcome?: string\n score?: number\n gaps?: string[]\n}\n\nexport interface TraceInsightSuite {\n name: string\n collectionId?: string\n tasks: TraceInsightTask[]\n}\n\nexport interface TraceInsightFinding {\n kind: string\n severity?: string\n taskIds: string[]\n evidence?: string\n proposedFixClass?: string\n}\n\nexport interface TraceInsightQuestion {\n id: string\n question: string\n why: string\n}\n\nexport interface TraceInsightPanelRole {\n id: string\n name: string\n responsibility: string\n}\n\nexport interface TraceInsightPromptInput {\n suite: TraceInsightSuite\n findings?: TraceInsightFinding[]\n agent?: Record<string, unknown>\n totals?: Record<string, unknown>\n maxRepresentativeTraces?: number\n}\n\nexport interface TraceInsightContext {\n suite: TraceInsightSuite\n scope: string\n keywords: string[]\n questions: TraceInsightQuestion[]\n panel: TraceInsightPanelRole[]\n findings: TraceInsightFinding[]\n agent: Record<string, unknown> | null\n totals: Record<string, unknown> | null\n}\n\nexport interface TraceInsightQualityGate {\n id: string\n label: string\n passed: boolean\n severity: 'critical' | 'high' | 'medium' | 'low'\n detail: string\n}\n\nexport interface TraceInsightReadiness {\n score: number\n grade: 'external-ready' | 'internal-review' | 'raw-analysis'\n gates: TraceInsightQualityGate[]\n}\n\nconst DOMAIN_STOP_WORDS = new Set([\n 'and',\n 'advanced',\n 'app',\n 'build',\n 'create',\n 'easy',\n 'expert',\n 'extreme',\n 'for',\n 'from',\n 'hard',\n 'implementation',\n 'integrate',\n 'medium',\n 'project',\n 'task',\n 'the',\n 'this',\n 'with',\n 'workflow',\n])\n\nexport function tokenizeDomainWords(value: string): string[] {\n return [...value.matchAll(/[A-Za-z][A-Za-z0-9.+#-]{2,}/g)]\n .map((match) => match[0].toLowerCase())\n .filter((word) => !DOMAIN_STOP_WORDS.has(word))\n}\n\nexport function inferDomainKeywords(suite: TraceInsightSuite): string[] {\n const suiteWords = new Set(tokenizeDomainWords(`${suite.name} ${suite.collectionId ?? ''}`))\n const source = [\n suite.name,\n suite.collectionId ?? '',\n ...suite.tasks.flatMap((task) => [\n task.id,\n task.name,\n task.prompt ?? '',\n task.difficulty ?? '',\n ...(task.tags ?? []),\n ...(task.gaps ?? []),\n ]),\n ].join(' ')\n const counts = new Map<string, number>()\n for (const word of tokenizeDomainWords(source)) counts.set(word, (counts.get(word) ?? 0) + 1)\n return [...counts.entries()]\n .filter(([word, count]) => count >= 2 || suiteWords.has(word))\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .map(([word]) => word)\n .slice(0, 18)\n}\n\nexport function domainEvidencePattern(keywords: string[]): RegExp {\n const escaped = keywords\n .filter((keyword) => keyword.length >= 3)\n .map((keyword) => keyword.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n return escaped.length > 0\n ? new RegExp(`(?<![A-Za-z0-9])(?:${escaped.join('|')})(?![A-Za-z0-9])`, 'i')\n : /(?<![A-Za-z0-9])(?:sdk|api|css|dns|xml|provider|client|service|integration|webhook|transaction|auth|oauth|graphql|rest)(?![A-Za-z0-9])/i\n}\n\nexport function describeTraceInsightScope(suite: TraceInsightSuite): string {\n const taskLabel =\n suite.tasks.length === 1\n ? '1 implementation task'\n : `${suite.tasks.length} implementation tasks`\n const tags = new Map<string, number>()\n for (const task of suite.tasks) {\n for (const tag of task.tags ?? []) tags.set(tag, (tags.get(tag) ?? 0) + 1)\n }\n const topTags = [...tags.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, 8)\n .map(([tag]) => tag)\n if (topTags.length > 0) return `${taskLabel} across ${topTags.join(', ')}.`\n const difficulties = [\n ...new Set(\n suite.tasks.map((task) => task.difficulty).filter((value): value is string => Boolean(value)),\n ),\n ].join(', ')\n return `${taskLabel} across ${difficulties || 'the selected benchmark scope'}.`\n}\n\nexport function planTraceInsightQuestions(input: TraceInsightPromptInput): TraceInsightQuestion[] {\n const hasFailures = input.suite.tasks.some((task) => task.outcome && task.outcome !== 'satisfied')\n const hasMultipleShots = input.suite.tasks.some((task) =>\n (task.gaps ?? []).some((gap) => /shot|review|retry|continue/i.test(gap)),\n )\n const questions: TraceInsightQuestion[] = [\n {\n id: 'execution-path',\n question: 'What did the worker actually do before the first meaningful implementation edit?',\n why: 'Separates grounded execution from polished but shallow output.',\n },\n {\n id: 'research-grounding',\n question:\n 'Did the worker inspect docs, source, examples, or package references before committing to an implementation path?',\n why: 'Identifies whether failures came from weak retrieval, weak examples, or premature coding.',\n },\n {\n id: 'domain-proof',\n question:\n 'Which tasks produced executable domain proof versus UI copy, placeholders, or inferred behavior?',\n why: 'Keeps product-quality claims tied to concrete evidence.',\n },\n {\n id: 'root-cause',\n question:\n 'For each major failure cluster, is the likely root cause prompt/scaffold, docs/examples, SDK/API ergonomics, evaluator, runtime, or model behavior?',\n why: 'Turns trace observations into actionable ownership.',\n },\n {\n id: 'evidence-quality',\n question:\n 'Which external-facing claims are directly supported by trace ids, span ids, verifier findings, reviewer notes, or generated code?',\n why: 'Prevents unsupported customer-report conclusions.',\n },\n ]\n if (hasMultipleShots) {\n questions.push({\n id: 'reviewer-lift',\n question: 'Where did reviewer feedback improve score, stall, or regress across shots?',\n why: 'Shows whether the driver loop is learning or merely repeating work.',\n })\n }\n if (hasFailures) {\n questions.push({\n id: 'optimization-targets',\n question:\n 'Which prompt, evaluator, scaffold, or workflow changes should feed the next GEPA/autoresearch optimization run?',\n why: 'Connects benchmark evidence to the optimization loop.',\n })\n }\n return questions\n}\n\nexport function buildTraceInsightContext(input: TraceInsightPromptInput): TraceInsightContext {\n return {\n suite: input.suite,\n scope: describeTraceInsightScope(input.suite),\n keywords: inferDomainKeywords(input.suite),\n questions: planTraceInsightQuestions(input),\n panel: defaultTraceInsightPanel(),\n findings: input.findings ?? [],\n agent: input.agent ?? null,\n totals: input.totals ?? null,\n }\n}\n\nexport function scoreTraceInsightReadiness(context: TraceInsightContext): TraceInsightReadiness {\n const failedTasks = context.suite.tasks.filter(\n (task) => task.outcome && task.outcome !== 'satisfied',\n )\n const findingTaskIds = new Set(context.findings.flatMap((finding) => finding.taskIds))\n const failedTasksWithFindings = failedTasks.filter((task) => findingTaskIds.has(task.id))\n const tasksWithGaps = context.suite.tasks.filter((task) => (task.gaps ?? []).length > 0)\n const gates: TraceInsightQualityGate[] = [\n {\n id: 'domain-context',\n label: 'Domain context inferred',\n passed: context.keywords.length > 0,\n severity: 'high',\n detail:\n context.keywords.length > 0\n ? `${context.keywords.length} domain terms inferred: ${context.keywords.slice(0, 8).join(', ')}`\n : 'No domain terms were inferred from suite, tasks, prompts, tags, or gaps.',\n },\n {\n id: 'panel-coverage',\n label: 'Analyst panel planned',\n passed: context.panel.length >= 4 && context.questions.length >= 5,\n severity: 'high',\n detail: `${context.panel.length} panel roles and ${context.questions.length} investigation questions planned.`,\n },\n {\n id: 'failure-coverage',\n label: 'Failures mapped to findings',\n passed:\n failedTasks.length === 0 || failedTasksWithFindings.length / failedTasks.length >= 0.5,\n severity: 'critical',\n detail:\n failedTasks.length === 0\n ? 'No failed tasks in suite.'\n : `${failedTasksWithFindings.length}/${failedTasks.length} failed tasks appear in finding clusters.`,\n },\n {\n id: 'gap-evidence',\n label: 'Task gaps captured',\n passed: failedTasks.length === 0 || tasksWithGaps.length / failedTasks.length >= 0.5,\n severity: 'medium',\n detail: `${tasksWithGaps.length} tasks include explicit evaluator or analyst gaps.`,\n },\n ]\n const penalty = gates.reduce((sum, gate) => {\n if (gate.passed) return sum\n if (gate.severity === 'critical') return sum + 35\n if (gate.severity === 'high') return sum + 20\n if (gate.severity === 'medium') return sum + 10\n return sum + 5\n }, 0)\n const score = Math.max(0, Math.min(1, 1 - penalty / 100))\n return {\n score,\n grade: score >= 0.9 ? 'external-ready' : score >= 0.7 ? 'internal-review' : 'raw-analysis',\n gates,\n }\n}\n\nexport function defaultTraceInsightPanel(): TraceInsightPanelRole[] {\n return [\n {\n id: 'trace-forensics',\n name: 'Trace Forensics',\n responsibility:\n 'Reconstruct what the worker did in order, including research, edits, reviewer interventions, verifier feedback, and stop reason.',\n },\n {\n id: 'root-cause',\n name: 'Root Cause',\n responsibility:\n 'Map failures to prompt/scaffold, docs/examples, SDK/API/product ergonomics, evaluator, runtime, or model behavior.',\n },\n {\n id: 'optimization',\n name: 'Optimization',\n responsibility:\n 'Identify prompt, reviewer, evaluator, scaffold, and GEPA/autoresearch changes that should be tested next.',\n },\n {\n id: 'external-evidence',\n name: 'External Evidence',\n responsibility:\n 'Separate customer-safe claims from internal harness findings and reject conclusions without task, trace, span, code, reviewer, or verifier evidence.',\n },\n ]\n}\n\nexport function buildTraceInsightPrompt(input: TraceInsightPromptInput): string {\n const context = buildTraceInsightContext(input)\n const maxRepresentativeTraces = input.maxRepresentativeTraces ?? 6\n return `Analyze this benchmark run and produce evidence-backed trace intelligence.\n\nAudience:\n- internal AI/product leadership\n- possible customer-facing report for ${input.suite.name}\n\nInvestigation plan:\n${context.questions.map((item, index) => `${index + 1}. ${item.question} (${item.why})`).join('\\n')}\n\nAnalyst panel:\n${context.panel.map((role) => `- ${role.name}: ${role.responsibility}`).join('\\n')}\n\nIf the task branches are independent, use subagents for the panel roles above and aggregate their findings. Do not run a panel role unless its answer will change the final report.\n\nRequired output:\n1. Executive verdict: what this run proves and does not prove.\n2. The investigation questions you answered and the evidence used.\n3. Failure taxonomy: agent prompting, evaluator/harness, docs/examples, SDK/API/product integration, infra.\n4. Evidence-backed examples with trace ids/task ids and concrete verifier findings.\n5. Highest-ROI fixes for the benchmark harness, prompt/GEPA optimization, and customer-facing product/docs surface.\n6. What is safe for an external report versus what must stay internal.\n7. One rerun plan that would validate lift after optimization.\n\nBudget:\n- Inspect the dataset overview, the failure summary, and at most ${maxRepresentativeTraces} representative traces.\n- Prefer traces named in the failure summary over broad exploration.\n- Do not do exhaustive trace sweeps.\n- Return the final report as soon as the taxonomy and examples are supported.\n\nRun summary:\n${JSON.stringify(\n {\n suite: input.suite.name,\n scope: context.scope,\n inferredKeywords: context.keywords,\n agent: context.agent,\n totals: context.totals,\n findings: context.findings.map((finding) => ({\n kind: finding.kind,\n severity: finding.severity,\n taskCount: finding.taskIds.length,\n proposedFixClass: finding.proposedFixClass,\n })),\n failures: input.suite.tasks\n .filter((task) => task.outcome && task.outcome !== 'satisfied')\n .map((task) => ({\n task: task.id,\n difficulty: task.difficulty,\n outcome: task.outcome,\n score: task.score,\n gaps: task.gaps ?? [],\n })),\n },\n null,\n 2,\n)}\n\nUse the trace tools. Do not invent facts. Cite task ids. Separate customer-facing claims from internal harness/model findings.`\n}\n","/**\n * `flattenOtlpExportToNdjson` — flatten an `OtlpExport` (the shape\n * `exportRunAsOtlp` produces) into the per-line JSON the analyst's\n * `OtlpFileTraceStore` index reads. Replaces three per-consumer OTLP\n * flatteners with one canonical projection.\n *\n * Pure function, no I/O — the caller does `.map(JSON.stringify).join('\\n')`\n * and writes the file (consumers want control over rotation + naming).\n */\n\nimport type { OtlpExport, OtlpSpan } from '../trace/otel'\n\nexport interface OtlpFlatLine {\n trace_id: string\n span_id: string\n parent_span_id: string | null\n name: string\n kind: string\n start_time: string\n end_time: string\n status: {\n code: 'STATUS_CODE_OK' | 'STATUS_CODE_ERROR' | 'STATUS_CODE_UNSET'\n message?: string\n }\n resource: { attributes: Record<string, string | number | boolean> }\n attributes: Record<string, string | number | boolean>\n events?: Array<{ name: string; timeUnixNano?: string; attributes?: Record<string, unknown> }>\n}\n\nexport interface FlattenOtlpOptions {\n /** `'openinference'` (default) mirrors per-span attributes into the\n * OpenInference vocabulary the analyst's `inferKind` reads\n * (`llm.model`→`llm.model_name`, `tool.name`→`inference.tool.name`,\n * `span.kind`→`openinference.span.kind` uppercased). `'none'` passes\n * attributes through untouched. */\n attributeVocabulary?: 'openinference' | 'none'\n /** Override the numeric-kind → otlp-string mapping. */\n kindMap?: Partial<Record<number, string>>\n}\n\nconst DEFAULT_KIND_MAP: Record<number, string> = {\n 0: 'SPAN_KIND_UNSPECIFIED',\n 1: 'SPAN_KIND_INTERNAL',\n 2: 'SPAN_KIND_SERVER',\n 3: 'SPAN_KIND_CLIENT',\n 4: 'SPAN_KIND_PRODUCER',\n 5: 'SPAN_KIND_CONSUMER',\n}\n\nconst STATUS_MAP: Record<number, OtlpFlatLine['status']['code']> = {\n 0: 'STATUS_CODE_UNSET',\n 1: 'STATUS_CODE_OK',\n 2: 'STATUS_CODE_ERROR',\n}\n\n/** Unwrap an OTLP attribute-value union to a scalar. */\nfunction attrValue(v: OtlpSpan['attributes'][number]['value']): string | number | boolean {\n if (v.stringValue !== undefined) return v.stringValue\n if (v.intValue !== undefined) return Number(v.intValue)\n if (v.doubleValue !== undefined) return v.doubleValue\n if (v.boolValue !== undefined) return v.boolValue\n return ''\n}\n\nfunction attrsToRecord(attrs: OtlpSpan['attributes']): Record<string, string | number | boolean> {\n const out: Record<string, string | number | boolean> = {}\n for (const a of attrs) out[a.key] = attrValue(a.value)\n return out\n}\n\nfunction nanoToIso(nano: string): string {\n const ms = Number(nano) / 1_000_000\n return Number.isFinite(ms) ? new Date(ms).toISOString() : new Date(0).toISOString()\n}\n\n/** Mirror selected attributes into the OpenInference vocabulary in place. */\nfunction applyOpenInference(attrs: Record<string, string | number | boolean>): void {\n if ('llm.model' in attrs && !('llm.model_name' in attrs)) {\n attrs['llm.model_name'] = attrs['llm.model']!\n }\n if ('tool.name' in attrs && !('inference.tool.name' in attrs)) {\n attrs['inference.tool.name'] = attrs['tool.name']!\n }\n if ('span.kind' in attrs && !('openinference.span.kind' in attrs)) {\n attrs['openinference.span.kind'] = String(attrs['span.kind']).toUpperCase()\n }\n}\n\nexport function flattenOtlpExportToNdjson(\n otlpExport: OtlpExport,\n opts: FlattenOtlpOptions = {},\n): OtlpFlatLine[] {\n const vocab = opts.attributeVocabulary ?? 'openinference'\n const kindMap = { ...DEFAULT_KIND_MAP, ...opts.kindMap }\n const lines: OtlpFlatLine[] = []\n\n for (const rs of otlpExport.resourceSpans ?? []) {\n const resource = { attributes: attrsToRecord(rs.resource?.attributes ?? []) }\n for (const scope of rs.scopeSpans ?? []) {\n for (const span of scope.spans ?? []) {\n const attributes = attrsToRecord(span.attributes ?? [])\n if (vocab === 'openinference') applyOpenInference(attributes)\n const line: OtlpFlatLine = {\n trace_id: span.traceId,\n span_id: span.spanId,\n parent_span_id: span.parentSpanId ?? null,\n name: span.name,\n kind: kindMap[span.kind] ?? 'SPAN_KIND_UNSPECIFIED',\n start_time: nanoToIso(span.startTimeUnixNano),\n end_time: nanoToIso(span.endTimeUnixNano),\n status: {\n code: STATUS_MAP[span.status?.code ?? 0] ?? 'STATUS_CODE_UNSET',\n ...(span.status?.message ? { message: span.status.message } : {}),\n },\n resource,\n attributes,\n }\n if (span.events && span.events.length > 0) {\n line.events = span.events.map((e) => ({\n name: e.name,\n timeUnixNano: e.timeUnixNano,\n ...(e.attributes ? { attributes: attrsToRecord(e.attributes) } : {}),\n }))\n }\n lines.push(line)\n }\n }\n }\n\n return lines\n}\n","/**\n * `otlpToRunRecords` — fold an OTLP traces.jsonl (one OTLP span per line;\n * the form AppWorld / HALO emit via their OpenInference OTLP exporter, the\n * same shape `flattenOtlpExportToNdjson` produces) into validated\n * `RunRecord[]` — one record per `trace_id` (one trace == one task).\n *\n * This is the offline ingestion primitive the AppWorld driver bench and the\n * hosted Intelligence product both stand on: traces in, paper-grade rows\n * out, ready for `compareDrivers` / `analyzeRuns` / the promotion gate.\n *\n * Aggregation per trace:\n * - tokenUsage: sum LLM-span `input` / `output` (+ `cached` when present)\n * across every LLM span in the trace.\n * - costUsd: sum per-span LLM cost when present; else priced via\n * `opts.priceUsdPerToken` from the aggregated tokens; else 0 with a\n * loud `raw.cost_unpriced = 1` marker so a missing price is visible, not\n * a silent zero folded into a gate.\n * - failureMode: the first `STATUS_CODE_ERROR` span's normalized status\n * message (carries the real failure signature, not a generic class).\n * - model: the dominant LLM model in the trace (snapshot-padded to satisfy\n * `validateRunRecord` when the trace's model is a bare alias).\n * - outcome score: `opts.scoreForTrace` (AppWorld `world.evaluate()` →\n * TGC/SGC) when supplied; else 1 when the trace had no error span, 0\n * when it did — a defensible default the caller can override.\n * - prompt / completion: carried into `raw` as token-count signals and,\n * when the first/last LLM span exposes `input.value` / `output.value`,\n * the verbatim text is preserved on the optional `promptText` /\n * `completionText` of the returned `OtlpTraceRunRecord`.\n *\n * Fail-loud: an OTLP file with zero valid spans throws. A trace with no\n * spans is impossible (a trace exists only because a span referenced it).\n * `validateRunRecord` runs on every row — a malformed projection throws\n * rather than silently producing a half-record.\n */\n\nimport {\n type RunRecord,\n type RunSplitTag,\n type RunTokenUsage,\n validateRunRecord,\n} from '../run-record'\nimport {\n firstNumberAttr,\n firstStringAttr,\n type ProjectedOtlpSpan,\n projectOtlpFlatLine,\n} from './otlp-span'\n\n/** Candidate attribute keys for LLM input (prompt) tokens, both dialects. */\nconst INPUT_TOKEN_KEYS = [\n 'llm.input_tokens',\n 'inference.llm.input_tokens',\n 'llm.token_count.prompt',\n 'gen_ai.usage.input_tokens',\n 'gen_ai.usage.prompt_tokens',\n] as const\n/** Candidate attribute keys for LLM output (completion) tokens. */\nconst OUTPUT_TOKEN_KEYS = [\n 'llm.output_tokens',\n 'inference.llm.output_tokens',\n 'llm.token_count.completion',\n 'gen_ai.usage.output_tokens',\n 'gen_ai.usage.completion_tokens',\n] as const\n/** Candidate attribute keys for cached/prompt-cache tokens. */\nconst CACHED_TOKEN_KEYS = [\n 'llm.cached_tokens',\n 'inference.llm.cached_tokens',\n 'llm.token_count.prompt_cache_hit',\n 'gen_ai.usage.cached_tokens',\n] as const\n/** Candidate attribute keys for per-span LLM cost in USD. */\nconst COST_KEYS = [\n 'llm.cost_usd',\n 'inference.llm.cost.total',\n 'llm.cost.total',\n 'gen_ai.usage.cost',\n] as const\n/** Candidate attribute keys for the model identifier. */\nconst MODEL_KEYS = [\n 'llm.model_name',\n 'inference.llm.model_name',\n 'llm.model',\n 'gen_ai.request.model',\n 'gen_ai.response.model',\n] as const\n\nexport interface OtlpToRunRecordsOptions {\n /** Logical experiment grouping for every produced record. */\n experimentId: string\n /** Candidate (variant) id — the surface these traces exercised. The\n * bench passes the driver label here so `compareDrivers` can pair rows. */\n candidateId: string\n /** Split assignment for every produced record. Default `'holdout'` —\n * ingested traces are evidence, not the optimizer's training pool. */\n splitTag?: RunSplitTag\n /** Git SHA the traces were produced from. Default `'unknown'`. */\n commitSha?: string\n /** sha256 of the effective prompt surface. Default `'unknown'`. */\n promptHash?: string\n /** sha256 of the effective config. Default `'unknown'`. */\n configHash?: string\n /** RNG seed recorded on every row. Default 0. */\n seed?: number\n /**\n * Fallback model snapshot when the trace exposes no LLM model attribute\n * OR exposes a bare alias `validateRunRecord` would reject. The trace's\n * own model wins when it already carries a snapshot. Default\n * `'unknown@otlp'` (opaque-snapshot form the validator accepts).\n */\n fallbackModel?: string\n /**\n * USD per total token (input+output) used to price a trace when no\n * per-span cost attribute is present. When unset, an unpriced trace\n * records `costUsd: 0` AND `raw.cost_unpriced = 1` — the zero is flagged,\n * never silent.\n */\n priceUsdPerToken?: number\n /**\n * Score for a trace's outcome (AppWorld `world.evaluate()` → TGC/SGC, or\n * any [0,1] task-success signal). Keyed by `trace_id`; falls through to\n * the error-derived default (1 = no error span, 0 = had one) when the map\n * has no entry or the function returns undefined.\n */\n scoreForTrace?: (traceId: string, span: TraceAggregate) => number | undefined\n /**\n * Per-record judge metadata when an external judge produced the score.\n * Keyed by `trace_id`.\n */\n judgeMetadataForTrace?: (traceId: string) => RunRecord['judgeMetadata'] | undefined\n}\n\n/** A `RunRecord` plus the verbatim prompt/completion text when the trace's\n * LLM spans exposed it. The text is NOT on the validated `RunRecord`\n * (`outcome.raw` is numeric-only) but consumers ingesting full traces want\n * it — so it rides alongside. */\nexport interface OtlpTraceRunRecord {\n record: RunRecord\n /** Verbatim first-LLM-span `input.value`, when present. */\n promptText?: string\n /** Verbatim last-LLM-span `output.value`, when present. */\n completionText?: string\n}\n\n/** Per-trace rollup the score callback can inspect. */\nexport interface TraceAggregate {\n traceId: string\n spanCount: number\n llmSpanCount: number\n toolSpanCount: number\n agentSpanCount: number\n errorSpanCount: number\n tokenUsage: RunTokenUsage\n /** First error span's normalized status message, if any. */\n firstErrorMessage?: string\n model: string\n startTime: string\n endTime: string\n wallMs: number\n}\n\n/**\n * Parse + aggregate an OTLP traces.jsonl string into validated\n * `RunRecord[]` (one per trace). Use {@link otlpToTraceRunRecords} when you\n * also want the verbatim prompt/completion text alongside each record.\n */\nexport function otlpToRunRecords(otlpJsonl: string, opts: OtlpToRunRecordsOptions): RunRecord[] {\n return otlpToTraceRunRecords(otlpJsonl, opts).map((r) => r.record)\n}\n\n/** As {@link otlpToRunRecords} but returns the prompt/completion text too. */\nexport function otlpToTraceRunRecords(\n otlpJsonl: string,\n opts: OtlpToRunRecordsOptions,\n): OtlpTraceRunRecord[] {\n const splitTag = opts.splitTag ?? 'holdout'\n const commitSha = opts.commitSha ?? 'unknown'\n const promptHash = opts.promptHash ?? 'unknown'\n const configHash = opts.configHash ?? 'unknown'\n const seed = opts.seed ?? 0\n const fallbackModel = opts.fallbackModel ?? 'unknown@otlp'\n\n const byTrace = groupSpansByTrace(otlpJsonl)\n if (byTrace.size === 0) {\n throw new Error(\n 'otlpToRunRecords: OTLP input produced zero valid spans — every line was empty, malformed, or missing trace_id/span_id',\n )\n }\n\n // Stable trace order (insertion order of first appearance is preserved by\n // Map; sort by trace_id for determinism across producers).\n const traceIds = [...byTrace.keys()].sort()\n const out: OtlpTraceRunRecord[] = []\n\n for (const traceId of traceIds) {\n const spans = byTrace.get(traceId)!\n const agg = aggregateTrace(traceId, spans, fallbackModel)\n\n const score = resolveScore(opts, traceId, agg)\n const { costUsd, costUnpriced } = resolveCost(opts, agg, spans)\n\n const raw: Record<string, number> = {\n span_count: agg.spanCount,\n llm_span_count: agg.llmSpanCount,\n tool_span_count: agg.toolSpanCount,\n agent_span_count: agg.agentSpanCount,\n error_span_count: agg.errorSpanCount,\n prompt_tokens: agg.tokenUsage.input,\n completion_tokens: agg.tokenUsage.output,\n }\n if (agg.tokenUsage.cached !== undefined) raw.cached_tokens = agg.tokenUsage.cached\n if (costUnpriced) raw.cost_unpriced = 1\n\n const outcome =\n splitTag === 'holdout' ? { holdoutScore: score, raw } : { searchScore: score, raw }\n\n const { promptText, completionText } = extractPromptCompletion(spans)\n const judgeMetadata = opts.judgeMetadataForTrace?.(traceId)\n\n const record = validateRunRecord({\n runId: `otlp:${opts.experimentId}:${opts.candidateId}:${traceId}`,\n experimentId: opts.experimentId,\n candidateId: opts.candidateId,\n seed,\n model: ensureSnapshot(agg.model, fallbackModel),\n promptHash,\n configHash,\n commitSha,\n wallMs: agg.wallMs,\n costUsd,\n tokenUsage: agg.tokenUsage,\n ...(judgeMetadata ? { judgeMetadata } : {}),\n outcome,\n ...(agg.firstErrorMessage ? { failureMode: agg.firstErrorMessage } : {}),\n splitTag,\n scenarioId: traceId,\n })\n\n out.push({\n record,\n ...(promptText !== undefined ? { promptText } : {}),\n ...(completionText !== undefined ? { completionText } : {}),\n })\n }\n\n return out\n}\n\n// ── Internals ──────────────────────────────────────────────────────────\n\nfunction groupSpansByTrace(otlpJsonl: string): Map<string, ProjectedOtlpSpan[]> {\n const byTrace = new Map<string, ProjectedOtlpSpan[]>()\n for (const line of otlpJsonl.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.length === 0) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed)\n } catch {\n // Tolerate a stray malformed line — mirrors the store's index, which\n // skips unparseable lines rather than nuking a whole dataset. A file\n // that is ENTIRELY malformed still throws (zero valid spans).\n continue\n }\n if (!parsed || typeof parsed !== 'object') continue\n const span = projectOtlpFlatLine(parsed as Record<string, unknown>)\n if (!span) continue\n const arr = byTrace.get(span.trace_id)\n if (arr) arr.push(span)\n else byTrace.set(span.trace_id, [span])\n }\n return byTrace\n}\n\nfunction aggregateTrace(\n traceId: string,\n spans: ProjectedOtlpSpan[],\n fallbackModel: string,\n): TraceAggregate {\n // Span order within a trace is by start time, then a stable tiebreak.\n const ordered = [...spans].sort(\n (a, b) => a.start_time.localeCompare(b.start_time) || a.span_id.localeCompare(b.span_id),\n )\n\n let input = 0\n let output = 0\n let cached = 0\n let sawCached = false\n let llmSpanCount = 0\n let toolSpanCount = 0\n let agentSpanCount = 0\n let errorSpanCount = 0\n let firstErrorMessage: string | undefined\n const modelVotes = new Map<string, number>()\n let earliest = ordered[0]?.start_time ?? ''\n let latest = ordered[0]?.end_time ?? ''\n\n for (const s of ordered) {\n if (s.start_time && (!earliest || s.start_time < earliest)) earliest = s.start_time\n if (s.end_time && s.end_time > latest) latest = s.end_time\n\n if (s.kind === 'LLM') {\n llmSpanCount += 1\n const i = firstNumberAttr(s.attributes, INPUT_TOKEN_KEYS)\n const o = firstNumberAttr(s.attributes, OUTPUT_TOKEN_KEYS)\n const c = firstNumberAttr(s.attributes, CACHED_TOKEN_KEYS)\n if (i !== null) input += i\n if (o !== null) output += o\n if (c !== null) {\n cached += c\n sawCached = true\n }\n const m = firstStringAttr(s.attributes, MODEL_KEYS) ?? s.model_name\n if (m) modelVotes.set(m, (modelVotes.get(m) ?? 0) + 1)\n } else if (s.kind === 'TOOL') {\n toolSpanCount += 1\n } else if (s.kind === 'AGENT') {\n agentSpanCount += 1\n }\n\n if (s.status === 'ERROR') {\n errorSpanCount += 1\n if (firstErrorMessage === undefined) {\n firstErrorMessage = (s.status_message ?? `${s.name} — STATUS_CODE_ERROR`).slice(0, 500)\n }\n }\n }\n\n // Dominant model across LLM spans; falls back to any model attribute on a\n // non-LLM span, then the supplied fallback snapshot.\n const model = topVote(modelVotes) ?? firstModelAttr(ordered) ?? fallbackModel\n\n let wallMs = 0\n if (earliest && latest) {\n const a = Date.parse(earliest)\n const b = Date.parse(latest)\n if (!Number.isNaN(a) && !Number.isNaN(b)) wallMs = Math.max(0, b - a)\n }\n\n const tokenUsage: RunTokenUsage = sawCached ? { input, output, cached } : { input, output }\n\n return {\n traceId,\n spanCount: spans.length,\n llmSpanCount,\n toolSpanCount,\n agentSpanCount,\n errorSpanCount,\n tokenUsage,\n firstErrorMessage,\n model,\n startTime: earliest,\n endTime: latest,\n wallMs,\n }\n}\n\nfunction resolveScore(opts: OtlpToRunRecordsOptions, traceId: string, agg: TraceAggregate): number {\n const supplied = opts.scoreForTrace?.(traceId, agg)\n if (supplied !== undefined) {\n if (!Number.isFinite(supplied)) {\n throw new Error(\n `otlpToRunRecords: scoreForTrace('${traceId}') returned non-finite ${supplied}`,\n )\n }\n return supplied\n }\n // Default: error-derived. A trace with any error span scores 0; otherwise 1.\n return agg.errorSpanCount > 0 ? 0 : 1\n}\n\nfunction resolveCost(\n opts: OtlpToRunRecordsOptions,\n agg: TraceAggregate,\n spans: ProjectedOtlpSpan[],\n): { costUsd: number; costUnpriced: boolean } {\n // Prefer per-span LLM cost attributes summed across the trace.\n let perSpanCost = 0\n let sawCost = false\n for (const s of spans) {\n if (s.kind !== 'LLM') continue\n const c = firstNumberAttr(s.attributes, COST_KEYS)\n if (c !== null) {\n perSpanCost += c\n sawCost = true\n }\n }\n if (sawCost) return { costUsd: perSpanCost, costUnpriced: false }\n\n if (opts.priceUsdPerToken !== undefined) {\n const totalTokens = agg.tokenUsage.input + agg.tokenUsage.output\n return { costUsd: totalTokens * opts.priceUsdPerToken, costUnpriced: false }\n }\n\n // No per-span cost, no price table — record 0 but flag it loudly so a\n // missing price never silently flatters a cost axis.\n return { costUsd: 0, costUnpriced: true }\n}\n\nfunction extractPromptCompletion(spans: ProjectedOtlpSpan[]): {\n promptText?: string\n completionText?: string\n} {\n const llm = spans\n .filter((s) => s.kind === 'LLM')\n .sort((a, b) => a.start_time.localeCompare(b.start_time) || a.span_id.localeCompare(b.span_id))\n if (llm.length === 0) return {}\n const promptText =\n firstStringAttr(llm[0]!.attributes, ['input.value', 'llm.input_messages', 'gen_ai.prompt']) ??\n undefined\n const last = llm[llm.length - 1]!\n const completionText =\n firstStringAttr(last.attributes, [\n 'output.value',\n 'llm.output_messages',\n 'gen_ai.completion',\n ]) ?? undefined\n return {\n ...(promptText !== undefined ? { promptText } : {}),\n ...(completionText !== undefined ? { completionText } : {}),\n }\n}\n\nfunction topVote(votes: Map<string, number>): string | null {\n let best: string | null = null\n let bestN = 0\n for (const [k, n] of votes) {\n // Strict > keeps the higher count; lexicographic tie-break makes the winner\n // independent of Map insertion order (reproducible across producers).\n if (n > bestN || (n === bestN && best !== null && k < best)) {\n best = k\n bestN = n\n }\n }\n return best\n}\n\nfunction firstModelAttr(spans: ProjectedOtlpSpan[]): string | null {\n for (const s of spans) {\n const m = firstStringAttr(s.attributes, MODEL_KEYS) ?? s.model_name\n if (m) return m\n }\n return null\n}\n\n/**\n * `validateRunRecord` rejects bare model aliases (`gpt-4o`) that remap\n * silently. AppWorld/HALO traces frequently carry such bare ids (or a null\n * model). When the model already encodes a snapshot we keep it; otherwise we\n * append the fallback snapshot token so the row is admissible without lying\n * about the model — the bare base name is preserved verbatim before `@`.\n */\nfunction ensureSnapshot(model: string, fallbackModel: string): string {\n if (modelHasSnapshot(model)) return model\n const fallbackTag = fallbackModel.includes('@')\n ? fallbackModel.slice(fallbackModel.indexOf('@'))\n : '@otlp'\n return `${model}${fallbackTag}`\n}\n\nfunction modelHasSnapshot(model: string): boolean {\n if (model.includes('@')) return true\n if (/-\\d{8}$/.test(model)) return true\n if (/-\\d{4}-\\d{2}-\\d{2}$/.test(model)) return true\n if (/:date-/.test(model)) return true\n return false\n}\n","/**\n * TraceStore — persistence + query over the TraceSchema v1 corpus.\n *\n * Two implementations ship in the core:\n * - InMemoryTraceStore: dev + tests, fully in-process\n * - FileSystemTraceStore: NDJSON append-only files per entity, suitable\n * for long-running CI jobs; rolled over at 32MB\n *\n * Downstream adapters (DuckDB, Langfuse, R2 parquet) implement this same\n * interface — the rest of the framework is storage-agnostic.\n */\n\nimport type {\n Artifact,\n BudgetLedgerEntry,\n EventKind,\n Run,\n RunStatus,\n Span,\n SpanKind,\n TraceEvent,\n} from './schema'\n\nexport interface RunFilter {\n scenarioId?: string\n variantId?: string\n status?: RunStatus\n since?: number\n until?: number\n tag?: { key: string; value: string }\n parentRunId?: string\n projectId?: string\n chatId?: string\n layer?: import('./schema').RunLayer\n}\n\nexport interface SpanFilter {\n runId?: string\n parentSpanId?: string\n kind?: SpanKind\n name?: string\n toolName?: string\n judgeId?: string\n since?: number\n until?: number\n}\n\nexport interface EventFilter {\n runId?: string\n spanId?: string\n kind?: EventKind\n since?: number\n until?: number\n}\n\nexport interface TraceStore {\n appendRun(run: Run): Promise<void>\n updateRun(runId: string, patch: Partial<Run>): Promise<void>\n appendSpan(span: Span): Promise<void>\n updateSpan(spanId: string, patch: Partial<Span>): Promise<void>\n appendEvent(event: TraceEvent): Promise<void>\n appendArtifact(artifact: Artifact): Promise<void>\n appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void>\n\n getRun(runId: string): Promise<Run | undefined>\n listRuns(filter?: RunFilter): Promise<Run[]>\n spans(filter?: SpanFilter): Promise<Span[]>\n events(filter?: EventFilter): Promise<TraceEvent[]>\n budget(runId: string): Promise<BudgetLedgerEntry[]>\n artifacts(runId: string): Promise<Artifact[]>\n}\n\n// ── In-memory ────────────────────────────────────────────────────────\n\nexport class InMemoryTraceStore implements TraceStore {\n private runs = new Map<string, Run>()\n private allSpans: Span[] = []\n private allEvents: TraceEvent[] = []\n private allArtifacts: Artifact[] = []\n private allBudget: BudgetLedgerEntry[] = []\n\n async appendRun(run: Run): Promise<void> {\n if (this.runs.has(run.runId)) throw new Error(`run ${run.runId} already exists`)\n this.runs.set(run.runId, { ...run })\n }\n\n async updateRun(runId: string, patch: Partial<Run>): Promise<void> {\n const existing = this.runs.get(runId)\n if (!existing) throw new Error(`run ${runId} not found`)\n this.runs.set(runId, { ...existing, ...patch })\n }\n\n async appendSpan(span: Span): Promise<void> {\n this.allSpans.push({ ...span })\n }\n\n async updateSpan(spanId: string, patch: Partial<Span>): Promise<void> {\n const idx = this.allSpans.findIndex((s) => s.spanId === spanId)\n if (idx < 0) throw new Error(`span ${spanId} not found`)\n this.allSpans[idx] = { ...this.allSpans[idx], ...patch } as Span\n }\n\n async appendEvent(event: TraceEvent): Promise<void> {\n this.allEvents.push({ ...event })\n }\n\n async appendArtifact(artifact: Artifact): Promise<void> {\n this.allArtifacts.push({ ...artifact })\n }\n\n async appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void> {\n this.allBudget.push({ ...entry })\n }\n\n async getRun(runId: string): Promise<Run | undefined> {\n const r = this.runs.get(runId)\n return r ? { ...r } : undefined\n }\n\n async listRuns(filter: RunFilter = {}): Promise<Run[]> {\n return [...this.runs.values()].filter((r) => matchesRun(r, filter))\n }\n\n async spans(filter: SpanFilter = {}): Promise<Span[]> {\n return this.allSpans.filter((s) => matchesSpan(s, filter)).map((s) => ({ ...s }))\n }\n\n async events(filter: EventFilter = {}): Promise<TraceEvent[]> {\n return this.allEvents.filter((e) => matchesEvent(e, filter)).map((e) => ({ ...e }))\n }\n\n async budget(runId: string): Promise<BudgetLedgerEntry[]> {\n return this.allBudget.filter((b) => b.runId === runId).map((b) => ({ ...b }))\n }\n\n async artifacts(runId: string): Promise<Artifact[]> {\n return this.allArtifacts.filter((a) => a.runId === runId).map((a) => ({ ...a }))\n }\n}\n\nfunction matchesRun(r: Run, f: RunFilter): boolean {\n if (f.scenarioId && r.scenarioId !== f.scenarioId) return false\n if (f.variantId && r.variantId !== f.variantId) return false\n if (f.status && r.status !== f.status) return false\n if (f.since !== undefined && r.startedAt < f.since) return false\n if (f.until !== undefined && r.startedAt > f.until) return false\n if (f.tag && r.tags?.[f.tag.key] !== f.tag.value) return false\n if (f.parentRunId && r.parentRunId !== f.parentRunId) return false\n if (f.projectId && r.projectId !== f.projectId) return false\n if (f.chatId && r.chatId !== f.chatId) return false\n if (f.layer && r.layer !== f.layer) return false\n return true\n}\n\nfunction matchesSpan(s: Span, f: SpanFilter): boolean {\n if (f.runId && s.runId !== f.runId) return false\n if (f.parentSpanId && s.parentSpanId !== f.parentSpanId) return false\n if (f.kind && s.kind !== f.kind) return false\n if (f.name && s.name !== f.name) return false\n if (f.toolName && (s.kind !== 'tool' || s.toolName !== f.toolName)) return false\n if (f.judgeId && (s.kind !== 'judge' || s.judgeId !== f.judgeId)) return false\n if (f.since !== undefined && s.startedAt < f.since) return false\n if (f.until !== undefined && s.startedAt > f.until) return false\n return true\n}\n\nfunction matchesEvent(e: TraceEvent, f: EventFilter): boolean {\n if (f.runId && e.runId !== f.runId) return false\n if (f.spanId && e.spanId !== f.spanId) return false\n if (f.kind && e.kind !== f.kind) return false\n if (f.since !== undefined && e.timestamp < f.since) return false\n if (f.until !== undefined && e.timestamp > f.until) return false\n return true\n}\n\n// ── Filesystem (NDJSON append-only, one file per entity) ─────────────\n\nexport interface FileSystemTraceStoreOptions {\n dir: string\n /** Roll over NDJSON files when they exceed this size in bytes. Default 32 MB. */\n maxBytes?: number\n}\n\nexport class FileSystemTraceStore implements TraceStore {\n private dir: string\n private maxBytes: number\n /** Lazy in-memory index for queries — populated on first read. */\n private index?: InMemoryTraceStore\n private loaded = false\n\n constructor(options: FileSystemTraceStoreOptions) {\n this.dir = options.dir\n this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024\n }\n\n private async ensureDir(): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.mkdir(this.dir, { recursive: true })\n }\n\n private async append(name: string, record: unknown): Promise<void> {\n await this.ensureDir()\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const active = path.join(this.dir, `${name}.ndjson`)\n try {\n const stat = await fs.stat(active)\n if (stat.size >= this.maxBytes) {\n const rolled = path.join(this.dir, `${name}.${Date.now()}.ndjson`)\n await fs.rename(active, rolled)\n }\n } catch {\n /* file doesn't exist yet */\n }\n await fs.appendFile(active, `${JSON.stringify(record)}\\n`, 'utf8')\n // Mirror genuinely-new rows into the lazy index. Update rows (marked\n // with `_update: true` by updateRun/updateSpan) are applied by those\n // methods directly via the index's update* APIs — re-inserting them\n // here triggers a duplicate-id error once the first read populates\n // the index.\n if (this.index && !(record as { _update?: boolean })?._update) {\n void this.insertInto(name, record)\n }\n }\n\n private async insertInto(name: string, record: unknown): Promise<void> {\n if (!this.index) return\n switch (name) {\n case 'runs':\n await this.index.appendRun(record as Run)\n break\n case 'spans':\n await this.index.appendSpan(record as Span)\n break\n case 'events':\n await this.index.appendEvent(record as TraceEvent)\n break\n case 'artifacts':\n await this.index.appendArtifact(record as Artifact)\n break\n case 'budget':\n await this.index.appendBudgetEntry(record as BudgetLedgerEntry)\n break\n }\n }\n\n private async load(): Promise<InMemoryTraceStore> {\n if (this.loaded && this.index) return this.index\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const store = new InMemoryTraceStore()\n try {\n const entries = await fs.readdir(this.dir)\n for (const file of entries) {\n if (!file.endsWith('.ndjson')) continue\n const full = path.join(this.dir, file)\n const content = await fs.readFile(full, 'utf8')\n const base = file.split('.')[0]\n for (const line of content.split('\\n')) {\n if (!line.trim()) continue\n const record = JSON.parse(line)\n if (base === 'runs') {\n // Allow re-loading without duplicate error\n try {\n await store.appendRun(record)\n } catch {\n await store.updateRun(record.runId, record)\n }\n } else if (base === 'spans') {\n // `updateSpan` appends an `_update: true` patch row instead of\n // rewriting the original span. On reload we must collapse those\n // patches onto the original span — otherwise a fresh\n // FileSystemTraceStore reading the same dir reports duplicate\n // spans (one full, one fragment with no runId/kind/name), which\n // breaks any downstream consumer that re-opens the store\n // cross-process (e.g. the OTLP converter).\n if (record?._update) {\n try {\n await store.updateSpan(record.spanId, record)\n } catch {\n // Patch row arrived before the original — should not happen\n // with locked append order, but fall through to append so we\n // don't lose data.\n await store.appendSpan(record)\n }\n } else {\n await store.appendSpan(record)\n }\n } else if (base === 'events') {\n await store.appendEvent(record)\n } else if (base === 'artifacts') {\n await store.appendArtifact(record)\n } else if (base === 'budget') {\n await store.appendBudgetEntry(record)\n }\n }\n }\n } catch {\n /* empty dir, first run */\n }\n this.index = store\n this.loaded = true\n return store\n }\n\n async appendRun(run: Run): Promise<void> {\n await this.append('runs', run)\n }\n async updateRun(runId: string, patch: Partial<Run>): Promise<void> {\n // NDJSON is append-only; record updates as new rows with the same runId —\n // readers collapse by last-write-wins on load.\n await this.append('runs', { runId, ...patch, _update: true })\n if (this.index) await this.index.updateRun(runId, patch)\n }\n async appendSpan(span: Span): Promise<void> {\n await this.append('spans', span)\n }\n async updateSpan(spanId: string, patch: Partial<Span>): Promise<void> {\n await this.append('spans', { spanId, ...patch, _update: true })\n if (this.index) await this.index.updateSpan(spanId, patch)\n }\n async appendEvent(event: TraceEvent): Promise<void> {\n await this.append('events', event)\n }\n async appendArtifact(artifact: Artifact): Promise<void> {\n await this.append('artifacts', artifact)\n }\n async appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void> {\n await this.append('budget', entry)\n }\n\n async getRun(runId: string): Promise<Run | undefined> {\n return (await this.load()).getRun(runId)\n }\n async listRuns(filter?: RunFilter): Promise<Run[]> {\n return (await this.load()).listRuns(filter)\n }\n async spans(filter?: SpanFilter): Promise<Span[]> {\n return (await this.load()).spans(filter)\n }\n async events(filter?: EventFilter): Promise<TraceEvent[]> {\n return (await this.load()).events(filter)\n }\n async budget(runId: string): Promise<BudgetLedgerEntry[]> {\n return (await this.load()).budget(runId)\n }\n async artifacts(runId: string): Promise<Artifact[]> {\n return (await this.load()).artifacts(runId)\n }\n}\n","/**\n * `captureFetchToRawSink` — wrap a `fetch` so every request / response / error\n * against a provider is recorded into a `RawProviderSink` as the canonical\n * `RawProviderEvent` triple. The one substrate copy of the fetch-capture\n * pattern four consumers hand-roll (legal ships two copies).\n *\n * The returned value is a plain `typeof fetch` — pass it as the `fetchImpl` to\n * any OpenAI-compatible backend factory. Capture is best-effort by default: a\n * sink write that throws does NOT take down the underlying LLM call (set\n * `failClosed` to change that). Uses the existing `defaultProviderRedactor` +\n * `providerFromBaseUrl` — no new redaction policy.\n */\n\nimport {\n defaultProviderRedactor,\n type ProviderRedactor,\n providerFromBaseUrl,\n type RawProviderDirection,\n type RawProviderEvent,\n type RawProviderSink,\n} from './raw-provider-sink'\n\nexport interface CaptureFetchContext {\n /** Logical run id stamped on every captured event. Required — without it\n * the raw events can't be paired with their parent `Run`. */\n runId: string\n /** Optional logical span id (enables span-level sink filtering). */\n spanId?: string\n /** Resolved base URL (normalised, no trailing slash). Used for the event's\n * `baseUrl` and for endpoint-path extraction. */\n baseUrl: string\n /** Model id the caller intends to invoke. Stamped on every event. */\n model: string\n /** Provider override. When omitted, `providerFromBaseUrl(baseUrl)`. */\n provider?: string\n}\n\nexport interface CaptureFetchOptions {\n /** Override the capture-time redactor. Default `defaultProviderRedactor`. */\n redactor?: ProviderRedactor\n /** Cap on captured response-body bytes; beyond it the body is truncated and\n * `body_truncated` is added to `redactedFields`. Default 2 MiB. */\n responseBodyByteCap?: number\n /** When true, a sink-write failure propagates to the caller. Default false\n * — capture is best-effort so a sink failure never kills the LLM call. */\n failClosed?: boolean\n}\n\nconst DEFAULT_BODY_CAP = 2 * 1024 * 1024\n\nfunction headersToRecord(headers: Headers | undefined): Record<string, string> | undefined {\n if (!headers) return undefined\n const out: Record<string, string> = {}\n headers.forEach((value, key) => {\n out[key.toLowerCase()] = value\n })\n return Object.keys(out).length > 0 ? out : undefined\n}\n\nfunction parseMaybeJson(text: string): unknown {\n if (text.length === 0) return undefined\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\n/** Best-effort request-body read across the `fetch` input forms. */\nasync function readRequestBody(\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n): Promise<unknown> {\n if (typeof init?.body === 'string') return parseMaybeJson(init.body)\n if (init?.body != null) return undefined // streams / FormData / Blob — not captured\n if (input instanceof Request) {\n try {\n return parseMaybeJson(await input.clone().text())\n } catch {\n return undefined\n }\n }\n return undefined\n}\n\nfunction endpointFromUrl(url: string, baseUrl: string): string {\n const normalisedBase = baseUrl.replace(/\\/+$/, '')\n if (url.startsWith(normalisedBase)) return url.slice(normalisedBase.length) || '/'\n try {\n return new URL(url).pathname\n } catch {\n return url\n }\n}\n\nexport function captureFetchToRawSink(\n fetch: typeof globalThis.fetch,\n sink: RawProviderSink,\n ctx: CaptureFetchContext,\n opts: CaptureFetchOptions = {},\n): typeof globalThis.fetch {\n const provider = ctx.provider ?? providerFromBaseUrl(ctx.baseUrl)\n const redactor = opts.redactor ?? defaultProviderRedactor\n const bodyCap = opts.responseBodyByteCap ?? DEFAULT_BODY_CAP\n let warned = false\n\n const baseEvent = (direction: RawProviderDirection, endpoint: string): RawProviderEvent => ({\n eventId: crypto.randomUUID(),\n runId: ctx.runId,\n spanId: ctx.spanId,\n provider,\n model: ctx.model,\n endpoint,\n baseUrl: ctx.baseUrl,\n attemptIndex: 0, // retries are re-invocations one layer up; documented in 0.x\n direction,\n timestamp: Date.now(),\n redactedFields: [],\n })\n\n const record = async (event: RawProviderEvent): Promise<void> => {\n try {\n await sink.record(redactor(event))\n } catch (err) {\n if (opts.failClosed) throw err\n if (!warned) {\n warned = true\n console.warn(\n `captureFetchToRawSink: sink.record failed (capture is best-effort) — ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n }\n\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const url =\n typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase()\n const endpoint = endpointFromUrl(url, ctx.baseUrl)\n\n const reqHeaders = new Headers(\n init?.headers ?? (input instanceof Request ? input.headers : undefined),\n )\n await record({\n ...baseEvent('request', endpoint),\n requestHeaders: { ...headersToRecord(reqHeaders), 'x-http-method': method },\n requestBody: await readRequestBody(input, init),\n })\n\n const start = Date.now()\n let response: Response\n try {\n response = await fetch(input, init)\n } catch (err) {\n await record({\n ...baseEvent('error', endpoint),\n durationMs: Date.now() - start,\n errorMessage: err instanceof Error ? err.message : String(err),\n })\n throw err\n }\n\n // Read the body off a clone so the caller still consumes the original.\n let responseBody: unknown\n const redactedFields: string[] = []\n try {\n const raw = await response.clone().text()\n if (raw.length > bodyCap) {\n responseBody = raw.slice(0, bodyCap)\n redactedFields.push('body_truncated')\n } else {\n responseBody = parseMaybeJson(raw)\n }\n } catch {\n responseBody = undefined\n }\n\n await record({\n ...baseEvent('response', endpoint),\n durationMs: Date.now() - start,\n statusCode: response.status,\n responseHeaders: headersToRecord(response.headers),\n responseBody,\n redactedFields,\n })\n\n return response\n }\n}\n","/**\n * OpenTelemetry JSON export — maps TraceSchema v1 to OTLP/JSON so\n * traces render natively in Jaeger / Honeycomb / Langfuse / Grafana.\n *\n * Wire format only. We do NOT depend on the @opentelemetry SDK — that\n * would drag in polyfills incompatible with Workers/Edge. Consumers\n * push the JSON to their collector of choice via HTTP.\n *\n * Reference: OTLP 1.3.2 (ResourceSpans / ScopeSpans / Span).\n */\n\nimport type { Run, Span, TraceEvent } from './schema'\nimport type { TraceStore } from './store'\n\nexport const OTEL_AGENT_EVAL_SCOPE = { name: '@tangle-network/agent-eval', version: '0.3.0' }\n\nexport interface OtlpSpan {\n traceId: string\n spanId: string\n parentSpanId?: string\n name: string\n kind: number\n startTimeUnixNano: string\n endTimeUnixNano: string\n attributes: Array<{\n key: string\n value: { stringValue?: string; intValue?: string; doubleValue?: number; boolValue?: boolean }\n }>\n events?: Array<{ timeUnixNano: string; name: string; attributes?: OtlpSpan['attributes'] }>\n status?: { code: number; message?: string }\n}\n\nexport interface OtlpResourceSpans {\n resource: { attributes: OtlpSpan['attributes'] }\n scopeSpans: Array<{ scope: typeof OTEL_AGENT_EVAL_SCOPE; spans: OtlpSpan[] }>\n}\n\nexport interface OtlpExport {\n resourceSpans: OtlpResourceSpans[]\n}\n\n/** Export a single run's spans + events in OTLP/JSON. */\nexport async function exportRunAsOtlp(\n store: TraceStore,\n runId: string,\n resourceAttrs: Record<string, string | number | boolean> = {},\n): Promise<OtlpExport> {\n const run = await store.getRun(runId)\n if (!run) throw new Error(`run ${runId} not found`)\n const spans = await store.spans({ runId })\n const events = await store.events({ runId })\n const eventsBySpan = new Map<string, TraceEvent[]>()\n for (const e of events) {\n if (!e.spanId) continue\n const arr = eventsBySpan.get(e.spanId) ?? []\n arr.push(e)\n eventsBySpan.set(e.spanId, arr)\n }\n const traceId = runToTraceId(run)\n const otlpSpans: OtlpSpan[] = spans.map((s) =>\n spanToOtlp(s, traceId, eventsBySpan.get(s.spanId) ?? []),\n )\n return {\n resourceSpans: [\n {\n resource: {\n attributes: toAttributes({\n 'service.name': 'agent-eval',\n 'run.id': run.runId,\n 'run.scenario_id': run.scenarioId,\n 'run.variant_id': run.variantId ?? '',\n 'run.dataset_version': run.datasetVersion ?? '',\n 'run.code_sha': run.codeSha ?? '',\n 'run.model_fingerprint': run.modelFingerprint ?? '',\n ...resourceAttrs,\n }),\n },\n scopeSpans: [{ scope: OTEL_AGENT_EVAL_SCOPE, spans: otlpSpans }],\n },\n ],\n }\n}\n\nfunction spanToOtlp(span: Span, traceId: string, events: TraceEvent[]): OtlpSpan {\n const endedAt = span.endedAt ?? span.startedAt\n return {\n traceId,\n spanId: padSpanId(span.spanId),\n parentSpanId: span.parentSpanId ? padSpanId(span.parentSpanId) : undefined,\n name: span.name,\n kind: 1, // SPAN_KIND_INTERNAL\n startTimeUnixNano: msToNs(span.startedAt),\n endTimeUnixNano: msToNs(endedAt),\n attributes: toAttributes(flattenSpanAttributes(span)),\n events: events.map((e) => ({\n timeUnixNano: msToNs(e.timestamp),\n name: e.kind,\n attributes: toAttributes(flattenPayload(e.payload)),\n })),\n status: span.status === 'error' ? { code: 2, message: span.error } : { code: 1 },\n }\n}\n\nfunction flattenSpanAttributes(span: Span): Record<string, string | number | boolean> {\n const base: Record<string, string | number | boolean> = {\n 'span.kind': span.kind,\n }\n if (span.kind === 'llm') {\n base['llm.model'] = span.model\n if (span.inputTokens !== undefined) base['llm.input_tokens'] = span.inputTokens\n if (span.outputTokens !== undefined) base['llm.output_tokens'] = span.outputTokens\n if (span.costUsd !== undefined) base['llm.cost_usd'] = span.costUsd\n if (span.finishReason) base['llm.finish_reason'] = span.finishReason\n } else if (span.kind === 'tool') {\n base['tool.name'] = span.toolName\n if (span.latencyMs !== undefined) base['tool.latency_ms'] = span.latencyMs\n } else if (span.kind === 'retrieval') {\n base['retrieval.query'] = span.query\n base['retrieval.hits'] = span.hits.length\n } else if (span.kind === 'judge') {\n base['judge.id'] = span.judgeId\n base['judge.dimension'] = span.dimension\n base['judge.score'] = span.score\n base['judge.target_span_id'] = span.targetSpanId\n } else if (span.kind === 'sandbox') {\n if (span.image) base['sandbox.image'] = span.image\n if (span.exitCode !== undefined) base['sandbox.exit_code'] = span.exitCode\n if (span.testsPassed !== undefined) base['sandbox.tests_passed'] = span.testsPassed\n if (span.testsTotal !== undefined) base['sandbox.tests_total'] = span.testsTotal\n }\n if (span.attributes) {\n for (const [k, v] of Object.entries(span.attributes)) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') base[k] = v\n }\n }\n return base\n}\n\nfunction flattenPayload(\n payload: Record<string, unknown>,\n): Record<string, string | number | boolean> {\n const out: Record<string, string | number | boolean> = {}\n for (const [k, v] of Object.entries(payload)) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') out[k] = v\n else out[k] = JSON.stringify(v)\n }\n return out\n}\n\nfunction toAttributes(record: Record<string, string | number | boolean>): OtlpSpan['attributes'] {\n return Object.entries(record).map(([key, value]) => ({\n key,\n value:\n typeof value === 'number'\n ? Number.isInteger(value)\n ? { intValue: value.toString() }\n : { doubleValue: value }\n : typeof value === 'boolean'\n ? { boolValue: value }\n : { stringValue: value },\n }))\n}\n\nfunction msToNs(ms: number): string {\n return (BigInt(Math.floor(ms)) * 1_000_000n).toString()\n}\n\nfunction padSpanId(id: string): string {\n // OTLP wants 16-hex spanIds. UUIDs are 32-hex; strip dashes and take first 16.\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 16).padEnd(16, '0')\n}\n\nfunction runToTraceId(run: Run): string {\n // OTLP wants 32-hex traceIds. Use runId directly when it's 32-hex already,\n // else SHA-ish truncate.\n const cleaned = run.runId.replace(/-/g, '')\n return cleaned.slice(0, 32).padEnd(32, '0')\n}\n","/**\n * OTEL bridge — connects TraceEmitter span lifecycle to the OtelExporter.\n *\n * When an OtelExporter is active, every span that closes through the\n * TraceEmitter is also pushed to the exporter for real-time streaming to\n * the user's OTEL collector.\n *\n * The bridge is opt-in: attach via `otelRunCompleteHook(exporter)` as a\n * RunCompleteHook, or wrap the store with `createOtelTracingStore` for\n * real-time per-span export.\n */\n\nimport type { RunCompleteHook } from './emitter'\nimport type { ExportableSpan, OtelExporter } from './otel-export'\nimport type { LlmSpan, Span } from './schema'\nimport type { TraceStore } from './store'\n\n/**\n * Create a RunCompleteHook that exports all spans from the completed run\n * to the OTEL exporter, then flushes.\n */\nexport function otelRunCompleteHook(exporter: OtelExporter): RunCompleteHook {\n return async (ctx) => {\n const spans = await ctx.store.spans({ runId: ctx.runId })\n for (const span of spans) {\n if (span.endedAt) {\n exporter.exportSpan(storeSpanToExportable(span, ctx.runId))\n }\n }\n await exporter.flush()\n }\n}\n\n/**\n * Create an auto-exporting TraceStore wrapper that intercepts updateSpan\n * calls. When a span gets an endedAt, it's exported immediately. This\n * gives real-time streaming instead of batch-at-end.\n *\n * This is the preferred integration path: wrap the store before\n * constructing the TraceEmitter.\n */\nexport function createOtelTracingStore(\n inner: TraceStore,\n exporter: OtelExporter,\n traceId: string,\n): TraceStore {\n return {\n async appendRun(run) {\n return inner.appendRun(run)\n },\n async updateRun(runId, patch) {\n return inner.updateRun(runId, patch)\n },\n async appendSpan(span) {\n if (span.endedAt) {\n exporter.exportSpan(storeSpanToExportable(span, traceId))\n }\n return inner.appendSpan(span)\n },\n async updateSpan(spanId, patch) {\n await inner.updateSpan(spanId, patch)\n if (patch.endedAt) {\n const spans = await inner.spans({ runId: traceId })\n const found = spans.find((s) => s.spanId === spanId)\n if (found) {\n exporter.exportSpan(storeSpanToExportable(found, traceId))\n }\n }\n },\n async appendEvent(event) {\n return inner.appendEvent(event)\n },\n async appendBudgetEntry(entry) {\n return inner.appendBudgetEntry(entry)\n },\n async appendArtifact(artifact) {\n return inner.appendArtifact(artifact)\n },\n getRun: inner.getRun.bind(inner),\n listRuns: inner.listRuns.bind(inner),\n spans: inner.spans.bind(inner),\n events: inner.events.bind(inner),\n budget: inner.budget.bind(inner),\n artifacts: inner.artifacts.bind(inner),\n }\n}\n\nfunction storeSpanToExportable(span: Span, traceId: string): ExportableSpan {\n const llm = span.kind === 'llm' ? (span as LlmSpan) : undefined\n return {\n traceId,\n spanId: span.spanId,\n parentSpanId: span.parentSpanId,\n name: span.name,\n kind: span.kind,\n startedAt: span.startedAt,\n endedAt: span.endedAt,\n status: span.status,\n error: span.error,\n model: llm?.model,\n inputTokens: llm?.inputTokens,\n outputTokens: llm?.outputTokens,\n costUsd: llm?.costUsd,\n attributes: span.attributes as Record<string, unknown> | undefined,\n }\n}\n","/**\n * OTEL span exporter — streams spans to an OTLP/HTTP collector.\n *\n * Reads OTEL_EXPORTER_OTLP_ENDPOINT + OTEL_EXPORTER_OTLP_HEADERS from env\n * when no explicit config is given. Batches spans and flushes periodically\n * or when the batch fills. No @opentelemetry SDK dependency — minimal\n * OTLP/JSON serializer (~120 LOC) using the existing otel.ts helpers.\n */\n\nimport { OTEL_AGENT_EVAL_SCOPE, type OtlpExport, type OtlpSpan } from './otel'\n\nexport interface OtelExportConfig {\n /** OTLP endpoint. Reads OTEL_EXPORTER_OTLP_ENDPOINT env by default. */\n endpoint?: string\n /** OTLP headers. Reads OTEL_EXPORTER_OTLP_HEADERS env by default. */\n headers?: Record<string, string>\n /** Batch size before flush. Default 64. */\n batchSize?: number\n /** Flush interval ms. Default 5000. */\n flushIntervalMs?: number\n /** Resource attributes stamped on every export. */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Service name. Default 'agent-eval'. */\n serviceName?: string\n}\n\nexport interface OtelExporter {\n /** Called by the TraceEmitter on every span close. */\n exportSpan(span: ExportableSpan): void\n /** Force flush pending spans. */\n flush(): Promise<void>\n /** Shutdown cleanly — flushes remaining spans and stops the timer. */\n shutdown(): Promise<void>\n}\n\nexport interface ExportableSpan {\n traceId: string\n spanId: string\n parentSpanId?: string\n name: string\n kind: string\n startedAt: number\n endedAt?: number\n status?: string\n error?: string\n model?: string\n inputTokens?: number\n outputTokens?: number\n costUsd?: number\n attributes?: Record<string, unknown>\n}\n\n/**\n * Create an OTEL exporter. Returns undefined when no endpoint is configured\n * (neither via config nor env) — callers should check before attaching.\n */\nexport function createOtelExporter(config?: OtelExportConfig): OtelExporter | undefined {\n const resolvedEndpoint =\n config?.endpoint ??\n (typeof process !== 'undefined' ? process.env.OTEL_EXPORTER_OTLP_ENDPOINT : undefined)\n if (!resolvedEndpoint) return undefined\n const endpoint: string = resolvedEndpoint\n\n const headers = config?.headers ?? parseHeadersFromEnv()\n const batchSize = config?.batchSize ?? 64\n const flushIntervalMs = config?.flushIntervalMs ?? 5000\n const serviceName = config?.serviceName ?? 'agent-eval'\n const resourceAttrs = config?.resourceAttributes ?? {}\n\n const pending: OtlpSpan[] = []\n let timer: ReturnType<typeof setInterval> | undefined\n let stopped = false\n\n const exporter: OtelExporter = {\n exportSpan(span: ExportableSpan): void {\n if (stopped) return\n pending.push(toOtlpSpan(span))\n if (pending.length >= batchSize) {\n void doFlush()\n }\n },\n\n async flush(): Promise<void> {\n await doFlush()\n },\n\n async shutdown(): Promise<void> {\n stopped = true\n if (timer !== undefined) {\n clearInterval(timer)\n timer = undefined\n }\n await doFlush()\n },\n }\n\n timer = setInterval(() => {\n if (pending.length > 0) void doFlush()\n }, flushIntervalMs)\n // Unref so the timer doesn't keep the process alive.\n if (typeof timer === 'object' && 'unref' in timer) {\n ;(timer as NodeJS.Timeout).unref()\n }\n\n async function doFlush(): Promise<void> {\n if (pending.length === 0) return\n const batch = pending.splice(0)\n const body: OtlpExport = {\n resourceSpans: [\n {\n resource: {\n attributes: toAttributes({\n 'service.name': serviceName,\n ...resourceAttrs,\n }),\n },\n scopeSpans: [{ scope: OTEL_AGENT_EVAL_SCOPE, spans: batch }],\n },\n ],\n }\n const url = `${endpoint.replace(/\\/+$/, '')}/v1/traces`\n try {\n await fetch(url, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...headers,\n },\n body: JSON.stringify(body),\n })\n } catch {\n // Best-effort — telemetry export must not crash the pipeline.\n }\n }\n\n return exporter\n}\n\nfunction parseHeadersFromEnv(): Record<string, string> {\n if (typeof process === 'undefined') return {}\n const raw = process.env.OTEL_EXPORTER_OTLP_HEADERS\n if (!raw) return {}\n const out: Record<string, string> = {}\n for (const pair of raw.split(',')) {\n const eq = pair.indexOf('=')\n if (eq < 0) continue\n const key = pair.slice(0, eq).trim()\n const value = pair.slice(eq + 1).trim()\n if (key) out[key] = value\n }\n return out\n}\n\nfunction toOtlpSpan(span: ExportableSpan): OtlpSpan {\n const endedAt = span.endedAt ?? span.startedAt\n const attrs: Record<string, string | number | boolean> = {\n 'span.kind': span.kind,\n }\n if (span.model) attrs['llm.model'] = span.model\n if (span.inputTokens !== undefined) attrs['llm.input_tokens'] = span.inputTokens\n if (span.outputTokens !== undefined) attrs['llm.output_tokens'] = span.outputTokens\n if (span.costUsd !== undefined) attrs['llm.cost_usd'] = span.costUsd\n if (span.attributes) {\n for (const [k, v] of Object.entries(span.attributes)) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') attrs[k] = v\n }\n }\n return {\n traceId: padTraceId(span.traceId),\n spanId: padSpanId(span.spanId),\n parentSpanId: span.parentSpanId ? padSpanId(span.parentSpanId) : undefined,\n name: span.name,\n kind: 1, // SPAN_KIND_INTERNAL\n startTimeUnixNano: msToNs(span.startedAt),\n endTimeUnixNano: msToNs(endedAt),\n attributes: toAttributes(attrs),\n status: span.status === 'error' ? { code: 2, message: span.error } : { code: 1 },\n }\n}\n\nfunction toAttributes(record: Record<string, string | number | boolean>): OtlpSpan['attributes'] {\n return Object.entries(record).map(([key, value]) => ({\n key,\n value:\n typeof value === 'number'\n ? Number.isInteger(value)\n ? { intValue: value.toString() }\n : { doubleValue: value }\n : typeof value === 'boolean'\n ? { boolValue: value }\n : { stringValue: value },\n }))\n}\n\nfunction msToNs(ms: number): string {\n return (BigInt(Math.floor(ms)) * 1_000_000n).toString()\n}\n\nfunction padSpanId(id: string): string {\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 16).padEnd(16, '0')\n}\n\nfunction padTraceId(id: string): string {\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 32).padEnd(32, '0')\n}\n","/**\n * Replay-from-raw-events — turn every captured campaign run into a\n * re-runnable artifact.\n *\n * `RawProviderSink` captures every provider HTTP envelope; `runEvalCampaign`\n * makes that capture the default. Together they make every past run a\n * complete fingerprint of what happened on the wire — enough to replay\n * the run without burning new LLM cost.\n *\n * Three use cases this primitive enables:\n *\n * 1. **Post-hoc judging** — apply a new judge / rubric / scoring callback\n * to last week's runs without re-calling any LLM. The cost of trying\n * a new rubric drops from \"another full sweep\" to a CPU-bound replay.\n * 2. **Determinism audits** — replay the same campaign and verify the\n * raw responses match byte-for-byte. Any drift is a non-determinism\n * bug (in the harness, the prompt builder, the sandbox, …).\n * 3. **Free judge calibration** — run two judges on identical responses\n * and measure inter-judge agreement without doubling LLM spend.\n *\n * The interface is deliberately fetch-shaped. Inject `createReplayFetch`\n * into `LlmClientOptions.fetch` and every `callLlm` transparently reads\n * from the cache instead of calling the network. No new code path through\n * the LLM client is needed; the cache hit is invisible to the runner.\n */\n\nimport { ReplayError } from './errors'\nimport { canonicalize, hashJson } from './pre-registration'\nimport type { RawProviderEvent, RawProviderSink } from './trace/raw-provider-sink'\n\nexport class ReplayCacheMissError extends ReplayError {\n constructor(\n public readonly url: string,\n public readonly requestKey: string,\n message?: string,\n ) {\n super(message ?? `replay cache miss for ${url} (key=${requestKey})`)\n }\n}\n\nexport interface ReplayCacheEntry {\n request: RawProviderEvent\n response: RawProviderEvent\n}\n\nexport interface ReplayCacheStats {\n total: number\n byProvider: Record<string, number>\n byModel: Record<string, number>\n /** Spans for which we have a request but no response (run aborted mid-call). */\n orphanRequests: number\n}\n\n/**\n * In-memory deterministic cache of (request → response) keyed on a stable\n * hash of the request body. Built from a `RawProviderSink` containing\n * paired `request` and `response` events from a previous run.\n *\n * The cache is the source of truth for replay; `createReplayFetch` is a\n * thin wrapper that reads from it.\n */\nexport class ReplayCache {\n private byKey = new Map<string, ReplayCacheEntry>()\n private orphans = 0\n private byProvider: Record<string, number> = {}\n private byModel: Record<string, number> = {}\n\n /**\n * Build a cache from a sink's events. The sink must implement `list()`.\n * Filter by `runId` / `spanId` to scope to a specific replay.\n */\n static async fromSink(\n sink: RawProviderSink,\n filter: { runId?: string; spanId?: string } = {},\n ): Promise<ReplayCache> {\n if (!sink.list) {\n throw new ReplayError('ReplayCache.fromSink: sink must implement list() to be replayable.')\n }\n const events = await sink.list(filter)\n return ReplayCache.fromEvents(events)\n }\n\n /** Build a cache from an in-memory event list. */\n static async fromEvents(events: RawProviderEvent[]): Promise<ReplayCache> {\n const cache = new ReplayCache()\n // Group by (runId, spanId, attemptIndex) so request/response/error pairs are matched.\n // A cell can have many spans; each retry attempt within a span is a separate group.\n type GroupKey = string\n const groups = new Map<GroupKey, { req?: RawProviderEvent; res?: RawProviderEvent }>()\n for (const e of events) {\n const k = `${e.runId ?? ''}::${e.spanId ?? ''}::${e.attemptIndex}`\n const g = groups.get(k) ?? {}\n if (e.direction === 'request') g.req = e\n else g.res = e\n groups.set(k, g)\n }\n for (const g of groups.values()) {\n if (!g.req) continue\n if (!g.res) {\n cache.orphans += 1\n continue\n }\n const key = await requestKey(g.req)\n cache.byKey.set(key, { request: g.req, response: g.res })\n cache.byProvider[g.req.provider] = (cache.byProvider[g.req.provider] ?? 0) + 1\n cache.byModel[g.req.model] = (cache.byModel[g.req.model] ?? 0) + 1\n }\n return cache\n }\n\n /** Number of cacheable (request, response) pairs in the cache. */\n size(): number {\n return this.byKey.size\n }\n\n stats(): ReplayCacheStats {\n return {\n total: this.byKey.size,\n byProvider: { ...this.byProvider },\n byModel: { ...this.byModel },\n orphanRequests: this.orphans,\n }\n }\n\n /** Iterate every cached `(request, response)` pair in insertion order. */\n *entries(): IterableIterator<ReplayCacheEntry> {\n for (const entry of this.byKey.values()) yield entry\n }\n\n /**\n * Look up a cached response by hashing the (model, messages, temperature,\n * maxTokens, response_format) shape. Returns `undefined` on miss; the\n * caller decides whether to throw, fall back to the network, or skip.\n */\n async lookup(requestBody: unknown): Promise<ReplayCacheEntry | undefined> {\n const key = await keyFromBody(requestBody)\n return this.byKey.get(key)\n }\n}\n\nexport interface ReplayFetchOptions {\n /**\n * Behaviour on cache miss. Default `'throw'`. `'fallback'` calls the\n * `fallbackFetch` (typically `globalThis.fetch`) so a partial replay can\n * still complete; `'fail-closed'` returns a synthetic 599 response so the\n * call site sees a non-retriable failure.\n */\n onMiss?: 'throw' | 'fallback' | 'fail-closed'\n fallbackFetch?: typeof fetch\n /** Optional callback fired once per replayed call (for telemetry / counters). */\n onHit?: (info: { url: string; provider: string; model: string }) => void\n /** Optional callback fired on cache miss before the `onMiss` policy applies. */\n onMissNotify?: (info: { url: string; requestBody: unknown }) => void\n}\n\n/**\n * Build a `fetch`-shaped function that serves cached responses out of a\n * `ReplayCache` for any URL ending in `/chat/completions`. Pass through\n * `LlmClientOptions.fetch` and `callLlm` becomes free.\n *\n * Non-`/chat/completions` URLs are passed straight to the fallback fetch\n * (default: `globalThis.fetch`). This matters because non-LLM HTTP work\n * (judge HTTP servers, sandbox callbacks) sometimes flows through the same\n * `fetch` and shouldn't be intercepted.\n */\nexport function createReplayFetch(cache: ReplayCache, opts: ReplayFetchOptions = {}): typeof fetch {\n const onMiss = opts.onMiss ?? 'throw'\n const fallback = opts.fallbackFetch ?? globalThis.fetch?.bind(globalThis)\n\n return (async (input: RequestInfo | URL, init?: RequestInit) => {\n const url =\n typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url\n if (!/\\/chat\\/completions(?:[?#].*)?$/.test(url)) {\n if (!fallback)\n throw new ReplayError(\n `replay fetch: non-completions URL ${url} but no fallbackFetch configured`,\n )\n return fallback(input as RequestInfo, init)\n }\n let bodyParsed: unknown\n if (init?.body && typeof init.body === 'string') {\n try {\n bodyParsed = JSON.parse(init.body)\n } catch {\n /* raw body, not JSON */\n }\n }\n const hit = bodyParsed === undefined ? undefined : await cache.lookup(bodyParsed)\n if (hit) {\n opts.onHit?.({ url, provider: hit.request.provider, model: hit.request.model })\n const status = hit.response.statusCode ?? 200\n const headers = new Headers(\n Object.entries(hit.response.responseHeaders ?? { 'Content-Type': 'application/json' }),\n )\n const bodyText =\n typeof hit.response.responseBody === 'string'\n ? hit.response.responseBody\n : JSON.stringify(hit.response.responseBody ?? {})\n return new Response(bodyText, { status, headers })\n }\n opts.onMissNotify?.({ url, requestBody: bodyParsed })\n if (onMiss === 'throw') {\n const key = bodyParsed === undefined ? '<unparseable>' : await keyFromBody(bodyParsed)\n throw new ReplayCacheMissError(url, key)\n }\n if (onMiss === 'fail-closed') {\n return new Response(JSON.stringify({ error: 'replay_cache_miss' }), { status: 599 })\n }\n if (!fallback)\n throw new ReplayError('replay fetch: onMiss=fallback but no fallbackFetch configured')\n return fallback(input as RequestInfo, init)\n }) as typeof fetch\n}\n\n/**\n * Convenience iterator over `(request, response)` pairs in a sink — for\n * post-hoc scoring that doesn't need a `fetch` shim. The judge or scorer\n * runs purely in-process over cached LLM outputs.\n */\nexport async function* iterateRawCalls(\n sink: RawProviderSink,\n filter: { runId?: string; spanId?: string } = {},\n): AsyncGenerator<ReplayCacheEntry> {\n if (!sink.list) {\n throw new ReplayError('iterateRawCalls: sink must implement list().')\n }\n const events = await sink.list(filter)\n const cache = await ReplayCache.fromEvents(events)\n for (const entry of cache.entries()) yield entry\n}\n\n// ── Hashing ──────────────────────────────────────────────────────────────\n\n/**\n * Canonical request key.\n *\n * `model + messages + temperature + max_tokens|max_completion_tokens +\n * response_format` are the dimensions that affect the response shape.\n * Other fields (timestamp headers, provider-specific metadata) are\n * intentionally excluded so a request hashes the same across re-runs.\n */\nasync function requestKey(event: RawProviderEvent): Promise<string> {\n return keyFromBody(event.requestBody)\n}\n\nasync function keyFromBody(body: unknown): Promise<string> {\n if (body == null || typeof body !== 'object') return hashJson({ raw: String(body) })\n const b = body as Record<string, unknown>\n const reduced = canonicalize({\n model: b.model ?? null,\n messages: b.messages ?? null,\n temperature: b.temperature ?? null,\n max_tokens: b.max_tokens ?? null,\n max_completion_tokens: b.max_completion_tokens ?? null,\n response_format: b.response_format ?? null,\n })\n return hashJson(reduced)\n}\n"],"mappings":"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","names":["fetch","toAttributes","padSpanId","msToNs","requestKey"]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runCampaign,
|
|
3
3
|
summarizeBackendIntegrity
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
DEFAULT_REDACTION_RULES
|
|
7
|
-
} from "./chunk-GGE4NNQT.js";
|
|
4
|
+
} from "./chunk-ZPSKPT3V.js";
|
|
8
5
|
import {
|
|
9
6
|
callLlm
|
|
10
7
|
} from "./chunk-IHDHUN2X.js";
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_REDACTION_RULES
|
|
10
|
+
} from "./chunk-GGE4NNQT.js";
|
|
11
11
|
import {
|
|
12
12
|
ValidationError
|
|
13
13
|
} from "./chunk-3BFEG2F6.js";
|
|
@@ -729,6 +729,35 @@ function buildReflectionPrompt(ctx) {
|
|
|
729
729
|
sections.push("```");
|
|
730
730
|
return sections.join("\n");
|
|
731
731
|
}
|
|
732
|
+
function renderAnalystEvidence(findings, report) {
|
|
733
|
+
const sections = [];
|
|
734
|
+
const rows = Array.isArray(findings) ? findings : [];
|
|
735
|
+
if (rows.length > 0) {
|
|
736
|
+
const order = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
|
|
737
|
+
const ranked = rows.map((f) => f && typeof f === "object" ? f : {}).sort((a, b) => (order[String(a.severity)] ?? 9) - (order[String(b.severity)] ?? 9)).slice(0, 12);
|
|
738
|
+
sections.push("## Diagnosed findings (act on these root causes)");
|
|
739
|
+
sections.push("");
|
|
740
|
+
for (const f of ranked) {
|
|
741
|
+
const sev = typeof f.severity === "string" ? f.severity : "info";
|
|
742
|
+
const area = typeof f.area === "string" ? ` [${f.area}]` : "";
|
|
743
|
+
const claim = typeof f.claim === "string" ? f.claim : JSON.stringify(f);
|
|
744
|
+
sections.push(`- **${sev}**${area} ${truncate(claim, 300)}`);
|
|
745
|
+
if (typeof f.recommended_action === "string" && f.recommended_action.trim()) {
|
|
746
|
+
sections.push(` - fix: ${truncate(f.recommended_action, 200)}`);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
sections.push("");
|
|
750
|
+
}
|
|
751
|
+
const reportText = typeof report === "string" ? report : report && typeof report === "object" ? JSON.stringify(report) : "";
|
|
752
|
+
if (reportText.trim()) {
|
|
753
|
+
sections.push("## Research report");
|
|
754
|
+
sections.push("");
|
|
755
|
+
sections.push(truncate(reportText.trim(), 1500));
|
|
756
|
+
sections.push("");
|
|
757
|
+
}
|
|
758
|
+
if (sections.length === 0) return null;
|
|
759
|
+
return sections.join("\n");
|
|
760
|
+
}
|
|
732
761
|
function truncate(s, max) {
|
|
733
762
|
if (s.length <= max) return s;
|
|
734
763
|
return `${s.slice(0, max)}\u2026 [truncated]`;
|
|
@@ -840,7 +869,7 @@ function parseReflectionResponse(raw, maxProposals) {
|
|
|
840
869
|
}
|
|
841
870
|
|
|
842
871
|
// src/campaign/drivers/gepa.ts
|
|
843
|
-
var REFLECTION_SYSTEM = 'You are an expert prompt engineer. Output ONLY a JSON object of shape {"proposals":[{"label":string,"rationale":string,"payload":string}]} where each `payload` is the FULL improved surface text. No prose outside the JSON.';
|
|
872
|
+
var REFLECTION_SYSTEM = 'You are an expert prompt engineer performing GEPA-style reflective mutation. You are given a prompt surface, its top trials (preserve what works) and its bottom trials (the evidence to fix). For each proposal, reason in this order before writing the payload: (1) LOCALIZE \u2014 point to the exact span of the current surface responsible for a bottom-trial failure; (2) DIAGNOSE the root cause (a missing rule, an ambiguous instruction, an over-broad directive), not just the symptom; (3) propose the MINIMAL, GENERALIZABLE edit that fixes the whole failure class \u2014 state it as a rule the agent should follow, never a patch memorized to the shown trials (that is overfitting and will not transfer to the held-out set); (4) PRESERVE every instruction the top trials depend on \u2014 do not delete or weaken working guidance. Put this localize\u2192diagnose\u2192fix reasoning in each proposal\'s `rationale`. Output ONLY a JSON object of shape {"proposals":[{"label":string,"rationale":string,"payload":string}]} where each `payload` is the FULL improved surface text. No prose outside the JSON.';
|
|
844
873
|
var COMBINE_SYSTEM = 'You are an expert prompt engineer performing a GEPA "combine complementary lessons" merge. You are given several non-dominated versions of one surface; each is uniquely best on different scenarios. Produce ONE new version that keeps what makes each version strong on its winning scenarios and resolves conflicts in favor of the more general rule. Output ONLY a JSON object of shape {"proposals":[{"label":string,"rationale":string,"payload":string}]} with exactly one proposal whose `payload` is the FULL merged surface text. No prose outside the JSON.';
|
|
845
874
|
function gepaDriver(opts) {
|
|
846
875
|
const evidenceK = opts.evidenceK ?? 3;
|
|
@@ -906,12 +935,16 @@ function gepaDriver(opts) {
|
|
|
906
935
|
childCount: reflectCount,
|
|
907
936
|
mutationPrimitives: opts.mutationPrimitives
|
|
908
937
|
});
|
|
938
|
+
const analyst = renderAnalystEvidence(ctx.findings, ctx.report);
|
|
939
|
+
const finalPrompt = analyst ? `${userPrompt}
|
|
940
|
+
|
|
941
|
+
${analyst}` : userPrompt;
|
|
909
942
|
const result = await callLlm(
|
|
910
943
|
{
|
|
911
944
|
model: opts.model,
|
|
912
945
|
messages: [
|
|
913
946
|
{ role: "system", content: REFLECTION_SYSTEM },
|
|
914
|
-
{ role: "user", content:
|
|
947
|
+
{ role: "user", content: finalPrompt }
|
|
915
948
|
],
|
|
916
949
|
jsonMode: true,
|
|
917
950
|
temperature: opts.temperature ?? 0.7,
|
|
@@ -1226,6 +1259,7 @@ async function runOptimization(opts) {
|
|
|
1226
1259
|
});
|
|
1227
1260
|
const generations = [];
|
|
1228
1261
|
const history = [];
|
|
1262
|
+
let currentFindings = opts.findings ?? [];
|
|
1229
1263
|
let currentSurfaces = [opts.baselineSurface];
|
|
1230
1264
|
let winnerSurface = opts.baselineSurface;
|
|
1231
1265
|
let winnerSurfaceHash = surfaceHash(opts.baselineSurface);
|
|
@@ -1241,7 +1275,7 @@ async function runOptimization(opts) {
|
|
|
1241
1275
|
const proposed = await opts.driver.propose({
|
|
1242
1276
|
currentSurface: currentSurfaces[0] ?? opts.baselineSurface,
|
|
1243
1277
|
history,
|
|
1244
|
-
findings:
|
|
1278
|
+
findings: currentFindings,
|
|
1245
1279
|
populationSize: opts.populationSize,
|
|
1246
1280
|
generation: gen,
|
|
1247
1281
|
signal: new AbortController().signal,
|
|
@@ -1305,6 +1339,19 @@ async function runOptimization(opts) {
|
|
|
1305
1339
|
campaign: s.campaign
|
|
1306
1340
|
}))
|
|
1307
1341
|
});
|
|
1342
|
+
if (opts.analyzeGeneration && gen < opts.maxGenerations - 1) {
|
|
1343
|
+
const fresh = await opts.analyzeGeneration({
|
|
1344
|
+
generation: gen,
|
|
1345
|
+
runDir: `${opts.runDir}/gen-${gen}`,
|
|
1346
|
+
candidates: surfaceResults.map((s) => ({
|
|
1347
|
+
surfaceHash: s.surfaceHash,
|
|
1348
|
+
campaign: s.campaign,
|
|
1349
|
+
composite: s.composite
|
|
1350
|
+
})),
|
|
1351
|
+
history
|
|
1352
|
+
});
|
|
1353
|
+
if (Array.isArray(fresh)) currentFindings = fresh;
|
|
1354
|
+
}
|
|
1308
1355
|
}
|
|
1309
1356
|
return {
|
|
1310
1357
|
generations,
|
|
@@ -1384,7 +1431,7 @@ async function runImprovementLoop(opts) {
|
|
|
1384
1431
|
const dispatchTimeoutMs = opts.dispatchTimeoutMs ?? DEFAULT_DISPATCH_TIMEOUT_MS;
|
|
1385
1432
|
const optimization = await runOptimization({ ...opts, dispatchTimeoutMs });
|
|
1386
1433
|
const winnerIsBaseline = optimization.winnerSurfaceHash === surfaceHash(opts.baselineSurface);
|
|
1387
|
-
const { runCampaign: runCampaign2 } = await import("./run-campaign-
|
|
1434
|
+
const { runCampaign: runCampaign2 } = await import("./run-campaign-OVEZF24D.js");
|
|
1388
1435
|
const baselineOnHoldout = await runCampaign2({
|
|
1389
1436
|
...opts,
|
|
1390
1437
|
dispatchTimeoutMs,
|
|
@@ -1763,6 +1810,7 @@ export {
|
|
|
1763
1810
|
runCanaries,
|
|
1764
1811
|
DEFAULT_MUTATION_PRIMITIVES,
|
|
1765
1812
|
buildReflectionPrompt,
|
|
1813
|
+
renderAnalystEvidence,
|
|
1766
1814
|
parseReflectionResponse,
|
|
1767
1815
|
gepaDriver,
|
|
1768
1816
|
extractH2Sections,
|
|
@@ -1784,4 +1832,4 @@ export {
|
|
|
1784
1832
|
provenanceSpansPath,
|
|
1785
1833
|
emitLoopProvenance
|
|
1786
1834
|
};
|
|
1787
|
-
//# sourceMappingURL=chunk-
|
|
1835
|
+
//# sourceMappingURL=chunk-JYE3WOTE.js.map
|