@tangle-network/agent-eval 0.161.1 → 0.163.2

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.
Files changed (139) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/{active-curriculum-CD5TU2yW.js → active-curriculum-OjIWgrUJ.js} +2 -2
  3. package/dist/{active-curriculum-CD5TU2yW.js.map → active-curriculum-OjIWgrUJ.js.map} +1 -1
  4. package/dist/analyst/index.d.ts +2 -2
  5. package/dist/analyst/index.d.ts.map +1 -1
  6. package/dist/analyst/index.js +3 -3
  7. package/dist/{baseline-BhPRQBVn.js → baseline-BC-eBZ7U.js} +2 -2
  8. package/dist/{baseline-BhPRQBVn.js.map → baseline-BC-eBZ7U.js.map} +1 -1
  9. package/dist/{benchmark-command-BDC3Gocz.js → benchmark-command-CF-4GEWZ.js} +9 -8
  10. package/dist/benchmark-command-CF-4GEWZ.js.map +1 -0
  11. package/dist/benchmarks/index.d.ts +1 -1
  12. package/dist/benchmarks/index.js +3 -3
  13. package/dist/builder-eval/index.d.ts.map +1 -1
  14. package/dist/builder-eval/index.js +22 -8
  15. package/dist/builder-eval/index.js.map +1 -1
  16. package/dist/campaign/index.js +8 -8
  17. package/dist/{campaign-BSmOwskD.js → campaign-DQZmc2Dq.js} +12 -12
  18. package/dist/{campaign-BSmOwskD.js.map → campaign-DQZmc2Dq.js.map} +1 -1
  19. package/dist/{chat-json-call-6g5sJobJ.js → chat-json-call-5Jxna-aV.js} +2 -2
  20. package/dist/{chat-json-call-6g5sJobJ.js.map → chat-json-call-5Jxna-aV.js.map} +1 -1
  21. package/dist/cli.js +3 -3
  22. package/dist/contract/index.js +7 -7
  23. package/dist/{counterfactual-D_VWavVm.js → counterfactual-Bjq1mlUu.js} +2 -2
  24. package/dist/{counterfactual-D_VWavVm.js.map → counterfactual-Bjq1mlUu.js.map} +1 -1
  25. package/dist/{define-agent-eval-h-s-sI-v.js → define-agent-eval-D08pWIJb.js} +13 -13
  26. package/dist/{define-agent-eval-h-s-sI-v.js.map → define-agent-eval-D08pWIJb.js.map} +1 -1
  27. package/dist/{descriptive-jDOuI6mz.js → descriptive-1V17A-qa.js} +2 -2
  28. package/dist/{descriptive-jDOuI6mz.js.map → descriptive-1V17A-qa.js.map} +1 -1
  29. package/dist/{dspy-rlm-engine-DptEII26.js → dspy-rlm-engine-DhA9qKIm.js} +2 -2
  30. package/dist/{dspy-rlm-engine-DptEII26.js.map → dspy-rlm-engine-DhA9qKIm.js.map} +1 -1
  31. package/dist/emitter-D_jYSGRd.d.ts.map +1 -1
  32. package/dist/{emitter-BpYFQPj4.js → emitter-DeQHiDMm.js} +13 -6
  33. package/dist/emitter-DeQHiDMm.js.map +1 -0
  34. package/dist/{eval-campaign-BsXWL2-2.js → eval-campaign-BfohKmzx.js} +3 -3
  35. package/dist/{eval-campaign-BsXWL2-2.js.map → eval-campaign-BfohKmzx.js.map} +1 -1
  36. package/dist/experiment/index.js +8 -8
  37. package/dist/{experiment-tracker-Ym6rEQT1.js → experiment-tracker-BKEumQug.js} +2 -2
  38. package/dist/{experiment-tracker-Ym6rEQT1.js.map → experiment-tracker-BKEumQug.js.map} +1 -1
  39. package/dist/{external-optimizer-process-WosTBChy.js → external-optimizer-process-BFmh36vW.js} +2 -2
  40. package/dist/{external-optimizer-process-WosTBChy.js.map → external-optimizer-process-BFmh36vW.js.map} +1 -1
  41. package/dist/{external-optimizer-subprocess-BIWbHpgD.js → external-optimizer-subprocess-CqLMW3nh.js} +2 -2
  42. package/dist/{external-optimizer-subprocess-BIWbHpgD.js.map → external-optimizer-subprocess-CqLMW3nh.js.map} +1 -1
  43. package/dist/fuzz.d.ts +1 -2
  44. package/dist/fuzz.d.ts.map +1 -1
  45. package/dist/fuzz.js +4 -10
  46. package/dist/fuzz.js.map +1 -1
  47. package/dist/index.d.ts +3 -3
  48. package/dist/index.js +26 -26
  49. package/dist/index.js.map +1 -1
  50. package/dist/{internal-BDHPCnjk.js → internal-BMFSR8Ns.js} +3 -19
  51. package/dist/internal-BMFSR8Ns.js.map +1 -0
  52. package/dist/{judge-calibration-zZjLz8hr.js → judge-calibration-BnpVKtnb.js} +3 -13
  53. package/dist/judge-calibration-BnpVKtnb.js.map +1 -0
  54. package/dist/judge-calibration-C5CbMYce.d.ts.map +1 -1
  55. package/dist/{llm-client-hgDieDNN.js → llm-client-BFMRpmqb.js} +8 -11
  56. package/dist/llm-client-BFMRpmqb.js.map +1 -0
  57. package/dist/{llm-judge-BhasIPFT.js → llm-judge-Du7WQPh7.js} +7 -7
  58. package/dist/{llm-judge-BhasIPFT.js.map → llm-judge-Du7WQPh7.js.map} +1 -1
  59. package/dist/meta-eval/index.d.ts +2 -1
  60. package/dist/meta-eval/index.d.ts.map +1 -1
  61. package/dist/meta-eval/index.js +14 -22
  62. package/dist/meta-eval/index.js.map +1 -1
  63. package/dist/openapi.json +1 -1
  64. package/dist/{paired-arms-D-XRF_fy.js → paired-arms-D4aeIHUy.js} +3 -3
  65. package/dist/{paired-arms-D-XRF_fy.js.map → paired-arms-D4aeIHUy.js.map} +1 -1
  66. package/dist/{paired-tests-BHIhYVdu.js → paired-tests-C8iCsioC.js} +3 -3
  67. package/dist/{paired-tests-BHIhYVdu.js.map → paired-tests-C8iCsioC.js.map} +1 -1
  68. package/dist/pipelines/index.d.ts +3 -2
  69. package/dist/pipelines/index.d.ts.map +1 -1
  70. package/dist/pipelines/index.js +4 -19
  71. package/dist/pipelines/index.js.map +1 -1
  72. package/dist/{power-and-mde-CHIrXJll.js → power-and-mde-B8F2RdcD.js} +3 -3
  73. package/dist/{power-and-mde-CHIrXJll.js.map → power-and-mde-B8F2RdcD.js.map} +1 -1
  74. package/dist/{power-preflight-DEw-uC7q.js → power-preflight-CFXm0Vjo.js} +3 -3
  75. package/dist/{power-preflight-DEw-uC7q.js.map → power-preflight-CFXm0Vjo.js.map} +1 -1
  76. package/dist/{produced-state-DZ89riy5.js → produced-state-Be0BK3RN.js} +3 -3
  77. package/dist/{produced-state-DZ89riy5.js.map → produced-state-Be0BK3RN.js.map} +1 -1
  78. package/dist/{promotion-policy-xzA40Evo.js → promotion-policy-LY9mVQ7W.js} +3 -3
  79. package/dist/{promotion-policy-xzA40Evo.js.map → promotion-policy-LY9mVQ7W.js.map} +1 -1
  80. package/dist/{query-DxPYqpmT.d.ts → query-CwnHlu5p.d.ts} +19 -2
  81. package/dist/query-CwnHlu5p.d.ts.map +1 -0
  82. package/dist/{query-CHmMP42p.js → query-_5g6re3_.js} +44 -2
  83. package/dist/query-_5g6re3_.js.map +1 -0
  84. package/dist/random-Dn5fPWkt.js +21 -0
  85. package/dist/random-Dn5fPWkt.js.map +1 -0
  86. package/dist/record-id-DUgsK5qp.js +17 -0
  87. package/dist/record-id-DUgsK5qp.js.map +1 -0
  88. package/dist/{release-confidence-DKfD2RYU.js → release-confidence-nGDJiiwc.js} +2 -2
  89. package/dist/{release-confidence-DKfD2RYU.js.map → release-confidence-nGDJiiwc.js.map} +1 -1
  90. package/dist/reporting.js +6 -6
  91. package/dist/{reward-hacking-t4lB1yt8.js → reward-hacking-O5zKDANP.js} +2 -2
  92. package/dist/{reward-hacking-t4lB1yt8.js.map → reward-hacking-O5zKDANP.js.map} +1 -1
  93. package/dist/rl.d.ts.map +1 -1
  94. package/dist/rl.js +9 -15
  95. package/dist/rl.js.map +1 -1
  96. package/dist/{rubric-predictive-validity-CK8SCOg-.js → rubric-predictive-validity-2D5Gw9z9.js} +3 -3
  97. package/dist/{rubric-predictive-validity-CK8SCOg-.js.map → rubric-predictive-validity-2D5Gw9z9.js.map} +1 -1
  98. package/dist/{semantic-concept-judge-BSkKKHeq.js → semantic-concept-judge-BsDMOwJr.js} +2 -2
  99. package/dist/{semantic-concept-judge-BSkKKHeq.js.map → semantic-concept-judge-BsDMOwJr.js.map} +1 -1
  100. package/dist/{sequential-rYW-Ophm.js → sequential-BLMbdrD7.js} +3 -3
  101. package/dist/{sequential-rYW-Ophm.js.map → sequential-BLMbdrD7.js.map} +1 -1
  102. package/dist/{server-BtFd4uzB.js → server-BjYiJHoJ.js} +2 -2
  103. package/dist/{server-BtFd4uzB.js.map → server-BjYiJHoJ.js.map} +1 -1
  104. package/dist/{skillopt-optimization-method-DbaekMcn.js → skillopt-optimization-method-UArRo-nr.js} +6 -6
  105. package/dist/{skillopt-optimization-method-DbaekMcn.js.map → skillopt-optimization-method-UArRo-nr.js.map} +1 -1
  106. package/dist/{store-tool-spans-Dlh9vkFK.js → store-tool-spans-BVga3c37.js} +21 -17
  107. package/dist/store-tool-spans-BVga3c37.js.map +1 -0
  108. package/dist/store-tool-spans-DPUG7UUY.d.ts.map +1 -1
  109. package/dist/{student-t-CvBq2mve.js → student-t-BA-Uy51p.js} +2 -2
  110. package/dist/{student-t-CvBq2mve.js.map → student-t-BA-Uy51p.js.map} +1 -1
  111. package/dist/{summary-report-BI5hUtvK.js → summary-report-BXeQ5Ues.js} +6 -6
  112. package/dist/{summary-report-BI5hUtvK.js.map → summary-report-BXeQ5Ues.js.map} +1 -1
  113. package/dist/supervisor-run/index.js +1 -1
  114. package/dist/{tool-waste-BqzmVdJk.js → tool-waste-8BQiUc8K.js} +4 -4
  115. package/dist/{tool-waste-BqzmVdJk.js.map → tool-waste-8BQiUc8K.js.map} +1 -1
  116. package/dist/{tool-waste-Dro0gJi3.d.ts → tool-waste-CKc7bYIg.d.ts} +2 -2
  117. package/dist/{tool-waste-Dro0gJi3.d.ts.map → tool-waste-CKc7bYIg.d.ts.map} +1 -1
  118. package/dist/trace-repair/index.js +1 -1
  119. package/dist/traces.d.ts +2 -2
  120. package/dist/traces.d.ts.map +1 -1
  121. package/dist/traces.js +8 -17
  122. package/dist/traces.js.map +1 -1
  123. package/dist/trajectory-replay/index.d.ts.map +1 -1
  124. package/dist/trajectory-replay/index.js +3 -13
  125. package/dist/trajectory-replay/index.js.map +1 -1
  126. package/dist/{types-BPb2Kf_C2.d.ts → types-BPb2Kf_C.d.ts} +1 -1
  127. package/dist/types-BPb2Kf_C.d.ts.map +1 -0
  128. package/dist/types-Bfk0uxRj.d.ts.map +1 -1
  129. package/dist/wire/index.js +1 -1
  130. package/package.json +1 -1
  131. package/dist/benchmark-command-BDC3Gocz.js.map +0 -1
  132. package/dist/emitter-BpYFQPj4.js.map +0 -1
  133. package/dist/internal-BDHPCnjk.js.map +0 -1
  134. package/dist/judge-calibration-zZjLz8hr.js.map +0 -1
  135. package/dist/llm-client-hgDieDNN.js.map +0 -1
  136. package/dist/query-CHmMP42p.js.map +0 -1
  137. package/dist/query-DxPYqpmT.d.ts.map +0 -1
  138. package/dist/store-tool-spans-Dlh9vkFK.js.map +0 -1
  139. package/dist/types-BPb2Kf_C2.d.ts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"emitter-BpYFQPj4.js","names":[],"sources":["../src/trace/emitter.ts"],"sourcesContent":["/**\n * TraceEmitter — hierarchical span builder that auto-parents using an\n * internal stack. One emitter per Run; emitters do NOT share state.\n *\n * Convenience methods (`llm`, `tool`, `retrieval`, `judge`, `sandbox`)\n * return a `SpanHandle` with `.end()` / `.fail()` so callers don't\n * have to thread spanIds manually. For async workflows that can't use\n * the stack (e.g. fan-out parallel calls), pass `parentSpanId`\n * explicitly.\n */\n\nimport type {\n Artifact,\n BudgetLedgerEntry,\n EventKind,\n JudgeSpan,\n LlmSpan,\n RetrievalSpan,\n Run,\n RunOutcome,\n SandboxSpan,\n Span,\n SpanKind,\n ToolSpan,\n TraceEvent,\n} from './schema'\nimport type { TraceStore } from './store'\n\nexport interface SpanHandle<S extends Span = Span> {\n span: S\n end(patch?: Partial<S>): Promise<void>\n fail(error: string | Error, patch?: Partial<S>): Promise<void>\n}\n\nexport interface RunCompleteHookContext {\n runId: string\n emitter: TraceEmitter\n store: TraceStore\n /** Outcome the caller passed to `endRun` (undefined for `abortRun`). */\n outcome?: RunOutcome\n /** Final run status. */\n status: 'completed' | 'failed' | 'aborted'\n}\n\nexport type RunCompleteHook = (ctx: RunCompleteHookContext) => Promise<void> | void\n\nexport interface TraceEmitterOptions {\n runId?: string\n /** Inject a clock for deterministic tests. */\n now?: () => number\n /** Inject an id generator for deterministic tests. */\n id?: () => string\n /**\n * Hooks fired after `endRun` / `abortRun` writes the final run state.\n * Designed for trace-analyst auto-execution, integrity assertions, and\n * outbound notifications. Hooks run sequentially in the order supplied.\n *\n * By default a hook that throws is swallowed and logged as a `note` event\n * on the run — auto-orchestration must not crash the underlying flow.\n * Set `hookErrors: 'throw'` to propagate.\n */\n onRunComplete?: RunCompleteHook[]\n /** `'swallow'` (default) | `'throw'`. */\n hookErrors?: 'swallow' | 'throw'\n}\n\nexport class TraceEmitter {\n private store: TraceStore\n private stack: string[] = []\n private _runId: string\n private now: () => number\n private id: () => string\n private hooks: RunCompleteHook[]\n private hookErrors: 'swallow' | 'throw'\n\n constructor(store: TraceStore, options: TraceEmitterOptions = {}) {\n this.store = store\n this.now = options.now ?? (() => Date.now())\n this.id = options.id ?? (() => cryptoRandomId())\n this._runId = options.runId ?? this.id()\n this.hooks = options.onRunComplete ?? []\n this.hookErrors = options.hookErrors ?? 'swallow'\n }\n\n get runId(): string {\n return this._runId\n }\n\n get traceStore(): TraceStore {\n return this.store\n }\n\n /** Append a hook after construction (e.g. attach the trace analyst). */\n addRunCompleteHook(hook: RunCompleteHook): void {\n this.hooks.push(hook)\n }\n\n // ── Run lifecycle ──────────────────────────────────────────────────\n\n /**\n * Begin a Run.\n *\n * `scenarioId` is required on the persisted Run shape — every Run downstream\n * gets a non-empty scenarioId so filters and aggregations stay simple — but\n * the INPUT here accepts it as optional. When omitted, startRun substitutes\n * a sensible default (`run.layer ?? run.tags?.['kind'] ?? 'runtime'`) so\n * runtime / operator / meta-eval runs that have no curated-scenario corpus\n * to anchor to don't have to invent placeholder strings at the call site.\n */\n async startRun(\n run: Omit<Run, 'runId' | 'scenarioId' | 'startedAt' | 'status'> & { scenarioId?: string },\n ): Promise<Run> {\n const scenarioId = run.scenarioId ?? run.layer ?? run.tags?.kind ?? 'runtime'\n const full: Run = {\n ...run,\n scenarioId,\n runId: this._runId,\n startedAt: this.now(),\n status: 'running',\n }\n await this.store.appendRun(full)\n return full\n }\n\n async endRun(outcome?: RunOutcome): Promise<void> {\n const status: 'completed' | 'failed' = outcome?.pass === false ? 'failed' : 'completed'\n await this.store.updateRun(this._runId, { endedAt: this.now(), status, outcome })\n await this.runHooks({ runId: this._runId, emitter: this, store: this.store, outcome, status })\n }\n\n async abortRun(reason: string): Promise<void> {\n const outcome = { pass: false, notes: reason }\n await this.store.updateRun(this._runId, {\n endedAt: this.now(),\n status: 'aborted',\n outcome,\n })\n await this.runHooks({\n runId: this._runId,\n emitter: this,\n store: this.store,\n outcome,\n status: 'aborted',\n })\n }\n\n private async runHooks(ctx: RunCompleteHookContext): Promise<void> {\n for (const hook of this.hooks) {\n try {\n await hook(ctx)\n } catch (err) {\n if (this.hookErrors === 'throw') throw err\n try {\n await this.store.appendEvent({\n eventId: this.id(),\n runId: this._runId,\n kind: 'log',\n timestamp: this.now(),\n payload: {\n source: 'run_complete_hook',\n error: err instanceof Error ? err.message : String(err),\n },\n })\n } catch {\n // best-effort\n }\n }\n }\n }\n\n // ── Generic span ───────────────────────────────────────────────────\n\n async span<S extends Span = Span>(\n init: {\n kind: SpanKind\n name: string\n parentSpanId?: string\n attributes?: Record<string, unknown>\n } & Partial<Omit<S, 'spanId' | 'runId' | 'startedAt' | 'kind' | 'name'>>,\n ): Promise<SpanHandle<S>> {\n const spanId = this.id()\n const parent = init.parentSpanId ?? this.stack[this.stack.length - 1]\n const span = {\n spanId,\n parentSpanId: parent,\n runId: this._runId,\n startedAt: this.now(),\n ...init,\n } as unknown as S\n await this.store.appendSpan(span)\n this.stack.push(spanId)\n return this.handle<S>(span)\n }\n\n private handle<S extends Span>(span: S): SpanHandle<S> {\n return {\n span,\n end: async (patch?: Partial<S>) => {\n const endedAt = this.now()\n await this.store.updateSpan(span.spanId, {\n endedAt,\n status: 'ok',\n ...patch,\n } as Partial<Span>)\n this.pop(span.spanId)\n },\n fail: async (error: string | Error, patch?: Partial<S>) => {\n const endedAt = this.now()\n const errStr = error instanceof Error ? error.message : error\n await this.store.updateSpan(span.spanId, {\n endedAt,\n status: 'error',\n error: errStr,\n ...patch,\n } as Partial<Span>)\n this.pop(span.spanId)\n },\n }\n }\n\n private pop(spanId: string): void {\n const idx = this.stack.lastIndexOf(spanId)\n if (idx >= 0) this.stack.splice(idx, 1)\n }\n\n // ── Typed span conveniences ────────────────────────────────────────\n\n llm(\n init: Omit<LlmSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<LlmSpan>> {\n return this.span<LlmSpan>({ kind: 'llm', ...init })\n }\n\n tool(\n init: Omit<ToolSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<ToolSpan>> {\n return this.span<ToolSpan>({ kind: 'tool', ...init })\n }\n\n retrieval(\n init: Omit<RetrievalSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<RetrievalSpan>> {\n return this.span<RetrievalSpan>({ kind: 'retrieval', ...init })\n }\n\n async recordJudge(\n verdict: Omit<JudgeSpan, 'spanId' | 'runId' | 'kind' | 'startedAt' | 'endedAt'>,\n ): Promise<JudgeSpan> {\n const spanId = this.id()\n const now = this.now()\n const full: JudgeSpan = {\n spanId,\n runId: this._runId,\n kind: 'judge',\n startedAt: now,\n endedAt: now,\n status: 'ok',\n ...verdict,\n }\n await this.store.appendSpan(full)\n return full\n }\n\n sandbox(\n init: Omit<SandboxSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>,\n ): Promise<SpanHandle<SandboxSpan>> {\n return this.span<SandboxSpan>({ kind: 'sandbox', ...init })\n }\n\n // ── Events ─────────────────────────────────────────────────────────\n\n async emit(event: {\n kind: EventKind\n spanId?: string\n payload?: Record<string, unknown>\n }): Promise<TraceEvent> {\n const full: TraceEvent = {\n eventId: this.id(),\n runId: this._runId,\n spanId: event.spanId ?? this.stack[this.stack.length - 1],\n kind: event.kind,\n timestamp: this.now(),\n payload: event.payload ?? {},\n }\n await this.store.appendEvent(full)\n return full\n }\n\n // ── Budget ledger ──────────────────────────────────────────────────\n\n async recordBudget(\n entry: Omit<BudgetLedgerEntry, 'runId' | 'timestamp'> & { timestamp?: number },\n ): Promise<BudgetLedgerEntry> {\n const full: BudgetLedgerEntry = {\n runId: this._runId,\n timestamp: entry.timestamp ?? this.now(),\n dimension: entry.dimension,\n limit: entry.limit,\n consumed: entry.consumed,\n remaining: entry.remaining,\n breached: entry.breached,\n spanId: entry.spanId ?? this.stack[this.stack.length - 1],\n }\n await this.store.appendBudgetEntry(full)\n if (full.breached) {\n await this.emit({\n kind: 'budget_breach',\n spanId: full.spanId,\n payload: { dimension: full.dimension, limit: full.limit, consumed: full.consumed },\n })\n }\n return full\n }\n\n // ── Artifacts ──────────────────────────────────────────────────────\n\n async recordArtifact(artifact: Omit<Artifact, 'artifactId' | 'runId'>): Promise<Artifact> {\n const full: Artifact = { artifactId: this.id(), runId: this._runId, ...artifact }\n await this.store.appendArtifact(full)\n return full\n }\n\n // ── Nested composition ─────────────────────────────────────────────\n\n /**\n * Runs `fn` inside a span; auto-ends on success, auto-fails on throw.\n * Returns the fn's return value. Use this for the 95% case.\n */\n async within<T>(\n init: Parameters<TraceEmitter['span']>[0],\n fn: (handle: SpanHandle) => Promise<T>,\n ): Promise<T> {\n const handle = await this.span(init)\n try {\n const result = await fn(handle)\n await handle.end()\n return result\n } catch (err) {\n await handle.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n\n// Helpers -------------------------------------------------------------\n\nfunction cryptoRandomId(): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') return globalThis.crypto.randomUUID()\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"internal-BDHPCnjk.js","names":[],"sources":["../src/math/special-functions.ts","../src/statistics/random.ts","../src/statistics/internal.ts"],"sourcesContent":["/** Lanczos approximation to ln Gamma(z). */\nexport function lnGamma(z: number): number {\n const g = 7\n const coefficients = [\n 0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313,\n -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6,\n 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 = coefficients[0]!\n for (let i = 1; i < g + 2; i++) x += coefficients[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/**\n * Regularized incomplete beta function I_x(a, b).\n *\n * The Lentz continued fraction converges only for `x < (a+1)/(a+b+2)`; outside\n * that domain it must be reached through the symmetry `I_x(a,b) = 1 −\n * I_{1−x}(b,a)`. `studentTCdf` drives `x → 1` as `|t| → 0`, so the mirrored\n * branch is the one every near-null t-statistic takes.\n */\nexport function regularizedIncompleteBeta(x: number, a: number, b: number): number {\n if (x <= 0) return 0\n if (x >= 1) return 1\n const logBeta = lnGamma(a) + lnGamma(b) - lnGamma(a + b)\n // x^a·(1−x)^b / B(a,b) — symmetric under (x,a,b) → (1−x,b,a), so the\n // mirrored branch reuses it unchanged.\n const front = Math.exp(Math.log(x) * a + Math.log(1 - x) * b - logBeta)\n if (x < (a + 1) / (a + b + 2)) {\n return (front * betaContinuedFraction(x, a, b)) / a\n }\n return 1 - (front * betaContinuedFraction(1 - x, b, a)) / b\n}\n\n/** Modified Lentz evaluation of the beta continued fraction at `x`. */\nfunction betaContinuedFraction(x: number, a: number, b: number): number {\n const maxIterations = 300\n const epsilon = 3e-15\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 fraction = d\n for (let m = 1; m <= maxIterations; m++) {\n const m2 = 2 * m\n let numerator = (m * (b - m) * x) / ((a + m2 - 1) * (a + m2))\n d = 1 + numerator * d\n if (Math.abs(d) < 1e-30) d = 1e-30\n c = 1 + numerator / c\n if (Math.abs(c) < 1e-30) c = 1e-30\n d = 1 / d\n fraction *= d * c\n numerator = -((a + m) * (a + b + m) * x) / ((a + m2) * (a + m2 + 1))\n d = 1 + numerator * d\n if (Math.abs(d) < 1e-30) d = 1e-30\n c = 1 + numerator / c\n if (Math.abs(c) < 1e-30) c = 1e-30\n d = 1 / d\n const delta = d * c\n fraction *= delta\n if (Math.abs(delta - 1) < epsilon) break\n }\n return fraction\n}\n","import { ValidationError } from '../errors'\n\n/** Tiny seedable PRNG (mulberry32) — deterministic resampling/shuffling, not\n * cryptographic. Exported so e-process shuffles and bootstrap resampling\n * share ONE PRNG implementation. Every distinct 32-bit seed gives a distinct\n * stream, including 0. */\nexport function mulberry32(seed: number): () => number {\n if (!Number.isFinite(seed)) {\n throw new ValidationError(`mulberry32: seed must be a finite number, got ${seed}`)\n }\n let s = seed | 0\n return () => {\n s = (s + 0x6d2b79f5) | 0\n let t = s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n","/**\n * Shared internals for the statistics modules. Nothing here is part of the\n * public statistics surface — `./index` does not re-export this module.\n */\n\nimport { ValidationError } from '../errors'\nimport { lnGamma } from '../math/special-functions'\nimport { mulberry32 } from './random'\n\n/** Every rank test refuses non-finite input. Beyond the arithmetic being\n * undefined, the tie-grouping scan compares values with `===`, and\n * `NaN === NaN` is false, so a NaN would leave the group boundary unable to\n * advance and spin the loop forever. */\nexport function assertFiniteSample(fn: string, label: string, xs: readonly number[]): void {\n for (let i = 0; i < xs.length; i++) {\n if (!Number.isFinite(xs[i])) {\n throw new ValidationError(`${fn}: ${label}[${i}] must be finite, got ${xs[i]}`)\n }\n }\n}\n\n/**\n * Two-sided exact p-value for b successes out of (b + c) Bernoulli(0.5) trials —\n * the exact-binomial core of {@link mcnemar}. `min(1, 2·P(X ≤ min(b,c)))`. No\n * discordant pairs ⇒ no evidence ⇒ p = 1. Summed in log space (lnGamma) so it\n * stays exact at large discordant counts without overflow.\n */\nexport function binomialSignTwoSided(b: number, c: number): number {\n const nd = b + c\n if (nd === 0) return 1\n return Math.min(1, 2 * binomialHalfLowerTail(Math.min(b, c), nd))\n}\n\n/** P(X >= successes) for X ~ Binomial(n, 0.5). */\nexport function binomialHalfUpperTail(successes: number, n: number): number {\n if (successes <= 0) return 1\n if (successes > n) return 0\n\n // Use the smaller side of the distribution. For lower thresholds the\n // complement sums at most half the mass; for upper thresholds symmetry\n // maps the upper tail to a lower tail without subtraction.\n if (successes <= n / 2) {\n return Math.max(0, 1 - binomialHalfLowerTail(successes - 1, n))\n }\n return binomialHalfLowerTail(n - successes, n)\n}\n\n/** P(X <= maxSuccesses) for X ~ Binomial(n, 0.5), accumulated in log space. */\nfunction binomialHalfLowerTail(maxSuccesses: number, n: number): number {\n if (maxSuccesses < 0) return 0\n if (maxSuccesses >= n) return 1\n if (maxSuccesses === 0) return 2 ** -n\n\n const logHalfN = n * Math.log(0.5)\n let logTail = Number.NEGATIVE_INFINITY\n for (let i = 0; i <= maxSuccesses; i++) {\n const logChoose = lnGamma(n + 1) - lnGamma(i + 1) - lnGamma(n - i + 1)\n logTail = logAddExp(logTail, logChoose + logHalfN)\n }\n return Math.min(1, Math.exp(logTail))\n}\n\nfunction logAddExp(a: number, b: number): number {\n if (a === Number.NEGATIVE_INFINITY) return b\n if (b === Number.NEGATIVE_INFINITY) return a\n const max = Math.max(a, b)\n const min = Math.min(a, b)\n return max + Math.log1p(Math.exp(min - max))\n}\n\n/** Standard-normal inverse CDF (Acklam approximation). */\nexport function zQuantile(p: number): number {\n if (p <= 0 || p >= 1) {\n if (p === 0) return -Infinity\n if (p === 1) return Infinity\n return NaN\n }\n const a = [\n -3.969683028665376e1, 2.209460984245205e2, -2.759285104469687e2, 1.38357751867269e2,\n -3.066479806614716e1, 2.506628277459239,\n ]\n const b = [\n -5.447609879822406e1, 1.615858368580409e2, -1.556989798598866e2, 6.680131188771972e1,\n -1.328068155288572e1,\n ]\n const c = [\n -7.784894002430293e-3, -3.223964580411365e-1, -2.400758277161838, -2.549732539343734,\n 4.374664141464968, 2.938163982698783,\n ]\n const d = [7.784695709041462e-3, 3.224671290700398e-1, 2.445134137142996, 3.754408661907416]\n const pLow = 0.02425\n const pHigh = 1 - pLow\n let q: number\n let r: number\n if (p < pLow) {\n q = Math.sqrt(-2 * Math.log(p))\n return (\n (((((c[0]! * q + c[1]!) * q + c[2]!) * q + c[3]!) * q + c[4]!) * q + c[5]!) /\n ((((d[0]! * q + d[1]!) * q + d[2]!) * q + d[3]!) * q + 1)\n )\n }\n if (p <= pHigh) {\n q = p - 0.5\n r = q * q\n return (\n ((((((a[0]! * r + a[1]!) * r + a[2]!) * r + a[3]!) * r + a[4]!) * r + a[5]!) * q) /\n (((((b[0]! * r + b[1]!) * r + b[2]!) * r + b[3]!) * r + b[4]!) * r + 1)\n )\n }\n q = Math.sqrt(-2 * Math.log(1 - p))\n return (\n -(((((c[0]! * q + c[1]!) * q + c[2]!) * q + c[3]!) * q + c[4]!) * q + c[5]!) /\n ((((d[0]! * q + d[1]!) * q + d[2]!) * q + d[3]!) * q + 1)\n )\n}\n\nexport function medianInPlace(xs: number[]): number {\n if (xs.length === 0) return 0\n xs.sort((a, b) => a - b)\n const mid = Math.floor(xs.length / 2)\n return xs.length % 2 === 0 ? (xs[mid - 1]! + xs[mid]!) / 2 : xs[mid]!\n}\n\n/**\n * PRNG for every resampling path in this module.\n *\n * With no caller seed the seed is DERIVED FROM THE DATA rather than taken from\n * `Math.random`, so re-running the same input reproduces the same interval —\n * a gate verdict that cannot be re-derived is not evidence. Distinct data\n * still gets a distinct stream. Same pattern as `promotion-gate.ts`.\n */\nexport function makeRng(\n seed: number | undefined,\n ...series: readonly (readonly number[])[]\n): () => number {\n return mulberry32(seed ?? seedFromData(series))\n}\n\n/** FNV-1a over the IEEE-754 bytes of every observation. */\nfunction seedFromData(series: readonly (readonly number[])[]): number {\n const view = new DataView(new ArrayBuffer(8))\n let hash = 0x811c9dc5\n for (const xs of series) {\n for (const x of xs) {\n view.setFloat64(0, x)\n for (let byte = 0; byte < 8; byte++) {\n hash = Math.imul(hash ^ view.getUint8(byte), 0x01000193)\n }\n }\n // Separator, so ([1],[2]) and ([1,2],[]) do not collide.\n hash = Math.imul(hash ^ 0xff, 0x01000193)\n }\n return hash | 0\n}\n\n/** Order-independent seed for a symmetric two-sample statistic. */\nexport function symmetricTwoSampleSeed(a: readonly number[], b: readonly number[]): number {\n const sortedA = [...a].sort((left, right) => left - right)\n const sortedB = [...b].sort((left, right) => left - right)\n const forward = seedFromData([sortedA, sortedB]) >>> 0\n const reversed = seedFromData([sortedB, sortedA]) >>> 0\n return Math.min(forward, reversed)\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"judge-calibration-zZjLz8hr.js","names":[],"sources":["../src/judge-calibration.ts"],"sourcesContent":["/**\n * Judge calibration — measure judge quality against human gold + bias.\n *\n * Workflow:\n * 1. Build a golden set: {itemId, humanScore}[].\n * 2. Run candidate judges; each produces {itemId, score}.\n * 3. `calibrateJudge(golden, candidate)` reports κ + Pearson + MAE.\n * 4. `calibrateJudgeContinuous(golden, candidate)` adds quadratic-weighted\n * κ over the un-rounded [0,1] scores plus ICC(2,1), Pearson, Spearman,\n * and bootstrap CIs — use this for fine-grained judges where rounding\n * to int discards information (e.g. 0.78 vs 0.81 both round to 1 and\n * look \"perfectly agreed\" to integer κ).\n * 5. Run bias probes (positional, verbosity, self-preference) to\n * detect systematic score inflation.\n * 6. For N≥2 judges on the same items, `continuousAgreement(scores)`\n * reports ICC(2,1) + κ_w + Pearson + Spearman with bootstrap CIs.\n *\n * Returns actionable diagnostics, not a single number. Consumers then\n * decide whether to trust the judge, retrain it, or add a tie-breaker.\n */\n\nimport { pearsonR, spearmanR } from './statistics/descriptive'\n\nexport interface GoldenItem {\n itemId: string\n humanScore: number\n /** Optional group used for per-group bias audits (e.g. model-of-output family). */\n group?: string\n}\n\nexport interface CandidateScore {\n itemId: string\n score: number\n /** Optional — enables positional-bias analysis (did order matter?). */\n positionOfAInput?: 'first' | 'second'\n}\n\nexport interface CalibrationResult {\n n: number\n pearson: number\n /** Cohen's κ with quadratic weights over integer-rounded scores. */\n kappa: number\n /** Mean absolute error vs human. */\n mae: number\n /** Worst-5 miscalibrations (largest |judge - human|). */\n worstItems: Array<{ itemId: string; judge: number; human: number; delta: number }>\n}\n\n/**\n * Measure judge quality against human gold labels: computes Cohen's κ, Pearson correlation, and MAE over matched item ids.\n */\nexport function calibrateJudge(\n golden: GoldenItem[],\n candidate: CandidateScore[],\n): CalibrationResult {\n const map = new Map<string, { h: number; j: number }>()\n for (const g of golden) map.set(g.itemId, { h: g.humanScore, j: NaN })\n for (const c of candidate) {\n const entry = map.get(c.itemId)\n if (entry) entry.j = c.score\n }\n const common = [...map.values()].filter((v) => Number.isFinite(v.j))\n const n = common.length\n if (n < 2) {\n return { n, pearson: NaN, kappa: NaN, mae: NaN, worstItems: [] }\n }\n const humans = common.map((c) => c.h)\n const judges = common.map((c) => c.j)\n const pearson = pearsonR(humans, judges)\n const kappa = weightedKappa(humans.map(Math.round), judges.map(Math.round))\n const absDiffs = common.map((c) => Math.abs(c.j - c.h))\n const mae = absDiffs.reduce((a, b) => a + b, 0) / n\n const worst = [...map.entries()]\n .filter(([, v]) => Number.isFinite(v.j))\n .map(([itemId, v]) => ({ itemId, judge: v.j, human: v.h, delta: Math.abs(v.j - v.h) }))\n .sort((a, b) => b.delta - a.delta)\n .slice(0, 5)\n return { n, pearson, kappa, mae, worstItems: worst }\n}\n\nexport interface PositionalBiasResult {\n /**\n * Score delta (first-position - second-position) averaged across items\n * presented in both positions. Non-zero = positional bias.\n */\n avgDelta: number\n n: number\n}\n\n/**\n * Feed the same items to the judge twice with A/B swapped and pass all\n * results here. Items that don't appear in both positions are ignored.\n */\nexport function positionalBias(scores: CandidateScore[]): PositionalBiasResult {\n const pairs = new Map<string, { first?: number; second?: number }>()\n for (const s of scores) {\n const slot = pairs.get(s.itemId) ?? {}\n if (s.positionOfAInput === 'first') slot.first = s.score\n else if (s.positionOfAInput === 'second') slot.second = s.score\n pairs.set(s.itemId, slot)\n }\n const deltas: number[] = []\n for (const { first, second } of pairs.values()) {\n if (first !== undefined && second !== undefined) deltas.push(first - second)\n }\n if (deltas.length === 0) return { avgDelta: 0, n: 0 }\n return { avgDelta: deltas.reduce((a, b) => a + b, 0) / deltas.length, n: deltas.length }\n}\n\nexport interface VerbosityBiasResult {\n /** Pearson correlation between output length and score. Strong positive = verbosity bias. */\n pearson: number\n n: number\n}\n\nexport function verbosityBias(\n samples: Array<{ outputLen: number; score: number }>,\n): VerbosityBiasResult {\n const n = samples.length\n if (n < 3) return { pearson: NaN, n }\n return {\n pearson: pearsonR(\n samples.map((s) => s.outputLen),\n samples.map((s) => s.score),\n ),\n n,\n }\n}\n\nexport interface SelfPreferenceResult {\n /** Mean judge score when judge's family matches output's family. */\n inFamilyMean: number\n outOfFamilyMean: number\n deltaMean: number\n n: number\n}\n\n/**\n * Pass the same scenarios scored with judge-model X grading outputs from\n * model X (in-family) and model Y (out-of-family). Non-zero delta\n * indicates self-preference.\n */\nexport function selfPreference(\n samples: Array<{ score: number; inFamily: boolean }>,\n): SelfPreferenceResult {\n const inF = samples.filter((s) => s.inFamily).map((s) => s.score)\n const outF = samples.filter((s) => !s.inFamily).map((s) => s.score)\n if (inF.length === 0 || outF.length === 0)\n return { inFamilyMean: 0, outOfFamilyMean: 0, deltaMean: 0, n: 0 }\n const inMean = inF.reduce((a, b) => a + b, 0) / inF.length\n const outMean = outF.reduce((a, b) => a + b, 0) / outF.length\n return {\n inFamilyMean: inMean,\n outOfFamilyMean: outMean,\n deltaMean: inMean - outMean,\n n: samples.length,\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\n/** Quadratic weighted Cohen's κ over bounded integer scores. */\nfunction weightedKappa(a: number[], b: number[]): number {\n if (a.length !== b.length || a.length === 0) return NaN\n const min = Math.min(...a, ...b)\n const max = Math.max(...a, ...b)\n const K = max - min + 1\n if (K < 2) return 1\n const observed: number[][] = Array.from({ length: K }, () => new Array(K).fill(0))\n const rowMarg = new Array(K).fill(0)\n const colMarg = new Array(K).fill(0)\n for (let i = 0; i < a.length; i++) {\n const ai = a[i]! - min\n const bi = b[i]! - min\n const row = observed[ai]!\n row[bi] = (row[bi] ?? 0) + 1\n rowMarg[ai]++\n colMarg[bi]++\n }\n let num = 0\n let den = 0\n for (let i = 0; i < K; i++) {\n for (let j = 0; j < K; j++) {\n const w = (i - j) ** 2 / (K - 1) ** 2\n const expected = (rowMarg[i] * colMarg[j]) / a.length\n num += w * observed[i]![j]!\n den += w * expected\n }\n }\n if (den === 0) return 1\n return 1 - num / den\n}\n\n// ── Continuous-value inter-rater agreement ──────────────────────────\n//\n// `weightedKappa` above quantises to integers. For [0,1] judges that is\n// lossy: 0.78 and 0.81 both round to 1 and look identical to integer κ.\n// `continuousAgreement` keeps the original magnitudes:\n//\n// - κ_w : Cohen's weighted κ generalised to continuous scores. For two\n// raters, weighted κ = 1 − Σ w_ij·o_ij / Σ w_ij·e_ij collapses\n// into the closed form below when each \"category\" is the score\n// itself (Janson & Olsson 2001; Cohen 1968 quadratic weights).\n// - ICC : Intraclass Correlation Coefficient, ICC(2,1) per Shrout &\n// Fleiss (1979) — two-way random effects, absolute agreement,\n// single rater. The right reliability coefficient when judges\n// are a random sample of the judge population.\n// - r, ρ : Pearson + Spearman for sanity-check. Pearson catches linear\n// association regardless of scale; Spearman catches monotone\n// association regardless of distribution.\n// - CIs : Bootstrap percentile CIs over items (rows). Bias is preserved\n// because we resample the full row, i.e. a judge's vector\n// stays internally consistent within each bootstrap replicate.\n//\n// References:\n// - Shrout, P. E. & Fleiss, J. L. (1979). Intraclass correlations: uses\n// in assessing rater reliability. Psychological Bulletin, 86(2), 420.\n// - McGraw, K. O. & Wong, S. P. (1996). Forming inferences about some\n// intraclass correlation coefficients. Psychological Methods, 1, 30.\n// - Janson, H. & Olsson, U. (2001). A measure of agreement for interval\n// or nominal multivariate observations. Educ. Psychol. Meas., 61, 277.\n\nexport interface ContinuousAgreement {\n /** Cohen's κ_w with quadratic weights, computed on raw [0,1] scores. */\n weightedKappa: number\n /** ICC(2,1): two-way random effects, absolute agreement, single rater. */\n icc: number\n /** Pearson product-moment correlation (averaged over rater pairs if N>2). */\n pearson: number\n /** Spearman rank correlation (averaged over rater pairs if N>2). */\n spearman: number\n /** 95% bootstrap percentile CIs over items. */\n ci: {\n icc: [number, number]\n weightedKappa: [number, number]\n }\n /** Number of complete items (no NaN across raters). */\n n: number\n /** Number of raters. */\n raters: number\n}\n\nexport interface ContinuousAgreementOptions {\n /** Bootstrap iterations. Default 1000. Set to 0 to skip CIs (CI = [NaN, NaN]). */\n bootstrap?: number\n /** κ weighting scheme. Default 'quadratic'. */\n weights?: 'linear' | 'quadratic'\n /** PRNG seed for reproducible bootstrap. Default 0xC0FFEE. */\n seed?: number\n /** Confidence level for percentile CI. Default 0.95. */\n ciLevel?: number\n}\n\n/**\n * Inter-rater agreement on continuous (typically [0,1]) scores.\n *\n * `scores` has shape [n_items][n_raters]. Rows with any non-finite entry\n * are dropped. Returns NaN metrics if fewer than 2 raters or 2 complete\n * items remain.\n */\nexport function continuousAgreement(\n scores: number[][],\n opts: ContinuousAgreementOptions = {},\n): ContinuousAgreement {\n const bootstrap = opts.bootstrap ?? 1000\n const weights = opts.weights ?? 'quadratic'\n const seed = opts.seed ?? 0xc0ffee\n const ciLevel = opts.ciLevel ?? 0.95\n\n const matrix = scores.filter((row) => row.length >= 2 && row.every((v) => Number.isFinite(v)))\n const raters = matrix[0]?.length ?? 0\n // All rows must have the same rater count, else drop the offenders.\n const clean = matrix.filter((row) => row.length === raters)\n const nClean = clean.length\n\n if (nClean < 2 || raters < 2) {\n return {\n weightedKappa: NaN,\n icc: NaN,\n pearson: NaN,\n spearman: NaN,\n ci: { icc: [NaN, NaN], weightedKappa: [NaN, NaN] },\n n: nClean,\n raters,\n }\n }\n\n const kappa = continuousWeightedKappa(clean, weights)\n const icc = icc21(clean)\n const pearson = avgPairwise(clean, pearsonR)\n const spearman = avgPairwise(clean, spearmanR)\n\n const ciIcc: [number, number] = [NaN, NaN]\n const ciKappa: [number, number] = [NaN, NaN]\n if (bootstrap > 0) {\n const rng = mulberry32(seed)\n const iccs: number[] = []\n const kappas: number[] = []\n for (let b = 0; b < bootstrap; b++) {\n const sample: number[][] = new Array(nClean)\n for (let i = 0; i < nClean; i++) {\n sample[i] = clean[Math.floor(rng() * nClean)]!\n }\n const iccB = icc21(sample)\n const kB = continuousWeightedKappa(sample, weights)\n if (Number.isFinite(iccB)) iccs.push(iccB)\n if (Number.isFinite(kB)) kappas.push(kB)\n }\n const [lo, hi] = percentileBounds(ciLevel)\n if (iccs.length > 0) {\n iccs.sort((a, b) => a - b)\n ciIcc[0] = quantile(iccs, lo)\n ciIcc[1] = quantile(iccs, hi)\n }\n if (kappas.length > 0) {\n kappas.sort((a, b) => a - b)\n ciKappa[0] = quantile(kappas, lo)\n ciKappa[1] = quantile(kappas, hi)\n }\n }\n\n return {\n weightedKappa: kappa,\n icc,\n pearson,\n spearman,\n ci: { icc: ciIcc, weightedKappa: ciKappa },\n n: nClean,\n raters,\n }\n}\n\nexport interface ContinuousCalibrationResult extends CalibrationResult {\n /** Cohen's κ_w computed on raw (un-rounded) scores. */\n weightedKappaContinuous: number\n /** ICC(2,1) treating golden + candidate as two raters. */\n icc: number\n spearman: number\n ci: {\n icc: [number, number]\n weightedKappa: [number, number]\n }\n}\n\n/**\n * Extends `calibrateJudge` with continuous-value agreement metrics while\n * retaining its base calibration summary.\n */\nexport function calibrateJudgeContinuous(\n golden: GoldenItem[],\n candidate: CandidateScore[],\n opts: ContinuousAgreementOptions = {},\n): ContinuousCalibrationResult {\n const base = calibrateJudge(golden, candidate)\n const map = new Map<string, { h: number; j: number }>()\n for (const g of golden) map.set(g.itemId, { h: g.humanScore, j: NaN })\n for (const c of candidate) {\n const entry = map.get(c.itemId)\n if (entry) entry.j = c.score\n }\n const rows: number[][] = []\n for (const v of map.values()) {\n if (Number.isFinite(v.j)) rows.push([v.h, v.j])\n }\n const agreement = continuousAgreement(rows, opts)\n return {\n ...base,\n weightedKappaContinuous: agreement.weightedKappa,\n icc: agreement.icc,\n spearman: agreement.spearman,\n ci: agreement.ci,\n }\n}\n\n// ── Continuous-agreement internals ──────────────────────────────────\n\n/**\n * Quadratic-weighted κ on continuous scores. With weights w(x,y) = (x-y)^2\n * (or |x-y| for linear) the formula collapses to:\n *\n * κ_w = 1 − E_obs[w] / E_exp[w]\n *\n * where E_obs averages w over paired (a_i, b_i) and E_exp averages w over\n * the independent product distribution (sum_{i,j} w(a_i, b_j) / n^2).\n * The normalisation by (max-min)^2 in the integer version cancels in the\n * ratio, so we don't need it here. Generalises to N raters by averaging κ_w\n * over all rater pairs (mean pairwise weighted agreement).\n */\nfunction continuousWeightedKappa(rows: number[][], scheme: 'linear' | 'quadratic'): number {\n if (rows.length === 0) return NaN\n const raters = rows[0]!.length\n if (raters < 2) return NaN\n const wFn =\n scheme === 'linear'\n ? (x: number, y: number) => Math.abs(x - y)\n : (x: number, y: number) => (x - y) ** 2\n let sum = 0\n let pairs = 0\n for (let r1 = 0; r1 < raters; r1++) {\n for (let r2 = r1 + 1; r2 < raters; r2++) {\n const a = rows.map((row) => row[r1]!)\n const b = rows.map((row) => row[r2]!)\n const n = a.length\n let obs = 0\n for (let i = 0; i < n; i++) obs += wFn(a[i]!, b[i]!)\n obs /= n\n // Expected under independence: average of w over all i,j cross pairs.\n let exp = 0\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) exp += wFn(a[i]!, b[j]!)\n }\n exp /= n * n\n if (exp === 0) {\n // Degenerate: at least one rater is constant. Convention: perfect\n // agreement iff observed disagreement is also zero, else 0.\n sum += obs === 0 ? 1 : 0\n } else {\n sum += 1 - obs / exp\n }\n pairs++\n }\n }\n return pairs === 0 ? NaN : sum / pairs\n}\n\n/**\n * ICC(2,1) — two-way random effects, absolute agreement, single rater.\n *\n * ICC(2,1) = (MSR − MSE) / (MSR + (k−1)·MSE + k·(MSC − MSE)/n)\n *\n * where MSR = between-rows MS, MSC = between-columns MS, MSE = residual MS,\n * n = rows (items), k = columns (raters).\n */\nfunction icc21(rows: number[][]): number {\n const n = rows.length\n if (n < 2) return NaN\n const k = rows[0]!.length\n if (k < 2) return NaN\n\n // Row means.\n const rowMeans = rows.map((row) => row.reduce((s, v) => s + v, 0) / k)\n // Column means.\n const colMeans = new Array(k).fill(0)\n for (let j = 0; j < k; j++) {\n let s = 0\n for (let i = 0; i < n; i++) s += rows[i]![j]!\n colMeans[j] = s / n\n }\n // Grand mean.\n let grand = 0\n for (let i = 0; i < n; i++) grand += rowMeans[i]!\n grand /= n\n\n let ssR = 0\n for (let i = 0; i < n; i++) ssR += (rowMeans[i]! - grand) ** 2\n ssR *= k\n let ssC = 0\n for (let j = 0; j < k; j++) ssC += (colMeans[j]! - grand) ** 2\n ssC *= n\n let ssT = 0\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < k; j++) ssT += (rows[i]![j]! - grand) ** 2\n }\n const ssE = ssT - ssR - ssC\n\n const dfR = n - 1\n const dfC = k - 1\n const dfE = (n - 1) * (k - 1)\n const msR = ssR / dfR\n const msC = ssC / dfC\n const msE = dfE > 0 ? ssE / dfE : 0\n\n const denom = msR + (k - 1) * msE + (k * (msC - msE)) / n\n if (denom === 0) {\n // Degenerate (all values equal): convention = 1 if rows identical,\n // else 0. Identical rows ⇒ msR = 0 too, so msR − msE near 0.\n return msR === 0 && msE === 0 ? 1 : 0\n }\n return (msR - msE) / denom\n}\n\n/** Average pairwise statistic over all rater pairs. */\nfunction avgPairwise(rows: number[][], fn: (a: number[], b: number[]) => number): number {\n const k = rows[0]?.length ?? 0\n if (k < 2) return NaN\n let sum = 0\n let pairs = 0\n for (let i = 0; i < k; i++) {\n for (let j = i + 1; j < k; j++) {\n const a = rows.map((row) => row[i]!)\n const b = rows.map((row) => row[j]!)\n const r = fn(a, b)\n if (Number.isFinite(r)) {\n sum += r\n pairs++\n }\n }\n }\n return pairs === 0 ? NaN : sum / pairs\n}\n\n/** Seeded PRNG — Mulberry32. Deterministic across platforms. */\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nfunction percentileBounds(ciLevel: number): [number, number] {\n const tail = (1 - ciLevel) / 2\n return [tail, 1 - tail]\n}\n\n/** Linear-interpolated quantile of a pre-sorted ascending array. */\nfunction quantile(sorted: number[], q: number): number {\n if (sorted.length === 0) return NaN\n if (sorted.length === 1) return sorted[0]!\n const pos = q * (sorted.length - 1)\n const lo = Math.floor(pos)\n const hi = Math.ceil(pos)\n if (lo === hi) return sorted[lo]!\n const frac = pos - lo\n return sorted[lo]! * (1 - frac) + sorted[hi]! * frac\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm-client-hgDieDNN.js","names":[],"sources":["../src/judge-families.ts","../src/integrity/served-model.ts","../src/llm-client.ts"],"sourcesContent":["/**\n * Judge model-family classification + cross-family enforcement.\n *\n * A judge ensemble built entirely from one provider family shares that\n * family's blind spots and self-preference — its \"agreement\" is correlated\n * bias, not independent signal. `assertCrossFamily` makes the consumer prove\n * the ensemble spans ≥2 families; `judgeFamily` is the single regex map that\n * replaces the per-consumer copies (tax/legal/creative/gtm each ship one).\n */\n\n/** Provider family a model belongs to. `unknown` when no rule matches. */\nexport type JudgeFamily =\n | 'anthropic'\n | 'openai'\n | 'google'\n | 'meta'\n | 'mistral'\n | 'deepseek'\n | 'xai'\n | 'qwen'\n | 'cohere'\n | 'amazon'\n | 'moonshot'\n | 'zhipu'\n | 'unknown'\n\n/** Explicit `provider/...` prefix → family (models.dev / OpenRouter style). */\nconst PROVIDER_PREFIX: Record<string, JudgeFamily> = {\n anthropic: 'anthropic',\n openai: 'openai',\n 'azure-openai': 'openai',\n google: 'google',\n 'google-vertex': 'google',\n meta: 'meta',\n 'meta-llama': 'meta',\n mistral: 'mistral',\n mistralai: 'mistral',\n deepseek: 'deepseek',\n xai: 'xai',\n qwen: 'qwen',\n alibaba: 'qwen',\n cohere: 'cohere',\n amazon: 'amazon',\n bedrock: 'amazon',\n moonshot: 'moonshot',\n moonshotai: 'moonshot',\n kimi: 'moonshot',\n 'kimi-code': 'moonshot',\n zhipu: 'zhipu',\n zhipuai: 'zhipu',\n zai: 'zhipu',\n 'z-ai': 'zhipu',\n glm: 'zhipu',\n}\n\n/** Fallback model-name patterns when there's no recognised provider prefix. */\nconst NAME_PATTERNS: Array<[RegExp, JudgeFamily]> = [\n [/claude/i, 'anthropic'],\n [/\\b(gpt|davinci|babbage)\\b|^o[134]\\b|[-/]o[134]\\b|gpt-/i, 'openai'],\n [/gemini|palm|gemma|bison/i, 'google'],\n [/llama/i, 'meta'],\n [/mi(s|x)tral|codestral|magistral/i, 'mistral'],\n [/deepseek/i, 'deepseek'],\n [/grok/i, 'xai'],\n [/qwen/i, 'qwen'],\n [/command-?(r|a)?/i, 'cohere'],\n [/\\b(nova|titan)\\b/i, 'amazon'],\n [/\\bkimi\\b|moonshot/i, 'moonshot'],\n [/\\bglm\\b|zhipu|\\bz-?ai\\b/i, 'zhipu'],\n]\n\n/**\n * Classify a model id into its provider family. Strips a `@snapshot` suffix\n * and prefers an explicit `provider/...` prefix; otherwise matches the model\n * name. Returns `unknown` when nothing matches (callers decide whether that's\n * acceptable — `assertCrossFamily` counts it as its own family).\n */\nexport function judgeFamily(modelId: string): JudgeFamily {\n const id = modelId.trim().split('@')[0]!.toLowerCase()\n const slash = id.indexOf('/')\n if (slash > 0) {\n const prefix = id.slice(0, slash)\n const mapped = PROVIDER_PREFIX[prefix]\n if (mapped) return mapped\n }\n for (const [pattern, family] of NAME_PATTERNS) {\n if (pattern.test(id)) return family\n }\n return 'unknown'\n}\n\nexport interface AssertCrossFamilyOptions {\n /** Minimum number of distinct families the ensemble must span. Default 2. */\n minFamilies?: number\n /** When false (default), `unknown`-family models do NOT count toward the\n * family total — an ensemble of all-unclassifiable models is not provably\n * cross-family. Set true to count `unknown` as one shared family. */\n allowUnknown?: boolean\n}\n\nexport class CrossFamilyError extends Error {\n constructor(\n message: string,\n public readonly families: JudgeFamily[],\n public readonly models: string[],\n ) {\n super(message)\n this.name = 'CrossFamilyError'\n }\n}\n\n/**\n * Throw unless the judge models span at least `minFamilies` distinct provider\n * families. Pass the model ids backing your judge ensemble. Fail-loud by\n * design — a correlated single-family ensemble silently inflates agreement.\n *\n * Scope: this reads the ids you REQUEST. It proves the panel was configured\n * across families; it cannot prove the panel RAN across families, because a\n * routing gateway may answer several different ids from one provider. Where\n * the diversity claim is load-bearing (a published leaderboard, a\n * certification, a non-self-judging exclusion), assert on the ids the\n * provider echoed instead: `assertCrossFamilyServed` in\n * ./integrity/served-model.\n */\nexport function assertCrossFamily(\n models: string[],\n opts: AssertCrossFamilyOptions = {},\n): JudgeFamily[] {\n const minFamilies = opts.minFamilies ?? 2\n const families = new Set<JudgeFamily>()\n for (const m of models) {\n const f = judgeFamily(m)\n if (f === 'unknown' && !opts.allowUnknown) continue\n families.add(f)\n }\n const list = [...families].sort()\n if (list.length < minFamilies) {\n throw new CrossFamilyError(\n `judge ensemble spans ${list.length} provider famil${list.length === 1 ? 'y' : 'ies'} ` +\n `(${list.join(', ') || 'none'}) but ${minFamilies} required — a single-family ensemble ` +\n 'is correlated bias, not independent signal',\n list,\n models,\n )\n }\n return list\n}\n","/**\n * Served-model identity: prove the model that ANSWERED is the model that was\n * REQUESTED.\n *\n * A routing gateway can accept `model: \"gpt-4.1-mini\"` and answer from a\n * different model entirely. Every guard that reasons about the requested id —\n * cross-family judge diversity, per-model leaderboard rows, non-self-judging\n * exclusions, cost attribution — then passes while measuring something else.\n * The requested id is an intent; only the id echoed on the response is\n * evidence.\n *\n * `checkServedModel` classifies one requested/served pair; `assertServedModel`\n * and `assertServedModels` are the fail-loud gates; `assertCrossFamilyServed`\n * is the family-diversity rule computed over SERVED ids (the requested-id\n * version lives in ../judge-families and cannot see substitution).\n *\n * Aliasing is tolerated, substitution is not: `openai/gpt-4.1-mini` and\n * `gpt-4.1-mini` are the same request expressed two ways, so a response\n * echoing either satisfies the other. A response echoing `gemini-2.5-flash-lite`\n * does not.\n */\n\nimport { AgentEvalError } from '../errors'\nimport { type JudgeFamily, judgeFamily } from '../judge-families'\n\n/**\n * Output-token budget a liveness probe must grant a model.\n *\n * Identity is only readable off a response the provider actually produced. A\n * reasoning model spends budget on hidden reasoning tokens before it emits a\n * single visible one, so a cap of a few tokens makes a HEALTHY deepseek/glm\n * model fail with `reasoning_budget_exhausted` — it names no model, its\n * identity reads as `unreported`, and a preflight scores it DEAD. 64 clears\n * that floor. Every probe in this package reads this constant, so two probes\n * cannot reach two different answers about the same router.\n *\n * Cost: a probe spends at most `PROBE_MAX_TOKENS` output tokens per model,\n * plus whatever reasoning tokens a reasoning model bills — roughly 400 output\n * tokens for a six-model preflight. That is fractions of a cent, and far\n * cheaper than a campaign that runs on a model nobody proved was alive.\n */\nexport const PROBE_MAX_TOKENS = 64\n\n/** How a served id relates to the id that was requested. */\nexport type ServedModelVerdict =\n /** Byte-identical after normalisation — the requested model answered. */\n | 'exact'\n /** Same model, different spelling (provider prefix, snapshot, tier suffix). */\n | 'alias'\n /** A different model of the SAME provider family answered. */\n | 'substituted-within-family'\n /** A different provider's model answered. */\n | 'substituted-cross-family'\n /** The response carried no model id — identity is unproven either way. */\n | 'unreported'\n\nexport interface ServedModelCheck {\n /** The id the caller asked for. */\n requested: string\n /** The id echoed on the response; `null` when the response omitted it. */\n served: string | null\n requestedFamily: JudgeFamily\n /** `null` when `served` is null. */\n servedFamily: JudgeFamily | null\n verdict: ServedModelVerdict\n /** True for every verdict except `exact` and `alias`. */\n substituted: boolean\n}\n\n/**\n * Reduce a model id to its comparable core: lowercase, no surrounding space,\n * no `provider/` prefix, no `@snapshot` / `:batch` / `:free` tier suffix, no\n * trailing build date, and `.`/`_` folded to `-` so one version is spelled one\n * way.\n *\n * Dropping the build date is what makes snapshot resolution legible as the\n * non-event it is: a router answering `gpt-4o-mini` with\n * `gpt-4o-mini-2024-07-18` pinned a floating alias to a reproducible build —\n * the same model, which is the behaviour we want. Only routing decoration is\n * stripped; version digits are load-bearing, so `deepseek-v3.2` and\n * `deepseek-v4-flash` stay distinct, and comparison is EXACT equality rather\n * than a prefix test (a prefix rule would accept `gpt-5` → `gpt-5-mini`, a\n * silent downgrade wearing the right vendor name).\n */\nexport function normalizeModelId(modelId: string): string {\n let id = modelId.trim().toLowerCase()\n const at = id.indexOf('@')\n if (at > 0) id = id.slice(0, at)\n const colon = id.indexOf(':')\n if (colon > 0) id = id.slice(0, colon)\n const slash = id.lastIndexOf('/')\n if (slash >= 0) id = id.slice(slash + 1)\n return id\n .replace(/-\\d{4}-\\d{2}-\\d{2}$/, '')\n .replace(/-\\d{8}$/, '')\n .replace(/[._]/g, '-')\n .replace(/-+$/, '')\n .trim()\n}\n\n/**\n * Classify one requested/served pair. Pure — no I/O — so it is safe inside\n * response handlers, reducers, and CI gates.\n *\n * `served` is the id echoed by the provider (OpenAI-compatible bodies put it\n * at `model`). `null`/`undefined` means the body omitted it; that is\n * `unreported`, NOT a pass — a provider that does not name what answered has\n * not proven identity, and a transport that drops the field must not read as\n * agreement.\n */\nexport function checkServedModel(\n requested: string,\n served: string | null | undefined,\n): ServedModelCheck {\n const requestedFamily = judgeFamily(requested)\n if (served === null || served === undefined || served.trim() === '') {\n return {\n requested,\n served: null,\n requestedFamily,\n servedFamily: null,\n verdict: 'unreported',\n substituted: true,\n }\n }\n const servedFamily = judgeFamily(served)\n if (requested.trim().toLowerCase() === served.trim().toLowerCase()) {\n return {\n requested,\n served,\n requestedFamily,\n servedFamily,\n verdict: 'exact',\n substituted: false,\n }\n }\n if (normalizeModelId(requested) === normalizeModelId(served)) {\n return {\n requested,\n served,\n requestedFamily,\n servedFamily,\n verdict: 'alias',\n substituted: false,\n }\n }\n return {\n requested,\n served,\n requestedFamily,\n servedFamily,\n verdict:\n requestedFamily === servedFamily ? 'substituted-within-family' : 'substituted-cross-family',\n substituted: true,\n }\n}\n\nexport class ModelSubstitutionError extends AgentEvalError {\n constructor(\n message: string,\n public readonly checks: ReadonlyArray<ServedModelCheck>,\n ) {\n super('model_substitution', message)\n this.name = 'ModelSubstitutionError'\n }\n}\n\n/**\n * Consumer-facing name for the substitution policy a metered surface applies.\n * `'exact'` rejects every substitution. `'allow-within-family'` accepts a\n * different model of the same provider family; it keeps family-level claims\n * valid and forfeits per-model claims. Maps to\n * `AssertServedModelOptions.allowWithinFamily`.\n */\nexport type ServedModelPolicy = 'exact' | 'allow-within-family'\n\nexport function assertServedModelPolicy(\n value: unknown,\n label: string,\n): asserts value is ServedModelPolicy | undefined {\n if (value !== undefined && value !== 'exact' && value !== 'allow-within-family') {\n throw new Error(`${label} must be 'exact' or 'allow-within-family'`)\n }\n}\n\nexport interface AssertServedModelOptions {\n /**\n * Accept a different model of the same provider family (e.g. requested\n * `deepseek-v3.2`, served `deepseek-v4-flash`). Default false. Setting this\n * keeps family-level claims valid and forfeits per-model claims.\n */\n allowWithinFamily?: boolean\n /**\n * Accept a response that carried no model id. Default false — an\n * unidentified response cannot support a per-model or per-family claim.\n */\n allowUnreported?: boolean\n /** Prefixed to the thrown message, e.g. the judge or campaign cell name. */\n context?: string\n}\n\n/**\n * The one place the accept/reject policy lives, so a caller that reports\n * substitution (a preflight table, a run record) and a caller that throws on it\n * can never drift apart. A cross-family substitution is never acceptable.\n */\nexport function servedModelAcceptable(\n check: ServedModelCheck,\n opts: AssertServedModelOptions = {},\n): boolean {\n switch (check.verdict) {\n case 'exact':\n case 'alias':\n return true\n case 'unreported':\n return opts.allowUnreported === true\n case 'substituted-within-family':\n return opts.allowWithinFamily === true\n default:\n return false\n }\n}\n\nfunction describe(check: ServedModelCheck): string {\n if (check.verdict === 'unreported')\n return `${check.requested}: response carried no model id (identity unproven)`\n return (\n `${check.requested} (${check.requestedFamily}) → served ${check.served} ` +\n `(${check.servedFamily}) [${check.verdict}]`\n )\n}\n\n/**\n * Throw `ModelSubstitutionError` unless the served id is the requested model.\n * Returns the check on success so callers can record the served id alongside\n * the result.\n */\nexport function assertServedModel(\n requested: string,\n served: string | null | undefined,\n opts: AssertServedModelOptions = {},\n): ServedModelCheck {\n const check = checkServedModel(requested, served)\n if (servedModelAcceptable(check, opts)) return check\n const prefix = opts.context ? `${opts.context}: ` : ''\n throw new ModelSubstitutionError(\n `${prefix}model substitution — ${describe(check)}. The measurement is of the SERVED model, ` +\n 'not the requested one; any per-model or per-family claim from this call is invalid.',\n [check],\n )\n}\n\n/**\n * Batch form: check every pair and throw naming EVERY substitution, so one\n * failure does not hide the rest. Returns all checks on success.\n */\nexport function assertServedModels(\n pairs: ReadonlyArray<{ requested: string; served: string | null | undefined }>,\n opts: AssertServedModelOptions = {},\n): ServedModelCheck[] {\n const checks = pairs.map((p) => checkServedModel(p.requested, p.served))\n const bad = checks.filter((c) => !servedModelAcceptable(c, opts))\n if (bad.length > 0) {\n const prefix = opts.context ? `${opts.context}: ` : ''\n throw new ModelSubstitutionError(\n `${prefix}${bad.length}/${checks.length} call(s) were answered by a different model than ` +\n `requested — ${bad.map(describe).join('; ')}. Per-model and per-family claims from this ` +\n 'run are invalid until the ids are re-measured.',\n checks,\n )\n }\n return checks\n}\n\nexport interface AssertCrossFamilyServedOptions extends AssertServedModelOptions {\n /** Minimum distinct SERVED families required. Default 2. */\n minFamilies?: number\n /** Count `unknown`-family served ids toward the total. Default false. */\n allowUnknown?: boolean\n}\n\nexport class ServedCrossFamilyError extends AgentEvalError {\n constructor(\n message: string,\n public readonly families: JudgeFamily[],\n public readonly checks: ReadonlyArray<ServedModelCheck>,\n ) {\n super('model_substitution', message)\n this.name = 'ServedCrossFamilyError'\n }\n}\n\n/**\n * Family-diversity rule over the models that actually ANSWERED.\n *\n * `assertCrossFamily` (../judge-families) reads the requested ids and so\n * cannot see a gateway that answers three \"different\" requests from one\n * provider. This one asserts no substitution first, then counts families from\n * the served ids — a panel that collapsed to one family under the hood fails\n * here even though its request list looked diverse.\n */\nexport function assertCrossFamilyServed(\n pairs: ReadonlyArray<{ requested: string; served: string | null | undefined }>,\n opts: AssertCrossFamilyServedOptions = {},\n): JudgeFamily[] {\n const checks = assertServedModels(pairs, opts)\n const families = new Set<JudgeFamily>()\n for (const check of checks) {\n const family = check.servedFamily\n if (family === null) continue\n if (family === 'unknown' && !opts.allowUnknown) continue\n families.add(family)\n }\n const list = [...families].sort()\n const minFamilies = opts.minFamilies ?? 2\n if (list.length < minFamilies) {\n const prefix = opts.context ? `${opts.context}: ` : ''\n throw new ServedCrossFamilyError(\n `${prefix}the models that ANSWERED span ${list.length} provider famil` +\n `${list.length === 1 ? 'y' : 'ies'} (${list.join(', ') || 'none'}) but ${minFamilies} ` +\n `required — served ids: ${checks.map((c) => c.served ?? 'unreported').join(', ')}`,\n list,\n checks,\n )\n }\n return list\n}\n","/**\n * INTERNAL OpenAI-compatible client. NOT part of the published surface.\n *\n * agent-eval executes no paid model on behalf of a consumer: `createChatClient`\n * binds a caller-supplied transport, and this module is not reachable through\n * any export subpath. Two in-repo callers hold it:\n * - the `agent-eval` binary (`src/cli-config.ts`), a deployed server whose\n * caller is a JSON-RPC client in another language and which therefore\n * configures its own endpoint from its own environment;\n * - the loopback optimizer proxy path (`src/analyst/benchmark-public-model.ts`,\n * `src/analyst/dspy-rlm-engine.ts`), which targets `http://127.0.0.1:<port>/v1`\n * with an ephemeral token and executes nothing itself.\n *\n * The canonical request/result TYPES it defines ARE public — they are the\n * contract every caller-owned transport speaks.\n *\n * OpenAI-compatible `/v1/chat/completions` client with:\n * - Exponential-backoff retry on 429 + 5xx gateway errors (502/503/504).\n * - Retry on transient network errors (fetch failed, AbortError, ECONNRESET).\n * - One retry at temperature 1 when a model explicitly requires it.\n * - Graceful json_schema → json_object degrade on 400 with schema-reject body.\n * - Fenced-JSON stripping (```json ... ```) for models that wrap structured output.\n * - Configurable base URL + api key / bearer, works with LiteLLM proxies, OpenAI\n * directly, cli-bridge subscriptions, and any router that speaks the spec.\n *\n * Usage:\n * const { value, result } = await callLlmJson<MyType>(\n * { model: 'gpt-4o', messages: [...], jsonSchema: { name: 'x', schema: {...} } },\n * { baseUrl: process.env.AGENT_EVAL_LLM_BASE_URL, apiKey: process.env.AGENT_EVAL_LLM_API_KEY },\n * )\n *\n */\n\nimport {\n type CostReceiptInput,\n type CustomTokenPricing,\n costForTokenPricing,\n type MaximumCharge,\n} from './cost-ledger'\nimport { AgentEvalError } from './errors'\nimport {\n type AssertServedModelOptions,\n assertServedModel as assertServedModelIdentity,\n} from './integrity/served-model'\nimport {\n defaultProviderRedactor,\n type ProviderRedactor,\n providerFromBaseUrl,\n type RawProviderEvent,\n type RawProviderSink,\n} from './trace/raw-provider-sink'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface LlmMessage {\n role: 'system' | 'user' | 'assistant' | 'tool'\n /**\n * Either a plain text content string OR a multimodal content array\n * (text + image_url parts) for vision-capable models.\n */\n content:\n | string\n | Array<\n | { type: 'text'; text: string }\n | { type: 'image_url'; image_url: { url: string; detail?: 'auto' | 'low' | 'high' } }\n >\n /** Tool invocations made by an `assistant` message earlier in the turn. */\n toolCalls?: LlmToolCall[]\n /** The invocation a `tool` message answers. Required when role is `tool`. */\n toolCallId?: string\n}\n\nexport type LlmThinkingMode = 'enabled' | 'disabled'\n\n/** Canonical function-tool definition offered to the model. */\nexport interface LlmToolDefinition {\n type: 'function'\n function: {\n name: string\n description?: string\n parameters: Record<string, unknown>\n }\n}\n\n/** Canonical tool-choice policy; meaningful only when `tools` is present. */\nexport type LlmToolChoice =\n | 'auto'\n | 'none'\n | 'required'\n | { type: 'function'; function: { name: string } }\n\n/** One tool invocation on a response or an assistant history message. */\nexport interface LlmToolCall {\n id: string\n name: string\n /** JSON-encoded arguments, exactly as the provider produced them. */\n argumentsJson: string\n}\n\nexport interface LlmCallRequest {\n model: string\n messages: LlmMessage[]\n /** Optional JSON-mode response format (response_format: json_object). */\n jsonMode?: boolean\n /** Optional structured output via JSON Schema. Falls back to json_object on 400. */\n jsonSchema?: { name: string; schema: Record<string, unknown> }\n /** Function tools offered to the model for this call. */\n tools?: LlmToolDefinition[]\n /** Tool-choice policy for `tools`. */\n toolChoice?: LlmToolChoice\n temperature?: number\n maxTokens?: number\n /** Ask the provider for the log-probability of each sampled token and its\n * `topLogprobs` most likely alternatives. Sends `logprobs: true` with\n * `top_logprobs`. A provider that ignores the field returns\n * `LlmCallResult.logprobs === null`; nothing is inferred from its absence. */\n logprobs?: { topLogprobs: number }\n /** OpenAI-compatible reasoning mode. Omitted when the provider default should apply. */\n thinking?: LlmThinkingMode\n /** Per-call timeout, default 300s. */\n timeoutMs?: number\n}\n\n/** Conservative priced bound for the exact text request sent to a provider.\n * Returns undefined when output or multimodal input is not bounded, causing a\n * capped CostLedger to reject the call before execution. Pass\n * `customTokenPricing` when package pricing does not cover the model or endpoint. */\nexport interface LlmChargeBounds {\n /** Total provider attempts the transport may make for this call. Default 3. */\n maximumAttempts?: number\n /** The transport sends JSON mode instead of a response schema. */\n jsonSchemaTransport?: 'native' | 'json-object'\n /** Default provider reasoning mode the transport applies. */\n thinking?: LlmThinkingMode\n /** Token rates used when the provider omits cost or package pricing does not cover the model. */\n customTokenPricing?: CustomTokenPricing\n}\n\nexport function maximumChargeForLlmRequest(\n request: Pick<\n LlmCallRequest,\n 'model' | 'messages' | 'jsonSchema' | 'tools' | 'toolChoice' | 'maxTokens' | 'thinking'\n >,\n options: LlmChargeBounds = {},\n): MaximumCharge | undefined {\n if (request.maxTokens === undefined) return undefined\n if (!Number.isInteger(request.maxTokens) || request.maxTokens <= 0) {\n throw new RangeError(`maximumChargeForLlmRequest: maxTokens must be a positive integer`)\n }\n if (\n request.messages.some(\n (message) =>\n Array.isArray(message.content) && message.content.some((part) => part.type === 'image_url'),\n )\n ) {\n return undefined\n }\n\n const attempts = resolveMaximumAttempts(options.maximumAttempts)\n const forceJsonObject = options.jsonSchemaTransport === 'json-object'\n // A byte-level tokenizer cannot emit more input tokens than request bytes.\n // Pricing the complete body also covers role/schema framing omitted from content-only estimates.\n const requestBytes = new TextEncoder().encode(\n JSON.stringify(buildBody(request, forceJsonObject, options.thinking)),\n ).byteLength\n // A rejected response schema can trigger one JSON-mode batch with the same output limit.\n const batches = request.jsonSchema && !forceJsonObject ? 2 : 1\n const usage = {\n inputTokens: requestBytes * attempts * batches,\n outputTokens: request.maxTokens * attempts * batches,\n }\n return options.customTokenPricing\n ? { customTokenPricing: options.customTokenPricing, ...usage }\n : { model: request.model, ...usage }\n}\n\nexport interface LlmUsage {\n promptTokens: number\n completionTokens: number\n totalTokens: number\n /** False when the provider omitted or malformed prompt/completion usage. */\n captured?: boolean\n /** Reasoning-token subset of completionTokens, when reported. */\n reasoningTokens?: number\n /** Proxies populate this when prompt caching is on. */\n cachedPromptTokens?: number\n}\n\n/** One sampled token with its own log probability and the alternatives the\n * provider ranked at that position. */\nexport interface LlmTokenLogprob {\n token: string\n logprob: number\n top: ReadonlyArray<{ token: string; logprob: number }>\n}\n\nexport interface LlmCallResult {\n /** The text content of the first choice. Empty string if none. */\n content: string\n /** Tool invocations from the first choice, when the model called tools. */\n toolCalls?: LlmToolCall[]\n usage: LlmUsage\n /**\n * Cost in USD. Uses the provider's reported cost when present, otherwise\n * caller-supplied token pricing. `null` when neither is available.\n */\n costUsd: number | null\n /**\n * Model id used for attribution (cost, pricing, log lines). The response's\n * echoed id when the provider sent one, else the requested id.\n *\n * NOT evidence of which model answered — read `servedModel` for that. A\n * provider that omits `model` makes this equal to the request, which is\n * exactly the case an identity check must be able to distinguish.\n */\n model: string\n /**\n * The model id the provider echoed on the response, verbatim; `null` when\n * the body carried none. This is the only field that can witness a gateway\n * substituting a different model for the one requested — compare it with\n * `assertServedModel` / `checkServedModel` (src/integrity/served-model.ts).\n *\n * Optional so hand-built results (mock/custom transports) still typecheck,\n * but omitting it is not a pass: the identity checks read `undefined` as\n * `unreported` and reject it by default. A transport that knows which model\n * answered should say so.\n */\n servedModel?: string | null\n /** Wall-clock duration of the HTTP call (last attempt, if retried). */\n durationMs: number\n /**\n * `finish_reason` echoed from the first choice (`stop`, `length`,\n * `content_filter`, `tool_calls`, ...). `null` when the provider omits it.\n * Exposed so a free-form `callLlm` caller CAN detect a truncated answer\n * (`length`) instead of treating a cut-off completion as complete. Note:\n * `callLlm` does not itself reject on it — acting on this signal is the\n * caller's responsibility (in-repo free-form drivers do not yet enforce it).\n */\n finishReason?: string | null\n /**\n * True when `content.trim()` is empty. An empty completion is a silent zero\n * for free-form `callLlm` callers; this flag is the signal a caller can\n * inspect to fail loud rather than proceed on an empty string. `callLlm`\n * surfaces it but does not throw on it.\n */\n contentEmpty?: boolean\n /**\n * Per-token log probabilities for the first choice, in emission order, when\n * the request asked for them and the provider returned\n * `choices[0].logprobs.content`. `null` when the provider returned none, so a\n * caller can tell \"not requested or not supported\" from \"requested and\n * empty\". Absent when the request did not ask for logprobs.\n */\n logprobs?: ReadonlyArray<LlmTokenLogprob> | null\n /** Raw response body. */\n raw: Record<string, unknown>\n}\n\nexport type LlmCallMetadata = Pick<LlmCallResult, 'usage' | 'costUsd' | 'model' | 'durationMs'>\n\n/** Convert a provider result into the canonical paid-call receipt input.\n * The receipt is JSON-clean: absent optional fields are omitted, never carried\n * as explicit-undefined keys. Receipts cross JSON boundaries (the external\n * optimizer's loopback proxy validates them with `assertJsonValue`), where an\n * explicit-undefined value is rejected as non-serializable. */\nexport function costReceiptFromLlm(\n result: LlmCallResult,\n customTokenPricing?: CustomTokenPricing,\n): CostReceiptInput {\n const cachedTokens = result.usage.cachedPromptTokens ?? 0\n const inputTokens = Math.max(0, result.usage.promptTokens - cachedTokens)\n const providerCostUsd = providerReportedCost(result.raw)\n return {\n model: result.model,\n inputTokens,\n outputTokens: result.usage.completionTokens,\n ...(result.usage.reasoningTokens === undefined\n ? {}\n : { reasoningTokens: result.usage.reasoningTokens }),\n ...(cachedTokens > 0 ? { cachedTokens } : {}),\n ...(providerCostUsd === undefined\n ? customTokenPricing && result.usage.captured !== false\n ? { customTokenPricing }\n : result.costUsd === null\n ? {}\n : { estimatedCostUsd: result.costUsd }\n : { actualCostUsd: providerCostUsd }),\n usageUnknown: result.usage.captured === false,\n }\n}\n\nfunction providerReportedCost(raw: Record<string, unknown>): number | undefined {\n const value = raw._response_cost ?? raw.cost_usd\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined\n}\n\n/** Structured-response failures retain their completed provider receipt. */\nexport function costReceiptFromLlmError(\n error: Error,\n customTokenPricing?: CustomTokenPricing,\n): CostReceiptInput | undefined {\n return error instanceof LlmResponseError\n ? costReceiptFromLlm(error.result, customTokenPricing)\n : undefined\n}\n\nexport class LlmCallError extends AgentEvalError {\n constructor(\n message: string,\n public readonly status: number,\n public readonly body: string,\n public readonly model: string,\n ) {\n super('judge', message)\n }\n}\n\n/** A provider response completed and incurred measurable usage, but its content\n * could not satisfy the caller's response contract. The response envelope is\n * retained so accounting can commit the receipt before the error propagates. */\nexport class LlmResponseError extends AgentEvalError {\n constructor(\n message: string,\n public readonly result: LlmCallResult,\n options?: { cause?: unknown },\n ) {\n super('judge', message, options)\n }\n}\n\nexport interface LlmClientOptions extends LlmChargeBounds {\n /** Base URL (without trailing slash), ending at the `/v1` prefix. Required: there is no default endpoint. */\n baseUrl?: string\n /** Bearer token — either `apiKey` or `bearer` populates `Authorization: Bearer ...`. */\n apiKey?: string\n bearer?: string\n /** Override for the `Authorization` header (e.g. `X-Auth: ...`). Takes precedence over apiKey/bearer. */\n authHeader?: { name: string; value: string }\n /** Stable provider idempotency key, reused across retries of this logical call. */\n idempotencyKey?: string\n /** Default timeout in ms. Per-call can override. */\n defaultTimeoutMs?: number\n /**\n * Caller-supplied abort signal — e.g. a campaign-wide cancel. Linked to\n * each attempt's per-attempt timeout controller, so aborting it cancels\n * the in-flight fetch. A caller abort is FATAL: it is not retried even\n * though an AbortError otherwise matches the transient patterns.\n */\n signal?: AbortSignal\n /**\n * Cross-attempt wall-clock budget in ms, measured from the first attempt.\n * Before launching each attempt the loop checks the remaining budget and\n * stops retrying once it is exhausted, rather than waiting the full\n * per-attempt timeout on every retry. Bounds total time independent of\n * total attempts × `timeoutMs`.\n */\n deadlineMs?: number\n /**\n * JSON payload parsing policy. `extract` accepts fenced or prose-prefixed JSON.\n * `exact` requires the complete response content to be one JSON value.\n * Default: `extract`.\n */\n jsonPayloadMode?: 'extract' | 'exact'\n /** Fetch implementation — defaults to global `fetch`. Override for custom transport (e.g. tests). */\n fetch?: typeof fetch\n /**\n * Optional raw HTTP capture sink. When provided, every request, response,\n * and error (across all retry attempts) is recorded to the sink, with auth\n * headers and credential-shaped body fields redacted by default. This is\n * the layer-1 forensics primitive: structured `LlmSpan`s record intent,\n * raw events record what actually crossed the wire.\n */\n rawSink?: RawProviderSink\n /**\n * Logical provider id attached to raw events. When omitted, derived from\n * `baseUrl` via `providerFromBaseUrl`.\n */\n provider?: string\n /** Trace context attached to raw events; populated by emitter-aware callers. */\n traceContext?: { runId?: string; spanId?: string }\n /** Override the redaction strategy for this call. Defaults to `defaultProviderRedactor`. */\n redactor?: ProviderRedactor\n /**\n * Reject a response whose echoed model is not the model that was requested.\n * A routing gateway can accept one id and answer from another, which\n * silently invalidates every per-model and per-family claim downstream.\n * `true` uses the strict default (aliases pass, substitutions and\n * unidentified responses throw `ModelSubstitutionError`); pass an options\n * object to relax a specific case. Off by default — turning it on for a\n * measurement run is the point.\n */\n assertServedModel?: boolean | AssertServedModelOptions\n}\n\n// ─── Internals ──────────────────────────────────────────────────────────\n\n// Flagship / reasoning models routinely take several minutes on large prompts (a\n// reflection over many failures, a long tool transcript). A tight cap aborts a\n// legitimately-slow but healthy call — and because every retry attempt re-uses\n// the same window, such a model aborts on ALL attempts and the loop throws. The\n// default is generous enough to let those complete, bounded enough that a truly\n// hung call still fails over after retries, and tunable per deployment via\n// TANGLE_LLM_TIMEOUT_MS. Per-call `req.timeoutMs` / `opts.defaultTimeoutMs`\n// still win for callers that know their model's latency.\nconst DEFAULT_TIMEOUT_MS = Number(process.env.TANGLE_LLM_TIMEOUT_MS) || 300_000\nconst DEFAULT_MAXIMUM_ATTEMPTS =\n process.env.TANGLE_LLM_MAXIMUM_ATTEMPTS === undefined\n ? 3\n : Number(process.env.TANGLE_LLM_MAXIMUM_ATTEMPTS)\n\nfunction resolveMaximumAttempts(configured: number | undefined): number {\n const attempts = configured ?? DEFAULT_MAXIMUM_ATTEMPTS\n if (!Number.isInteger(attempts) || attempts <= 0) {\n throw new RangeError('LLM maximum attempts must be a positive integer')\n }\n return attempts\n}\n\nfunction providerTokenCount(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined\n}\n\n// 522/524: Cloudflare edge timeouts (origin connect/respond) — transient\n// exactly like 504. Router deployments serve through Cloudflare, so a long\n// non-streaming call can draw these from the edge, not the origin.\nconst RETRYABLE_STATUS = new Set([429, 502, 503, 504, 522, 524])\n\n/**\n * Transient transport/network error signatures, matched against an error's\n * name, message, and `code`. Covers fetch/undici network failures, aborts\n * and timeouts, and — critically — HTTP/2 transport faults a keep-alive\n * connection raises mid-response: `terminated`, `NGHTTP2_INTERNAL_ERROR`,\n * `UND_ERR_*`, `other side closed`. Those last ones carry no clean HTTP\n * status; unrecognised, they escape the retry loop and surface as an\n * uncaught rejection.\n */\nconst TRANSIENT_ERROR_PATTERNS: readonly RegExp[] = [\n /AbortError/i,\n /TimeoutError/i,\n /this operation was aborted/i,\n /fetch failed/i,\n /ECONNRESET/i,\n /ETIMEDOUT/i,\n /EAI_AGAIN/i,\n /socket hang up/i,\n /stream.*ended.*unexpectedly/i,\n /terminated/i,\n /other side closed/i,\n /NGHTTP2/i,\n /UND_ERR/i,\n]\n\n/**\n * True when an error is a transient transport/network fault worth retrying,\n * as opposed to a deterministic failure (4xx schema reject, JSON parse) that\n * a retry cannot fix. Inspects `LlmCallError.status`, then the error's\n * name/message/code, then recurses into `error.cause` — undici nests the\n * real socket fault one or more levels under `.cause`.\n *\n * This is the retry classifier for the package: `callLlm` and\n * `withJudgeRetry` both route through it, so connection failures are treated\n * consistently across transports.\n */\nexport function isTransientLlmError(err: unknown): boolean {\n return classifyTransient(err, 0)\n}\n\nfunction classifyTransient(err: unknown, depth: number): boolean {\n if (err instanceof LlmCallError) return RETRYABLE_STATUS.has(err.status)\n if (!(err instanceof Error)) return false\n // Foreign transport errors can carry a numeric HTTP status without being an\n // LlmCallError. A retryable status is decisive.\n const status = (err as { status?: unknown }).status\n if (typeof status === 'number' && RETRYABLE_STATUS.has(status)) return true\n const code = (err as { code?: unknown }).code\n const haystack = `${err.name}\\n${err.message}\\n${typeof code === 'string' ? code : ''}`\n if (TRANSIENT_ERROR_PATTERNS.some((p) => p.test(haystack))) return true\n const cause = (err as { cause?: unknown }).cause\n if (depth < 4 && cause instanceof Error && cause !== err) {\n return classifyTransient(cause, depth + 1)\n }\n return false\n}\n\nfunction parseRetryAfter(headers: Headers): number | null {\n const h = headers.get('retry-after')\n if (!h) return null\n const asNumber = Number(h)\n if (Number.isFinite(asNumber) && asNumber > 0) return asNumber * 1000\n const asDate = Date.parse(h)\n if (Number.isFinite(asDate)) return Math.max(0, asDate - Date.now())\n return null\n}\n\n/** Exponential backoff: 500ms, 1s, 2s, 4s, ... capped at 16s. Attempt is 0-indexed. */\nexport function backoffMs(attempt: number): number {\n return Math.min(500 * 2 ** attempt, 16_000)\n}\n\nfunction buildHeaders(opts: LlmClientOptions): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n }\n if (opts.authHeader) {\n headers[opts.authHeader.name] = opts.authHeader.value\n } else if (opts.bearer || opts.apiKey) {\n headers.Authorization = `Bearer ${opts.bearer ?? opts.apiKey}`\n }\n if (opts.idempotencyKey) headers['Idempotency-Key'] = opts.idempotencyKey\n return headers\n}\n\nfunction isSchemaRejection(status: number, body: string): boolean {\n if (status !== 400) return false\n const lower = body.toLowerCase()\n return (\n lower.includes('response_format') ||\n lower.includes('json_schema') ||\n lower.includes('is unavailable') ||\n lower.includes('not supported')\n )\n}\n\nfunction isTemperatureOneRejection(status: number, body: string): boolean {\n if (status !== 400 || !/temperature/i.test(body)) return false\n return (\n /temperature[^.\\n]{0,120}\\b(?:only|must|should|required|requires?)\\b[^.\\n]{0,40}\\b1(?:\\.0+)?\\b/i.test(\n body,\n ) || /\\bonly\\s+1(?:\\.0+)?\\s+is\\s+allowed\\b[^.\\n]{0,120}\\btemperature\\b/i.test(body)\n )\n}\n\nfunction buildBody(\n req: LlmCallRequest,\n forceJsonObject: boolean,\n defaultThinking?: LlmThinkingMode,\n): Record<string, unknown> {\n const body: Record<string, unknown> = {\n model: req.model,\n messages: req.messages.map(encodeWireMessage),\n temperature: req.temperature ?? 0,\n }\n if (req.maxTokens != null) {\n if (usesMaxCompletionTokens(req.model)) body.max_completion_tokens = req.maxTokens\n else body.max_tokens = req.maxTokens\n }\n if (req.logprobs !== undefined) {\n body.logprobs = true\n body.top_logprobs = req.logprobs.topLogprobs\n }\n if (req.tools !== undefined) body.tools = req.tools\n if (req.toolChoice !== undefined) body.tool_choice = req.toolChoice\n const thinking = req.thinking ?? defaultThinking\n if (thinking !== undefined) {\n body.thinking = { type: thinking }\n }\n\n if (req.jsonSchema && !forceJsonObject) {\n body.response_format = {\n type: 'json_schema',\n json_schema: { name: req.jsonSchema.name, schema: req.jsonSchema.schema, strict: true },\n }\n } else if (req.jsonMode || req.jsonSchema) {\n body.response_format = { type: 'json_object' }\n }\n\n return body\n}\n\nfunction usesMaxCompletionTokens(model: string): boolean {\n return /^gpt-5(?:[.-]|$)/i.test(model)\n}\n\n/** Encode one canonical message as its OpenAI chat-completions wire shape. */\nfunction encodeWireMessage(message: LlmMessage): Record<string, unknown> {\n if (message.role === 'tool') {\n return { role: 'tool', tool_call_id: message.toolCallId, content: message.content }\n }\n if (message.toolCalls === undefined) {\n return { role: message.role, content: message.content }\n }\n return {\n role: message.role,\n content: message.content,\n tool_calls: message.toolCalls.map((call) => ({\n id: call.id,\n type: 'function',\n function: { name: call.name, arguments: call.argumentsJson },\n })),\n }\n}\n\n/**\n * Parse `choices[0].logprobs.content` into the canonical per-token shape.\n * `null` when the provider returned nothing for a request that asked: a\n * provider that ignores `logprobs` is a fact the caller must be able to read,\n * not an error. A malformed entry is a contract violation and throws.\n */\nfunction parseWireLogprobs(value: unknown, model: string): ReadonlyArray<LlmTokenLogprob> | null {\n if (value === undefined || value === null) return null\n if (!Array.isArray(value)) {\n throw new Error(`LLM response logprobs.content must be an array (model=${model})`)\n }\n return value.map((entry, index) => {\n const record = entry as { token?: unknown; logprob?: unknown; top_logprobs?: unknown } | null\n if (\n !record ||\n typeof record !== 'object' ||\n typeof record.token !== 'string' ||\n typeof record.logprob !== 'number' ||\n !Number.isFinite(record.logprob)\n ) {\n throw new Error(\n `LLM response logprobs.content[${index}] is not a token with a finite logprob (model=${model})`,\n )\n }\n const top = record.top_logprobs\n if (top !== undefined && top !== null && !Array.isArray(top)) {\n throw new Error(\n `LLM response logprobs.content[${index}].top_logprobs must be an array (model=${model})`,\n )\n }\n return {\n token: record.token,\n logprob: record.logprob,\n top: (Array.isArray(top) ? top : []).map((alternative, position) => {\n const candidate = alternative as { token?: unknown; logprob?: unknown } | null\n if (\n !candidate ||\n typeof candidate !== 'object' ||\n typeof candidate.token !== 'string' ||\n typeof candidate.logprob !== 'number' ||\n !Number.isFinite(candidate.logprob)\n ) {\n throw new Error(\n `LLM response logprobs.content[${index}].top_logprobs[${position}] is not a token with a finite logprob (model=${model})`,\n )\n }\n return { token: candidate.token, logprob: candidate.logprob }\n }),\n }\n })\n}\n\n/** Parse provider tool_calls into the canonical shape. A malformed entry is a\n * provider-contract violation and throws rather than degrading silently. */\nfunction parseWireToolCalls(value: unknown, model: string): LlmToolCall[] | undefined {\n if (value === undefined || value === null) return undefined\n if (!Array.isArray(value)) {\n throw new Error(`LLM response tool_calls must be an array (model=${model})`)\n }\n if (value.length === 0) return undefined\n return value.map((entry, index) => {\n const record = entry as {\n id?: unknown\n type?: unknown\n function?: { name?: unknown; arguments?: unknown } | null\n } | null\n const fn = record && typeof record === 'object' ? record.function : undefined\n if (\n !record ||\n typeof record !== 'object' ||\n typeof record.id !== 'string' ||\n record.id.length === 0 ||\n (record.type !== undefined && record.type !== 'function') ||\n !fn ||\n typeof fn !== 'object' ||\n typeof fn.name !== 'string' ||\n fn.name.length === 0 ||\n typeof fn.arguments !== 'string'\n ) {\n throw new Error(\n `LLM response tool_calls[${index}] is not a function call with string arguments (model=${model})`,\n )\n }\n return { id: record.id, name: fn.name, argumentsJson: fn.arguments }\n })\n}\n\nasync function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Combine the per-attempt timeout signal with an optional caller signal into\n * one signal the fetch listens on. Prefers the native `AbortSignal.any`; falls\n * back to manual wiring on runtimes that predate it. The caller signal is also\n * propagated to the timeout controller so aborting it cancels the in-flight\n * fetch immediately.\n */\nfunction linkSignals(timeoutController: AbortController, caller?: AbortSignal): AbortSignal {\n if (!caller) return timeoutController.signal\n if (typeof (AbortSignal as { any?: unknown }).any === 'function') {\n return AbortSignal.any([timeoutController.signal, caller])\n }\n if (caller.aborted) {\n timeoutController.abort()\n } else {\n caller.addEventListener('abort', () => timeoutController.abort(), { once: true })\n }\n return timeoutController.signal\n}\n\n/** True once the cross-attempt wall-clock budget (if any) is exhausted. */\nfunction deadlineExceeded(start: number, deadlineMs: number | undefined): boolean {\n return deadlineMs != null && Date.now() - start >= deadlineMs\n}\n\n// ─── Public API ─────────────────────────────────────────────────────────\n\n/**\n * Strip a ```json / ``` code fence if the model emitted one.\n * Idempotent for naked JSON. Some models (claude-code via router, certain\n * deepseek models) wrap output even under json_object.\n */\nexport function stripFencedJson(raw: string): string {\n const trimmed = raw.trim()\n const m = trimmed.match(/^```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?```\\s*$/)\n return m ? m[1]!.trim() : trimmed\n}\n\nexport function extractJsonPayload(raw: string): string {\n const stripped = stripFencedJson(raw)\n try {\n JSON.parse(stripped)\n return stripped\n } catch {\n // A response that declares a JSON root must parse as that complete root.\n // Scanning onward could turn a truncated object into one of its valid nested\n // arrays or objects and silently change the response schema.\n if (stripped.startsWith('{') || stripped.startsWith('[')) return stripped\n }\n\n // Only prose-leading responses may contain a recoverable JSON payload.\n const starts = [...stripped.matchAll(/[[{]/g)]\n .map((match) => match.index)\n .filter((index) => index != null)\n for (const start of starts) {\n const candidate = extractBalancedJson(stripped, start)\n if (!candidate) continue\n try {\n JSON.parse(candidate)\n return candidate\n } catch {\n // Keep scanning; earlier braces may belong to prose.\n }\n }\n\n return stripped\n}\n\nfunction extractBalancedJson(input: string, start: number): string | null {\n const opener = input[start]\n const closer = opener === '{' ? '}' : opener === '[' ? ']' : null\n if (!closer) return null\n\n const stack: string[] = [closer]\n let isInString = false\n let isEscaped = false\n\n for (let i = start + 1; i < input.length; i++) {\n const char = input[i]!\n if (isEscaped) {\n isEscaped = false\n continue\n }\n if (char === '\\\\') {\n isEscaped = isInString\n continue\n }\n if (char === '\"') {\n isInString = !isInString\n continue\n }\n if (isInString) continue\n\n if (char === '{') stack.push('}')\n else if (char === '[') stack.push(']')\n else if (char === stack[stack.length - 1]) {\n stack.pop()\n if (stack.length === 0) return input.slice(start, i + 1)\n }\n }\n\n return null\n}\n\n/**\n * Low-level call. Returns raw content + usage + cost. Retries on transient\n * failures; does NOT degrade schema here — callers that want graceful\n * degrade use `callLlmJson`.\n */\nexport async function callLlm(\n req: LlmCallRequest,\n opts: LlmClientOptions = {},\n): Promise<LlmCallResult> {\n // No default endpoint. This client is internal to the `agent-eval` binary\n // and the loopback optimizer proxy; both name their endpoint explicitly, and\n // a fallback would let a misconfigured caller bill an unintended provider.\n if (!opts.baseUrl) throw new Error('callLlm: opts.baseUrl is required')\n const baseUrl = opts.baseUrl.replace(/\\/+$/, '')\n const url = `${baseUrl}/chat/completions`\n const endpoint = '/chat/completions'\n const timeoutMs = req.timeoutMs ?? opts.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS\n const maximumAttempts = resolveMaximumAttempts(opts.maximumAttempts)\n const fetchFn = opts.fetch ?? globalThis.fetch\n const headers = buildHeaders(opts)\n const provider = opts.provider ?? providerFromBaseUrl(baseUrl)\n const sink = opts.rawSink\n const redactor = opts.redactor ?? defaultProviderRedactor\n const traceContext = opts.traceContext\n const callerSignal = opts.signal\n const deadlineMs = opts.deadlineMs\n const deadlineStart = Date.now()\n if (opts.customTokenPricing) {\n costForTokenPricing(opts.customTokenPricing, { inputTokens: 0, outputTokens: 0 })\n }\n\n let lastErr: unknown\n let effectiveRequest = req\n for (let attempt = 0; attempt < maximumAttempts; attempt++) {\n // A caller cancel is fatal — never retried. Checking before each attempt\n // means an already-aborted signal short-circuits without firing fetch.\n if (callerSignal?.aborted) {\n throw new DOMException('callLlm aborted by caller signal', 'AbortError')\n }\n // Stop retrying once the cross-attempt budget is spent rather than burning\n // a full per-attempt timeout on each remaining retry.\n if (attempt > 0 && deadlineExceeded(deadlineStart, deadlineMs)) {\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr))\n }\n const controller = new AbortController()\n const attemptSignal = linkSignals(controller, callerSignal)\n const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs)\n const started = Date.now()\n const requestBody = buildBody(\n effectiveRequest,\n opts.jsonSchemaTransport === 'json-object',\n opts.thinking,\n )\n let attemptErrorRecorded = false\n if (sink) {\n await recordRaw(sink, redactor, {\n eventId: cryptoEventId(),\n runId: traceContext?.runId,\n spanId: traceContext?.spanId,\n provider,\n model: req.model,\n endpoint,\n baseUrl,\n attemptIndex: attempt,\n direction: 'request',\n timestamp: started,\n requestHeaders: headers,\n requestBody,\n redactedFields: [],\n })\n }\n\n try {\n const res = await fetchFn(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n signal: attemptSignal,\n })\n clearTimeout(timeoutHandle)\n const responseHeaders = sink ? headersToObject(res.headers) : undefined\n\n if (!res.ok) {\n const body = await res.text()\n if (sink) {\n await recordRaw(sink, redactor, {\n eventId: cryptoEventId(),\n runId: traceContext?.runId,\n spanId: traceContext?.spanId,\n provider,\n model: req.model,\n endpoint,\n baseUrl,\n attemptIndex: attempt,\n direction: 'error',\n timestamp: Date.now(),\n durationMs: Date.now() - started,\n statusCode: res.status,\n responseHeaders,\n responseBody: body,\n errorMessage: `HTTP ${res.status}`,\n redactedFields: [],\n })\n attemptErrorRecorded = true\n }\n const err = new LlmCallError(\n `LLM call failed with HTTP ${res.status}`,\n res.status,\n body,\n req.model,\n )\n if (\n isTemperatureOneRejection(res.status, body) &&\n effectiveRequest.temperature !== 1 &&\n attempt < maximumAttempts - 1 &&\n !deadlineExceeded(deadlineStart, deadlineMs)\n ) {\n lastErr = err\n effectiveRequest = { ...effectiveRequest, temperature: 1 }\n continue\n }\n if (\n RETRYABLE_STATUS.has(res.status) &&\n attempt < maximumAttempts - 1 &&\n !deadlineExceeded(deadlineStart, deadlineMs)\n ) {\n lastErr = err\n const retryAfter = parseRetryAfter(res.headers)\n await sleep(retryAfter ?? backoffMs(attempt))\n continue\n }\n throw err\n }\n\n const text = await res.text()\n let json: Record<string, unknown>\n try {\n json = JSON.parse(text) as Record<string, unknown>\n } catch (parseErr) {\n if (sink) {\n await recordRaw(sink, redactor, {\n eventId: cryptoEventId(),\n runId: traceContext?.runId,\n spanId: traceContext?.spanId,\n provider,\n model: req.model,\n endpoint,\n baseUrl,\n attemptIndex: attempt,\n direction: 'error',\n timestamp: Date.now(),\n durationMs: Date.now() - started,\n statusCode: res.status,\n responseHeaders,\n responseBody: text,\n errorMessage: `non-JSON response: ${parseErr instanceof Error ? parseErr.message : String(parseErr)}`,\n redactedFields: [],\n })\n attemptErrorRecorded = true\n }\n throw parseErr\n }\n if (sink) {\n await recordRaw(sink, redactor, {\n eventId: cryptoEventId(),\n runId: traceContext?.runId,\n spanId: traceContext?.spanId,\n provider,\n model: req.model,\n endpoint,\n baseUrl,\n attemptIndex: attempt,\n direction: 'response',\n timestamp: Date.now(),\n durationMs: Date.now() - started,\n statusCode: res.status,\n responseHeaders,\n responseBody: json,\n redactedFields: [],\n })\n }\n const choice = (\n json.choices as\n | Array<{\n message?: { content?: string | null; tool_calls?: unknown }\n finish_reason?: string | null\n logprobs?: { content?: unknown } | null\n }>\n | undefined\n )?.[0]\n const toolCalls = parseWireToolCalls(choice?.message?.tool_calls, req.model)\n const usageRaw =\n json.usage && typeof json.usage === 'object' && !Array.isArray(json.usage)\n ? (json.usage as Record<string, unknown>)\n : undefined\n const promptTokens = providerTokenCount(usageRaw?.prompt_tokens)\n const completionTokens = providerTokenCount(usageRaw?.completion_tokens)\n const totalTokens = providerTokenCount(usageRaw?.total_tokens)\n const completionDetails =\n usageRaw?.completion_tokens_details &&\n typeof usageRaw.completion_tokens_details === 'object' &&\n !Array.isArray(usageRaw.completion_tokens_details)\n ? (usageRaw.completion_tokens_details as Record<string, unknown>)\n : undefined\n const reasoningRaw = completionDetails?.reasoning_tokens\n const reasoningTokens =\n reasoningRaw === undefined ? undefined : providerTokenCount(reasoningRaw)\n const cachedRaw =\n usageRaw?.prompt_tokens_details &&\n typeof usageRaw.prompt_tokens_details === 'object' &&\n !Array.isArray(usageRaw.prompt_tokens_details)\n ? (usageRaw.prompt_tokens_details as Record<string, unknown>).cached_tokens\n : undefined\n const cachedPromptTokens = cachedRaw === undefined ? undefined : providerTokenCount(cachedRaw)\n const usageCaptured =\n promptTokens !== undefined &&\n completionTokens !== undefined &&\n (reasoningRaw === undefined ||\n (reasoningTokens !== undefined && reasoningTokens <= completionTokens)) &&\n (cachedRaw === undefined ||\n (cachedPromptTokens !== undefined && cachedPromptTokens <= promptTokens)) &&\n (totalTokens === undefined || totalTokens === promptTokens + completionTokens)\n const costFromProxy = (json._response_cost ?? json.cost_usd) as number | undefined\n const content = choice?.message?.content ?? ''\n\n const configuredCost =\n typeof costFromProxy !== 'number' && usageCaptured && opts.customTokenPricing\n ? costForTokenPricing(opts.customTokenPricing, {\n inputTokens: promptTokens! - (cachedPromptTokens ?? 0),\n ...(cachedPromptTokens ? { cachedTokens: cachedPromptTokens } : {}),\n outputTokens: completionTokens!,\n })\n : undefined\n\n // The echoed id, kept separate from the attribution id: a provider that\n // omits it must read as \"unproven\", never as \"the model I asked for\".\n const servedModel =\n typeof json.model === 'string' && json.model.trim() !== '' ? json.model : null\n if (opts.assertServedModel) {\n assertServedModelIdentity(\n req.model,\n servedModel,\n opts.assertServedModel === true ? {} : opts.assertServedModel,\n )\n }\n\n return {\n content,\n ...(toolCalls === undefined ? {} : { toolCalls }),\n ...(req.logprobs === undefined\n ? {}\n : { logprobs: parseWireLogprobs(choice?.logprobs?.content, req.model) }),\n finishReason: choice?.finish_reason ?? null,\n contentEmpty: content.trim().length === 0,\n usage: {\n promptTokens: promptTokens ?? 0,\n completionTokens: completionTokens ?? 0,\n totalTokens: totalTokens ?? (promptTokens ?? 0) + (completionTokens ?? 0),\n captured: usageCaptured,\n reasoningTokens,\n cachedPromptTokens,\n },\n costUsd: typeof costFromProxy === 'number' ? costFromProxy : (configuredCost ?? null),\n model: servedModel ?? req.model,\n servedModel,\n durationMs: Date.now() - started,\n raw: json,\n }\n } catch (err) {\n clearTimeout(timeoutHandle)\n lastErr = err\n // A caller cancel is fatal even though an AbortError matches the\n // transient patterns — a cancelled call must surface immediately, not\n // be retried against the same dead intent.\n if (callerSignal?.aborted) {\n if (sink && !attemptErrorRecorded) {\n await recordRaw(sink, redactor, {\n eventId: cryptoEventId(),\n runId: traceContext?.runId,\n spanId: traceContext?.spanId,\n provider,\n model: req.model,\n endpoint,\n baseUrl,\n attemptIndex: attempt,\n direction: 'error',\n timestamp: Date.now(),\n durationMs: Date.now() - started,\n errorMessage: err instanceof Error ? err.message : String(err),\n redactedFields: [],\n })\n }\n throw err\n }\n if (sink && !attemptErrorRecorded) {\n // Record only if neither the !res.ok branch nor the JSON.parse catch\n // already produced an error event for this attempt. Covers network\n // failures, timeouts, and aborts.\n await recordRaw(sink, redactor, {\n eventId: cryptoEventId(),\n runId: traceContext?.runId,\n spanId: traceContext?.spanId,\n provider,\n model: req.model,\n endpoint,\n baseUrl,\n attemptIndex: attempt,\n direction: 'error',\n timestamp: Date.now(),\n durationMs: Date.now() - started,\n errorMessage: err instanceof Error ? err.message : String(err),\n redactedFields: [],\n })\n }\n if (\n attempt < maximumAttempts - 1 &&\n isTransientLlmError(err) &&\n !deadlineExceeded(deadlineStart, deadlineMs)\n ) {\n await sleep(backoffMs(attempt))\n continue\n }\n throw err\n }\n }\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr))\n}\n\nasync function recordRaw(\n sink: RawProviderSink,\n redactor: ProviderRedactor,\n event: RawProviderEvent,\n): Promise<void> {\n // Errors from sinks must not crash the LLM call. Forensic capture is\n // best-effort; the structured trace is the system of record.\n try {\n await sink.record(redactor(event))\n } catch {\n // Intentionally swallowed.\n }\n}\n\nfunction headersToObject(h: Headers): Record<string, string> {\n const out: Record<string, string> = {}\n h.forEach((value, key) => {\n out[key] = value\n })\n return out\n}\n\nfunction cryptoEventId(): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') return globalThis.crypto.randomUUID()\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n}\n\n/**\n * Structured-output call. Returns parsed JSON plus the raw result envelope.\n * Degrades `jsonSchema` → `jsonMode` on a 400 that names the schema param —\n * critical for deepseek-v3/v4, kimi-k2.6, and other models that don't accept\n * the `response_format.json_schema` shape but DO accept `json_object`.\n */\nexport async function callLlmJson<T = unknown>(\n req: LlmCallRequest,\n opts: LlmClientOptions = {},\n): Promise<{ value: T; result: LlmCallResult }> {\n const result = await callLlmStructured(req, opts)\n const value = parseJsonResult<T>(result, opts.jsonPayloadMode ?? 'extract')\n return { value, result }\n}\n\n/** Shared schema-to-JSON-mode fallback that preserves the raw result. */\nasync function callLlmStructured(\n req: LlmCallRequest,\n opts: LlmClientOptions = {},\n): Promise<LlmCallResult> {\n try {\n return await callLlm({ ...req, jsonMode: req.jsonMode ?? !req.jsonSchema }, opts)\n } catch (err) {\n if (\n opts.jsonSchemaTransport !== 'json-object' &&\n err instanceof LlmCallError &&\n isSchemaRejection(err.status, err.body) &&\n req.jsonSchema\n ) {\n const degradedReq: LlmCallRequest = { ...req, jsonMode: true, jsonSchema: undefined }\n return await callLlm(degradedReq, opts)\n }\n throw err\n }\n}\n\nfunction parseJsonResult<T>(\n result: LlmCallResult,\n jsonPayloadMode: NonNullable<LlmClientOptions['jsonPayloadMode']>,\n): T {\n try {\n if (result.finishReason === 'length') {\n throw new Error(\n `LLM returned truncated JSON content (model=${result.model}, finishReason=length)`,\n )\n }\n return parseJsonSafely<T>(result.content, result.model, jsonPayloadMode)\n } catch (error) {\n if (error instanceof LlmResponseError) throw error\n const cause = error instanceof Error ? error : new Error(String(error))\n throw new LlmResponseError(cause.message, result, { cause })\n }\n}\n\nfunction parseJsonSafely<T>(\n content: string,\n model: string,\n jsonPayloadMode: NonNullable<LlmClientOptions['jsonPayloadMode']>,\n): T {\n const payload = jsonPayloadMode === 'exact' ? content : extractJsonPayload(content)\n try {\n return JSON.parse(payload) as T\n } catch {\n throw new Error(`LLM returned non-JSON content (model=${model})`)\n }\n}\n\n/**\n * Stateful client — construct once with defaults, call many times.\n * Thin wrapper around the free functions; exists for callers that want\n * to inject a single configured instance into multiple primitives.\n */\nexport class LlmClient {\n readonly maximumAttempts: number\n private readonly opts: LlmClientOptions\n\n constructor(opts: LlmClientOptions = {}) {\n this.opts = opts\n this.maximumAttempts = resolveMaximumAttempts(opts.maximumAttempts)\n }\n\n call(req: LlmCallRequest, per?: LlmClientOptions): Promise<LlmCallResult> {\n const options = { ...this.opts, ...per }\n return req.jsonSchema ? callLlmStructured(req, options) : callLlm(req, options)\n }\n\n callJson<T = unknown>(\n req: LlmCallRequest,\n per?: LlmClientOptions,\n ): Promise<{ value: T; result: LlmCallResult }> {\n return callLlmJson<T>(req, { ...this.opts, ...per })\n }\n}\n"],"mappings":";;;;;AA2BA,MAAM,kBAA+C;CACnD,WAAW;CACX,QAAQ;CACR,gBAAgB;CAChB,QAAQ;CACR,iBAAiB;CACjB,MAAM;CACN,cAAc;CACd,SAAS;CACT,WAAW;CACX,UAAU;CACV,KAAK;CACL,MAAM;CACN,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,UAAU;CACV,YAAY;CACZ,MAAM;CACN,aAAa;CACb,OAAO;CACP,SAAS;CACT,KAAK;CACL,QAAQ;CACR,KAAK;AACP;;AAGA,MAAM,gBAA8C;CAClD,CAAC,WAAW,WAAW;CACvB,CAAC,0DAA0D,QAAQ;CACnE,CAAC,4BAA4B,QAAQ;CACrC,CAAC,UAAU,MAAM;CACjB,CAAC,oCAAoC,SAAS;CAC9C,CAAC,aAAa,UAAU;CACxB,CAAC,SAAS,KAAK;CACf,CAAC,SAAS,MAAM;CAChB,CAAC,oBAAoB,QAAQ;CAC7B,CAAC,qBAAqB,QAAQ;CAC9B,CAAC,sBAAsB,UAAU;CACjC,CAAC,4BAA4B,OAAO;AACtC;;;;;;;AAQA,SAAgB,YAAY,SAA8B;CACxD,MAAM,KAAK,QAAQ,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAE,YAAY;CACrD,MAAM,QAAQ,GAAG,QAAQ,GAAG;CAC5B,IAAI,QAAQ,GAAG;EACb,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK;EAChC,MAAM,SAAS,gBAAgB;EAC/B,IAAI,QAAQ,OAAO;CACrB;CACA,KAAK,MAAM,CAAC,SAAS,WAAW,eAC9B,IAAI,QAAQ,KAAK,EAAE,GAAG,OAAO;CAE/B,OAAO;AACT;AAWA,IAAa,mBAAb,cAAsC,MAAM;CAGxB;CACA;CAHlB,YACE,SACA,UACA,QACA;EACA,MAAM,OAAO;EAHG,KAAA,WAAA;EACA,KAAA,SAAA;EAGhB,KAAK,OAAO;CACd;AACF;;;;;;;;;;;;;;AAeA,SAAgB,kBACd,QACA,OAAiC,CAAC,GACnB;CACf,MAAM,cAAc,KAAK,eAAe;CACxC,MAAM,2BAAW,IAAI,IAAiB;CACtC,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,IAAI,YAAY,CAAC;EACvB,IAAI,MAAM,aAAa,CAAC,KAAK,cAAc;EAC3C,SAAS,IAAI,CAAC;CAChB;CACA,MAAM,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,KAAK;CAChC,IAAI,KAAK,SAAS,aAChB,MAAM,IAAI,iBACR,wBAAwB,KAAK,OAAO,iBAAiB,KAAK,WAAW,IAAI,MAAM,MAAM,IAC/E,KAAK,KAAK,IAAI,KAAK,OAAO,QAAQ,YAAY,kFAEpD,MACA,MACF;CAEF,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9DA,SAAgB,iBAAiB,SAAyB;CACxD,IAAI,KAAK,QAAQ,KAAK,CAAC,CAAC,YAAY;CACpC,MAAM,KAAK,GAAG,QAAQ,GAAG;CACzB,IAAI,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,EAAE;CAC/B,MAAM,QAAQ,GAAG,QAAQ,GAAG;CAC5B,IAAI,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK;CACrC,MAAM,QAAQ,GAAG,YAAY,GAAG;CAChC,IAAI,SAAS,GAAG,KAAK,GAAG,MAAM,QAAQ,CAAC;CACvC,OAAO,GACJ,QAAQ,uBAAuB,EAAE,CAAC,CAClC,QAAQ,WAAW,EAAE,CAAC,CACtB,QAAQ,SAAS,GAAG,CAAC,CACrB,QAAQ,OAAO,EAAE,CAAC,CAClB,KAAK;AACV;;;;;;;;;;;AAYA,SAAgB,iBACd,WACA,QACkB;CAClB,MAAM,kBAAkB,YAAY,SAAS;CAC7C,IAAI,WAAW,QAAQ,WAAW,KAAA,KAAa,OAAO,KAAK,MAAM,IAC/D,OAAO;EACL;EACA,QAAQ;EACR;EACA,cAAc;EACd,SAAS;EACT,aAAa;CACf;CAEF,MAAM,eAAe,YAAY,MAAM;CACvC,IAAI,UAAU,KAAK,CAAC,CAAC,YAAY,MAAM,OAAO,KAAK,CAAC,CAAC,YAAY,GAC/D,OAAO;EACL;EACA;EACA;EACA;EACA,SAAS;EACT,aAAa;CACf;CAEF,IAAI,iBAAiB,SAAS,MAAM,iBAAiB,MAAM,GACzD,OAAO;EACL;EACA;EACA;EACA;EACA,SAAS;EACT,aAAa;CACf;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA,SACE,oBAAoB,eAAe,8BAA8B;EACnE,aAAa;CACf;AACF;AAEA,IAAa,yBAAb,cAA4C,eAAe;CAGvC;CAFlB,YACE,SACA,QACA;EACA,MAAM,sBAAsB,OAAO;EAFnB,KAAA,SAAA;EAGhB,KAAK,OAAO;CACd;AACF;AAWA,SAAgB,wBACd,OACA,OACgD;CAChD,IAAI,UAAU,KAAA,KAAa,UAAU,WAAW,UAAU,uBACxD,MAAM,IAAI,MAAM,GAAG,MAAM,0CAA0C;AAEvE;;;;;;AAuBA,SAAgB,sBACd,OACA,OAAiC,CAAC,GACzB;CACT,QAAQ,MAAM,SAAd;EACE,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK,cACH,OAAO,KAAK,oBAAoB;EAClC,KAAK,6BACH,OAAO,KAAK,sBAAsB;EACpC,SACE,OAAO;CACX;AACF;AAEA,SAAS,SAAS,OAAiC;CACjD,IAAI,MAAM,YAAY,cACpB,OAAO,GAAG,MAAM,UAAU;CAC5B,OACE,GAAG,MAAM,UAAU,IAAI,MAAM,gBAAgB,aAAa,MAAM,OAAO,IACnE,MAAM,aAAa,KAAK,MAAM,QAAQ;AAE9C;;;;;;AAOA,SAAgB,kBACd,WACA,QACA,OAAiC,CAAC,GAChB;CAClB,MAAM,QAAQ,iBAAiB,WAAW,MAAM;CAChD,IAAI,sBAAsB,OAAO,IAAI,GAAG,OAAO;CAE/C,MAAM,IAAI,uBACR,GAFa,KAAK,UAAU,GAAG,KAAK,QAAQ,MAAM,GAExC,uBAAuB,SAAS,KAAK,EAAE,gIAEjD,CAAC,KAAK,CACR;AACF;;;;;AAMA,SAAgB,mBACd,OACA,OAAiC,CAAC,GACd;CACpB,MAAM,SAAS,MAAM,KAAK,MAAM,iBAAiB,EAAE,WAAW,EAAE,MAAM,CAAC;CACvE,MAAM,MAAM,OAAO,QAAQ,MAAM,CAAC,sBAAsB,GAAG,IAAI,CAAC;CAChE,IAAI,IAAI,SAAS,GAEf,MAAM,IAAI,uBACR,GAFa,KAAK,UAAU,GAAG,KAAK,QAAQ,MAAM,KAEtC,IAAI,OAAO,GAAG,OAAO,OAAO,+DACvB,IAAI,IAAI,QAAQ,CAAC,CAAC,KAAK,IAAI,EAAE,6FAE9C,MACF;CAEF,OAAO;AACT;AASA,IAAa,yBAAb,cAA4C,eAAe;CAGvC;CACA;CAHlB,YACE,SACA,UACA,QACA;EACA,MAAM,sBAAsB,OAAO;EAHnB,KAAA,WAAA;EACA,KAAA,SAAA;EAGhB,KAAK,OAAO;CACd;AACF;;;;;;;;;;AAWA,SAAgB,wBACd,OACA,OAAuC,CAAC,GACzB;CACf,MAAM,SAAS,mBAAmB,OAAO,IAAI;CAC7C,MAAM,2BAAW,IAAI,IAAiB;CACtC,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,SAAS,MAAM;EACrB,IAAI,WAAW,MAAM;EACrB,IAAI,WAAW,aAAa,CAAC,KAAK,cAAc;EAChD,SAAS,IAAI,MAAM;CACrB;CACA,MAAM,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,KAAK;CAChC,MAAM,cAAc,KAAK,eAAe;CACxC,IAAI,KAAK,SAAS,aAEhB,MAAM,IAAI,uBACR,GAFa,KAAK,UAAU,GAAG,KAAK,QAAQ,MAAM,GAExC,gCAAgC,KAAK,OAAO,iBACjD,KAAK,WAAW,IAAI,MAAM,MAAM,IAAI,KAAK,KAAK,IAAI,KAAK,OAAO,QAAQ,YAAY,0BAC3D,OAAO,KAAK,MAAM,EAAE,UAAU,YAAY,CAAC,CAAC,KAAK,IAAI,KACjF,MACA,MACF;CAEF,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5LA,SAAgB,2BACd,SAIA,UAA2B,CAAC,GACD;CAC3B,IAAI,QAAQ,cAAc,KAAA,GAAW,OAAO,KAAA;CAC5C,IAAI,CAAC,OAAO,UAAU,QAAQ,SAAS,KAAK,QAAQ,aAAa,GAC/D,MAAM,IAAI,WAAW,kEAAkE;CAEzF,IACE,QAAQ,SAAS,MACd,YACC,MAAM,QAAQ,QAAQ,OAAO,KAAK,QAAQ,QAAQ,MAAM,SAAS,KAAK,SAAS,WAAW,CAC9F,GAEA;CAGF,MAAM,WAAW,uBAAuB,QAAQ,eAAe;CAC/D,MAAM,kBAAkB,QAAQ,wBAAwB;CAGxD,MAAM,eAAe,IAAI,YAAY,CAAC,CAAC,OACrC,KAAK,UAAU,UAAU,SAAS,iBAAiB,QAAQ,QAAQ,CAAC,CACtE,CAAC,CAAC;CAEF,MAAM,UAAU,QAAQ,cAAc,CAAC,kBAAkB,IAAI;CAC7D,MAAM,QAAQ;EACZ,aAAa,eAAe,WAAW;EACvC,cAAc,QAAQ,YAAY,WAAW;CAC/C;CACA,OAAO,QAAQ,qBACX;EAAE,oBAAoB,QAAQ;EAAoB,GAAG;CAAM,IAC3D;EAAE,OAAO,QAAQ;EAAO,GAAG;CAAM;AACvC;;;;;;AA2FA,SAAgB,mBACd,QACA,oBACkB;CAClB,MAAM,eAAe,OAAO,MAAM,sBAAsB;CACxD,MAAM,cAAc,KAAK,IAAI,GAAG,OAAO,MAAM,eAAe,YAAY;CACxE,MAAM,kBAAkB,qBAAqB,OAAO,GAAG;CACvD,OAAO;EACL,OAAO,OAAO;EACd;EACA,cAAc,OAAO,MAAM;EAC3B,GAAI,OAAO,MAAM,oBAAoB,KAAA,IACjC,CAAC,IACD,EAAE,iBAAiB,OAAO,MAAM,gBAAgB;EACpD,GAAI,eAAe,IAAI,EAAE,aAAa,IAAI,CAAC;EAC3C,GAAI,oBAAoB,KAAA,IACpB,sBAAsB,OAAO,MAAM,aAAa,QAC9C,EAAE,mBAAmB,IACrB,OAAO,YAAY,OACjB,CAAC,IACD,EAAE,kBAAkB,OAAO,QAAQ,IACvC,EAAE,eAAe,gBAAgB;EACrC,cAAc,OAAO,MAAM,aAAa;CAC1C;AACF;AAEA,SAAS,qBAAqB,KAAkD;CAC9E,MAAM,QAAQ,IAAI,kBAAkB,IAAI;CACxC,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,SAAS,IAAI,QAAQ,KAAA;AACrF;;AAGA,SAAgB,wBACd,OACA,oBAC8B;CAC9B,OAAO,iBAAiB,mBACpB,mBAAmB,MAAM,QAAQ,kBAAkB,IACnD,KAAA;AACN;AAEA,IAAa,eAAb,cAAkC,eAAe;CAG7B;CACA;CACA;CAJlB,YACE,SACA,QACA,MACA,OACA;EACA,MAAM,SAAS,OAAO;EAJN,KAAA,SAAA;EACA,KAAA,OAAA;EACA,KAAA,QAAA;CAGlB;AACF;;;;AAKA,IAAa,mBAAb,cAAsC,eAAe;CAGjC;CAFlB,YACE,SACA,QACA,SACA;EACA,MAAM,SAAS,SAAS,OAAO;EAHf,KAAA,SAAA;CAIlB;AACF;AA4EA,MAAM,qBAAqB,OAAO,QAAQ,IAAI,qBAAqB,KAAK;AACxE,MAAM,2BACJ,QAAQ,IAAI,gCAAgC,KAAA,IACxC,IACA,OAAO,QAAQ,IAAI,2BAA2B;AAEpD,SAAS,uBAAuB,YAAwC;CACtE,MAAM,WAAW,cAAc;CAC/B,IAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,YAAY,GAC7C,MAAM,IAAI,WAAW,iDAAiD;CAExE,OAAO;AACT;AAEA,SAAS,mBAAmB,OAAoC;CAC9D,OAAO,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,SAAS,IAAI,QAAQ,KAAA;AAC1F;AAKA,MAAM,mCAAmB,IAAI,IAAI;CAAC;CAAK;CAAK;CAAK;CAAK;CAAK;AAAG,CAAC;;;;;;;;;;AAW/D,MAAM,2BAA8C;CAClD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;AAaA,SAAgB,oBAAoB,KAAuB;CACzD,OAAO,kBAAkB,KAAK,CAAC;AACjC;AAEA,SAAS,kBAAkB,KAAc,OAAwB;CAC/D,IAAI,eAAe,cAAc,OAAO,iBAAiB,IAAI,IAAI,MAAM;CACvE,IAAI,EAAE,eAAe,QAAQ,OAAO;CAGpC,MAAM,SAAU,IAA6B;CAC7C,IAAI,OAAO,WAAW,YAAY,iBAAiB,IAAI,MAAM,GAAG,OAAO;CACvE,MAAM,OAAQ,IAA2B;CACzC,MAAM,WAAW,GAAG,IAAI,KAAK,IAAI,IAAI,QAAQ,IAAI,OAAO,SAAS,WAAW,OAAO;CACnF,IAAI,yBAAyB,MAAM,MAAM,EAAE,KAAK,QAAQ,CAAC,GAAG,OAAO;CACnE,MAAM,QAAS,IAA4B;CAC3C,IAAI,QAAQ,KAAK,iBAAiB,SAAS,UAAU,KACnD,OAAO,kBAAkB,OAAO,QAAQ,CAAC;CAE3C,OAAO;AACT;AAEA,SAAS,gBAAgB,SAAiC;CACxD,MAAM,IAAI,QAAQ,IAAI,aAAa;CACnC,IAAI,CAAC,GAAG,OAAO;CACf,MAAM,WAAW,OAAO,CAAC;CACzB,IAAI,OAAO,SAAS,QAAQ,KAAK,WAAW,GAAG,OAAO,WAAW;CACjE,MAAM,SAAS,KAAK,MAAM,CAAC;CAC3B,IAAI,OAAO,SAAS,MAAM,GAAG,OAAO,KAAK,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;CACnE,OAAO;AACT;;AAGA,SAAgB,UAAU,SAAyB;CACjD,OAAO,KAAK,IAAI,MAAM,KAAK,SAAS,IAAM;AAC5C;AAEA,SAAS,aAAa,MAAgD;CACpE,MAAM,UAAkC;EACtC,gBAAgB;EAChB,QAAQ;CACV;CACA,IAAI,KAAK,YACP,QAAQ,KAAK,WAAW,QAAQ,KAAK,WAAW;MAC3C,IAAI,KAAK,UAAU,KAAK,QAC7B,QAAQ,gBAAgB,UAAU,KAAK,UAAU,KAAK;CAExD,IAAI,KAAK,gBAAgB,QAAQ,qBAAqB,KAAK;CAC3D,OAAO;AACT;AAEA,SAAS,kBAAkB,QAAgB,MAAuB;CAChE,IAAI,WAAW,KAAK,OAAO;CAC3B,MAAM,QAAQ,KAAK,YAAY;CAC/B,OACE,MAAM,SAAS,iBAAiB,KAChC,MAAM,SAAS,aAAa,KAC5B,MAAM,SAAS,gBAAgB,KAC/B,MAAM,SAAS,eAAe;AAElC;AAEA,SAAS,0BAA0B,QAAgB,MAAuB;CACxE,IAAI,WAAW,OAAO,CAAC,eAAe,KAAK,IAAI,GAAG,OAAO;CACzD,OACE,iGAAiG,KAC/F,IACF,KAAK,oEAAoE,KAAK,IAAI;AAEtF;AAEA,SAAS,UACP,KACA,iBACA,iBACyB;CACzB,MAAM,OAAgC;EACpC,OAAO,IAAI;EACX,UAAU,IAAI,SAAS,IAAI,iBAAiB;EAC5C,aAAa,IAAI,eAAe;CAClC;CACA,IAAI,IAAI,aAAa,MACnB,IAAI,wBAAwB,IAAI,KAAK,GAAG,KAAK,wBAAwB,IAAI;MACpE,KAAK,aAAa,IAAI;CAE7B,IAAI,IAAI,aAAa,KAAA,GAAW;EAC9B,KAAK,WAAW;EAChB,KAAK,eAAe,IAAI,SAAS;CACnC;CACA,IAAI,IAAI,UAAU,KAAA,GAAW,KAAK,QAAQ,IAAI;CAC9C,IAAI,IAAI,eAAe,KAAA,GAAW,KAAK,cAAc,IAAI;CACzD,MAAM,WAAW,IAAI,YAAY;CACjC,IAAI,aAAa,KAAA,GACf,KAAK,WAAW,EAAE,MAAM,SAAS;CAGnC,IAAI,IAAI,cAAc,CAAC,iBACrB,KAAK,kBAAkB;EACrB,MAAM;EACN,aAAa;GAAE,MAAM,IAAI,WAAW;GAAM,QAAQ,IAAI,WAAW;GAAQ,QAAQ;EAAK;CACxF;MACK,IAAI,IAAI,YAAY,IAAI,YAC7B,KAAK,kBAAkB,EAAE,MAAM,cAAc;CAG/C,OAAO;AACT;AAEA,SAAS,wBAAwB,OAAwB;CACvD,OAAO,oBAAoB,KAAK,KAAK;AACvC;;AAGA,SAAS,kBAAkB,SAA8C;CACvE,IAAI,QAAQ,SAAS,QACnB,OAAO;EAAE,MAAM;EAAQ,cAAc,QAAQ;EAAY,SAAS,QAAQ;CAAQ;CAEpF,IAAI,QAAQ,cAAc,KAAA,GACxB,OAAO;EAAE,MAAM,QAAQ;EAAM,SAAS,QAAQ;CAAQ;CAExD,OAAO;EACL,MAAM,QAAQ;EACd,SAAS,QAAQ;EACjB,YAAY,QAAQ,UAAU,KAAK,UAAU;GAC3C,IAAI,KAAK;GACT,MAAM;GACN,UAAU;IAAE,MAAM,KAAK;IAAM,WAAW,KAAK;GAAc;EAC7D,EAAE;CACJ;AACF;;;;;;;AAQA,SAAS,kBAAkB,OAAgB,OAAsD;CAC/F,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM,OAAO;CAClD,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,MAAM,IAAI,MAAM,yDAAyD,MAAM,EAAE;CAEnF,OAAO,MAAM,KAAK,OAAO,UAAU;EACjC,MAAM,SAAS;EACf,IACE,CAAC,UACD,OAAO,WAAW,YAClB,OAAO,OAAO,UAAU,YACxB,OAAO,OAAO,YAAY,YAC1B,CAAC,OAAO,SAAS,OAAO,OAAO,GAE/B,MAAM,IAAI,MACR,iCAAiC,MAAM,gDAAgD,MAAM,EAC/F;EAEF,MAAM,MAAM,OAAO;EACnB,IAAI,QAAQ,KAAA,KAAa,QAAQ,QAAQ,CAAC,MAAM,QAAQ,GAAG,GACzD,MAAM,IAAI,MACR,iCAAiC,MAAM,yCAAyC,MAAM,EACxF;EAEF,OAAO;GACL,OAAO,OAAO;GACd,SAAS,OAAO;GAChB,MAAM,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,EAAA,CAAG,KAAK,aAAa,aAAa;IAClE,MAAM,YAAY;IAClB,IACE,CAAC,aACD,OAAO,cAAc,YACrB,OAAO,UAAU,UAAU,YAC3B,OAAO,UAAU,YAAY,YAC7B,CAAC,OAAO,SAAS,UAAU,OAAO,GAElC,MAAM,IAAI,MACR,iCAAiC,MAAM,iBAAiB,SAAS,gDAAgD,MAAM,EACzH;IAEF,OAAO;KAAE,OAAO,UAAU;KAAO,SAAS,UAAU;IAAQ;GAC9D,CAAC;EACH;CACF,CAAC;AACH;;;AAIA,SAAS,mBAAmB,OAAgB,OAA0C;CACpF,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM,OAAO,KAAA;CAClD,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,MAAM,IAAI,MAAM,mDAAmD,MAAM,EAAE;CAE7E,IAAI,MAAM,WAAW,GAAG,OAAO,KAAA;CAC/B,OAAO,MAAM,KAAK,OAAO,UAAU;EACjC,MAAM,SAAS;EAKf,MAAM,KAAK,UAAU,OAAO,WAAW,WAAW,OAAO,WAAW,KAAA;EACpE,IACE,CAAC,UACD,OAAO,WAAW,YAClB,OAAO,OAAO,OAAO,YACrB,OAAO,GAAG,WAAW,KACpB,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,cAC9C,CAAC,MACD,OAAO,OAAO,YACd,OAAO,GAAG,SAAS,YACnB,GAAG,KAAK,WAAW,KACnB,OAAO,GAAG,cAAc,UAExB,MAAM,IAAI,MACR,2BAA2B,MAAM,wDAAwD,MAAM,EACjG;EAEF,OAAO;GAAE,IAAI,OAAO;GAAI,MAAM,GAAG;GAAM,eAAe,GAAG;EAAU;CACrE,CAAC;AACH;AAEA,eAAe,MAAM,IAA2B;CAC9C,OAAO,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;;;;;;;;AASA,SAAS,YAAY,mBAAoC,QAAmC;CAC1F,IAAI,CAAC,QAAQ,OAAO,kBAAkB;CACtC,IAAI,OAAQ,YAAkC,QAAQ,YACpD,OAAO,YAAY,IAAI,CAAC,kBAAkB,QAAQ,MAAM,CAAC;CAE3D,IAAI,OAAO,SACT,kBAAkB,MAAM;MAExB,OAAO,iBAAiB,eAAe,kBAAkB,MAAM,GAAG,EAAE,MAAM,KAAK,CAAC;CAElF,OAAO,kBAAkB;AAC3B;;AAGA,SAAS,iBAAiB,OAAe,YAAyC;CAChF,OAAO,cAAc,QAAQ,KAAK,IAAI,IAAI,SAAS;AACrD;;;;;;AASA,SAAgB,gBAAgB,KAAqB;CACnD,MAAM,UAAU,IAAI,KAAK;CACzB,MAAM,IAAI,QAAQ,MAAM,yCAAyC;CACjE,OAAO,IAAI,EAAE,EAAE,CAAE,KAAK,IAAI;AAC5B;AAEA,SAAgB,mBAAmB,KAAqB;CACtD,MAAM,WAAW,gBAAgB,GAAG;CACpC,IAAI;EACF,KAAK,MAAM,QAAQ;EACnB,OAAO;CACT,QAAQ;EAIN,IAAI,SAAS,WAAW,GAAG,KAAK,SAAS,WAAW,GAAG,GAAG,OAAO;CACnE;CAGA,MAAM,SAAS,CAAC,GAAG,SAAS,SAAS,OAAO,CAAC,CAAC,CAC3C,KAAK,UAAU,MAAM,KAAK,CAAC,CAC3B,QAAQ,UAAU,SAAS,IAAI;CAClC,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,YAAY,oBAAoB,UAAU,KAAK;EACrD,IAAI,CAAC,WAAW;EAChB,IAAI;GACF,KAAK,MAAM,SAAS;GACpB,OAAO;EACT,QAAQ,CAER;CACF;CAEA,OAAO;AACT;AAEA,SAAS,oBAAoB,OAAe,OAA8B;CACxE,MAAM,SAAS,MAAM;CACrB,MAAM,SAAS,WAAW,MAAM,MAAM,WAAW,MAAM,MAAM;CAC7D,IAAI,CAAC,QAAQ,OAAO;CAEpB,MAAM,QAAkB,CAAC,MAAM;CAC/B,IAAI,aAAa;CACjB,IAAI,YAAY;CAEhB,KAAK,IAAI,IAAI,QAAQ,GAAG,IAAI,MAAM,QAAQ,KAAK;EAC7C,MAAM,OAAO,MAAM;EACnB,IAAI,WAAW;GACb,YAAY;GACZ;EACF;EACA,IAAI,SAAS,MAAM;GACjB,YAAY;GACZ;EACF;EACA,IAAI,SAAS,MAAK;GAChB,aAAa,CAAC;GACd;EACF;EACA,IAAI,YAAY;EAEhB,IAAI,SAAS,KAAK,MAAM,KAAK,GAAG;OAC3B,IAAI,SAAS,KAAK,MAAM,KAAK,GAAG;OAChC,IAAI,SAAS,MAAM,MAAM,SAAS,IAAI;GACzC,MAAM,IAAI;GACV,IAAI,MAAM,WAAW,GAAG,OAAO,MAAM,MAAM,OAAO,IAAI,CAAC;EACzD;CACF;CAEA,OAAO;AACT;;;;;;AAOA,eAAsB,QACpB,KACA,OAAyB,CAAC,GACF;CAIxB,IAAI,CAAC,KAAK,SAAS,MAAM,IAAI,MAAM,mCAAmC;CACtE,MAAM,UAAU,KAAK,QAAQ,QAAQ,QAAQ,EAAE;CAC/C,MAAM,MAAM,GAAG,QAAQ;CACvB,MAAM,WAAW;CACjB,MAAM,YAAY,IAAI,aAAa,KAAK,oBAAoB;CAC5D,MAAM,kBAAkB,uBAAuB,KAAK,eAAe;CACnE,MAAM,UAAU,KAAK,SAAS,WAAW;CACzC,MAAM,UAAU,aAAa,IAAI;CACjC,MAAM,WAAW,KAAK,YAAY,oBAAoB,OAAO;CAC7D,MAAM,OAAO,KAAK;CAClB,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,eAAe,KAAK;CAC1B,MAAM,eAAe,KAAK;CAC1B,MAAM,aAAa,KAAK;CACxB,MAAM,gBAAgB,KAAK,IAAI;CAC/B,IAAI,KAAK,oBACP,oBAAoB,KAAK,oBAAoB;EAAE,aAAa;EAAG,cAAc;CAAE,CAAC;CAGlF,IAAI;CACJ,IAAI,mBAAmB;CACvB,KAAK,IAAI,UAAU,GAAG,UAAU,iBAAiB,WAAW;EAG1D,IAAI,cAAc,SAChB,MAAM,IAAI,aAAa,oCAAoC,YAAY;EAIzE,IAAI,UAAU,KAAK,iBAAiB,eAAe,UAAU,GAC3D,MAAM,mBAAmB,QAAQ,UAAU,IAAI,MAAM,OAAO,OAAO,CAAC;EAEtE,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,gBAAgB,YAAY,YAAY,YAAY;EAC1D,MAAM,gBAAgB,iBAAiB,WAAW,MAAM,GAAG,SAAS;EACpE,MAAM,UAAU,KAAK,IAAI;EACzB,MAAM,cAAc,UAClB,kBACA,KAAK,wBAAwB,eAC7B,KAAK,QACP;EACA,IAAI,uBAAuB;EAC3B,IAAI,MACF,MAAM,UAAU,MAAM,UAAU;GAC9B,SAAS,cAAc;GACvB,OAAO,cAAc;GACrB,QAAQ,cAAc;GACtB;GACA,OAAO,IAAI;GACX;GACA;GACA,cAAc;GACd,WAAW;GACX,WAAW;GACX,gBAAgB;GAChB;GACA,gBAAgB,CAAC;EACnB,CAAC;EAGH,IAAI;GACF,MAAM,MAAM,MAAM,QAAQ,KAAK;IAC7B,QAAQ;IACR;IACA,MAAM,KAAK,UAAU,WAAW;IAChC,QAAQ;GACV,CAAC;GACD,aAAa,aAAa;GAC1B,MAAM,kBAAkB,OAAO,gBAAgB,IAAI,OAAO,IAAI,KAAA;GAE9D,IAAI,CAAC,IAAI,IAAI;IACX,MAAM,OAAO,MAAM,IAAI,KAAK;IAC5B,IAAI,MAAM;KACR,MAAM,UAAU,MAAM,UAAU;MAC9B,SAAS,cAAc;MACvB,OAAO,cAAc;MACrB,QAAQ,cAAc;MACtB;MACA,OAAO,IAAI;MACX;MACA;MACA,cAAc;MACd,WAAW;MACX,WAAW,KAAK,IAAI;MACpB,YAAY,KAAK,IAAI,IAAI;MACzB,YAAY,IAAI;MAChB;MACA,cAAc;MACd,cAAc,QAAQ,IAAI;MAC1B,gBAAgB,CAAC;KACnB,CAAC;KACD,uBAAuB;IACzB;IACA,MAAM,MAAM,IAAI,aACd,6BAA6B,IAAI,UACjC,IAAI,QACJ,MACA,IAAI,KACN;IACA,IACE,0BAA0B,IAAI,QAAQ,IAAI,KAC1C,iBAAiB,gBAAgB,KACjC,UAAU,kBAAkB,KAC5B,CAAC,iBAAiB,eAAe,UAAU,GAC3C;KACA,UAAU;KACV,mBAAmB;MAAE,GAAG;MAAkB,aAAa;KAAE;KACzD;IACF;IACA,IACE,iBAAiB,IAAI,IAAI,MAAM,KAC/B,UAAU,kBAAkB,KAC5B,CAAC,iBAAiB,eAAe,UAAU,GAC3C;KACA,UAAU;KAEV,MAAM,MADa,gBAAgB,IAAI,OAClB,KAAK,UAAU,OAAO,CAAC;KAC5C;IACF;IACA,MAAM;GACR;GAEA,MAAM,OAAO,MAAM,IAAI,KAAK;GAC5B,IAAI;GACJ,IAAI;IACF,OAAO,KAAK,MAAM,IAAI;GACxB,SAAS,UAAU;IACjB,IAAI,MAAM;KACR,MAAM,UAAU,MAAM,UAAU;MAC9B,SAAS,cAAc;MACvB,OAAO,cAAc;MACrB,QAAQ,cAAc;MACtB;MACA,OAAO,IAAI;MACX;MACA;MACA,cAAc;MACd,WAAW;MACX,WAAW,KAAK,IAAI;MACpB,YAAY,KAAK,IAAI,IAAI;MACzB,YAAY,IAAI;MAChB;MACA,cAAc;MACd,cAAc,sBAAsB,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ;MAClG,gBAAgB,CAAC;KACnB,CAAC;KACD,uBAAuB;IACzB;IACA,MAAM;GACR;GACA,IAAI,MACF,MAAM,UAAU,MAAM,UAAU;IAC9B,SAAS,cAAc;IACvB,OAAO,cAAc;IACrB,QAAQ,cAAc;IACtB;IACA,OAAO,IAAI;IACX;IACA;IACA,cAAc;IACd,WAAW;IACX,WAAW,KAAK,IAAI;IACpB,YAAY,KAAK,IAAI,IAAI;IACzB,YAAY,IAAI;IAChB;IACA,cAAc;IACd,gBAAgB,CAAC;GACnB,CAAC;GAEH,MAAM,SACJ,KAAK,UAOH;GACJ,MAAM,YAAY,mBAAmB,QAAQ,SAAS,YAAY,IAAI,KAAK;GAC3E,MAAM,WACJ,KAAK,SAAS,OAAO,KAAK,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,KAAK,IACpE,KAAK,QACN,KAAA;GACN,MAAM,eAAe,mBAAmB,UAAU,aAAa;GAC/D,MAAM,mBAAmB,mBAAmB,UAAU,iBAAiB;GACvE,MAAM,cAAc,mBAAmB,UAAU,YAAY;GAO7D,MAAM,gBALJ,UAAU,6BACV,OAAO,SAAS,8BAA8B,YAC9C,CAAC,MAAM,QAAQ,SAAS,yBAAyB,IAC5C,SAAS,4BACV,KAAA,EAAA,EACkC;GACxC,MAAM,kBACJ,iBAAiB,KAAA,IAAY,KAAA,IAAY,mBAAmB,YAAY;GAC1E,MAAM,YACJ,UAAU,yBACV,OAAO,SAAS,0BAA0B,YAC1C,CAAC,MAAM,QAAQ,SAAS,qBAAqB,IACxC,SAAS,sBAAkD,gBAC5D,KAAA;GACN,MAAM,qBAAqB,cAAc,KAAA,IAAY,KAAA,IAAY,mBAAmB,SAAS;GAC7F,MAAM,gBACJ,iBAAiB,KAAA,KACjB,qBAAqB,KAAA,MACpB,iBAAiB,KAAA,KACf,oBAAoB,KAAA,KAAa,mBAAmB,sBACtD,cAAc,KAAA,KACZ,uBAAuB,KAAA,KAAa,sBAAsB,kBAC5D,gBAAgB,KAAA,KAAa,gBAAgB,eAAe;GAC/D,MAAM,gBAAiB,KAAK,kBAAkB,KAAK;GACnD,MAAM,UAAU,QAAQ,SAAS,WAAW;GAE5C,MAAM,iBACJ,OAAO,kBAAkB,YAAY,iBAAiB,KAAK,qBACvD,oBAAoB,KAAK,oBAAoB;IAC3C,aAAa,gBAAiB,sBAAsB;IACpD,GAAI,qBAAqB,EAAE,cAAc,mBAAmB,IAAI,CAAC;IACjE,cAAc;GAChB,CAAC,IACD,KAAA;GAIN,MAAM,cACJ,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,QAAQ;GAC5E,IAAI,KAAK,mBACP,kBACE,IAAI,OACJ,aACA,KAAK,sBAAsB,OAAO,CAAC,IAAI,KAAK,iBAC9C;GAGF,OAAO;IACL;IACA,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU;IAC/C,GAAI,IAAI,aAAa,KAAA,IACjB,CAAC,IACD,EAAE,UAAU,kBAAkB,QAAQ,UAAU,SAAS,IAAI,KAAK,EAAE;IACxE,cAAc,QAAQ,iBAAiB;IACvC,cAAc,QAAQ,KAAK,CAAC,CAAC,WAAW;IACxC,OAAO;KACL,cAAc,gBAAgB;KAC9B,kBAAkB,oBAAoB;KACtC,aAAa,gBAAgB,gBAAgB,MAAM,oBAAoB;KACvE,UAAU;KACV;KACA;IACF;IACA,SAAS,OAAO,kBAAkB,WAAW,gBAAiB,kBAAkB;IAChF,OAAO,eAAe,IAAI;IAC1B;IACA,YAAY,KAAK,IAAI,IAAI;IACzB,KAAK;GACP;EACF,SAAS,KAAK;GACZ,aAAa,aAAa;GAC1B,UAAU;GAIV,IAAI,cAAc,SAAS;IACzB,IAAI,QAAQ,CAAC,sBACX,MAAM,UAAU,MAAM,UAAU;KAC9B,SAAS,cAAc;KACvB,OAAO,cAAc;KACrB,QAAQ,cAAc;KACtB;KACA,OAAO,IAAI;KACX;KACA;KACA,cAAc;KACd,WAAW;KACX,WAAW,KAAK,IAAI;KACpB,YAAY,KAAK,IAAI,IAAI;KACzB,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KAC7D,gBAAgB,CAAC;IACnB,CAAC;IAEH,MAAM;GACR;GACA,IAAI,QAAQ,CAAC,sBAIX,MAAM,UAAU,MAAM,UAAU;IAC9B,SAAS,cAAc;IACvB,OAAO,cAAc;IACrB,QAAQ,cAAc;IACtB;IACA,OAAO,IAAI;IACX;IACA;IACA,cAAc;IACd,WAAW;IACX,WAAW,KAAK,IAAI;IACpB,YAAY,KAAK,IAAI,IAAI;IACzB,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;IAC7D,gBAAgB,CAAC;GACnB,CAAC;GAEH,IACE,UAAU,kBAAkB,KAC5B,oBAAoB,GAAG,KACvB,CAAC,iBAAiB,eAAe,UAAU,GAC3C;IACA,MAAM,MAAM,UAAU,OAAO,CAAC;IAC9B;GACF;GACA,MAAM;EACR;CACF;CACA,MAAM,mBAAmB,QAAQ,UAAU,IAAI,MAAM,OAAO,OAAO,CAAC;AACtE;AAEA,eAAe,UACb,MACA,UACA,OACe;CAGf,IAAI;EACF,MAAM,KAAK,OAAO,SAAS,KAAK,CAAC;CACnC,QAAQ,CAER;AACF;AAEA,SAAS,gBAAgB,GAAoC;CAC3D,MAAM,MAA8B,CAAC;CACrC,EAAE,SAAS,OAAO,QAAQ;EACxB,IAAI,OAAO;CACb,CAAC;CACD,OAAO;AACT;AAEA,SAAS,gBAAwB;CAC/B,IAAI,OAAO,WAAW,QAAQ,eAAe,YAAY,OAAO,WAAW,OAAO,WAAW;CAC7F,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,EAAE;AAC7E;;;;;;;AAQA,eAAsB,YACpB,KACA,OAAyB,CAAC,GACoB;CAC9C,MAAM,SAAS,MAAM,kBAAkB,KAAK,IAAI;CAEhD,OAAO;EAAE,OADK,gBAAmB,QAAQ,KAAK,mBAAmB,SACpD;EAAG;CAAO;AACzB;;AAGA,eAAe,kBACb,KACA,OAAyB,CAAC,GACF;CACxB,IAAI;EACF,OAAO,MAAM,QAAQ;GAAE,GAAG;GAAK,UAAU,IAAI,YAAY,CAAC,IAAI;EAAW,GAAG,IAAI;CAClF,SAAS,KAAK;EACZ,IACE,KAAK,wBAAwB,iBAC7B,eAAe,gBACf,kBAAkB,IAAI,QAAQ,IAAI,IAAI,KACtC,IAAI,YAGJ,OAAO,MAAM,QAAQ;GADiB,GAAG;GAAK,UAAU;GAAM,YAAY,KAAA;EAC3C,GAAG,IAAI;EAExC,MAAM;CACR;AACF;AAEA,SAAS,gBACP,QACA,iBACG;CACH,IAAI;EACF,IAAI,OAAO,iBAAiB,UAC1B,MAAM,IAAI,MACR,8CAA8C,OAAO,MAAM,uBAC7D;EAEF,OAAO,gBAAmB,OAAO,SAAS,OAAO,OAAO,eAAe;CACzE,SAAS,OAAO;EACd,IAAI,iBAAiB,kBAAkB,MAAM;EAC7C,MAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;EACtE,MAAM,IAAI,iBAAiB,MAAM,SAAS,QAAQ,EAAE,MAAM,CAAC;CAC7D;AACF;AAEA,SAAS,gBACP,SACA,OACA,iBACG;CACH,MAAM,UAAU,oBAAoB,UAAU,UAAU,mBAAmB,OAAO;CAClF,IAAI;EACF,OAAO,KAAK,MAAM,OAAO;CAC3B,QAAQ;EACN,MAAM,IAAI,MAAM,wCAAwC,MAAM,EAAE;CAClE;AACF;;;;;;AAOA,IAAa,YAAb,MAAuB;CACrB;CACA;CAEA,YAAY,OAAyB,CAAC,GAAG;EACvC,KAAK,OAAO;EACZ,KAAK,kBAAkB,uBAAuB,KAAK,eAAe;CACpE;CAEA,KAAK,KAAqB,KAAgD;EACxE,MAAM,UAAU;GAAE,GAAG,KAAK;GAAM,GAAG;EAAI;EACvC,OAAO,IAAI,aAAa,kBAAkB,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO;CAChF;CAEA,SACE,KACA,KAC8C;EAC9C,OAAO,YAAe,KAAK;GAAE,GAAG,KAAK;GAAM,GAAG;EAAI,CAAC;CACrD;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"query-CHmMP42p.js","names":[],"sources":["../src/trace/query.ts"],"sourcesContent":["/**\n * Typed query helpers over TraceStore.\n *\n * Not a full SQL engine — a minimal, composable set of operators that\n * cover the canned-pipeline use cases. For ad-hoc analytics, persist to\n * NDJSON and point DuckDB at it; the schema is stable so external SQL\n * tooling works out of the box.\n */\n\nimport { canonicalString } from '../ledger-core/canonical'\nimport type { FailureClass, JudgeSpan, LlmSpan, Run, ToolSpan } from './schema'\nimport { isJudgeSpan, isLlmSpan, isToolSpan } from './schema'\nimport type { TraceStore } from './store'\n\nexport async function runsForScenario(store: TraceStore, scenarioId: string): Promise<Run[]> {\n return store.listRuns({ scenarioId })\n}\n\nexport async function llmSpans(store: TraceStore, runId?: string): Promise<LlmSpan[]> {\n const spans = await store.spans({ runId, kind: 'llm' })\n return spans.filter(isLlmSpan)\n}\n\nexport async function toolSpans(\n store: TraceStore,\n runId?: string,\n toolName?: string,\n): Promise<ToolSpan[]> {\n const spans = await store.spans({ runId, kind: 'tool', toolName })\n return spans.filter(isToolSpan)\n}\n\n/** Query judge-kind spans from the trace store, optionally scoped to a single run. */\nexport async function judgeSpans(store: TraceStore, runId?: string): Promise<JudgeSpan[]> {\n const spans = await store.spans({ runId, kind: 'judge' })\n return spans.filter(isJudgeSpan)\n}\n\n/** Group spans by any key selector. */\nexport function groupBy<T, K extends string | number>(items: T[], key: (t: T) => K): Map<K, T[]> {\n const map = new Map<K, T[]>()\n for (const item of items) {\n const k = key(item)\n let bucket = map.get(k)\n if (!bucket) {\n bucket = []\n map.set(k, bucket)\n }\n bucket.push(item)\n }\n return map\n}\n\n/**\n * Key tool arguments for de-duplication: RFC 8785 canonical JSON, so key\n * order cannot split one call into two keys. Uncaptured args (`undefined`)\n * key to the string `'undefined'` so every call still keys to a string; an\n * args value with no canonical JSON form (a nested `undefined`, a function, a\n * non-finite number) throws `LedgerCanonicalizationError`.\n */\nexport function argHash(args: unknown): string {\n if (args === undefined) return 'undefined'\n return canonicalString(args)\n}\n\n/** Whether argument-based comparisons are valid for this tool call. */\nexport function hasCapturedToolArgs(span: ToolSpan): boolean {\n return span.argsCaptured !== false\n}\n\n/** Sum an LLM-span array into aggregate token + cost. */\nexport function aggregateLlm(spans: LlmSpan[]): {\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n cacheWriteTokens: number\n reasoningTokens: number\n costUsd: number\n} {\n return spans.reduce(\n (acc, s) => ({\n inputTokens: acc.inputTokens + (s.inputTokens ?? 0),\n outputTokens: acc.outputTokens + (s.outputTokens ?? 0),\n cachedTokens: acc.cachedTokens + (s.cachedTokens ?? 0),\n cacheWriteTokens: acc.cacheWriteTokens + (s.cacheWriteTokens ?? 0),\n reasoningTokens: acc.reasoningTokens + (s.reasoningTokens ?? 0),\n costUsd: acc.costUsd + (s.costUsd ?? 0),\n }),\n {\n inputTokens: 0,\n outputTokens: 0,\n cachedTokens: 0,\n cacheWriteTokens: 0,\n reasoningTokens: 0,\n costUsd: 0,\n },\n )\n}\n\n/** Pick the outcome's failure class when present, else derive 'success' from run status. */\nexport function runFailureClass(run: Run): FailureClass {\n if (run.outcome?.failureClass) return run.outcome.failureClass\n if (run.status === 'completed' && run.outcome?.pass !== false) return 'success'\n if (run.status === 'aborted') return 'budget_exceeded'\n return 'unknown'\n}\n"],"mappings":";;;;;;;;;;;AAcA,eAAsB,gBAAgB,OAAmB,YAAoC;CAC3F,OAAO,MAAM,SAAS,EAAE,WAAW,CAAC;AACtC;AAEA,eAAsB,SAAS,OAAmB,OAAoC;CAEpF,QAAO,MADa,MAAM,MAAM;EAAE;EAAO,MAAM;CAAM,CAAC,EAAA,CACzC,OAAO,SAAS;AAC/B;AAEA,eAAsB,UACpB,OACA,OACA,UACqB;CAErB,QAAO,MADa,MAAM,MAAM;EAAE;EAAO,MAAM;EAAQ;CAAS,CAAC,EAAA,CACpD,OAAO,UAAU;AAChC;;AAGA,eAAsB,WAAW,OAAmB,OAAsC;CAExF,QAAO,MADa,MAAM,MAAM;EAAE;EAAO,MAAM;CAAQ,CAAC,EAAA,CAC3C,OAAO,WAAW;AACjC;;AAGA,SAAgB,QAAsC,OAAY,KAA+B;CAC/F,MAAM,sBAAM,IAAI,IAAY;CAC5B,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,IAAI,IAAI,IAAI;EAClB,IAAI,SAAS,IAAI,IAAI,CAAC;EACtB,IAAI,CAAC,QAAQ;GACX,SAAS,CAAC;GACV,IAAI,IAAI,GAAG,MAAM;EACnB;EACA,OAAO,KAAK,IAAI;CAClB;CACA,OAAO;AACT;;;;;;;;AASA,SAAgB,QAAQ,MAAuB;CAC7C,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,OAAO,gBAAgB,IAAI;AAC7B;;AAGA,SAAgB,oBAAoB,MAAyB;CAC3D,OAAO,KAAK,iBAAiB;AAC/B;;AAGA,SAAgB,aAAa,OAO3B;CACA,OAAO,MAAM,QACV,KAAK,OAAO;EACX,aAAa,IAAI,eAAe,EAAE,eAAe;EACjD,cAAc,IAAI,gBAAgB,EAAE,gBAAgB;EACpD,cAAc,IAAI,gBAAgB,EAAE,gBAAgB;EACpD,kBAAkB,IAAI,oBAAoB,EAAE,oBAAoB;EAChE,iBAAiB,IAAI,mBAAmB,EAAE,mBAAmB;EAC7D,SAAS,IAAI,WAAW,EAAE,WAAW;CACvC,IACA;EACE,aAAa;EACb,cAAc;EACd,cAAc;EACd,kBAAkB;EAClB,iBAAiB;EACjB,SAAS;CACX,CACF;AACF;;AAGA,SAAgB,gBAAgB,KAAwB;CACtD,IAAI,IAAI,SAAS,cAAc,OAAO,IAAI,QAAQ;CAClD,IAAI,IAAI,WAAW,eAAe,IAAI,SAAS,SAAS,OAAO,OAAO;CACtE,IAAI,IAAI,WAAW,WAAW,OAAO;CACrC,OAAO;AACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"query-DxPYqpmT.d.ts","names":[],"sources":["../src/trace/query.ts"],"mappings":";;;iBAcsB,gBAAgB,OAAO,YAAY,qBAAqB,QAAQ;iBAIhE,SAAS,OAAO,YAAY,iBAAiB,QAAQ;iBAKrD,UACpB,OAAO,YACP,gBACA,oBACC,QAAQ;;iBAMW,WAAW,OAAO,YAAY,iBAAiB,QAAQ;;iBAM7D,QAAQ,GAAG,2BAA2B,OAAO,KAAK,MAAM,GAAG,MAAM,IAAI,IAAI,GAAG;;;;;;;;iBAqB5E,QAAQ;;iBAMR,oBAAoB,MAAM;;iBAK1B,aAAa,OAAO;EAClC;EACA;EACA;EACA;EACA;EACA;;;iBAuBc,gBAAgB,KAAK,MAAM"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"store-tool-spans-Dlh9vkFK.js","names":[],"sources":["../src/trace/capture-fetch.ts","../src/trace/wire-ids.ts","../src/trace/otel.ts","../src/trace-analyst/prompts.ts","../src/trace-analyst/analyst.ts","../src/trace-analyst/insights.ts","../src/trace/otlp-flat.ts","../src/trace-analyst/store-tool-spans.ts"],"sourcesContent":["/**\n * Wrap a provider `fetch` and record request, response, and error events.\n *\n * The returned value is a plain `typeof fetch`. Capture is best-effort by\n * default; set `failClosed` when telemetry loss must stop the provider call.\n */\n\nimport {\n type ExtractedUsage,\n extractUsage,\n extractUsageFromSse,\n type SseUsageMode,\n} from './extract-usage'\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 * Invoked with the token usage parsed off each successful response (JSON or\n * SSE), keyed by the captured context. Lets a caller fold usage → cost without\n * re-cloning the response themselves. Not called when the response carries no\n * usage. Best-effort: a throw here is swallowed (it never kills the LLM call)\n * unless `failClosed` is set.\n */\n onUsage?: (usage: ExtractedUsage, ctx: CaptureFetchContext) => void\n /** How repeated SSE usage events should be reconciled. Default `cumulative`. */\n sseUsageMode?: SseUsageMode\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 let rawText: string | undefined\n const redactedFields: string[] = []\n try {\n rawText = await response.clone().text()\n if (rawText.length > bodyCap) {\n responseBody = rawText.slice(0, bodyCap)\n redactedFields.push('body_truncated')\n } else {\n responseBody = parseMaybeJson(rawText)\n }\n } catch {\n responseBody = undefined\n }\n\n if (opts.onUsage && rawText !== undefined) {\n // Reuse the body already read for capture; no extra clone. JSON first,\n // then SSE accumulation. A throw in the consumer's callback is swallowed\n // (best-effort) unless failClosed is set — the LLM call must not die here.\n try {\n const parsedForUsage = parseMaybeJson(rawText)\n const usage =\n extractUsage(parsedForUsage) ??\n (typeof parsedForUsage === 'string'\n ? extractUsageFromSse(rawText, { mode: opts.sseUsageMode })\n : null)\n if (usage) opts.onUsage(usage, ctx)\n } catch (err) {\n if (opts.failClosed) throw err\n }\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 * The ONE mapping from agent-eval's human-readable ids (run ids, span labels)\n * to W3C/OTLP wire ids. Every exporter in this package MUST route through\n * these two functions — two exporters with private paddings once produced\n * DIFFERENT trace ids for the same run, and one emitted invalid hex embedding\n * the raw run id in the wire id (tangle-network/agent-runtime#694).\n *\n * Semantics:\n * - an id that is ALREADY a valid W3C id passes through unchanged, so a\n * trace id received from an inbound `traceparent` survives the round-trip\n * and cross-process correlation is preserved;\n * - anything else is derived with the contract's `deriveHexId`, the only\n * legal derivation — deterministic, so every process that derives from the\n * same human id mints the SAME wire id.\n */\n\nimport { deriveHexId, isW3CSpanId, isW3CTraceId } from '@tangle-network/agent-trace-contract'\n\n/** 32-hex W3C trace id for any id string. */\nexport function traceIdForWire(id: string): string {\n return isW3CTraceId(id) ? id : deriveHexId(id, 16)\n}\n\n/** 16-hex W3C span id for any id string. */\nexport function spanIdForWire(id: string): string {\n return isW3CSpanId(id) ? id : deriveHexId(id, 8)\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 {\n applyLlmSpanOtlpAttributes,\n applyToolSpanOtlpAttributes,\n OPENINFERENCE_SPAN_KIND,\n traceSpanKindToOpenInferenceKind,\n} from './otlp-attributes'\nimport type { Run, Span, TraceEvent } from './schema'\nimport type { TraceStore } from './store'\nimport { spanIdForWire, traceIdForWire } from './wire-ids'\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: spanIdForWire(span.spanId),\n parentSpanId: span.parentSpanId ? spanIdForWire(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 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 base[OPENINFERENCE_SPAN_KIND] = traceSpanKindToOpenInferenceKind(span.kind)\n if (span.kind === 'llm') {\n applyLlmSpanOtlpAttributes(base, span)\n } else if (span.kind === 'tool') {\n applyToolSpanOtlpAttributes(base, span)\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 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 runToTraceId(run: Run): string {\n return traceIdForWire(run.runId)\n}\n","/** General policy for recursive, evidence-backed trace analysis. */\n\nexport const TRACE_ANALYST_ACTOR_DESCRIPTION = `Answer the question by inspecting the OTLP trace dataset with the available tools.\n\n1. Call getDatasetOverview first. Use its real trace ids and dataset size to plan the investigation.\n2. Narrow with queryTraces and countTraces before scanning large payloads.\n3. For a small trace, use viewTrace. For a large trace, use searchTrace and then viewSpans or searchSpan.\n4. Never invent a trace id, span id, tool result, error, frequency, or final outcome.\n5. When a search reports has_more, refine the query before drawing a conclusion.\n6. Use llm_query only over evidence already loaded. A recursive query cannot inspect traces itself.\n7. Cite exact evidence URIs returned by the tools. Include a short exact excerpt when it supports the claim.\n8. Return no finding when the available evidence cannot support one.\n\nThe prose answer must directly answer the question and state important uncertainty.\nThe findings array contains only actionable or decision-relevant claims supported by inspected evidence.`\n\nexport const TRACE_ANALYST_ACTOR_DESCRIPTION_VERSION = 'trace-analyst-research-v1-2026-07-30'\n","import { randomUUID } from 'node:crypto'\nimport type {\n TraceAnalysisEngine,\n TraceAnalysisEngineResult,\n TraceAnalystLimits,\n} from '../analyst/engine'\nimport { runTraceAnalyst } from '../analyst/kind-factory'\nimport type { TraceToolGroupName } from '../analyst/tool-groups'\nimport type { AnalystFinding, AnalystUsageReceipt } from '../analyst/types'\nimport type { CostLedgerHandle } from '../cost-ledger'\nimport { TRACE_ANALYST_ACTOR_DESCRIPTION, TRACE_ANALYST_ACTOR_DESCRIPTION_VERSION } from './prompts'\nimport type { TraceAnalysisStore } from './store'\nimport { OtlpFileTraceStore } from './store-otlp'\n\nexport interface AnalyzeTracesInput {\n question: string\n id?: string\n description?: string\n area?: string\n}\n\nexport type AnalyzeTracesResult = TraceAnalysisEngineResult\n\nexport interface AnalyzeTracesOptions {\n /** OTLP JSONL path or a caller-owned store. */\n source: string | TraceAnalysisStore\n /** Recursive research engine. */\n engine: TraceAnalysisEngine\n /** Override the general trace-research policy. */\n instructions?: string\n /** Smallest tool set that can answer the question. Default: all. */\n toolGroup?: TraceToolGroupName\n limits?: Partial<TraceAnalystLimits>\n runId?: string\n budgetUsd?: number\n costLedger?: CostLedgerHandle\n costPhase?: string\n priorFindings?: readonly AnalystFinding[]\n upstreamFindings?: readonly AnalystFinding[]\n recordUsage?: (receipt: AnalystUsageReceipt) => void\n tags?: Record<string, string>\n log?: (message: string, fields?: Record<string, unknown>) => void\n signal?: AbortSignal\n}\n\n/**\n * Answer one question by recursively inspecting a trace store.\n *\n * The returned answer, cited findings, engine steps, call counts, and runtime\n * identity are one audit record. A direct one-shot model call is not used.\n */\nexport async function analyzeTraces(\n input: AnalyzeTracesInput,\n options: AnalyzeTracesOptions,\n): Promise<AnalyzeTracesResult> {\n if (typeof input.question !== 'string' || !input.question.trim()) {\n throw new TypeError('analyzeTraces: input.question must be a non-empty string')\n }\n const id = input.id?.trim() || 'trace-analysis'\n const store =\n typeof options.source === 'string'\n ? new OtlpFileTraceStore({ path: options.source })\n : options.source\n if (store instanceof OtlpFileTraceStore) {\n await store.ensureIndexed(options.signal ? { signal: options.signal } : undefined)\n }\n\n return runTraceAnalyst({\n definition: {\n id,\n description:\n input.description?.trim() ||\n 'Answers a caller-defined question by recursively inspecting trace evidence.',\n area: input.area?.trim() || 'trace-analysis',\n version: TRACE_ANALYST_ACTOR_DESCRIPTION_VERSION,\n question: input.question,\n instructions: options.instructions ?? TRACE_ANALYST_ACTOR_DESCRIPTION,\n toolGroup: options.toolGroup ?? 'all',\n limits: options.limits,\n },\n engine: options.engine,\n store,\n context: {\n runId: options.runId ?? id,\n correlationId: randomUUID(),\n budgetUsd: options.budgetUsd,\n costLedger: options.costLedger,\n costPhase: options.costPhase ?? 'trace-analysis',\n priorFindings: options.priorFindings,\n upstreamFindings: options.upstreamFindings,\n recordUsage: options.recordUsage,\n tags: options.tags,\n log: options.log,\n signal: options.signal,\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","/** Canonical flattened OTLP span shape shared by trace producers and readers. */\n\nimport type { SpanStatus } from './schema'\n\nexport type OtlpStatusCode = 'STATUS_CODE_OK' | 'STATUS_CODE_ERROR' | 'STATUS_CODE_UNSET'\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: OtlpStatusCode\n message?: string\n }\n resource: { attributes: Record<string, unknown> }\n attributes: Record<string, unknown>\n events?: Array<{ name: string; timeUnixNano?: string; attributes?: Record<string, unknown> }>\n}\n\nexport interface CreateOtlpFlatLineInput {\n traceId: string\n spanId: string\n parentSpanId: string | null\n name: string\n kind: string\n startTime: string\n endTime: string\n statusCode: OtlpStatusCode\n statusMessage?: string\n resource: OtlpFlatLine['resource']\n attributes: Record<string, unknown>\n events?: OtlpFlatLine['events']\n}\n\nexport function createOtlpFlatLine(input: CreateOtlpFlatLineInput): OtlpFlatLine {\n return {\n trace_id: input.traceId,\n span_id: input.spanId,\n parent_span_id: input.parentSpanId,\n name: input.name,\n kind: input.kind,\n start_time: input.startTime,\n end_time: input.endTime,\n status: {\n code: input.statusCode,\n ...(input.statusMessage !== undefined ? { message: input.statusMessage } : {}),\n },\n resource: input.resource,\n attributes: input.attributes,\n ...(input.events && input.events.length > 0 ? { events: input.events } : {}),\n }\n}\n\n/** Map the canonical trace status while letting each caller choose its legacy default. */\nexport function spanStatusToOtlp(\n status: SpanStatus | undefined,\n error: string | undefined,\n defaultCode: OtlpStatusCode,\n): OtlpStatusCode {\n if (status === 'error' || error) return 'STATUS_CODE_ERROR'\n if (status === 'ok') return 'STATUS_CODE_OK'\n return defaultCode\n}\n\n/** Convert epoch milliseconds, returning `undefined` for invalid or out-of-range values. */\nexport function epochMillisToIso(value: number): string | undefined {\n if (!Number.isFinite(value)) return undefined\n try {\n return new Date(value).toISOString()\n } catch {\n return undefined\n }\n}\n","import { CaptureIntegrityError } from '../errors'\nimport { applyToolSpanOtlpAttributes, OPENINFERENCE_SPAN_KIND } from '../trace/otlp-attributes'\nimport { createOtlpFlatLine, epochMillisToIso, spanStatusToOtlp } from '../trace/otlp-flat'\nimport type { ToolSpan } from '../trace/schema'\nimport type { TraceAnalysisStore } from './store'\nimport { createOtlpBufferTraceStore, type ToolSpansToTraceAnalysisStoreOptions } from './store-otlp'\n\n/** Missing tool spans cannot distinguish a tool-free run from broken capture. */\nexport class ToolTraceMissingError extends CaptureIntegrityError {\n constructor() {\n super('toolSpansToTraceAnalysisStore: no tool spans supplied; trace evidence is missing')\n }\n}\n\n/**\n * Snapshot canonical tool spans into the read interface used by trace analysts.\n * One run becomes one trace while arguments, results, errors, and timing remain searchable.\n */\nexport function toolSpansToTraceAnalysisStore(\n spans: readonly ToolSpan[] | null | undefined,\n options: ToolSpansToTraceAnalysisStoreOptions = {},\n): TraceAnalysisStore {\n if (!spans || spans.length === 0) throw new ToolTraceMissingError()\n\n const seen = new Set<string>()\n const lines = spans.map((span, index) => {\n assertToolSpanIdentity(span, index)\n const identity = `${span.runId}\\u0000${span.spanId}`\n if (seen.has(identity)) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: duplicate span '${span.spanId}' in run '${span.runId}'`,\n )\n }\n seen.add(identity)\n\n const attributes = { ...(span.attributes ?? {}) }\n applyToolSpanOtlpAttributes(attributes, span)\n attributes[OPENINFERENCE_SPAN_KIND] = 'TOOL'\n\n const endedAt = span.endedAt ?? span.startedAt + (span.latencyMs ?? 0)\n const line = createOtlpFlatLine({\n traceId: span.runId,\n spanId: span.spanId,\n parentSpanId: span.parentSpanId ?? null,\n name: span.name,\n kind: 'SPAN_KIND_INTERNAL',\n startTime: toolSpanTimeIso(span.startedAt, span.spanId, 'startedAt'),\n endTime: toolSpanTimeIso(endedAt, span.spanId, 'endedAt'),\n statusCode: spanStatusToOtlp(span.status, span.error, 'STATUS_CODE_UNSET'),\n statusMessage: span.error,\n resource: { attributes: {} },\n attributes,\n })\n try {\n return JSON.stringify(line)\n } catch (cause) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' in run '${span.runId}' is not JSON-serializable`,\n { cause },\n )\n }\n })\n\n return createOtlpBufferTraceStore(Buffer.from(`${lines.join('\\n')}\\n`, 'utf8'), options)\n}\n\nfunction assertToolSpanIdentity(span: ToolSpan, index: number): void {\n if (span.kind !== 'tool') {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span at index ${index} has kind '${String(span.kind)}', not 'tool'`,\n )\n }\n if (!span.runId || !span.spanId || !span.name || !span.toolName) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span at index ${index} is missing runId, spanId, name, or toolName`,\n )\n }\n if (!Number.isFinite(span.startedAt)) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' has invalid startedAt`,\n )\n }\n if (span.endedAt !== undefined && !Number.isFinite(span.endedAt)) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' has invalid endedAt`,\n )\n }\n if (span.endedAt !== undefined && span.endedAt < span.startedAt) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' ends before it starts`,\n )\n }\n if (span.latencyMs !== undefined && (!Number.isFinite(span.latencyMs) || span.latencyMs < 0)) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' has invalid latencyMs`,\n )\n }\n}\n\nfunction toolSpanTimeIso(value: number, spanId: string, field: string): string {\n const iso = epochMillisToIso(value)\n if (iso) return iso\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${spanId}' has invalid ${field}`,\n )\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-BPb2Kf_C2.d.ts","names":[],"sources":["../src/benchmarks/types.ts"],"mappings":";;;KASY;KAQA;UAgBK,qBAAqB;;;EAGpC;;EAEA,SAAS;;EAET,QAAQ;;EAER,SAAS;;EAET,WAAW;;EAEX;;EAEA,SAAS;EACT,WAAW;;UAGI;;;;EAIf;;EAEA;;EAEA,aAAa;;;EAGb,KAAK;EACL;;UAGe;EACf;EACA;EACA;EACA;EACA;;;UAQe,iBAAiB,kBAAkB,oBAAoB;;EAEtE;EACA,SAAS;EACT,WAAW;EACX;EACA,SAAS;EACT;;;;;EAKA,YAAY,OAAO,cAAc,QAAQ,qBAAqB;;EAE9D,SAAS,MAAM,qBAAqB,WAAW,UAAU,YAAY,QAAQ;;;;EAI7E,YAAY,iBAAiB;;UAGd,kBAAkB,4BAA4B;EAC7D;EACA;EACA,QAAQ;EACR,UAAU;EACV,UAAU;EACV,MAAM,qBAAqB;;KAGjB,mBAAmB,oBAAoB,uBAAuB;EACxE,UAAU,kBAAkB;EAC5B,MAAM,qBAAqB;EAC3B,SAAS;MACL,QAAQ,aAAa;;;cAoBd;;;;;;;;;iBAUG,mBACd,gBACA,gBACC"}