@tangle-network/agent-eval 0.117.0 → 0.118.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/analyst/index.d.ts +2772 -21
  3. package/dist/analyst/index.js +7 -6
  4. package/dist/analyst/index.js.map +1 -1
  5. package/dist/belief-state/index.d.ts +706 -10
  6. package/dist/belief-state/index.js +2 -1
  7. package/dist/belief-state/index.js.map +1 -1
  8. package/dist/benchmarks/index.d.ts +958 -14
  9. package/dist/benchmarks/index.js +12 -10
  10. package/dist/builder-eval/index.d.ts +449 -4
  11. package/dist/builder-eval/index.js +4 -3
  12. package/dist/builder-eval/index.js.map +1 -1
  13. package/dist/campaign/index.d.ts +4276 -74
  14. package/dist/campaign/index.js +12 -10
  15. package/dist/{chunk-VF3XSYTI.js → chunk-33JA4TFA.js} +6 -6
  16. package/dist/{chunk-4JLWXDYA.js → chunk-3EHHMC6E.js} +2 -2
  17. package/dist/{chunk-CCZIVI3F.js → chunk-BFW56GTT.js} +2 -2
  18. package/dist/{chunk-YZPO4UHR.js → chunk-DP3BBMYJ.js} +100 -143
  19. package/dist/chunk-DP3BBMYJ.js.map +1 -0
  20. package/dist/{chunk-E4BUPP7Z.js → chunk-HKUCJ437.js} +38 -66
  21. package/dist/chunk-HKUCJ437.js.map +1 -0
  22. package/dist/{chunk-HZHNRYHK.js → chunk-K6N6XJJX.js} +2 -2
  23. package/dist/chunk-KSDQVPLR.js +286 -0
  24. package/dist/chunk-KSDQVPLR.js.map +1 -0
  25. package/dist/chunk-MA6HLL3S.js +65 -0
  26. package/dist/chunk-MA6HLL3S.js.map +1 -0
  27. package/dist/{chunk-MGEHEHSN.js → chunk-OIIMMLRB.js} +11 -11
  28. package/dist/{chunk-DXZRATT5.js → chunk-OYZAPX5G.js} +3 -3
  29. package/dist/chunk-PXE2VKMX.js +140 -0
  30. package/dist/chunk-PXE2VKMX.js.map +1 -0
  31. package/dist/{chunk-ZUXV7UWZ.js → chunk-Q442S5AS.js} +73 -19
  32. package/dist/{chunk-ZUXV7UWZ.js.map → chunk-Q442S5AS.js.map} +1 -1
  33. package/dist/{chunk-ODVOOEWQ.js → chunk-QBRSJK47.js} +2 -2
  34. package/dist/{chunk-S2F4J57L.js → chunk-QKEGNI5B.js} +77 -32
  35. package/dist/chunk-QKEGNI5B.js.map +1 -0
  36. package/dist/{chunk-5UF54T55.js → chunk-S3UZOQ5Y.js} +34 -7
  37. package/dist/chunk-S3UZOQ5Y.js.map +1 -0
  38. package/dist/{chunk-FQNLDL4D.js → chunk-SVH2ANFD.js} +136 -4
  39. package/dist/chunk-SVH2ANFD.js.map +1 -0
  40. package/dist/{chunk-GQCZRZ7L.js → chunk-U5CHZ5M3.js} +9 -9
  41. package/dist/{chunk-TVVP3ZZQ.js → chunk-VQMK5FMP.js} +2 -1
  42. package/dist/{chunk-TVVP3ZZQ.js.map → chunk-VQMK5FMP.js.map} +1 -1
  43. package/dist/chunk-WDHBCA3M.js +31 -0
  44. package/dist/chunk-WDHBCA3M.js.map +1 -0
  45. package/dist/{chunk-HQPHZGL6.js → chunk-YLMUS4MM.js} +9 -9
  46. package/dist/{chunk-LQUTGLOZ.js → chunk-ZET2UAYW.js} +15 -65
  47. package/dist/chunk-ZET2UAYW.js.map +1 -0
  48. package/dist/contract/index.d.ts +4012 -38
  49. package/dist/contract/index.js +56 -29
  50. package/dist/contract/index.js.map +1 -1
  51. package/dist/control.d.ts +1013 -9
  52. package/dist/control.js +4 -3
  53. package/dist/fuzz.d.ts +194 -4
  54. package/dist/fuzz.js +3 -3
  55. package/dist/hosted/index.d.ts +498 -17
  56. package/dist/index.d.ts +10982 -1286
  57. package/dist/index.js +97 -80
  58. package/dist/index.js.map +1 -1
  59. package/dist/matrix/index.d.ts +139 -4
  60. package/dist/meta-eval/index.d.ts +862 -15
  61. package/dist/meta-eval/index.js +2 -1
  62. package/dist/meta-eval/index.js.map +1 -1
  63. package/dist/multishot/index.d.ts +214 -14
  64. package/dist/openapi.json +1 -1
  65. package/dist/pipelines/index.d.ts +392 -7
  66. package/dist/pipelines/index.js +5 -3
  67. package/dist/pipelines/index.js.map +1 -1
  68. package/dist/reporting.d.ts +1277 -17
  69. package/dist/rl.d.ts +2359 -28
  70. package/dist/rl.js +6 -5
  71. package/dist/rl.js.map +1 -1
  72. package/dist/storyboard/index.d.ts +86 -1
  73. package/dist/trace-attributes.d.ts +16 -0
  74. package/dist/trace-attributes.js +32 -0
  75. package/dist/trace-attributes.js.map +1 -0
  76. package/dist/traces.d.ts +1970 -697
  77. package/dist/traces.js +49 -32
  78. package/dist/wire/index.d.ts +655 -9
  79. package/docs/insight-report.md +44 -0
  80. package/package.json +9 -3
  81. package/dist/adversarial-B7loGVVX.d.ts +0 -19
  82. package/dist/analyst-C8HHvfJp.d.ts +0 -88
  83. package/dist/analyze-runs--2x39HZ7.d.ts +0 -81
  84. package/dist/baseline-DKq3gJpP.d.ts +0 -141
  85. package/dist/calibration-C8MTS7cw.d.ts +0 -101
  86. package/dist/chunk-5UF54T55.js.map +0 -1
  87. package/dist/chunk-E4BUPP7Z.js.map +0 -1
  88. package/dist/chunk-FQNLDL4D.js.map +0 -1
  89. package/dist/chunk-LQUTGLOZ.js.map +0 -1
  90. package/dist/chunk-S2F4J57L.js.map +0 -1
  91. package/dist/chunk-YZPO4UHR.js.map +0 -1
  92. package/dist/code-agent-session-CjZsVd19.d.ts +0 -87
  93. package/dist/control-6vuGfmDH.d.ts +0 -258
  94. package/dist/cost-ledger-DWy3XdJc.d.ts +0 -183
  95. package/dist/dataset-NENEzRgk.d.ts +0 -115
  96. package/dist/default-registry-DaK8b3fv.d.ts +0 -155
  97. package/dist/emitter-CjD7vUwv.d.ts +0 -122
  98. package/dist/errors-oeQrLqXC.d.ts +0 -74
  99. package/dist/failure-cluster-DOAcSJ87.d.ts +0 -76
  100. package/dist/feedback-trajectory-BUnM58xL.d.ts +0 -348
  101. package/dist/gepa-eESocoDi.d.ts +0 -642
  102. package/dist/index-PdX4VnPA.d.ts +0 -423
  103. package/dist/insight-report-DY4nDW9Q.d.ts +0 -310
  104. package/dist/integrity-DqlBiLyK.d.ts +0 -81
  105. package/dist/judge-calibration-7C-IDmKr.d.ts +0 -145
  106. package/dist/kind-factory-ClZmO25A.d.ts +0 -171
  107. package/dist/llm-client-qoDd18Qz.d.ts +0 -289
  108. package/dist/multi-layer-verifier-BsqKuLyN.d.ts +0 -150
  109. package/dist/off-policy-DiwuKKg7.d.ts +0 -132
  110. package/dist/outcome-store-rnXLEqSn.d.ts +0 -63
  111. package/dist/policy-edit-wG9uFEFm.d.ts +0 -455
  112. package/dist/pre-registration-BWQhJ3vz.d.ts +0 -761
  113. package/dist/provenance-DpjwyseI.d.ts +0 -541
  114. package/dist/query-CF7PG61p.d.ts +0 -35
  115. package/dist/raw-provider-sink-C46HDghv.d.ts +0 -132
  116. package/dist/release-report-C8G2i5Xi.d.ts +0 -236
  117. package/dist/researcher-C8XyxQsu.d.ts +0 -387
  118. package/dist/rubric-predictive-validity-p49lLVrE.d.ts +0 -105
  119. package/dist/run-record-BDH49H2E.d.ts +0 -360
  120. package/dist/runtime-trajectory-DGBIUt4B.d.ts +0 -49
  121. package/dist/schema-B3Q3l9Z_.d.ts +0 -201
  122. package/dist/semantic-concept-judge-CXnPEJbf.d.ts +0 -723
  123. package/dist/sequential-5iSVfzl2.d.ts +0 -139
  124. package/dist/series-convergence-D5OWMBg6.d.ts +0 -33
  125. package/dist/statistics-KUnG73jH.d.ts +0 -494
  126. package/dist/storage-DrX3v_5B.d.ts +0 -50
  127. package/dist/store-C1YxJDEK.d.ts +0 -248
  128. package/dist/store-DGqD0Pyo.d.ts +0 -116
  129. package/dist/summary-report-C5bKFfm-.d.ts +0 -445
  130. package/dist/test-graded-scenario-B0ybnPY7.d.ts +0 -166
  131. package/dist/types-BSw1rOUB.d.ts +0 -634
  132. package/dist/types-BUxNaJ8c.d.ts +0 -108
  133. package/dist/types-BkfcQnxV.d.ts +0 -313
  134. package/dist/verdict-C9MlYujm.d.ts +0 -35
  135. /package/dist/{chunk-VF3XSYTI.js.map → chunk-33JA4TFA.js.map} +0 -0
  136. /package/dist/{chunk-4JLWXDYA.js.map → chunk-3EHHMC6E.js.map} +0 -0
  137. /package/dist/{chunk-CCZIVI3F.js.map → chunk-BFW56GTT.js.map} +0 -0
  138. /package/dist/{chunk-HZHNRYHK.js.map → chunk-K6N6XJJX.js.map} +0 -0
  139. /package/dist/{chunk-MGEHEHSN.js.map → chunk-OIIMMLRB.js.map} +0 -0
  140. /package/dist/{chunk-DXZRATT5.js.map → chunk-OYZAPX5G.js.map} +0 -0
  141. /package/dist/{chunk-ODVOOEWQ.js.map → chunk-QBRSJK47.js.map} +0 -0
  142. /package/dist/{chunk-GQCZRZ7L.js.map → chunk-U5CHZ5M3.js.map} +0 -0
  143. /package/dist/{chunk-HQPHZGL6.js.map → chunk-YLMUS4MM.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/contract/intake/code-agent-session.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\nimport { estimateCost, isModelPriced } from '../../metrics'\nimport type { RunCostProvenance, RunRecord, RunSplitTag, RunTokenUsage } from '../../run-record'\nimport { extractUsage } from '../../trace/extract-usage'\n\nexport type CodeAgentSessionSource = 'codex' | 'claude-code' | 'opencode' | 'kimi-code' | 'pi'\n\nexport interface ParsedCodeAgentJsonl {\n entries: unknown[]\n malformedLines: number\n}\n\nexport interface CodeAgentSessionMetrics {\n entries: number\n userMessages: number\n assistantMessages: number\n reasoningItems: number\n toolCalls: number\n toolOutputs: number\n toolErrors: number\n patchAttempts: number\n patchSuccesses: number\n patchFailures: number\n turnsStarted: number\n turnsCompleted: number\n turnsAborted: number\n contextCompactions: number\n prLinks: number\n fileSnapshots: number\n graphNodes: number\n graphEdges: number\n actionCandidates: number\n verificationReports: number\n completionDecisions: number\n reliabilityRows: number\n reliabilityLift: number\n inputTokens: number\n outputTokens: number\n reasoningTokens: number\n cachedTokens: number\n cacheWriteTokens: number\n observedCostUsd: number\n observedCostCaptured?: boolean\n wallMs: number\n processScore: number\n}\n\nexport interface CodeAgentSessionDiagnostic {\n source: CodeAgentSessionSource\n sessionId: string\n sourcePath?: string\n entries: number\n malformedLines: number\n inferredScore: boolean\n hasExplicitTerminalSignal: boolean\n hasQualityLabel: boolean\n hasTokenUsage: boolean\n hasCost: boolean\n costKind?: RunCostProvenance['kind']\n warnings: string[]\n}\n\nexport interface CodeAgentSessionIntakeResult {\n runs: RunRecord[]\n diagnostics: CodeAgentSessionDiagnostic[]\n metrics: CodeAgentSessionMetrics[]\n}\n\nexport interface CodeAgentSessionIntakeOptions {\n entries: unknown[]\n malformedLines?: number\n sourcePath?: string\n experimentId?: string\n candidateId?: string\n seed?: number\n splitTag?: RunSplitTag\n scenarioId?: string\n model?: string\n promptHash?: string\n configHash?: string\n commitSha?: string\n score?: number\n /** Explicit cost receipt. Use `uncaptured` when the source says dollars\n * were not captured; the adapter will not relabel its compatibility $0\n * sentinel as observed. When omitted, source-reported cost wins, then a\n * token-priced estimate, then uncaptured. */\n costProvenance?: RunCostProvenance\n}\n\nexport function parseCodeAgentJsonl(jsonl: string): ParsedCodeAgentJsonl {\n const entries: unknown[] = []\n let malformedLines = 0\n for (const line of jsonl.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n entries.push(JSON.parse(trimmed))\n } catch {\n malformedLines += 1\n }\n }\n return { entries, malformedLines }\n}\n\nexport function fromCodexSession(\n options: CodeAgentSessionIntakeOptions,\n): CodeAgentSessionIntakeResult {\n return fromCodeAgentSession('codex', options)\n}\n\nexport function fromClaudeCodeSession(\n options: CodeAgentSessionIntakeOptions,\n): CodeAgentSessionIntakeResult {\n return fromCodeAgentSession('claude-code', options)\n}\n\nexport function fromOpenCodeSession(\n options: CodeAgentSessionIntakeOptions,\n): CodeAgentSessionIntakeResult {\n return fromCodeAgentSession('opencode', options)\n}\n\nexport function fromKimiCodeSession(\n options: CodeAgentSessionIntakeOptions,\n): CodeAgentSessionIntakeResult {\n return fromCodeAgentSession('kimi-code', options)\n}\n\nexport function fromPiSession(\n options: CodeAgentSessionIntakeOptions,\n): CodeAgentSessionIntakeResult {\n return fromCodeAgentSession('pi', options)\n}\n\nexport const fromPigraphSession = fromPiSession\n\nfunction fromCodeAgentSession(\n source: CodeAgentSessionSource,\n options: CodeAgentSessionIntakeOptions,\n): CodeAgentSessionIntakeResult {\n const entries = options.entries.filter(isRecord)\n if (entries.length === 0) {\n return {\n runs: [],\n diagnostics: [\n {\n source,\n sessionId: fallbackSessionId(source, options.sourcePath),\n sourcePath: options.sourcePath,\n entries: 0,\n malformedLines: options.malformedLines ?? 0,\n inferredScore: true,\n hasExplicitTerminalSignal: false,\n hasQualityLabel: false,\n hasTokenUsage: false,\n hasCost: false,\n costKind: 'uncaptured',\n warnings: ['no parseable session entries'],\n },\n ],\n metrics: [],\n }\n }\n\n const metrics = metricsFor(source, entries)\n const sessionId =\n sessionIdFromEntries(source, entries) ?? fallbackSessionId(source, options.sourcePath)\n const model = withSnapshot(options.model ?? modelFromEntries(source, entries) ?? source)\n const tokenUsage: RunTokenUsage = {\n input: metrics.inputTokens,\n output: metrics.outputTokens,\n ...(metrics.reasoningTokens > 0 ? { reasoning: metrics.reasoningTokens } : {}),\n ...(metrics.cachedTokens > 0 ? { cached: metrics.cachedTokens } : {}),\n ...(metrics.cacheWriteTokens > 0 ? { cacheWrite: metrics.cacheWriteTokens } : {}),\n }\n const { costUsd, costProvenance } = resolveSessionCost(options.costProvenance, metrics, model)\n const score = clamp01(options.score ?? metrics.processScore)\n const promptHash =\n options.promptHash ?? hashString(`prompt:${source}:${firstUserText(entries) ?? ''}`)\n const configHash =\n options.configHash ??\n hashJson({\n source,\n model,\n sourcePath: options.sourcePath,\n cwd: cwdFromEntries(entries),\n entryCount: entries.length,\n })\n const explicitTerminal = hasExplicitTerminalSignal(source, metrics)\n const warnings = diagnosticsFor(metrics, {\n model,\n explicitTerminal,\n malformedLines: options.malformedLines ?? 0,\n scoreOverridden: options.score !== undefined,\n costKind: costProvenance.kind,\n })\n\n const run: RunRecord = {\n runId: `${source}:${sessionId}`,\n experimentId: options.experimentId ?? `${source}-local-sessions`,\n candidateId: options.candidateId ?? model,\n seed: options.seed ?? stableSeed(sessionId),\n model,\n promptHash,\n configHash,\n commitSha: options.commitSha ?? 'local-session',\n wallMs: metrics.wallMs,\n costUsd,\n costProvenance,\n tokenUsage,\n outcome: {\n holdoutScore: score,\n raw: {\n entries: metrics.entries,\n user_messages: metrics.userMessages,\n assistant_messages: metrics.assistantMessages,\n reasoning_items: metrics.reasoningItems,\n tool_calls: metrics.toolCalls,\n tool_outputs: metrics.toolOutputs,\n tool_errors: metrics.toolErrors,\n patch_attempts: metrics.patchAttempts,\n patch_successes: metrics.patchSuccesses,\n patch_failures: metrics.patchFailures,\n turns_started: metrics.turnsStarted,\n turns_completed: metrics.turnsCompleted,\n turns_aborted: metrics.turnsAborted,\n context_compactions: metrics.contextCompactions,\n pr_links: metrics.prLinks,\n file_snapshots: metrics.fileSnapshots,\n graph_nodes: metrics.graphNodes,\n graph_edges: metrics.graphEdges,\n action_candidates: metrics.actionCandidates,\n verification_reports: metrics.verificationReports,\n completion_decisions: metrics.completionDecisions,\n reliability_rows: metrics.reliabilityRows,\n reliability_lift: metrics.reliabilityLift,\n input_tokens: metrics.inputTokens,\n output_tokens: metrics.outputTokens,\n reasoning_tokens: metrics.reasoningTokens,\n cached_tokens: metrics.cachedTokens,\n cache_write_tokens: metrics.cacheWriteTokens,\n observed_cost_usd: metrics.observedCostUsd,\n observed_cost_captured: metrics.observedCostCaptured ? 1 : 0,\n estimated_cost_usd: costProvenance.kind === 'estimated' ? costUsd : 0,\n process_score: score,\n inferred_score: options.score === undefined ? 1 : 0,\n explicit_terminal_signal: explicitTerminal ? 1 : 0,\n quality_label_present: options.score !== undefined ? 1 : 0,\n cost_observed: costProvenance.kind === 'observed' ? 1 : 0,\n cost_estimated: costProvenance.kind === 'estimated' ? 1 : 0,\n cost_uncaptured: costProvenance.kind === 'uncaptured' ? 1 : 0,\n cost_unknown: costProvenance.kind === 'uncaptured' ? 1 : 0,\n },\n },\n splitTag: options.splitTag ?? 'holdout',\n ...(options.scenarioId ? { scenarioId: options.scenarioId } : {}),\n ...(metrics.toolErrors > 0 || metrics.turnsAborted > 0\n ? { failureMode: metrics.turnsAborted > 0 ? 'turn_aborted' : 'tool_error' }\n : {}),\n }\n\n return {\n runs: [run],\n diagnostics: [\n {\n source,\n sessionId,\n sourcePath: options.sourcePath,\n entries: entries.length,\n malformedLines: options.malformedLines ?? 0,\n inferredScore: options.score === undefined,\n hasExplicitTerminalSignal: explicitTerminal,\n hasQualityLabel: options.score !== undefined,\n hasTokenUsage:\n metrics.inputTokens > 0 ||\n metrics.outputTokens > 0 ||\n metrics.reasoningTokens > 0 ||\n metrics.cachedTokens > 0 ||\n metrics.cacheWriteTokens > 0,\n hasCost: costProvenance.kind !== 'uncaptured',\n costKind: costProvenance.kind,\n warnings,\n },\n ],\n metrics: [metrics],\n }\n}\n\nfunction metricsFor(\n source: CodeAgentSessionSource,\n entries: Record<string, unknown>[],\n): CodeAgentSessionMetrics {\n switch (source) {\n case 'codex':\n return codexMetrics(entries)\n case 'claude-code':\n return claudeCodeMetrics(entries)\n case 'opencode':\n return openCodeMetrics(entries)\n case 'kimi-code':\n return kimiCodeMetrics(entries)\n case 'pi':\n return piMetrics(entries)\n }\n}\n\nfunction codexMetrics(entries: Record<string, unknown>[]): CodeAgentSessionMetrics {\n const metrics = emptyMetrics(entries.length)\n const startedToolIds = new Set<string>()\n let startedAt: number | undefined\n let completedAt: number | undefined\n\n for (const entry of entries) {\n const payload = record(entry.payload) ?? {}\n const entryType = stringField(entry, 'type')\n const payloadType = stringField(payload, 'type')\n const timestamp = timestampMs(entry.timestamp)\n if (timestamp !== undefined) {\n startedAt = startedAt === undefined ? timestamp : Math.min(startedAt, timestamp)\n completedAt = completedAt === undefined ? timestamp : Math.max(completedAt, timestamp)\n }\n\n if (entryType === 'turn.started') metrics.turnsStarted += 1\n if (entryType === 'turn.completed') {\n metrics.turnsCompleted += 1\n addCodexExecUsage(metrics, record(entry.usage))\n }\n if (entryType === 'turn.failed') metrics.turnsAborted += 1\n if (entryType === 'error') metrics.toolErrors += 1\n\n const item = record(entry.item)\n if (item && (entryType === 'item.started' || entryType === 'item.completed')) {\n addCodexExecItem(metrics, startedToolIds, entryType, item)\n }\n\n if (entryType === 'response_item') {\n if (payloadType === 'function_call' || payloadType === 'custom_tool_call')\n metrics.toolCalls += 1\n if (payloadType === 'function_call_output' || payloadType === 'custom_tool_call_output')\n metrics.toolOutputs += 1\n if (payloadType === 'reasoning') metrics.reasoningItems += 1\n if (payloadType === 'message' && stringField(payload, 'role') === 'assistant')\n metrics.assistantMessages += 1\n }\n\n if (entryType === 'event_msg') {\n if (payloadType === 'user_message') metrics.userMessages += 1\n if (payloadType === 'agent_message') metrics.assistantMessages += 1\n if (payloadType === 'task_started') {\n metrics.turnsStarted += 1\n const started = timestampMs(payload.started_at)\n if (started !== undefined) {\n startedAt = startedAt === undefined ? started : Math.min(startedAt, started)\n }\n }\n if (payloadType === 'task_complete') {\n metrics.turnsCompleted += 1\n const completed = timestampMs(payload.completed_at)\n if (completed !== undefined) {\n completedAt = completedAt === undefined ? completed : Math.max(completedAt, completed)\n }\n const duration = numberField(payload, 'duration_ms')\n if (duration !== undefined) metrics.wallMs = Math.max(metrics.wallMs, duration)\n }\n if (payloadType === 'turn_aborted') {\n metrics.turnsAborted += 1\n const completed = timestampMs(payload.completed_at)\n if (completed !== undefined) {\n completedAt = completedAt === undefined ? completed : Math.max(completedAt, completed)\n }\n }\n if (payloadType === 'context_compacted') metrics.contextCompactions += 1\n if (payloadType === 'patch_apply_end') {\n metrics.patchAttempts += 1\n if (payload.success === true) metrics.patchSuccesses += 1\n else {\n metrics.patchFailures += 1\n metrics.toolErrors += 1\n }\n }\n if (payloadType === 'token_count')\n setCodexCumulativeUsage(metrics, record(record(payload.info)?.total_token_usage))\n const result = record(payload.result)\n if (result && 'Err' in result) metrics.toolErrors += 1\n }\n }\n\n if (metrics.wallMs === 0 && startedAt !== undefined && completedAt !== undefined) {\n metrics.wallMs = Math.max(0, completedAt - startedAt)\n }\n metrics.processScore = codexProcessScore(metrics)\n return metrics\n}\n\nfunction addCodexExecItem(\n metrics: CodeAgentSessionMetrics,\n startedToolIds: Set<string>,\n eventType: 'item.started' | 'item.completed',\n item: Record<string, unknown>,\n): void {\n const itemType = stringField(item, 'type')\n const itemId = stringField(item, 'id')\n const isTool =\n itemType === 'command_execution' ||\n itemType === 'mcp_tool_call' ||\n itemType === 'collab_tool_call' ||\n itemType === 'web_search'\n\n if (eventType === 'item.started' && isTool) {\n metrics.toolCalls += 1\n if (itemId) startedToolIds.add(itemId)\n }\n if (eventType === 'item.completed' && isTool) {\n if (!itemId || !startedToolIds.has(itemId)) metrics.toolCalls += 1\n metrics.toolOutputs += 1\n }\n if (eventType !== 'item.completed') return\n\n if (itemType === 'agent_message' || itemType === 'message') metrics.assistantMessages += 1\n if (itemType === 'reasoning') metrics.reasoningItems += 1\n if (itemType === 'file_change') {\n metrics.patchAttempts += 1\n const status = stringField(item, 'status')\n if (status === 'completed') metrics.patchSuccesses += 1\n if (status === 'failed') {\n metrics.patchFailures += 1\n metrics.toolErrors += 1\n }\n }\n if (itemType === 'error' || codexExecToolFailed(itemType, item)) metrics.toolErrors += 1\n}\n\nfunction codexExecToolFailed(itemType: string | undefined, item: Record<string, unknown>): boolean {\n const status = stringField(item, 'status')\n if (itemType === 'command_execution') {\n const exitCode = numberField(item, 'exit_code')\n return (\n status === 'failed' || status === 'declined' || (exitCode !== undefined && exitCode !== 0)\n )\n }\n if (itemType === 'mcp_tool_call') return status === 'failed' || record(item.error) !== null\n return itemType === 'collab_tool_call' && status === 'failed'\n}\n\nfunction addCodexExecUsage(\n metrics: CodeAgentSessionMetrics,\n usage: Record<string, unknown> | null,\n): void {\n const parsed = readUsage(usage)\n metrics.inputTokens += parsed.input\n metrics.outputTokens += parsed.output\n metrics.reasoningTokens += parsed.reasoning\n metrics.cachedTokens += parsed.cached\n metrics.cacheWriteTokens += parsed.cacheWrite\n}\n\nfunction setCodexCumulativeUsage(\n metrics: CodeAgentSessionMetrics,\n usage: Record<string, unknown> | null,\n): void {\n const parsed = readUsage(usage)\n metrics.inputTokens = Math.max(metrics.inputTokens, parsed.input)\n metrics.outputTokens = Math.max(metrics.outputTokens, parsed.output)\n metrics.reasoningTokens = Math.max(metrics.reasoningTokens, parsed.reasoning)\n metrics.cachedTokens = Math.max(metrics.cachedTokens, parsed.cached)\n metrics.cacheWriteTokens = Math.max(metrics.cacheWriteTokens, parsed.cacheWrite)\n}\n\nfunction claudeCodeMetrics(entries: Record<string, unknown>[]): CodeAgentSessionMetrics {\n const metrics = emptyMetrics(entries.length)\n let startedAt: number | undefined\n let completedAt: number | undefined\n\n for (const entry of entries) {\n const type = stringField(entry, 'type')\n const timestamp = timestampMs(entry.timestamp)\n if (timestamp !== undefined) {\n startedAt = startedAt === undefined ? timestamp : Math.min(startedAt, timestamp)\n completedAt = completedAt === undefined ? timestamp : Math.max(completedAt, timestamp)\n }\n\n if (type === 'user') metrics.userMessages += 1\n if (type === 'assistant') metrics.assistantMessages += 1\n if (type === 'pr-link') metrics.prLinks += 1\n if (type === 'file-history-snapshot') metrics.fileSnapshots += 1\n\n const message = record(entry.message)\n if (message) addUsage(metrics, record(message.usage))\n const content = Array.isArray(message?.content) ? message.content : []\n for (const item of content) {\n const part = record(item)\n if (!part) continue\n const partType = stringField(part, 'type')\n if (partType === 'thinking') metrics.reasoningItems += 1\n if (partType === 'tool_use') metrics.toolCalls += 1\n if (partType === 'tool_result') {\n metrics.toolOutputs += 1\n if (part.is_error === true) metrics.toolErrors += 1\n }\n }\n }\n\n if (startedAt !== undefined && completedAt !== undefined)\n metrics.wallMs = Math.max(0, completedAt - startedAt)\n metrics.processScore = claudeProcessScore(metrics)\n return metrics\n}\n\nfunction openCodeMetrics(entries: Record<string, unknown>[]): CodeAgentSessionMetrics {\n const metrics = emptyMetrics(entries.length)\n const messageUsage = emptyTokenTotals()\n const partUsage = emptyTokenTotals()\n let messageCost = 0\n let partCost = 0\n let messageCostCaptured = false\n let partCostCaptured = false\n let startedAt: number | undefined\n let completedAt: number | undefined\n\n for (const entry of entries) {\n const time = record(entry.time)\n const created = timestampMs(time?.created)\n const completed = timestampMs(time?.completed)\n if (created !== undefined)\n startedAt = startedAt === undefined ? created : Math.min(startedAt, created)\n if (completed !== undefined)\n completedAt = completedAt === undefined ? completed : Math.max(completedAt, completed)\n\n const role = stringField(entry, 'role')\n if (role === 'user') metrics.userMessages += 1\n if (role === 'assistant') {\n metrics.assistantMessages += 1\n const finish = stringField(entry, 'finish')\n if (finish === 'stop') metrics.turnsCompleted += 1\n if (finish === 'error') metrics.turnsAborted += 1\n }\n\n const type = stringField(entry, 'type')\n if (type === 'reasoning') metrics.reasoningItems += 1\n if (type === 'tool') {\n metrics.toolCalls += 1\n const status = stringField(record(entry.state) ?? {}, 'status')\n if (status === 'completed') metrics.toolOutputs += 1\n if (status === 'error') {\n metrics.toolOutputs += 1\n metrics.toolErrors += 1\n }\n }\n if (type === 'patch') {\n metrics.patchAttempts += 1\n metrics.patchSuccesses += 1\n }\n\n const cost = numberField(entry, 'cost')\n if (record(entry.tokens) && role) {\n addUsageTo(messageUsage, record(entry.tokens))\n if (cost !== undefined) {\n messageCost += cost\n messageCostCaptured = true\n }\n } else if (record(entry.tokens)) {\n addUsageTo(partUsage, record(entry.tokens))\n if (cost !== undefined) {\n partCost += cost\n partCostCaptured = true\n }\n }\n }\n\n const usage = hasTokenTotals(messageUsage) ? messageUsage : partUsage\n metrics.inputTokens = usage.input\n metrics.outputTokens = usage.output\n metrics.reasoningTokens = usage.reasoning\n metrics.cachedTokens = usage.cached\n metrics.cacheWriteTokens = usage.cacheWrite\n metrics.observedCostUsd = messageCostCaptured ? messageCost : partCost\n metrics.observedCostCaptured = messageCostCaptured || partCostCaptured\n if (metrics.wallMs === 0 && startedAt !== undefined && completedAt !== undefined)\n metrics.wallMs = Math.max(0, completedAt - startedAt)\n metrics.processScore = terminalProcessScore(metrics)\n return metrics\n}\n\nfunction kimiCodeMetrics(entries: Record<string, unknown>[]): CodeAgentSessionMetrics {\n const metrics = emptyMetrics(entries.length)\n let startedAt: number | undefined\n let completedAt: number | undefined\n\n for (const entry of entries) {\n const timestamp = timestampMs(entry.timestamp)\n if (timestamp !== undefined) {\n startedAt = startedAt === undefined ? timestamp : Math.min(startedAt, timestamp)\n completedAt = completedAt === undefined ? timestamp : Math.max(completedAt, timestamp)\n }\n\n const role = stringField(entry, 'role')\n if (role === 'user') metrics.userMessages += 1\n if (role === 'assistant') metrics.assistantMessages += 1\n if (role === '_usage') addUsage(metrics, entry)\n\n const message = record(entry.message)\n const messageType = message ? stringField(message, 'type') : undefined\n const payload = record(message?.payload) ?? {}\n if (messageType === 'TurnBegin') {\n metrics.userMessages += 1\n metrics.turnsStarted += 1\n }\n if (messageType === 'TurnEnd') metrics.turnsCompleted += 1\n if (messageType === 'StepInterrupted') metrics.turnsAborted += 1\n if (messageType === 'StepBegin') metrics.reasoningItems += 1\n if (messageType === 'ContentPart') {\n const payloadType = stringField(payload, 'type')\n if (payloadType === 'think') metrics.reasoningItems += 1\n if (payloadType === 'text') metrics.assistantMessages += 1\n }\n if (messageType === 'ToolCall') metrics.toolCalls += 1\n if (messageType === 'ToolResult') {\n metrics.toolOutputs += 1\n if (record(payload.return_value)?.is_error === true) metrics.toolErrors += 1\n }\n if (messageType === 'StatusUpdate') addUsage(metrics, record(payload.token_usage))\n if (messageType === 'Notification') {\n const notification = record(payload.payload)\n const exitCode = numberField(notification ?? {}, 'exit_code')\n if (notification?.timed_out === true || (exitCode !== undefined && exitCode !== 0)) {\n metrics.toolErrors += 1\n }\n }\n }\n\n if (startedAt !== undefined && completedAt !== undefined)\n metrics.wallMs = Math.max(0, completedAt - startedAt)\n metrics.processScore = terminalProcessScore(metrics)\n return metrics\n}\n\nfunction piMetrics(entries: Record<string, unknown>[]): CodeAgentSessionMetrics {\n const metrics = emptyMetrics(entries.length)\n let bestReliabilityScore: number | undefined\n\n for (const entry of entries) {\n const nodes = Array.isArray(entry.nodes) ? entry.nodes : []\n const edges = Array.isArray(entry.edges) ? entry.edges : []\n metrics.graphNodes += nodes.length\n metrics.graphEdges += edges.length\n\n for (const node of nodes) {\n const obj = record(node)\n const ir = record(obj?.ir) ?? obj\n const kind = stringField(ir ?? {}, 'kind')\n if (kind === 'ActionCandidate') metrics.actionCandidates += 1\n if (kind === 'ToolInvocation') metrics.toolCalls += 1\n if (kind === 'ToolResult') metrics.toolOutputs += 1\n if (kind === 'VerificationReport') metrics.verificationReports += 1\n if (kind === 'CompletionDecision') {\n metrics.completionDecisions += 1\n metrics.turnsCompleted += 1\n }\n }\n\n const averageReliability = numberField(entry, 'averageNodeReliability')\n if (averageReliability !== undefined)\n bestReliabilityScore = maxOptional(bestReliabilityScore, averageReliability)\n const pessimisticPath = numberField(entry, 'pessimisticPathEstimate')\n if (pessimisticPath !== undefined)\n bestReliabilityScore = maxOptional(bestReliabilityScore, pessimisticPath)\n\n const rows = Array.isArray(entry.rows) ? entry.rows : []\n metrics.reliabilityRows += rows.length\n for (const row of rows) {\n const obj = record(row)\n if (!obj) continue\n const lift = numberField(obj, 'lift')\n if (lift !== undefined) metrics.reliabilityLift = Math.max(metrics.reliabilityLift, lift)\n const validated = numberField(obj, 'validatedSuccessEstimate')\n if (validated !== undefined)\n bestReliabilityScore = maxOptional(bestReliabilityScore, validated)\n }\n }\n\n metrics.processScore =\n bestReliabilityScore !== undefined\n ? clamp01(bestReliabilityScore)\n : metrics.completionDecisions > 0\n ? 1\n : 0\n return metrics\n}\n\nfunction emptyMetrics(entries: number): CodeAgentSessionMetrics {\n return {\n entries,\n userMessages: 0,\n assistantMessages: 0,\n reasoningItems: 0,\n toolCalls: 0,\n toolOutputs: 0,\n toolErrors: 0,\n patchAttempts: 0,\n patchSuccesses: 0,\n patchFailures: 0,\n turnsStarted: 0,\n turnsCompleted: 0,\n turnsAborted: 0,\n contextCompactions: 0,\n prLinks: 0,\n fileSnapshots: 0,\n graphNodes: 0,\n graphEdges: 0,\n actionCandidates: 0,\n verificationReports: 0,\n completionDecisions: 0,\n reliabilityRows: 0,\n reliabilityLift: 0,\n inputTokens: 0,\n outputTokens: 0,\n reasoningTokens: 0,\n cachedTokens: 0,\n cacheWriteTokens: 0,\n observedCostUsd: 0,\n observedCostCaptured: false,\n wallMs: 0,\n processScore: 0,\n }\n}\n\nfunction codexProcessScore(metrics: CodeAgentSessionMetrics): number {\n const terminalTurns = metrics.turnsCompleted + metrics.turnsAborted\n const base =\n terminalTurns > 0\n ? metrics.turnsCompleted / terminalTurns\n : metrics.assistantMessages > 0\n ? 0.5\n : 0\n return penalizeErrors(base, metrics)\n}\n\nfunction claudeProcessScore(metrics: CodeAgentSessionMetrics): number {\n const base = metrics.prLinks > 0 ? 1 : metrics.assistantMessages > 0 ? 0.75 : 0\n return penalizeErrors(base, metrics)\n}\n\nfunction terminalProcessScore(metrics: CodeAgentSessionMetrics): number {\n const terminalTurns = metrics.turnsCompleted + metrics.turnsAborted\n const base =\n terminalTurns > 0\n ? metrics.turnsCompleted / terminalTurns\n : metrics.assistantMessages > 0\n ? 0.75\n : metrics.toolCalls > 0\n ? 0.5\n : 0\n return penalizeErrors(base, metrics)\n}\n\nfunction penalizeErrors(base: number, metrics: CodeAgentSessionMetrics): number {\n const operations = Math.max(1, metrics.toolCalls + metrics.patchAttempts)\n const errorRate = Math.min(1, (metrics.toolErrors + metrics.patchFailures) / operations)\n return clamp01(base * (1 - 0.5 * errorRate))\n}\n\ntype TokenTotals = Required<RunTokenUsage>\n\nfunction emptyTokenTotals(): TokenTotals {\n return { input: 0, output: 0, reasoning: 0, cached: 0, cacheWrite: 0 }\n}\n\nfunction hasTokenTotals(usage: TokenTotals): boolean {\n return (\n usage.input > 0 ||\n usage.output > 0 ||\n usage.reasoning > 0 ||\n usage.cached > 0 ||\n usage.cacheWrite > 0\n )\n}\n\nfunction addUsage(\n metrics: CodeAgentSessionMetrics,\n usage: Record<string, unknown> | null | undefined,\n): void {\n const parsed = readUsage(usage)\n metrics.inputTokens += parsed.input\n metrics.outputTokens += parsed.output\n metrics.reasoningTokens += parsed.reasoning\n metrics.cachedTokens += parsed.cached\n metrics.cacheWriteTokens += parsed.cacheWrite\n}\n\nfunction addUsageTo(totals: TokenTotals, usage: Record<string, unknown> | null | undefined): void {\n const parsed = readUsage(usage)\n totals.input += parsed.input\n totals.output += parsed.output\n totals.reasoning += parsed.reasoning\n totals.cached += parsed.cached\n totals.cacheWrite += parsed.cacheWrite\n}\n\nfunction readUsage(usage: Record<string, unknown> | null | undefined): TokenTotals {\n const parsed = extractUsage(usage)\n return {\n input: parsed?.input ?? 0,\n output: parsed?.output ?? 0,\n reasoning: parsed?.reasoning ?? 0,\n cached: parsed?.cached ?? 0,\n cacheWrite: parsed?.cacheWrite ?? 0,\n }\n}\n\nfunction resolveSessionCost(\n explicit: RunCostProvenance | undefined,\n metrics: CodeAgentSessionMetrics,\n model: string,\n): { costUsd: number; costProvenance: RunCostProvenance } {\n if (explicit) {\n if (explicit.kind === 'uncaptured') {\n if (explicit.usd !== null) throw new Error('uncaptured cost must have usd: null')\n return { costUsd: 0, costProvenance: explicit }\n }\n if (!Number.isFinite(explicit.usd) || explicit.usd < 0) {\n throw new Error(`${explicit.kind} cost must be a finite, non-negative USD amount`)\n }\n return { costUsd: explicit.usd, costProvenance: explicit }\n }\n\n if (metrics.observedCostCaptured) {\n const costProvenance = { kind: 'observed', usd: metrics.observedCostUsd } as const\n return { costUsd: metrics.observedCostUsd, costProvenance }\n }\n\n const hasUsage = metrics.inputTokens > 0 || metrics.outputTokens > 0\n if (hasUsage && isModelPriced(model)) {\n const costUsd = estimateCost(metrics.inputTokens, metrics.outputTokens, model)\n return { costUsd, costProvenance: { kind: 'estimated', usd: costUsd } }\n }\n\n return { costUsd: 0, costProvenance: { kind: 'uncaptured', usd: null } }\n}\n\nfunction diagnosticsFor(\n metrics: CodeAgentSessionMetrics,\n options: {\n model: string\n explicitTerminal: boolean\n malformedLines: number\n scoreOverridden: boolean\n costKind: RunCostProvenance['kind']\n },\n): string[] {\n const warnings: string[] = []\n if (!options.scoreOverridden) warnings.push('outcome score is inferred from process telemetry')\n if (!options.explicitTerminal) warnings.push('no explicit terminal success/failure signal')\n if (\n metrics.inputTokens === 0 &&\n metrics.outputTokens === 0 &&\n metrics.reasoningTokens === 0 &&\n metrics.cachedTokens === 0 &&\n metrics.cacheWriteTokens === 0\n ) {\n warnings.push('missing token usage')\n }\n if (options.costKind === 'estimated')\n warnings.push('USD cost estimated from token usage and model pricing')\n if (options.costKind === 'uncaptured') warnings.push('USD cost uncaptured')\n if (options.costKind === 'uncaptured' && !isModelPriced(options.model))\n warnings.push('model pricing unknown')\n if (options.malformedLines > 0)\n warnings.push(`${options.malformedLines} malformed JSONL lines skipped`)\n return warnings\n}\n\nfunction hasExplicitTerminalSignal(\n source: CodeAgentSessionSource,\n metrics: CodeAgentSessionMetrics,\n): boolean {\n if (source === 'codex') return metrics.turnsCompleted + metrics.turnsAborted > 0\n if (source === 'opencode' || source === 'kimi-code')\n return metrics.turnsCompleted + metrics.turnsAborted > 0\n if (source === 'pi') return metrics.completionDecisions > 0 || metrics.reliabilityRows > 0\n return metrics.prLinks > 0 || metrics.toolErrors > 0\n}\n\nfunction sessionIdFromEntries(\n source: CodeAgentSessionSource,\n entries: Record<string, unknown>[],\n): string | undefined {\n for (const entry of entries) {\n if (source === 'codex') {\n const threadId = stringField(entry, 'thread_id')\n if (threadId) return threadId\n const payload = record(entry.payload)\n const id = payload ? stringField(payload, 'id') : undefined\n if (id) return id\n }\n const message = record(entry.message)\n const payload = record(message?.payload)\n const sessionId =\n stringField(entry, 'sessionID') ??\n stringField(entry, 'sessionId') ??\n stringField(entry, 'session_id') ??\n stringField(payload ?? {}, 'session_id')\n if (sessionId) return sessionId\n }\n return undefined\n}\n\nfunction modelFromEntries(\n source: CodeAgentSessionSource,\n entries: Record<string, unknown>[],\n): string | undefined {\n let providerModel: string | undefined\n for (const entry of entries) {\n if (source === 'codex') {\n const payload = record(entry.payload)\n const model = payload ? stringField(payload, 'model') : undefined\n if (model) return model\n providerModel =\n providerModel ?? (payload ? stringField(payload, 'model_provider') : undefined)\n }\n const openCodeModel = stringField(entry, 'modelID')\n if (openCodeModel) {\n const provider = stringField(entry, 'providerID')\n return provider ? `${provider}/${openCodeModel}` : openCodeModel\n }\n const modelObject = record(entry.model)\n const nestedModel = stringField(modelObject ?? {}, 'modelID')\n if (nestedModel) {\n const provider = stringField(modelObject ?? {}, 'providerID')\n return provider ? `${provider}/${nestedModel}` : nestedModel\n }\n const message = record(entry.message)\n const model = message ? stringField(message, 'model') : undefined\n if (model) return model\n }\n return providerModel\n}\n\nfunction cwdFromEntries(entries: Record<string, unknown>[]): string | undefined {\n for (const entry of entries) {\n const path = record(entry.path)\n const cwd =\n stringField(entry, 'cwd') ??\n stringField(path ?? {}, 'cwd') ??\n stringField(path ?? {}, 'root') ??\n (record(entry.payload) ? stringField(record(entry.payload)!, 'cwd') : undefined)\n if (cwd) return cwd\n }\n return undefined\n}\n\nfunction firstUserText(entries: Record<string, unknown>[]): string | undefined {\n for (const entry of entries) {\n const payload = record(entry.payload)\n const payloadType = payload ? stringField(payload, 'type') : undefined\n if (payloadType === 'user_message') return stringField(payload!, 'message')\n\n if (stringField(entry, 'role') === 'user') {\n const content = entry.content\n if (typeof content === 'string') return content\n }\n\n const wirePayload = record(record(entry.message)?.payload)\n const userInput = wirePayload ? stringField(wirePayload, 'user_input') : undefined\n if (userInput) return userInput\n\n const message = record(entry.message)\n if (message && stringField(message, 'role') === 'user') {\n const content = message.content\n if (typeof content === 'string') return content\n if (Array.isArray(content)) {\n const text = content\n .map((part) => {\n const obj = record(part)\n return obj ? stringField(obj, 'text') : undefined\n })\n .filter((part): part is string => part !== undefined)\n .join('\\n')\n if (text) return text\n }\n }\n }\n return undefined\n}\n\nfunction fallbackSessionId(source: CodeAgentSessionSource, sourcePath: string | undefined): string {\n return hashString(`${source}:${sourcePath ?? 'unknown-session'}`).slice(\n 'sha256:'.length,\n 'sha256:'.length + 20,\n )\n}\n\nfunction withSnapshot(model: string): string {\n const trimmed = model.trim() || 'unknown'\n if (trimmed.includes('@') || /-\\d{8}$/.test(trimmed) || /-\\d{4}-\\d{2}-\\d{2}$/.test(trimmed)) {\n return trimmed\n }\n return `${trimmed}@observed-local`\n}\n\nfunction hashJson(value: unknown): string {\n return hashString(JSON.stringify(value))\n}\n\nfunction hashString(value: string): string {\n return `sha256:${createHash('sha256').update(value).digest('hex')}`\n}\n\nfunction stableSeed(value: string): number {\n return createHash('sha256').update(value).digest().readUInt32BE(0)\n}\n\nfunction maxOptional(current: number | undefined, next: number): number {\n return current === undefined ? next : Math.max(current, next)\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return isRecord(value) ? value : null\n}\n\nfunction stringField(obj: Record<string, unknown>, key: string): string | undefined {\n const value = obj[key]\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction numberField(obj: Record<string, unknown>, key: string): number | undefined {\n const value = obj[key]\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n\nfunction timestampMs(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value > 1_000_000_000_000 ? value : value * 1000\n }\n if (typeof value === 'string' && value.length > 0) {\n const parsed = Date.parse(value)\n return Number.isFinite(parsed) ? parsed : undefined\n }\n return undefined\n}\n"],"mappings":"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","names":["payload","model"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TraceEmitter
3
- } from "./chunk-TVVP3ZZQ.js";
3
+ } from "./chunk-VQMK5FMP.js";
4
4
  import {
5
5
  ConfigError
6
6
  } from "./chunk-ONWEPEDO.js";
@@ -303,4 +303,4 @@ export {
303
303
  SandboxHarness,
304
304
  runTestGradedScenario
305
305
  };
306
- //# sourceMappingURL=chunk-HZHNRYHK.js.map
306
+ //# sourceMappingURL=chunk-K6N6XJJX.js.map
@@ -0,0 +1,286 @@
1
+ import {
2
+ LLM_CACHED_TOKEN_ATTR_KEYS,
3
+ LLM_CACHE_WRITE_TOKEN_ATTR_KEYS,
4
+ LLM_COST_ATTR_KEYS,
5
+ LLM_INPUT_TOKEN_ATTR_KEYS,
6
+ LLM_OUTPUT_TOKEN_ATTR_KEYS,
7
+ LLM_REASONING_TOKEN_ATTR_KEYS,
8
+ RUN_COST_ATTR_KEYS
9
+ } from "./chunk-QKEGNI5B.js";
10
+
11
+ // src/trace/execution-measurements.ts
12
+ var TOKEN_MEASUREMENT_KEY_GROUPS = [
13
+ LLM_INPUT_TOKEN_ATTR_KEYS,
14
+ LLM_OUTPUT_TOKEN_ATTR_KEYS,
15
+ LLM_REASONING_TOKEN_ATTR_KEYS,
16
+ LLM_CACHED_TOKEN_ATTR_KEYS,
17
+ LLM_CACHE_WRITE_TOKEN_ATTR_KEYS
18
+ ];
19
+ var EXECUTION_MEASUREMENT_KEY_GROUPS = [
20
+ ...TOKEN_MEASUREMENT_KEY_GROUPS,
21
+ LLM_COST_ATTR_KEYS
22
+ ];
23
+ function summarizeExecutionMeasurements(spans) {
24
+ const byId = /* @__PURE__ */ new Map();
25
+ for (const span of spans) {
26
+ if (byId.has(span.id)) {
27
+ throw new Error(`summarizeExecutionMeasurements: duplicate span id "${span.id}"`);
28
+ }
29
+ byId.set(span.id, span);
30
+ }
31
+ const tokenMeasurementKeys = TOKEN_MEASUREMENT_KEY_GROUPS.flat();
32
+ const candidates = spans.filter(
33
+ (span) => span.modelCall || !span.aggregate && readNumber(span.attributes, tokenMeasurementKeys) !== void 0
34
+ );
35
+ const candidateIds = new Set(candidates.map((span) => span.id));
36
+ const candidateChildren = /* @__PURE__ */ new Map();
37
+ for (const candidate of candidates) {
38
+ const parentId = nearestCandidateParent(candidate, byId, candidateIds);
39
+ if (!parentId) continue;
40
+ const children = candidateChildren.get(parentId) ?? [];
41
+ children.push(candidate);
42
+ candidateChildren.set(parentId, children);
43
+ }
44
+ const aggregateIds = classifyAggregateSpans(candidates, candidateChildren);
45
+ const untypedRunCostIds = new Set(
46
+ spans.filter(
47
+ (span) => !span.modelCall && !span.aggregate && !candidateIds.has(span.id) && readNumber(span.attributes, RUN_COST_ATTR_KEYS) !== void 0
48
+ ).map((span) => span.id)
49
+ );
50
+ const aggregateSourceIds = new Set(
51
+ spans.filter(
52
+ (span) => span.aggregate || aggregateIds.has(span.id) || untypedRunCostIds.has(span.id)
53
+ ).map((span) => span.id)
54
+ );
55
+ const calls = candidates.filter((span) => !aggregateIds.has(span.id));
56
+ const input = reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_INPUT_TOKEN_ATTR_KEYS);
57
+ const reasoning = reconcileMeasurement(
58
+ calls,
59
+ byId,
60
+ aggregateSourceIds,
61
+ LLM_REASONING_TOKEN_ATTR_KEYS
62
+ );
63
+ const output = reconcileMeasurement(
64
+ calls,
65
+ byId,
66
+ aggregateSourceIds,
67
+ LLM_OUTPUT_TOKEN_ATTR_KEYS,
68
+ LLM_REASONING_TOKEN_ATTR_KEYS
69
+ );
70
+ const cached = reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_CACHED_TOKEN_ATTR_KEYS);
71
+ const cacheWrite = reconcileMeasurement(
72
+ calls,
73
+ byId,
74
+ aggregateSourceIds,
75
+ LLM_CACHE_WRITE_TOKEN_ATTR_KEYS
76
+ );
77
+ const aggregate = summarizeAggregateMeasurements(
78
+ spans,
79
+ byId,
80
+ /* @__PURE__ */ new Set([...aggregateIds, ...untypedRunCostIds])
81
+ );
82
+ return {
83
+ tokenUsage: {
84
+ input: input.value ?? 0,
85
+ output: Math.max(output.value ?? 0, reasoning.value ?? 0),
86
+ ...reasoning.value !== void 0 ? { reasoning: reasoning.value } : {},
87
+ ...cached.value !== void 0 ? { cached: cached.value } : {},
88
+ ...cacheWrite.value !== void 0 ? { cacheWrite: cacheWrite.value } : {}
89
+ },
90
+ modelCallCount: calls.length,
91
+ callSpanIds: calls.map((span) => span.id),
92
+ cost: reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_COST_ATTR_KEYS),
93
+ ...aggregate ? { aggregate } : {}
94
+ };
95
+ }
96
+ function recordAggregateMeasurements(raw, aggregate) {
97
+ if (!aggregate) return;
98
+ raw.aggregate_prompt_tokens = aggregate.tokenUsage.input;
99
+ raw.aggregate_completion_tokens = aggregate.tokenUsage.output;
100
+ if (aggregate.tokenUsage.reasoning !== void 0)
101
+ raw.aggregate_reasoning_tokens = aggregate.tokenUsage.reasoning;
102
+ if (aggregate.tokenUsage.cached !== void 0)
103
+ raw.aggregate_cached_tokens = aggregate.tokenUsage.cached;
104
+ if (aggregate.tokenUsage.cacheWrite !== void 0)
105
+ raw.aggregate_cache_write_tokens = aggregate.tokenUsage.cacheWrite;
106
+ if (aggregate.costUsd !== void 0) raw.aggregate_cost_usd = aggregate.costUsd;
107
+ }
108
+ function summarizeAggregateMeasurements(spans, byId, aggregateIds) {
109
+ const aggregates = spans.filter((span) => span.aggregate || aggregateIds.has(span.id));
110
+ const input = reconcileTopLevelMeasurement(aggregates, byId, LLM_INPUT_TOKEN_ATTR_KEYS);
111
+ const output = reconcileTopLevelMeasurement(aggregates, byId, LLM_OUTPUT_TOKEN_ATTR_KEYS);
112
+ const reasoning = reconcileTopLevelMeasurement(aggregates, byId, LLM_REASONING_TOKEN_ATTR_KEYS);
113
+ const cached = reconcileTopLevelMeasurement(aggregates, byId, LLM_CACHED_TOKEN_ATTR_KEYS);
114
+ const cacheWrite = reconcileTopLevelMeasurement(aggregates, byId, LLM_CACHE_WRITE_TOKEN_ATTR_KEYS);
115
+ const costUsd = reconcileTopLevelMeasurement(aggregates, byId, LLM_COST_ATTR_KEYS);
116
+ if (input === void 0 && output === void 0 && reasoning === void 0 && cached === void 0 && cacheWrite === void 0 && costUsd === void 0)
117
+ return void 0;
118
+ return {
119
+ tokenUsage: {
120
+ input: input ?? 0,
121
+ output: output ?? reasoning ?? 0,
122
+ ...reasoning !== void 0 ? { reasoning } : {},
123
+ ...cached !== void 0 ? { cached } : {},
124
+ ...cacheWrite !== void 0 ? { cacheWrite } : {}
125
+ },
126
+ ...costUsd !== void 0 ? { costUsd } : {}
127
+ };
128
+ }
129
+ function reconcileTopLevelMeasurement(spans, byId, keys) {
130
+ const selected = /* @__PURE__ */ new Map();
131
+ for (const span of spans) {
132
+ const value = readNumber(span.attributes, keys);
133
+ if (value !== void 0) selected.set(span.id, value);
134
+ }
135
+ for (const spanId of [...selected.keys()]) {
136
+ const span = byId.get(spanId);
137
+ if (!span) continue;
138
+ if (ancestorIds(span, byId).some((ancestorId) => selected.has(ancestorId))) {
139
+ selected.delete(spanId);
140
+ }
141
+ }
142
+ return selected.size > 0 ? [...selected.values()].reduce((total, value) => total + value, 0) : void 0;
143
+ }
144
+ function reconcileMeasurement(calls, byId, aggregateSourceIds, keys, fallbackKeys) {
145
+ const selected = /* @__PURE__ */ new Map();
146
+ const callIds = new Set(calls.map((call) => call.id));
147
+ let reportingCalls = 0;
148
+ for (const call of calls) {
149
+ const primary = nearestMeasurement(call, byId, callIds, aggregateSourceIds, keys);
150
+ const fallback = fallbackKeys ? nearestMeasurement(call, byId, callIds, aggregateSourceIds, fallbackKeys) : void 0;
151
+ const source = primary && fallback && primary.span.id === fallback.span.id ? { span: primary.span, value: Math.max(primary.value, fallback.value) } : primary ?? fallback;
152
+ if (!source) continue;
153
+ reportingCalls += 1;
154
+ selected.set(source.span.id, source.value);
155
+ }
156
+ for (const spanId of [...selected.keys()]) {
157
+ const span = byId.get(spanId);
158
+ if (!span) continue;
159
+ if (ancestorIds(span, byId).some(
160
+ (ancestorId) => selected.has(ancestorId) && !callIds.has(ancestorId)
161
+ )) {
162
+ selected.delete(spanId);
163
+ }
164
+ }
165
+ return {
166
+ ...selected.size > 0 ? { value: [...selected.values()].reduce((total, value) => total + value, 0) } : {},
167
+ reportingCalls,
168
+ complete: calls.length > 0 && reportingCalls === calls.length
169
+ };
170
+ }
171
+ function nearestMeasurement(call, byId, callIds, aggregateSourceIds, keys) {
172
+ let current = call;
173
+ const seen = /* @__PURE__ */ new Set();
174
+ while (current && !seen.has(current.id)) {
175
+ seen.add(current.id);
176
+ const value = readNumber(current.attributes, keys);
177
+ if (value !== void 0 && (current.id === call.id || !callIds.has(current.id) && aggregateSourceIds.has(current.id))) {
178
+ return { span: current, value };
179
+ }
180
+ current = current.parentId ? byId.get(current.parentId) : void 0;
181
+ }
182
+ return void 0;
183
+ }
184
+ function classifyAggregateSpans(candidates, childrenById) {
185
+ const aggregateIds = /* @__PURE__ */ new Set();
186
+ const summaries = /* @__PURE__ */ new Map();
187
+ const visiting = /* @__PURE__ */ new Set();
188
+ const visit = (span) => {
189
+ const cached = summaries.get(span.id);
190
+ if (cached) return cached;
191
+ if (visiting.has(span.id)) return emptyRetainedCallSummary();
192
+ visiting.add(span.id);
193
+ const descendants = emptyRetainedCallSummary();
194
+ for (const child of childrenById.get(span.id) ?? []) {
195
+ const childDescendants = visit(child);
196
+ if (!aggregateIds.has(child.id)) addRetainedCall(descendants, child);
197
+ addRetainedCallSummary(descendants, childDescendants);
198
+ }
199
+ if (descendants.callCount > 0 && (!span.modelCall || hasCompatibleDescendantMeasurements(span, descendants))) {
200
+ aggregateIds.add(span.id);
201
+ }
202
+ visiting.delete(span.id);
203
+ summaries.set(span.id, descendants);
204
+ return descendants;
205
+ };
206
+ for (const candidate of candidates) visit(candidate);
207
+ return aggregateIds;
208
+ }
209
+ function emptyRetainedCallSummary() {
210
+ return {
211
+ callCount: 0,
212
+ measurements: EXECUTION_MEASUREMENT_KEY_GROUPS.map(() => ({
213
+ total: 0,
214
+ reportingCalls: 0
215
+ }))
216
+ };
217
+ }
218
+ function addRetainedCall(summary, span) {
219
+ summary.callCount += 1;
220
+ for (let index = 0; index < EXECUTION_MEASUREMENT_KEY_GROUPS.length; index += 1) {
221
+ const value = readNumber(span.attributes, EXECUTION_MEASUREMENT_KEY_GROUPS[index]);
222
+ if (value === void 0) continue;
223
+ const measurement = summary.measurements[index];
224
+ measurement.total += value;
225
+ measurement.reportingCalls += 1;
226
+ }
227
+ }
228
+ function addRetainedCallSummary(target, source) {
229
+ target.callCount += source.callCount;
230
+ for (let index = 0; index < target.measurements.length; index += 1) {
231
+ const measurement = target.measurements[index];
232
+ const sourceMeasurement = source.measurements[index];
233
+ measurement.total += sourceMeasurement.total;
234
+ measurement.reportingCalls += sourceMeasurement.reportingCalls;
235
+ }
236
+ }
237
+ function hasCompatibleDescendantMeasurements(span, descendants) {
238
+ let parentMeasurements = 0;
239
+ let descendantMeasurements = 0;
240
+ for (let index = 0; index < EXECUTION_MEASUREMENT_KEY_GROUPS.length; index += 1) {
241
+ const keys = EXECUTION_MEASUREMENT_KEY_GROUPS[index];
242
+ const parentValue = readNumber(span.attributes, keys);
243
+ const measurement = descendants.measurements[index];
244
+ if (parentValue !== void 0) parentMeasurements += 1;
245
+ if (measurement.reportingCalls > 0) descendantMeasurements += 1;
246
+ if (parentValue === void 0 || measurement.reportingCalls === 0) continue;
247
+ if (measurement.reportingCalls !== descendants.callCount) continue;
248
+ if (Math.abs(parentValue - measurement.total) > 1e-12) return false;
249
+ }
250
+ return parentMeasurements === 0 || descendantMeasurements > 0;
251
+ }
252
+ function ancestorIds(span, byId) {
253
+ const ids = [];
254
+ const seen = /* @__PURE__ */ new Set();
255
+ let parentId = span.parentId;
256
+ while (parentId && !seen.has(parentId)) {
257
+ ids.push(parentId);
258
+ seen.add(parentId);
259
+ parentId = byId.get(parentId)?.parentId;
260
+ }
261
+ return ids;
262
+ }
263
+ function nearestCandidateParent(span, byId, candidateIds) {
264
+ const seen = /* @__PURE__ */ new Set();
265
+ let parentId = span.parentId;
266
+ while (parentId && !seen.has(parentId)) {
267
+ if (candidateIds.has(parentId)) return parentId;
268
+ seen.add(parentId);
269
+ parentId = byId.get(parentId)?.parentId;
270
+ }
271
+ return void 0;
272
+ }
273
+ function readNumber(attributes, keys) {
274
+ for (const key of keys) {
275
+ const value = attributes[key];
276
+ const parsed = typeof value === "number" ? value : typeof value === "string" && value.length > 0 ? Number(value) : Number.NaN;
277
+ if (Number.isFinite(parsed) && parsed >= 0) return parsed;
278
+ }
279
+ return void 0;
280
+ }
281
+
282
+ export {
283
+ summarizeExecutionMeasurements,
284
+ recordAggregateMeasurements
285
+ };
286
+ //# sourceMappingURL=chunk-KSDQVPLR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trace/execution-measurements.ts"],"sourcesContent":["import type { RunTokenUsage } from '../run-record'\nimport {\n LLM_CACHE_WRITE_TOKEN_ATTR_KEYS,\n LLM_CACHED_TOKEN_ATTR_KEYS,\n LLM_COST_ATTR_KEYS,\n LLM_INPUT_TOKEN_ATTR_KEYS,\n LLM_OUTPUT_TOKEN_ATTR_KEYS,\n LLM_REASONING_TOKEN_ATTR_KEYS,\n RUN_COST_ATTR_KEYS,\n} from './otlp-attributes'\n\nexport interface ExecutionMeasurementSpan {\n id: string\n parentId?: string\n attributes: Record<string, unknown>\n modelCall: boolean\n aggregate: boolean\n}\n\nexport interface MeasurementCoverage {\n value?: number\n reportingCalls: number\n complete: boolean\n}\n\nexport interface ExecutionMeasurements {\n tokenUsage: RunTokenUsage\n modelCallCount: number\n callSpanIds: string[]\n cost: MeasurementCoverage\n aggregate?: {\n tokenUsage: RunTokenUsage\n costUsd?: number\n }\n}\n\nconst TOKEN_MEASUREMENT_KEY_GROUPS = [\n LLM_INPUT_TOKEN_ATTR_KEYS,\n LLM_OUTPUT_TOKEN_ATTR_KEYS,\n LLM_REASONING_TOKEN_ATTR_KEYS,\n LLM_CACHED_TOKEN_ATTR_KEYS,\n LLM_CACHE_WRITE_TOKEN_ATTR_KEYS,\n] as const\n\nconst EXECUTION_MEASUREMENT_KEY_GROUPS = [\n ...TOKEN_MEASUREMENT_KEY_GROUPS,\n LLM_COST_ATTR_KEYS,\n] as const\n\ninterface RetainedCallSummary {\n callCount: number\n measurements: Array<{\n total: number\n reportingCalls: number\n }>\n}\n\n/**\n * Reconcile execution measurements across nested telemetry wrappers.\n * A measured parent is used only when a descendant call does not report the\n * same field, so aggregate wrappers neither duplicate complete child data nor\n * erase complementary parent fields.\n */\nexport function summarizeExecutionMeasurements(\n spans: ExecutionMeasurementSpan[],\n): ExecutionMeasurements {\n const byId = new Map<string, ExecutionMeasurementSpan>()\n for (const span of spans) {\n if (byId.has(span.id)) {\n throw new Error(`summarizeExecutionMeasurements: duplicate span id \"${span.id}\"`)\n }\n byId.set(span.id, span)\n }\n const tokenMeasurementKeys = TOKEN_MEASUREMENT_KEY_GROUPS.flat()\n const candidates = spans.filter(\n (span) =>\n span.modelCall ||\n (!span.aggregate && readNumber(span.attributes, tokenMeasurementKeys) !== undefined),\n )\n const candidateIds = new Set(candidates.map((span) => span.id))\n const candidateChildren = new Map<string, ExecutionMeasurementSpan[]>()\n for (const candidate of candidates) {\n const parentId = nearestCandidateParent(candidate, byId, candidateIds)\n if (!parentId) continue\n const children = candidateChildren.get(parentId) ?? []\n children.push(candidate)\n candidateChildren.set(parentId, children)\n }\n const aggregateIds = classifyAggregateSpans(candidates, candidateChildren)\n const untypedRunCostIds = new Set(\n spans\n .filter(\n (span) =>\n !span.modelCall &&\n !span.aggregate &&\n !candidateIds.has(span.id) &&\n readNumber(span.attributes, RUN_COST_ATTR_KEYS) !== undefined,\n )\n .map((span) => span.id),\n )\n const aggregateSourceIds = new Set(\n spans\n .filter(\n (span) => span.aggregate || aggregateIds.has(span.id) || untypedRunCostIds.has(span.id),\n )\n .map((span) => span.id),\n )\n\n const calls = candidates.filter((span) => !aggregateIds.has(span.id))\n const input = reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_INPUT_TOKEN_ATTR_KEYS)\n const reasoning = reconcileMeasurement(\n calls,\n byId,\n aggregateSourceIds,\n LLM_REASONING_TOKEN_ATTR_KEYS,\n )\n const output = reconcileMeasurement(\n calls,\n byId,\n aggregateSourceIds,\n LLM_OUTPUT_TOKEN_ATTR_KEYS,\n LLM_REASONING_TOKEN_ATTR_KEYS,\n )\n const cached = reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_CACHED_TOKEN_ATTR_KEYS)\n const cacheWrite = reconcileMeasurement(\n calls,\n byId,\n aggregateSourceIds,\n LLM_CACHE_WRITE_TOKEN_ATTR_KEYS,\n )\n const aggregate = summarizeAggregateMeasurements(\n spans,\n byId,\n new Set([...aggregateIds, ...untypedRunCostIds]),\n )\n\n return {\n tokenUsage: {\n input: input.value ?? 0,\n output: Math.max(output.value ?? 0, reasoning.value ?? 0),\n ...(reasoning.value !== undefined ? { reasoning: reasoning.value } : {}),\n ...(cached.value !== undefined ? { cached: cached.value } : {}),\n ...(cacheWrite.value !== undefined ? { cacheWrite: cacheWrite.value } : {}),\n },\n modelCallCount: calls.length,\n callSpanIds: calls.map((span) => span.id),\n cost: reconcileMeasurement(calls, byId, aggregateSourceIds, LLM_COST_ATTR_KEYS),\n ...(aggregate ? { aggregate } : {}),\n }\n}\n\nexport function recordAggregateMeasurements(\n raw: Record<string, number>,\n aggregate: ExecutionMeasurements['aggregate'],\n): void {\n if (!aggregate) return\n raw.aggregate_prompt_tokens = aggregate.tokenUsage.input\n raw.aggregate_completion_tokens = aggregate.tokenUsage.output\n if (aggregate.tokenUsage.reasoning !== undefined)\n raw.aggregate_reasoning_tokens = aggregate.tokenUsage.reasoning\n if (aggregate.tokenUsage.cached !== undefined)\n raw.aggregate_cached_tokens = aggregate.tokenUsage.cached\n if (aggregate.tokenUsage.cacheWrite !== undefined)\n raw.aggregate_cache_write_tokens = aggregate.tokenUsage.cacheWrite\n if (aggregate.costUsd !== undefined) raw.aggregate_cost_usd = aggregate.costUsd\n}\n\nfunction summarizeAggregateMeasurements(\n spans: ExecutionMeasurementSpan[],\n byId: Map<string, ExecutionMeasurementSpan>,\n aggregateIds: Set<string>,\n): ExecutionMeasurements['aggregate'] {\n const aggregates = spans.filter((span) => span.aggregate || aggregateIds.has(span.id))\n const input = reconcileTopLevelMeasurement(aggregates, byId, LLM_INPUT_TOKEN_ATTR_KEYS)\n const output = reconcileTopLevelMeasurement(aggregates, byId, LLM_OUTPUT_TOKEN_ATTR_KEYS)\n const reasoning = reconcileTopLevelMeasurement(aggregates, byId, LLM_REASONING_TOKEN_ATTR_KEYS)\n const cached = reconcileTopLevelMeasurement(aggregates, byId, LLM_CACHED_TOKEN_ATTR_KEYS)\n const cacheWrite = reconcileTopLevelMeasurement(aggregates, byId, LLM_CACHE_WRITE_TOKEN_ATTR_KEYS)\n const costUsd = reconcileTopLevelMeasurement(aggregates, byId, LLM_COST_ATTR_KEYS)\n if (\n input === undefined &&\n output === undefined &&\n reasoning === undefined &&\n cached === undefined &&\n cacheWrite === undefined &&\n costUsd === undefined\n )\n return undefined\n return {\n tokenUsage: {\n input: input ?? 0,\n output: output ?? reasoning ?? 0,\n ...(reasoning !== undefined ? { reasoning } : {}),\n ...(cached !== undefined ? { cached } : {}),\n ...(cacheWrite !== undefined ? { cacheWrite } : {}),\n },\n ...(costUsd !== undefined ? { costUsd } : {}),\n }\n}\n\nfunction reconcileTopLevelMeasurement(\n spans: ExecutionMeasurementSpan[],\n byId: Map<string, ExecutionMeasurementSpan>,\n keys: readonly string[],\n): number | undefined {\n const selected = new Map<string, number>()\n for (const span of spans) {\n const value = readNumber(span.attributes, keys)\n if (value !== undefined) selected.set(span.id, value)\n }\n for (const spanId of [...selected.keys()]) {\n const span = byId.get(spanId)\n if (!span) continue\n if (ancestorIds(span, byId).some((ancestorId) => selected.has(ancestorId))) {\n selected.delete(spanId)\n }\n }\n return selected.size > 0\n ? [...selected.values()].reduce((total, value) => total + value, 0)\n : undefined\n}\n\nfunction reconcileMeasurement(\n calls: ExecutionMeasurementSpan[],\n byId: Map<string, ExecutionMeasurementSpan>,\n aggregateSourceIds: Set<string>,\n keys: readonly string[],\n fallbackKeys?: readonly string[],\n): MeasurementCoverage {\n const selected = new Map<string, number>()\n const callIds = new Set(calls.map((call) => call.id))\n let reportingCalls = 0\n\n for (const call of calls) {\n const primary = nearestMeasurement(call, byId, callIds, aggregateSourceIds, keys)\n const fallback = fallbackKeys\n ? nearestMeasurement(call, byId, callIds, aggregateSourceIds, fallbackKeys)\n : undefined\n const source =\n primary && fallback && primary.span.id === fallback.span.id\n ? { span: primary.span, value: Math.max(primary.value, fallback.value) }\n : (primary ?? fallback)\n if (!source) continue\n reportingCalls += 1\n selected.set(source.span.id, source.value)\n }\n\n for (const spanId of [...selected.keys()]) {\n const span = byId.get(spanId)\n if (!span) continue\n if (\n ancestorIds(span, byId).some(\n (ancestorId) => selected.has(ancestorId) && !callIds.has(ancestorId),\n )\n ) {\n selected.delete(spanId)\n }\n }\n\n return {\n ...(selected.size > 0\n ? { value: [...selected.values()].reduce((total, value) => total + value, 0) }\n : {}),\n reportingCalls,\n complete: calls.length > 0 && reportingCalls === calls.length,\n }\n}\n\nfunction nearestMeasurement(\n call: ExecutionMeasurementSpan,\n byId: Map<string, ExecutionMeasurementSpan>,\n callIds: Set<string>,\n aggregateSourceIds: Set<string>,\n keys: readonly string[],\n): { span: ExecutionMeasurementSpan; value: number } | undefined {\n let current: ExecutionMeasurementSpan | undefined = call\n const seen = new Set<string>()\n while (current && !seen.has(current.id)) {\n seen.add(current.id)\n const value = readNumber(current.attributes, keys)\n if (\n value !== undefined &&\n (current.id === call.id || (!callIds.has(current.id) && aggregateSourceIds.has(current.id)))\n ) {\n return { span: current, value }\n }\n current = current.parentId ? byId.get(current.parentId) : undefined\n }\n return undefined\n}\n\nfunction classifyAggregateSpans(\n candidates: ExecutionMeasurementSpan[],\n childrenById: Map<string, ExecutionMeasurementSpan[]>,\n): Set<string> {\n const aggregateIds = new Set<string>()\n const summaries = new Map<string, RetainedCallSummary>()\n const visiting = new Set<string>()\n\n const visit = (span: ExecutionMeasurementSpan): RetainedCallSummary => {\n const cached = summaries.get(span.id)\n if (cached) return cached\n if (visiting.has(span.id)) return emptyRetainedCallSummary()\n visiting.add(span.id)\n\n const descendants = emptyRetainedCallSummary()\n for (const child of childrenById.get(span.id) ?? []) {\n const childDescendants = visit(child)\n if (!aggregateIds.has(child.id)) addRetainedCall(descendants, child)\n addRetainedCallSummary(descendants, childDescendants)\n }\n\n if (\n descendants.callCount > 0 &&\n (!span.modelCall || hasCompatibleDescendantMeasurements(span, descendants))\n ) {\n aggregateIds.add(span.id)\n }\n\n visiting.delete(span.id)\n summaries.set(span.id, descendants)\n return descendants\n }\n\n for (const candidate of candidates) visit(candidate)\n return aggregateIds\n}\n\nfunction emptyRetainedCallSummary(): RetainedCallSummary {\n return {\n callCount: 0,\n measurements: EXECUTION_MEASUREMENT_KEY_GROUPS.map(() => ({\n total: 0,\n reportingCalls: 0,\n })),\n }\n}\n\nfunction addRetainedCall(summary: RetainedCallSummary, span: ExecutionMeasurementSpan): void {\n summary.callCount += 1\n for (let index = 0; index < EXECUTION_MEASUREMENT_KEY_GROUPS.length; index += 1) {\n const value = readNumber(span.attributes, EXECUTION_MEASUREMENT_KEY_GROUPS[index]!)\n if (value === undefined) continue\n const measurement = summary.measurements[index]!\n measurement.total += value\n measurement.reportingCalls += 1\n }\n}\n\nfunction addRetainedCallSummary(target: RetainedCallSummary, source: RetainedCallSummary): void {\n target.callCount += source.callCount\n for (let index = 0; index < target.measurements.length; index += 1) {\n const measurement = target.measurements[index]!\n const sourceMeasurement = source.measurements[index]!\n measurement.total += sourceMeasurement.total\n measurement.reportingCalls += sourceMeasurement.reportingCalls\n }\n}\n\nfunction hasCompatibleDescendantMeasurements(\n span: ExecutionMeasurementSpan,\n descendants: RetainedCallSummary,\n): boolean {\n let parentMeasurements = 0\n let descendantMeasurements = 0\n for (let index = 0; index < EXECUTION_MEASUREMENT_KEY_GROUPS.length; index += 1) {\n const keys = EXECUTION_MEASUREMENT_KEY_GROUPS[index]!\n const parentValue = readNumber(span.attributes, keys)\n const measurement = descendants.measurements[index]!\n if (parentValue !== undefined) parentMeasurements += 1\n if (measurement.reportingCalls > 0) descendantMeasurements += 1\n if (parentValue === undefined || measurement.reportingCalls === 0) continue\n if (measurement.reportingCalls !== descendants.callCount) continue\n if (Math.abs(parentValue - measurement.total) > 1e-12) return false\n }\n return parentMeasurements === 0 || descendantMeasurements > 0\n}\n\nfunction ancestorIds(\n span: ExecutionMeasurementSpan,\n byId: Map<string, ExecutionMeasurementSpan>,\n): string[] {\n const ids: string[] = []\n const seen = new Set<string>()\n let parentId = span.parentId\n while (parentId && !seen.has(parentId)) {\n ids.push(parentId)\n seen.add(parentId)\n parentId = byId.get(parentId)?.parentId\n }\n return ids\n}\n\nfunction nearestCandidateParent(\n span: ExecutionMeasurementSpan,\n byId: Map<string, ExecutionMeasurementSpan>,\n candidateIds: Set<string>,\n): string | undefined {\n const seen = new Set<string>()\n let parentId = span.parentId\n while (parentId && !seen.has(parentId)) {\n if (candidateIds.has(parentId)) return parentId\n seen.add(parentId)\n parentId = byId.get(parentId)?.parentId\n }\n return undefined\n}\n\nfunction readNumber(\n attributes: Record<string, unknown>,\n keys: readonly string[],\n): number | undefined {\n for (const key of keys) {\n const value = attributes[key]\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string' && value.length > 0\n ? Number(value)\n : Number.NaN\n if (Number.isFinite(parsed) && parsed >= 0) return parsed\n }\n return undefined\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,65 @@
1
+ // src/trace/schema.ts
2
+ var TRACE_SCHEMA_VERSION = "1.0.0";
3
+ var FAILURE_CLASSES = [
4
+ "success",
5
+ "reasoning_error",
6
+ "tool_selection_error",
7
+ "tool_argument_error",
8
+ "tool_recovery_failure",
9
+ "hallucination",
10
+ "instruction_following",
11
+ "safety_refusal_miss",
12
+ "policy_violation",
13
+ "budget_exceeded",
14
+ "format_drift",
15
+ "permission_escalation",
16
+ "pii_leak",
17
+ "cost_overrun",
18
+ "timeout",
19
+ "sandbox_failure",
20
+ "missing_user_data",
21
+ "missing_domain_data",
22
+ "missing_codebase_context",
23
+ "missing_runtime_context",
24
+ "missing_credentials",
25
+ "missing_integration_connection",
26
+ "missing_integration_scope",
27
+ "integration_approval_required",
28
+ "integration_auth_expired",
29
+ "integration_provider_failure",
30
+ "bad_integration_manifest",
31
+ "unsafe_integration_write_denied",
32
+ "stale_external_data",
33
+ "bad_retrieval",
34
+ "insufficient_evidence",
35
+ "contradictory_evidence",
36
+ "ambiguous_user_intent",
37
+ "knowledge_readiness_blocked",
38
+ "unknown"
39
+ ];
40
+ function isLlmSpan(s) {
41
+ return s.kind === "llm";
42
+ }
43
+ function isToolSpan(s) {
44
+ return s.kind === "tool";
45
+ }
46
+ function isRetrievalSpan(s) {
47
+ return s.kind === "retrieval";
48
+ }
49
+ function isJudgeSpan(s) {
50
+ return s.kind === "judge";
51
+ }
52
+ function isSandboxSpan(s) {
53
+ return s.kind === "sandbox";
54
+ }
55
+
56
+ export {
57
+ TRACE_SCHEMA_VERSION,
58
+ FAILURE_CLASSES,
59
+ isLlmSpan,
60
+ isToolSpan,
61
+ isRetrievalSpan,
62
+ isJudgeSpan,
63
+ isSandboxSpan
64
+ };
65
+ //# sourceMappingURL=chunk-MA6HLL3S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trace/schema.ts"],"sourcesContent":["/**\n * TraceSchema v1 — the canonical data model for agent-eval.\n *\n * Every score, every failure class, every pipeline in the framework is\n * a view over this data. Shape it once, live with it.\n *\n * Wire-compatible with OpenTelemetry span semantics (see trace/otel.ts)\n * but extended with agent-specific span kinds (llm, tool, retrieval,\n * judge, sandbox) and first-class BudgetLedger / Artifact / JudgeVerdict\n * entities that OTEL leaves as free-form attributes.\n */\n\nexport const TRACE_SCHEMA_VERSION = '1.0.0'\n\n// ── Run ──────────────────────────────────────────────────────────────\n\nexport type RunStatus = 'running' | 'completed' | 'failed' | 'aborted'\n\nexport interface BudgetSpec {\n tokens?: number\n wallMs?: number\n calls?: number\n usd?: number\n}\n\nexport interface RunOutcome {\n score?: number\n pass?: boolean\n failureClass?: FailureClass\n notes?: string\n}\n\n/**\n * Layer — optional classification in a nested build workflow.\n * `builder`: the meta-agent editing a project (e.g. agent-builder Forge chat).\n * `app-build`: sandbox harness that compiled + tested the generated scaffold.\n * `app-runtime`: a run of the generated agent against a domain scenario.\n * `meta`: any meta-eval (judge replay, correlation analysis).\n */\nexport type RunLayer = 'builder' | 'app-build' | 'app-runtime' | 'meta' | 'custom'\n\nexport interface Run {\n runId: string\n /**\n * Stable identifier of the scenario being executed.\n *\n * Always populated on the persisted Run — but `TraceEmitter.startRun` accepts\n * input WITHOUT this field, substituting a sensible default\n * (`run.layer ?? run.tags?.['kind'] ?? 'runtime'`) when the caller has no\n * curated scenario to anchor to (runtime / operator / meta-eval runs). This\n * keeps the persisted shape unambiguous for downstream filters + aggregations\n * while removing the boilerplate of inventing placeholder ids at the call site.\n */\n scenarioId: string\n variantId?: string\n datasetVersion?: string\n /** Git SHA of agent code at run time. */\n codeSha?: string\n /** Hash of the prompt template + any system prompt. */\n promptSha?: string\n /** Model id + date + system-prompt hash, concatenated. */\n modelFingerprint?: string\n seed?: number\n /** Arbitrary environment markers (shell, docker version, tz). */\n envFingerprint?: Record<string, string>\n /** Version of the redaction rules applied to this run. */\n redactionVersion?: string\n /** Parent run in a nested build workflow. A builder run's children are\n * app-build runs; those children are app-runtime runs. */\n parentRunId?: string\n /** Stable project identifier — groups runs across chats + sessions. */\n projectId?: string\n /** Chat/conversation identifier within a project. */\n chatId?: string\n /** Layer classification — hint for aggregation; not enforced. */\n layer?: RunLayer\n startedAt: number\n endedAt?: number\n status: RunStatus\n outcome?: RunOutcome\n budget?: BudgetSpec\n /** Free-form labels for downstream grouping. */\n tags?: Record<string, string>\n}\n\n// ── Spans (hierarchical work units) ──────────────────────────────────\n\nexport type SpanKind = 'agent' | 'llm' | 'tool' | 'retrieval' | 'judge' | 'sandbox' | 'custom'\n\nexport type SpanStatus = 'ok' | 'error'\n\nexport interface SpanBase {\n spanId: string\n parentSpanId?: string\n runId: string\n kind: SpanKind\n name: string\n startedAt: number\n endedAt?: number\n status?: SpanStatus\n error?: string\n /** Anything not covered by typed fields. Kept deliberately free-form. */\n attributes?: Record<string, unknown>\n}\n\nexport interface Message {\n role: 'system' | 'user' | 'assistant' | 'tool'\n content: string\n tokens?: number\n /** Multi-modal content descriptors; blobs themselves live in Artifacts. */\n images?: Array<{ artifactId?: string; url?: string; mime?: string }>\n}\n\nexport interface LlmSpan extends SpanBase {\n kind: 'llm'\n model: string\n messages: Message[]\n output?: string\n inputTokens?: number\n /** All generated tokens, including the reasoning subset when present. */\n outputTokens?: number\n cachedTokens?: number\n cacheWriteTokens?: number\n /** Reasoning-token subset of `outputTokens`. */\n reasoningTokens?: number\n costUsd?: number\n finishReason?: string\n}\n\nexport interface ToolSpan extends SpanBase {\n kind: 'tool'\n toolName: string\n args: unknown\n /** False when the source observed the call but did not capture its arguments. */\n argsCaptured?: boolean\n result?: unknown\n latencyMs?: number\n}\n\nexport interface RetrievalSpan extends SpanBase {\n kind: 'retrieval'\n query: string\n hits: Array<{ docId: string; score: number; content?: string }>\n}\n\nexport interface JudgeSpan extends SpanBase {\n kind: 'judge'\n judgeId: string\n /** Span this judgment applies to. */\n targetSpanId: string\n dimension: string\n /** Numeric score (free-range; interpretation up to the judge). */\n score: number\n rationale?: string\n evidence?: string\n}\n\nexport interface SandboxSpan extends SpanBase {\n kind: 'sandbox'\n image?: string\n command?: string\n exitCode?: number\n testsTotal?: number\n testsPassed?: number\n stdoutHash?: string\n stderrHash?: string\n /** Duration in ms; the harness fills this explicitly (endedAt - startedAt may miss setup). */\n wallMs?: number\n}\n\nexport interface GenericSpan extends SpanBase {\n kind: 'agent' | 'custom'\n}\n\nexport type Span = LlmSpan | ToolSpan | RetrievalSpan | JudgeSpan | SandboxSpan | GenericSpan\n\n// ── Events (point-in-time occurrences within a span) ─────────────────\n\nexport type EventKind =\n | 'log'\n | 'error'\n | 'budget_decrement'\n | 'budget_breach'\n | 'state_mutation'\n | 'policy_violation'\n | 'redaction_applied'\n | 'custom'\n\nexport interface TraceEvent {\n eventId: string\n runId: string\n spanId?: string\n kind: EventKind\n timestamp: number\n payload: Record<string, unknown>\n}\n\n// ── Budget ledger (running token/wall/call/$ accounting) ─────────────\n\nexport interface BudgetLedgerEntry {\n runId: string\n dimension: keyof BudgetSpec\n limit: number\n consumed: number\n remaining: number\n timestamp: number\n breached: boolean\n /** Span that triggered this entry, if any. */\n spanId?: string\n}\n\n// ── Artifacts (blobs addressed by hash) ──────────────────────────────\n\nexport interface Artifact {\n artifactId: string\n runId: string\n spanId?: string\n contentType: string\n sizeBytes: number\n /** sha256 in hex. */\n hash: string\n /** External storage URL (R2, S3, filesystem path). */\n storageUrl?: string\n /** Inline content for small blobs — keep under ~64KB. */\n inlineContent?: string\n}\n\n// ── Failure taxonomy ─────────────────────────────────────────────────\n\nexport type FailureClass =\n | 'success'\n | 'reasoning_error'\n | 'tool_selection_error'\n | 'tool_argument_error'\n | 'tool_recovery_failure'\n | 'hallucination'\n | 'instruction_following'\n | 'safety_refusal_miss'\n | 'policy_violation'\n | 'budget_exceeded'\n | 'format_drift'\n | 'permission_escalation'\n | 'pii_leak'\n | 'cost_overrun'\n | 'timeout'\n | 'sandbox_failure'\n | 'missing_user_data'\n | 'missing_domain_data'\n | 'missing_codebase_context'\n | 'missing_runtime_context'\n | 'missing_credentials'\n | 'missing_integration_connection'\n | 'missing_integration_scope'\n | 'integration_approval_required'\n | 'integration_auth_expired'\n | 'integration_provider_failure'\n | 'bad_integration_manifest'\n | 'unsafe_integration_write_denied'\n | 'stale_external_data'\n | 'bad_retrieval'\n | 'insufficient_evidence'\n | 'contradictory_evidence'\n | 'ambiguous_user_intent'\n | 'knowledge_readiness_blocked'\n | 'unknown'\n\nexport const FAILURE_CLASSES: readonly FailureClass[] = [\n 'success',\n 'reasoning_error',\n 'tool_selection_error',\n 'tool_argument_error',\n 'tool_recovery_failure',\n 'hallucination',\n 'instruction_following',\n 'safety_refusal_miss',\n 'policy_violation',\n 'budget_exceeded',\n 'format_drift',\n 'permission_escalation',\n 'pii_leak',\n 'cost_overrun',\n 'timeout',\n 'sandbox_failure',\n 'missing_user_data',\n 'missing_domain_data',\n 'missing_codebase_context',\n 'missing_runtime_context',\n 'missing_credentials',\n 'missing_integration_connection',\n 'missing_integration_scope',\n 'integration_approval_required',\n 'integration_auth_expired',\n 'integration_provider_failure',\n 'bad_integration_manifest',\n 'unsafe_integration_write_denied',\n 'stale_external_data',\n 'bad_retrieval',\n 'insufficient_evidence',\n 'contradictory_evidence',\n 'ambiguous_user_intent',\n 'knowledge_readiness_blocked',\n 'unknown',\n] as const\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nexport function isLlmSpan(s: Span): s is LlmSpan {\n return s.kind === 'llm'\n}\nexport function isToolSpan(s: Span): s is ToolSpan {\n return s.kind === 'tool'\n}\nexport function isRetrievalSpan(s: Span): s is RetrievalSpan {\n return s.kind === 'retrieval'\n}\nexport function isJudgeSpan(s: Span): s is JudgeSpan {\n return s.kind === 'judge'\n}\nexport function isSandboxSpan(s: Span): s is SandboxSpan {\n return s.kind === 'sandbox'\n}\n"],"mappings":";AAYO,IAAM,uBAAuB;AA8P7B,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,SAAS,UAAU,GAAuB;AAC/C,SAAO,EAAE,SAAS;AACpB;AACO,SAAS,WAAW,GAAwB;AACjD,SAAO,EAAE,SAAS;AACpB;AACO,SAAS,gBAAgB,GAA6B;AAC3D,SAAO,EAAE,SAAS;AACpB;AACO,SAAS,YAAY,GAAyB;AACnD,SAAO,EAAE,SAAS;AACpB;AACO,SAAS,cAAc,GAA2B;AACvD,SAAO,EAAE,SAAS;AACpB;","names":[]}
@@ -1,13 +1,3 @@
1
- import {
2
- TraceFileMissingError,
3
- buildTraceAnalystTools
4
- } from "./chunk-S2F4J57L.js";
5
- import {
6
- validateAgentProfileCell
7
- } from "./chunk-XJYR7XFV.js";
8
- import {
9
- canonicalize
10
- } from "./chunk-VSMTAMNK.js";
11
1
  import {
12
2
  callLlm,
13
3
  costReceiptFromLlm,
@@ -17,6 +7,16 @@ import {
17
7
  import {
18
8
  CostLedger
19
9
  } from "./chunk-VCTY3W6J.js";
10
+ import {
11
+ TraceFileMissingError,
12
+ buildTraceAnalystTools
13
+ } from "./chunk-QKEGNI5B.js";
14
+ import {
15
+ validateAgentProfileCell
16
+ } from "./chunk-XJYR7XFV.js";
17
+ import {
18
+ canonicalize
19
+ } from "./chunk-VSMTAMNK.js";
20
20
  import {
21
21
  ValidationError
22
22
  } from "./chunk-ONWEPEDO.js";
@@ -1940,4 +1940,4 @@ export {
1940
1940
  aggregateRunScore,
1941
1941
  clamp012 as clamp01
1942
1942
  };
1943
- //# sourceMappingURL=chunk-MGEHEHSN.js.map
1943
+ //# sourceMappingURL=chunk-OIIMMLRB.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  TraceEmitter
3
- } from "./chunk-TVVP3ZZQ.js";
3
+ } from "./chunk-VQMK5FMP.js";
4
4
  import {
5
5
  validateRunRecord
6
- } from "./chunk-5UF54T55.js";
6
+ } from "./chunk-S3UZOQ5Y.js";
7
7
 
8
8
  // src/action-policy.ts
9
9
  function evaluateActionPolicy(action, policy = {}, options = {}) {
@@ -1523,4 +1523,4 @@ export {
1523
1523
  runProposeReviewAsControlLoop,
1524
1524
  controlFailureClassFromVerification
1525
1525
  };
1526
- //# sourceMappingURL=chunk-DXZRATT5.js.map
1526
+ //# sourceMappingURL=chunk-OYZAPX5G.js.map