@tangle-network/agent-eval 0.137.0 → 0.138.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 (150) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +33 -0
  3. package/dist/analyst/index.d.ts +473 -39
  4. package/dist/analyst/index.d.ts.map +1 -1
  5. package/dist/analyst/index.js +11 -593
  6. package/dist/analyst/index.js.map +1 -1
  7. package/dist/{analyze-runs-PVtnfjvA.d.ts → analyze-runs-CPYxfPWT.d.ts} +5 -5
  8. package/dist/{analyze-runs-PVtnfjvA.d.ts.map → analyze-runs-CPYxfPWT.d.ts.map} +1 -1
  9. package/dist/{benchmark-YDrpumqB.js → benchmark-D8dkki-J.js} +299 -159
  10. package/dist/benchmark-D8dkki-J.js.map +1 -0
  11. package/dist/{benchmark-CHX4orG7.d.ts → benchmark-DlQgU_XI.d.ts} +67 -15
  12. package/dist/benchmark-DlQgU_XI.d.ts.map +1 -0
  13. package/dist/benchmark-command-CMqVqReF.js +4332 -0
  14. package/dist/benchmark-command-CMqVqReF.js.map +1 -0
  15. package/dist/benchmarks/index.d.ts +1 -1
  16. package/dist/benchmarks/index.js +1 -1
  17. package/dist/{benchmarks-DCLkQOmc.js → benchmarks-BJ_xK5rQ.js} +4 -3
  18. package/dist/{benchmarks-DCLkQOmc.js.map → benchmarks-BJ_xK5rQ.js.map} +1 -1
  19. package/dist/campaign/index.d.ts +5 -5
  20. package/dist/campaign/index.js +3 -3
  21. package/dist/{campaign-lgObcHFC.js → campaign-BIBS-NHV.js} +16 -9
  22. package/dist/campaign-BIBS-NHV.js.map +1 -0
  23. package/dist/cli.js +9 -2
  24. package/dist/cli.js.map +1 -1
  25. package/dist/{client-C8L6h6Wf.d.ts → client-BwPKohkJ.d.ts} +4 -4
  26. package/dist/{client-C8L6h6Wf.d.ts.map → client-BwPKohkJ.d.ts.map} +1 -1
  27. package/dist/{completion-verifier-DSyRNVzU.d.ts → completion-verifier-B4-IMYcS.d.ts} +3 -3
  28. package/dist/{completion-verifier-DSyRNVzU.d.ts.map → completion-verifier-B4-IMYcS.d.ts.map} +1 -1
  29. package/dist/contract/index.d.ts +10 -10
  30. package/dist/contract/index.js +8 -8
  31. package/dist/control.d.ts +2 -2
  32. package/dist/{cost-ledger-D2o6JOrL.d.ts → cost-ledger-B1D3COAc.d.ts} +5 -4
  33. package/dist/{cost-ledger-D2o6JOrL.d.ts.map → cost-ledger-B1D3COAc.d.ts.map} +1 -1
  34. package/dist/{cost-ledger-D-5_-dhi.js → cost-ledger-CHDLA0Ss.js} +90 -45
  35. package/dist/cost-ledger-CHDLA0Ss.js.map +1 -0
  36. package/dist/{default-registry-Dc5D_Loc.d.ts → default-registry-PUhIVRWz.d.ts} +18 -5
  37. package/dist/default-registry-PUhIVRWz.d.ts.map +1 -0
  38. package/dist/{default-registry-CLXbRt0f.js → default-registry-lp5R0lve.js} +1503 -258
  39. package/dist/default-registry-lp5R0lve.js.map +1 -0
  40. package/dist/{eval-campaign-CHqfLnff.js → eval-campaign-9MozgKL7.js} +2 -2
  41. package/dist/{eval-campaign-CHqfLnff.js.map → eval-campaign-9MozgKL7.js.map} +1 -1
  42. package/dist/exact-types-Dpw2LeHA.d.ts +234 -0
  43. package/dist/exact-types-Dpw2LeHA.d.ts.map +1 -0
  44. package/dist/{extract-usage-p-56bh8q.js → extract-usage-CS391dOE.js} +2 -2
  45. package/dist/{extract-usage-p-56bh8q.js.map → extract-usage-CS391dOE.js.map} +1 -1
  46. package/dist/{feedback-trajectory-N_F0PwHz.d.ts → feedback-trajectory-CoNep7rl.d.ts} +3 -2
  47. package/dist/feedback-trajectory-CoNep7rl.d.ts.map +1 -0
  48. package/dist/fuzz.d.ts +1 -1
  49. package/dist/fuzz.js +1 -1
  50. package/dist/hosted/index.d.ts +3 -3
  51. package/dist/{index-U3RHOShi.d.ts → index-B2-IxCMB.d.ts} +2 -2
  52. package/dist/{index-U3RHOShi.d.ts.map → index-B2-IxCMB.d.ts.map} +1 -1
  53. package/dist/{index-BnP1QJUv.d.ts → index-CjVYlVBK.d.ts} +5 -5
  54. package/dist/{index-BnP1QJUv.d.ts.map → index-CjVYlVBK.d.ts.map} +1 -1
  55. package/dist/{index-C-Pr4OWg.d.ts → index-D0cxAdaV.d.ts} +11 -10
  56. package/dist/index-D0cxAdaV.d.ts.map +1 -0
  57. package/dist/index-DEb46kc6.d.ts.map +1 -1
  58. package/dist/{index-DRNl6g_N.d.ts → index-sMN_hI4E.d.ts} +3 -3
  59. package/dist/{index-DRNl6g_N.d.ts.map → index-sMN_hI4E.d.ts.map} +1 -1
  60. package/dist/index.d.ts +24 -23
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +19 -353
  63. package/dist/index.js.map +1 -1
  64. package/dist/{insight-report-B9ooYH_g.d.ts → insight-report-CXd8VBDR.d.ts} +4 -4
  65. package/dist/{insight-report-B9ooYH_g.d.ts.map → insight-report-CXd8VBDR.d.ts.map} +1 -1
  66. package/dist/{integrity-CKxosZ5Z.d.ts → integrity-B-MLFz0I.d.ts} +2 -2
  67. package/dist/{integrity-CKxosZ5Z.d.ts.map → integrity-B-MLFz0I.d.ts.map} +1 -1
  68. package/dist/ledger-core/index.js +1 -1
  69. package/dist/{ledger-core-t6sItivm.js → ledger-core-C0Yx1I14.js} +220 -27
  70. package/dist/ledger-core-C0Yx1I14.js.map +1 -0
  71. package/dist/{llm-client-DKB25jV8.js → llm-client-Cj3c7PEm.js} +5 -5
  72. package/dist/llm-client-Cj3c7PEm.js.map +1 -0
  73. package/dist/meta-eval/index.d.ts +2 -2
  74. package/dist/multishot/index.d.ts +2 -2
  75. package/dist/openapi.json +1 -1
  76. package/dist/{proposal-findings-DCawte-y.js → proposal-findings-2GIUo1et.js} +2 -68
  77. package/dist/proposal-findings-2GIUo1et.js.map +1 -0
  78. package/dist/{registry-BdM7SuTr.d.ts → registry-C4yJTza7.d.ts} +60 -6
  79. package/dist/registry-C4yJTza7.d.ts.map +1 -0
  80. package/dist/{release-report-CofgVNZt.d.ts → release-report-CoyvyLBs.d.ts} +3 -3
  81. package/dist/{release-report-CofgVNZt.d.ts.map → release-report-CoyvyLBs.d.ts.map} +1 -1
  82. package/dist/{replay-Bju0T8Ls.js → replay-Cb-4Vf0k.js} +8 -7
  83. package/dist/replay-Cb-4Vf0k.js.map +1 -0
  84. package/dist/{replay-K8FaC0CB.d.ts → replay-DbIYwso6.d.ts} +7 -7
  85. package/dist/{replay-K8FaC0CB.d.ts.map → replay-DbIYwso6.d.ts.map} +1 -1
  86. package/dist/reporting.d.ts +4 -4
  87. package/dist/{researcher-Da0Wj-bt.d.ts → researcher-BCeOEjtR.d.ts} +5 -5
  88. package/dist/{researcher-Da0Wj-bt.d.ts.map → researcher-BCeOEjtR.d.ts.map} +1 -1
  89. package/dist/{reward-hacking-CQ3hTCO3.d.ts → reward-hacking-sE2l_NV6.d.ts} +2 -2
  90. package/dist/{reward-hacking-CQ3hTCO3.d.ts.map → reward-hacking-sE2l_NV6.d.ts.map} +1 -1
  91. package/dist/rl.d.ts +5 -5
  92. package/dist/rl.js +1 -1
  93. package/dist/rollout/index.d.ts +1 -1
  94. package/dist/{rubric-predictive-validity-C4sztLR3.d.ts → rubric-predictive-validity-w2klGv1u.d.ts} +2 -2
  95. package/dist/{rubric-predictive-validity-C4sztLR3.d.ts.map → rubric-predictive-validity-w2klGv1u.d.ts.map} +1 -1
  96. package/dist/{run-evidence-BDIircdA.d.ts → run-evidence-CbE0A8Xg.d.ts} +3 -3
  97. package/dist/{run-evidence-BDIircdA.d.ts.map → run-evidence-CbE0A8Xg.d.ts.map} +1 -1
  98. package/dist/{run-record-BPCa2rQ8.d.ts → run-record-DwHMk1Ai.d.ts} +2 -2
  99. package/dist/{run-record-BPCa2rQ8.d.ts.map → run-record-DwHMk1Ai.d.ts.map} +1 -1
  100. package/dist/{semantic-concept-judge-Bz64IckK.js → semantic-concept-judge-DYXDPZW0.js} +11 -5
  101. package/dist/semantic-concept-judge-DYXDPZW0.js.map +1 -0
  102. package/dist/{server-KjXZZUDX.js → server-DLEvyW2z.js} +3 -3
  103. package/dist/{server-KjXZZUDX.js.map → server-DLEvyW2z.js.map} +1 -1
  104. package/dist/single-run-lock-D_bS5xhj.js +318 -0
  105. package/dist/single-run-lock-D_bS5xhj.js.map +1 -0
  106. package/dist/{skill-usage-CFDLLlhF.d.ts → skill-usage-Bv3G4VkA.d.ts} +18 -8
  107. package/dist/skill-usage-Bv3G4VkA.d.ts.map +1 -0
  108. package/dist/{skillopt-optimization-method-f4o9sUT4.js → skillopt-optimization-method-CjKMZy0d.js} +7 -182
  109. package/dist/skillopt-optimization-method-CjKMZy0d.js.map +1 -0
  110. package/dist/{skillopt-optimization-method-BpbnlvAZ.d.ts → skillopt-optimization-method-CzfnA8O-.d.ts} +10 -10
  111. package/dist/{skillopt-optimization-method-BpbnlvAZ.d.ts.map → skillopt-optimization-method-CzfnA8O-.d.ts.map} +1 -1
  112. package/dist/{statistics-_7P642CN.d.ts → statistics-mf70aXKp.d.ts} +2 -2
  113. package/dist/{statistics-_7P642CN.d.ts.map → statistics-mf70aXKp.d.ts.map} +1 -1
  114. package/dist/{tools-DZk2Jn64.js → store-otlp-BenKynPE.js} +4 -192
  115. package/dist/store-otlp-BenKynPE.js.map +1 -0
  116. package/dist/{summary-report-DHipz9Kx.d.ts → summary-report-BKinV4yD.d.ts} +3 -3
  117. package/dist/{summary-report-DHipz9Kx.d.ts.map → summary-report-BKinV4yD.d.ts.map} +1 -1
  118. package/dist/tools-DZGdROtG.js +255 -0
  119. package/dist/tools-DZGdROtG.js.map +1 -0
  120. package/dist/traces.d.ts +5 -5
  121. package/dist/traces.js +4 -3
  122. package/dist/{types-CTvKfr5F.d.ts → types-5q2T25iW.d.ts} +2 -2
  123. package/dist/{types-CTvKfr5F.d.ts.map → types-5q2T25iW.d.ts.map} +1 -1
  124. package/dist/{types-CKswbJGO.d.ts → types-BtJhn8v6.d.ts} +4 -4
  125. package/dist/{types-CKswbJGO.d.ts.map → types-BtJhn8v6.d.ts.map} +1 -1
  126. package/dist/{types-CTGbIm57.d.ts → types-zFYez3PK.d.ts} +5 -5
  127. package/dist/{types-CTGbIm57.d.ts.map → types-zFYez3PK.d.ts.map} +1 -1
  128. package/dist/wire/index.d.ts +3 -3
  129. package/dist/wire/index.js +1 -1
  130. package/docs/trace-analysis.md +123 -3
  131. package/package.json +5 -3
  132. package/dist/benchmark-CHX4orG7.d.ts.map +0 -1
  133. package/dist/benchmark-YDrpumqB.js.map +0 -1
  134. package/dist/campaign-lgObcHFC.js.map +0 -1
  135. package/dist/concurrency-MUjT7VjM.js +0 -109
  136. package/dist/concurrency-MUjT7VjM.js.map +0 -1
  137. package/dist/cost-ledger-D-5_-dhi.js.map +0 -1
  138. package/dist/default-registry-CLXbRt0f.js.map +0 -1
  139. package/dist/default-registry-Dc5D_Loc.d.ts.map +0 -1
  140. package/dist/feedback-trajectory-N_F0PwHz.d.ts.map +0 -1
  141. package/dist/index-C-Pr4OWg.d.ts.map +0 -1
  142. package/dist/ledger-core-t6sItivm.js.map +0 -1
  143. package/dist/llm-client-DKB25jV8.js.map +0 -1
  144. package/dist/proposal-findings-DCawte-y.js.map +0 -1
  145. package/dist/registry-BdM7SuTr.d.ts.map +0 -1
  146. package/dist/replay-Bju0T8Ls.js.map +0 -1
  147. package/dist/semantic-concept-judge-Bz64IckK.js.map +0 -1
  148. package/dist/skill-usage-CFDLLlhF.d.ts.map +0 -1
  149. package/dist/skillopt-optimization-method-f4o9sUT4.js.map +0 -1
  150. package/dist/tools-DZk2Jn64.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"tools-DZk2Jn64.js","names":[],"sources":["../src/trace/otlp-attributes.ts","../src/trace-analyst/otlp-span.ts","../src/trace-analyst/errors.ts","../src/trace-analyst/shared-abortable-task.ts","../src/trace-analyst/store-contract.ts","../src/trace-analyst/types.ts","../src/trace-analyst/store-bounds.ts","../src/trace-analyst/store-schemas.ts","../src/trace-analyst/store-boundary.ts","../src/trace-analyst/store-otlp.ts","../src/trace-analyst/loop.ts","../src/trace-analyst/tools.ts"],"sourcesContent":["/** Canonical OpenInference-over-OTLP attribute vocabulary used at the trace boundary. */\n\nimport {\n INPUT_VALUE,\n LLM_MODEL_ATTR_KEYS,\n OUTPUT_VALUE,\n SPAN_KIND_ATTR_KEYS,\n TOOL_ARGS_CAPTURED,\n TOOL_LATENCY_MS,\n TOOL_NAME,\n TOOL_NAME_ATTR_KEYS,\n} from './attribute-vocabulary'\nimport type { ToolSpan } from './schema'\n\nexport * from './attribute-vocabulary'\n\nconst TOOL_SPAN_ATTRIBUTE_KEYS = [\n TOOL_NAME,\n TOOL_ARGS_CAPTURED,\n TOOL_LATENCY_MS,\n INPUT_VALUE,\n OUTPUT_VALUE,\n] as const\n\nexport type ToolSpanOtlpInput = Pick<\n ToolSpan,\n 'toolName' | 'args' | 'argsCaptured' | 'result' | 'latencyMs'\n>\n\nexport type OtlpSpanRole =\n | 'AGENT'\n | 'CHAIN'\n | 'EVALUATOR'\n | 'GUARDRAIL'\n | 'LLM'\n | 'SPAN'\n | 'TOOL'\n | 'UNKNOWN'\n\nexport interface OtlpSpanRoleInput {\n name: string\n attributes: Record<string, unknown>\n kind?: string | null\n}\n\nconst EXPLICIT_SPAN_ROLES = new Set<OtlpSpanRole>([\n 'AGENT',\n 'CHAIN',\n 'EVALUATOR',\n 'GUARDRAIL',\n 'LLM',\n 'SPAN',\n 'TOOL',\n])\n\n/**\n * Classify a span once for both measurement and error accounting.\n * An explicit OpenInference kind wins; untyped spans use the same tool and\n * model signals in online and offline intake.\n */\nexport function classifyOtlpSpanRole(input: OtlpSpanRoleInput): OtlpSpanRole {\n const explicitKind = input.kind ?? firstStringAttribute(input.attributes, SPAN_KIND_ATTR_KEYS)\n if (explicitKind) {\n const normalized = explicitKind.toUpperCase() as OtlpSpanRole\n if (EXPLICIT_SPAN_ROLES.has(normalized)) return normalized\n }\n\n if (\n firstStringAttribute(input.attributes, TOOL_NAME_ATTR_KEYS) !== undefined ||\n /^(?:function|tool)[.:/]/i.test(input.name)\n ) {\n return 'TOOL'\n }\n\n const spanType = input.attributes['span.type']\n if (\n (typeof spanType === 'string' && spanType.toLowerCase() === 'llm_request') ||\n /(?:^|[.:/_-])(?:chat[._-]?completions?|llm)(?:$|[.:/_-])/i.test(input.name) ||\n firstStringAttribute(input.attributes, LLM_MODEL_ATTR_KEYS) !== undefined ||\n typeof input.attributes['gen_ai.operation.name'] === 'string'\n ) {\n return 'LLM'\n }\n\n return 'UNKNOWN'\n}\n\nexport function isOtlpModelCall(input: OtlpSpanRoleInput): boolean {\n return classifyOtlpSpanRole(input) === 'LLM'\n}\n\nfunction toolSpanOtlpAttributes(\n span: ToolSpanOtlpInput,\n): Record<string, string | number | boolean> {\n const argsCaptured = span.argsCaptured !== false\n const attributes: Record<string, string | number | boolean> = {\n [TOOL_NAME]: span.toolName,\n [TOOL_ARGS_CAPTURED]: argsCaptured,\n }\n if (span.latencyMs !== undefined) attributes[TOOL_LATENCY_MS] = span.latencyMs\n if (argsCaptured) attributes[INPUT_VALUE] = stringifyTraceValue(span.args)\n if (span.result !== undefined) attributes[OUTPUT_VALUE] = stringifyTraceValue(span.result)\n return attributes\n}\n\nexport function applyToolSpanOtlpAttributes(\n attributes: Record<string, unknown>,\n span: ToolSpanOtlpInput,\n): void {\n for (const key of TOOL_SPAN_ATTRIBUTE_KEYS) delete attributes[key]\n Object.assign(attributes, toolSpanOtlpAttributes(span))\n}\n\nexport function traceSpanKindToOpenInferenceKind(kind: string): string {\n switch (kind) {\n case 'llm':\n return 'LLM'\n case 'tool':\n return 'TOOL'\n case 'retrieval':\n return 'CHAIN'\n case 'judge':\n return 'EVALUATOR'\n case 'sandbox':\n return 'CHAIN'\n case 'agent':\n return 'AGENT'\n default:\n return 'SPAN'\n }\n}\n\nfunction firstStringAttribute(\n attributes: Record<string, unknown>,\n keys: readonly string[],\n): string | undefined {\n for (const key of keys) {\n const value = attributes[key]\n if (typeof value === 'string' && value.length > 0) return value\n }\n return undefined\n}\n\nfunction stringifyTraceValue(value: unknown): string {\n if (value === undefined) return 'null'\n if (typeof value === 'string') return value\n try {\n return JSON.stringify(value) ?? String(value)\n } catch {\n return String(value)\n }\n}\n","/**\n * Canonical OTLP-flat-line readers shared by every consumer of the\n * OTLP-JSONL wire shape (one OTLP span per line; the form\n * `flattenOtlpExportToNdjson` produces and the form AppWorld / HALO\n * emit via their OpenInference OTLP exporter).\n *\n * `OtlpFileTraceStore` indexes spans with these; `otlpToRunRecords`\n * aggregates spans into `RunRecord`s with the same readers. One parser,\n * one vocabulary — a divergence between the analyst's view of a trace and\n * the RunRecord projected from it is a class of bug this consolidation\n * removes by construction.\n *\n * Vocabulary. The readers understand BOTH dialects that appear in the\n * wild:\n * - the substrate's own `llm.*` / `tool.*` / `span.kind` attributes\n * (`flattenSpanAttributes` in `trace/otel.ts`), and\n * - the OpenInference / inference-export attributes AppWorld / HALO\n * emit (`openinference.span.kind`, `inference.observation_kind`,\n * `inference.llm.input_tokens`, `llm.token_count.prompt`, …).\n *\n * Pure, no I/O.\n */\n\nimport {\n LLM_MODEL_ATTR_KEYS,\n SPAN_KIND_ATTR_KEYS,\n TOOL_NAME_ATTR_KEYS,\n} from '../trace/otlp-attributes'\nimport type { TraceAnalystSpanKind, TraceAnalystSpanStatus } from './types'\n\n/**\n * The structural fields a flat OTLP-JSONL line projects to. `attributes`\n * is the merged resource+span attribute map (span overrides resource);\n * the named fields are the pivots every reader of a trace needs without\n * paying the full attribute materialisation.\n */\nexport interface ProjectedOtlpSpan {\n trace_id: string\n span_id: string\n parent_span_id: string | null\n name: string\n kind: TraceAnalystSpanKind\n start_time: string\n end_time: string\n duration_ms: number\n status: TraceAnalystSpanStatus\n status_message: string | undefined\n service_name: string | null\n agent_name: string | null\n model_name: string | null\n tool_name: string | null\n /** Merged resource + span attributes, span winning on overlap. */\n attributes: Record<string, unknown>\n}\n\n/**\n * Project one parsed OTLP-JSONL object to `ProjectedOtlpSpan`, or `null`\n * when the line is missing the mandatory `trace_id` + `span_id`.\n */\nexport function projectOtlpFlatLine(raw: Record<string, unknown>): ProjectedOtlpSpan | null {\n const trace_id = stringField(raw, 'trace_id') ?? stringField(raw, 'traceId')\n const span_id = stringField(raw, 'span_id') ?? stringField(raw, 'spanId')\n if (!trace_id || !span_id) return null\n\n const rawParentId = stringField(raw, 'parent_span_id') ?? stringField(raw, 'parentSpanId') ?? null\n const parent_id = normalizeParentSpanId(trace_id, span_id, rawParentId)\n const name = stringField(raw, 'name') ?? 'unknown'\n const start_time = stringField(raw, 'start_time') ?? stringField(raw, 'startTime') ?? ''\n const end_time = stringField(raw, 'end_time') ?? stringField(raw, 'endTime') ?? start_time\n\n const status = readOtlpStatus(raw)\n const attributes = extractOtlpAttributes(raw)\n\n const service_name =\n asString(attributes['service.name']) ??\n asString(attributes['resource.attributes.service.name']) ??\n null\n const agent_name =\n asString(attributes['agent.name']) ??\n asString(attributes['inference.agent.name']) ??\n asString(attributes['inference.agent_name']) ??\n null\n const model_name = firstStringAttr(attributes, LLM_MODEL_ATTR_KEYS)\n const tool_name = firstStringAttr(attributes, TOOL_NAME_ATTR_KEYS)\n\n const kind = inferOtlpKind(attributes)\n\n let duration_ms = 0\n if (start_time && end_time) {\n const a = spanEpochMillis(start_time)\n const b = spanEpochMillis(end_time)\n if (a !== null && b !== null) duration_ms = Math.max(0, b - a)\n }\n\n return {\n trace_id,\n span_id,\n parent_span_id: parent_id && parent_id.length > 0 ? parent_id : null,\n name,\n kind,\n start_time,\n end_time,\n duration_ms,\n status: status.code,\n status_message: status.message,\n service_name,\n agent_name,\n model_name,\n tool_name,\n attributes,\n }\n}\n\nfunction normalizeParentSpanId(\n traceId: string,\n spanId: string,\n parentId: string | null,\n): string | null {\n if (!parentId) return null\n const prefix = `${traceId}:`\n return spanId.startsWith(prefix) && !parentId.startsWith(prefix)\n ? `${prefix}${parentId}`\n : parentId\n}\n\nexport function readOtlpStatus(raw: Record<string, unknown>): {\n code: TraceAnalystSpanStatus\n message: string | undefined\n} {\n const status = raw.status\n if (status && typeof status === 'object' && !Array.isArray(status)) {\n const codeRaw = (status as Record<string, unknown>).code\n const code: TraceAnalystSpanStatus =\n codeRaw === 'STATUS_CODE_OK' || codeRaw === 'OK'\n ? 'OK'\n : codeRaw === 'STATUS_CODE_ERROR' || codeRaw === 'ERROR'\n ? 'ERROR'\n : 'UNSET'\n const messageRaw = (status as Record<string, unknown>).message\n const message = typeof messageRaw === 'string' && messageRaw.length > 0 ? messageRaw : undefined\n return { code, message }\n }\n return { code: 'UNSET', message: undefined }\n}\n\nexport function inferOtlpKind(attrs: Record<string, unknown>): TraceAnalystSpanKind {\n const opik = firstStringAttr(attrs, SPAN_KIND_ATTR_KEYS)\n if (opik) {\n const upper = opik.toUpperCase()\n if (\n upper === 'AGENT' ||\n upper === 'LLM' ||\n upper === 'TOOL' ||\n upper === 'CHAIN' ||\n upper === 'EVALUATOR' ||\n upper === 'GUARDRAIL' ||\n upper === 'SPAN'\n ) {\n return upper as TraceAnalystSpanKind\n }\n }\n return 'UNKNOWN'\n}\n\n/**\n * Flatten OTLP `attributes` + `resource.attributes` into a single\n * dotted-key map. Span attributes override resource attributes when keys\n * overlap. Nested objects/arrays are preserved as-is.\n */\nexport function extractOtlpAttributes(raw: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const resource = raw.resource\n if (resource && typeof resource === 'object' && !Array.isArray(resource)) {\n const ra = (resource as Record<string, unknown>).attributes\n if (ra && typeof ra === 'object' && !Array.isArray(ra)) {\n for (const [k, v] of Object.entries(ra as Record<string, unknown>)) {\n out[k] = v\n }\n }\n }\n const spanAttrs = raw.attributes\n if (spanAttrs && typeof spanAttrs === 'object' && !Array.isArray(spanAttrs)) {\n for (const [k, v] of Object.entries(spanAttrs as Record<string, unknown>)) {\n out[k] = v\n }\n }\n return out\n}\n\nexport function stringField(raw: Record<string, unknown>, key: string): string | undefined {\n const v = raw[key]\n return typeof v === 'string' ? v : undefined\n}\n\nexport function asString(v: unknown): string | null {\n return typeof v === 'string' && v.length > 0 ? v : null\n}\n\n/** First non-empty string value across a list of candidate attribute keys. */\nexport function firstStringAttr(\n attrs: Record<string, unknown>,\n keys: readonly string[],\n): string | null {\n for (const k of keys) {\n const s = asString(attrs[k])\n if (s !== null) return s\n }\n return null\n}\n\n/**\n * Parse a span timestamp to epoch millis, or null when empty/unparseable. The\n * OTLP readers accept BOTH ISO-8601 and epoch-millis-string dialects, so raw\n * string comparison (`<`, `localeCompare`) mis-orders across dialects and\n * `Date.parse` returns NaN for a bare epoch-millis string.\n */\nexport function spanEpochMillis(ts: string | undefined | null): number | null {\n if (!ts) return null\n if (/^\\d+$/.test(ts)) return Number(ts)\n const n = Date.parse(ts)\n return Number.isNaN(n) ? null : n\n}\n\n/**\n * Order comparator for span timestamps across mixed ISO/epoch dialects.\n * Unparseable timestamps sort as epoch 0 (earliest), never NaN (which would\n * make the sort non-deterministic).\n */\nexport function compareSpanTime(a: string, b: string): number {\n return (spanEpochMillis(a) ?? 0) - (spanEpochMillis(b) ?? 0)\n}\n","import {\n AgentEvalError,\n CaptureIntegrityError,\n LimitExceededError,\n NotFoundError,\n ValidationError,\n} from '../errors'\n\n/** Invalid trace-tool arguments, including malformed filters and regexes. */\nexport class TraceAnalysisValidationError extends ValidationError {\n declare readonly code: 'validation'\n}\n\n/** A trace read cannot fit within a documented count or byte limit. */\nexport class TraceAnalysisLimitError extends LimitExceededError {\n declare readonly code: 'limit_exceeded'\n readonly operation: string\n readonly actual: number\n readonly limit: number\n\n constructor(operation: string, actual: number, limit: number, message?: string) {\n super(message ?? `${operation} produced ${actual}, over the limit of ${limit}`)\n this.operation = operation\n this.actual = actual\n this.limit = limit\n }\n}\n\n/** A supplied store returned a shape that violates the trace read contract. */\nexport class TraceAnalysisStoreContractError extends AgentEvalError {\n declare readonly code: 'backend_integrity'\n readonly operation: string\n\n constructor(operation: string, message: string, options?: { cause?: unknown }) {\n super('backend_integrity', `${operation}: ${message}`, options)\n this.operation = operation\n }\n}\n\nexport class TraceFileMissingError extends NotFoundError {\n declare readonly code: 'not_found'\n readonly path: string\n\n constructor(path: string) {\n super(`trace file not found: ${path}`)\n this.path = path\n }\n}\n\nexport class TraceFileTooLargeError extends TraceAnalysisLimitError {\n readonly path: string\n readonly size_bytes: number\n readonly max_bytes: number\n\n constructor(path: string, size_bytes: number, max_bytes: number) {\n super(\n 'OtlpFileTraceStore.readBuffer',\n size_bytes,\n max_bytes,\n `trace file ${path} is ${size_bytes} bytes, over the ${max_bytes}-byte limit; ` +\n 'raise OtlpFileTraceStoreOptions.maxFileBytes or pre-split the file',\n )\n this.path = path\n this.size_bytes = size_bytes\n this.max_bytes = max_bytes\n }\n}\n\nexport class TraceFileMalformedError extends CaptureIntegrityError {\n readonly path: string\n readonly line_number: number\n readonly byte_offset: number\n\n constructor(path: string, line_number: number, byte_offset: number, cause?: unknown) {\n super(`malformed trace row in ${path} at line ${line_number}, byte ${byte_offset}`, { cause })\n this.path = path\n this.line_number = line_number\n this.byte_offset = byte_offset\n }\n}\n\nexport class TraceNotFoundError extends NotFoundError {\n declare readonly code: 'not_found'\n readonly trace_id: string\n\n constructor(trace_id: string) {\n super(`trace not found: ${trace_id}`)\n this.trace_id = trace_id\n }\n}\n\nexport class SpanNotFoundError extends NotFoundError {\n declare readonly code: 'not_found'\n readonly trace_id: string\n readonly span_id: string\n\n constructor(trace_id: string, span_id: string) {\n super(`span ${span_id} not found in trace ${trace_id}`)\n this.trace_id = trace_id\n this.span_id = span_id\n }\n}\n","export interface SharedAbortableTask<T> {\n controller: AbortController\n promise: Promise<T>\n consumers: number\n settled: boolean\n}\n\nexport function createSharedAbortableTask<T>(\n factory: (signal: AbortSignal) => Promise<T>,\n): SharedAbortableTask<T> {\n const controller = new AbortController()\n const task: SharedAbortableTask<T> = {\n controller,\n promise: factory(controller.signal),\n consumers: 0,\n settled: false,\n }\n void task.promise.then(\n () => {\n task.settled = true\n },\n () => {\n task.settled = true\n },\n )\n return task\n}\n\nexport function waitForSharedTask<T>(\n task: SharedAbortableTask<T>,\n signal: AbortSignal | undefined,\n): Promise<T> {\n signal?.throwIfAborted()\n task.consumers += 1\n\n return new Promise<T>((resolve, reject) => {\n let finished = false\n const finish = (callback: () => void): void => {\n if (finished) return\n finished = true\n signal?.removeEventListener('abort', onAbort)\n task.consumers -= 1\n callback()\n }\n const onAbort = (): void => {\n finish(() => {\n reject(signal?.reason)\n if (!task.settled && task.consumers === 0) {\n task.controller.abort(signal?.reason)\n }\n })\n }\n\n signal?.addEventListener('abort', onAbort, { once: true })\n task.promise.then(\n (value) => finish(() => resolve(value)),\n (error: unknown) => finish(() => reject(error)),\n )\n if (signal?.aborted) onAbort()\n })\n}\n","import type {\n DatasetOverview,\n QueryTracesPage,\n SearchSpanResult,\n SearchTraceResult,\n TraceAnalystByteBudgets,\n TraceAnalystFilters,\n ViewSpansResult,\n ViewTraceResult,\n} from './types'\n\nexport const TRACE_ANALYSIS_LIMITS = {\n sampleTraceIds: 20,\n queryTraces: 200,\n viewSpans: 100,\n searchMatches: 500,\n filterValues: 100,\n identifierCharacters: 256,\n regexCharacters: 4_096,\n minimumTextBudget: 64,\n} as const\n\nexport interface TraceAnalysisStoreContext {\n signal?: AbortSignal\n}\n\n/**\n * Storage adapter for trace reads.\n *\n * Bind third-party implementations with `createBoundedTraceAnalysisStore()`.\n * The binding validates every input and result, applies byte limits, and\n * forwards one cancellation signal through existence checks and reads.\n */\nexport interface TraceAnalysisStore {\n hasTrace(trace_id: string, context?: TraceAnalysisStoreContext): Promise<boolean>\n\n hasSpans(\n input: { trace_id: string; span_ids: readonly string[] },\n context?: TraceAnalysisStoreContext,\n ): Promise<string[]>\n\n getOverview(\n filters?: TraceAnalystFilters,\n context?: TraceAnalysisStoreContext,\n ): Promise<DatasetOverview>\n\n queryTraces(\n input: { filters?: TraceAnalystFilters; limit: number; offset?: number },\n context?: TraceAnalysisStoreContext,\n ): Promise<QueryTracesPage>\n\n countTraces(filters?: TraceAnalystFilters, context?: TraceAnalysisStoreContext): Promise<number>\n\n viewTrace(\n input: {\n trace_id: string\n per_attribute_byte_cap?: number\n },\n context?: TraceAnalysisStoreContext,\n ): Promise<ViewTraceResult>\n\n viewSpans(\n input: {\n trace_id: string\n span_ids: readonly string[]\n per_attribute_byte_cap?: number\n },\n context?: TraceAnalysisStoreContext,\n ): Promise<ViewSpansResult>\n\n searchTrace(\n input: {\n trace_id: string\n regex_pattern: string\n max_matches?: number\n },\n context?: TraceAnalysisStoreContext,\n ): Promise<SearchTraceResult>\n\n searchSpan(\n input: {\n trace_id: string\n span_id: string\n regex_pattern: string\n max_matches?: number\n },\n context?: TraceAnalysisStoreContext,\n ): Promise<SearchSpanResult>\n}\n\nexport interface BoundedTraceAnalysisStoreOptions {\n budgets?: Partial<TraceAnalystByteBudgets>\n}\n","/**\n * Shared types for the trace-analyst module.\n *\n * Wire format. The store interface speaks `OtlpSpanLike` rows — one JSONL\n * line per span, OTLP-shaped. We do NOT depend on a specific tracing\n * vendor at the type level. Adapter\n * layers map upstream shapes onto this interface.\n *\n * Design constraint. Every read operation that can return arbitrary\n * payload must carry a byte budget so the agent's tool result stays\n * bounded regardless of input trace size. Oversized responses\n * substitute a deterministic summary instead of bytes — see\n * `ViewTraceOversized`.\n */\n\n/** OTLP span kind (subset we actually use). */\nexport type TraceAnalystSpanKind =\n | 'AGENT'\n | 'LLM'\n | 'TOOL'\n | 'CHAIN'\n | 'EVALUATOR'\n | 'GUARDRAIL'\n | 'SPAN'\n | 'UNKNOWN'\n\nexport type TraceAnalystSpanStatus = 'OK' | 'ERROR' | 'UNSET'\n\n/** Subset of OTLP span fields the analyst exposes to the agent. The\n * store's job is to project upstream's full span shape down to this\n * view — the analyst never sees vendor extensions directly. */\nexport interface TraceAnalystSpan {\n trace_id: string\n span_id: string\n parent_span_id: string | null\n name: string\n kind: TraceAnalystSpanKind\n start_time: string\n end_time: string\n duration_ms: number\n status: TraceAnalystSpanStatus\n status_message?: string\n service_name: string | null\n agent_name: string | null\n model_name: string | null\n tool_name: string | null\n /** Raw JSON-serialisable attribute map. May contain large strings;\n * callers must respect the per-attribute byte cap. */\n attributes: Record<string, unknown>\n}\n\nexport interface TraceAnalystTraceSummary {\n trace_id: string\n service_name: string | null\n agent_name: string | null\n span_count: number\n has_errors: boolean\n start_time: string\n end_time: string\n duration_ms: number\n raw_jsonl_bytes: number\n models: string[]\n tools: string[]\n}\n\nexport interface TraceAnalystFilters {\n /** Restrict to traces that contain at least one error span. */\n has_errors?: boolean\n /** Match if any span's `service.name` is in this list. */\n service_names?: string[]\n /** Match if any span's `agent.name` is in this list. */\n agent_names?: string[]\n /** Match if any LLM span's `llm.model_name` is in this list. */\n model_names?: string[]\n /** Match if any tool span's `tool.name` is in this list. */\n tool_names?: string[]\n /** ISO-8601 lower bound on the trace's earliest start time. */\n start_time_after?: string\n /** ISO-8601 upper bound on the trace's earliest start time. */\n start_time_before?: string\n /** Single regex applied to raw JSONL bytes for the trace. Opt-in;\n * expensive on large datasets. Use the indexed filters above first. */\n regex_pattern?: string\n}\n\n/** One distinct error signature across the dataset — the deterministic unit of\n * failure coverage. Signatures normalize volatile tokens (digits, hex/uuids,\n * paths, durations) out of the span `status_message` so semantically identical\n * failures collapse into one cluster. An analyst that accounts for every\n * cluster has, by construction, covered every distinct failure mode. */\nexport interface ErrorCluster {\n /** Normalized status_message — the cluster key. */\n signature: string\n /** A verbatim, un-normalized exemplar message (for exact-string citation). */\n status_message_sample: string\n /** The span name that most often carries this signature, if any. */\n span_name: string | null\n /** The tool that most often carries this signature, if any. */\n tool_name: string | null\n trace_count: number\n span_count: number\n /** trace_count / total error traces in the matched set (0..1). */\n prevalence: number\n /** Real trace ids carrying this signature (capped), passable to view/search. */\n exemplar_trace_ids: string[]\n /** Real span ids carrying this signature (capped). */\n exemplar_span_ids: string[]\n}\n\nexport interface DatasetOverview {\n total_traces: number\n raw_jsonl_bytes: number\n services: string[]\n agents: string[]\n models: string[]\n tool_names: string[]\n /** Up to 20 real trace ids the agent may pass to view/search tools. */\n sample_trace_ids: string[]\n errors: { trace_count: number; span_count: number }\n /** The COMPLETE deterministic error-signature population, sorted by\n * trace_count desc. This is the failure-coverage checklist: an analysis is\n * complete only when every cluster here is accounted for. Empty when the\n * matched set has no error spans. */\n error_clusters: ErrorCluster[]\n time_range: { earliest: string; latest: string } | null\n}\n\nexport interface QueryTracesPage {\n traces: TraceAnalystTraceSummary[]\n total: number\n has_more: boolean\n}\n\n/** Full-trace view. When the response would exceed the per-call byte\n * budget, `oversized` is populated INSTEAD of `spans` so the agent\n * knows to switch to `searchTrace` / `viewSpans`. */\nexport interface ViewTraceResult {\n trace_id: string\n spans?: TraceAnalystSpan[]\n oversized?: ViewTraceOversized\n}\n\nexport interface ViewTraceOversized {\n span_count: number\n /** Names with their counts, sorted desc. Capped at 20 entries. */\n top_span_names: Array<[string, number]>\n /** Largest single span body (bytes after attribute-cap projection). */\n span_response_bytes_max: number\n error_span_count: number\n}\n\nexport interface ViewSpansResult {\n trace_id: string\n spans: TraceAnalystSpan[]\n /** Number of requested span ids that were not found in the trace. */\n missing_span_ids: string[]\n /** Requested span ids that exist but did not fit in this response. */\n omitted_span_ids: string[]\n /** True exactly when `omitted_span_ids` contains continuation work. */\n has_more: boolean\n /** Number of attribute fields truncated to fit the per-attribute cap. */\n truncated_attribute_count: number\n}\n\nexport interface SpanMatchRecord {\n trace_id: string\n span_id: string\n span_name: string\n span_kind: TraceAnalystSpanKind\n /** JSON pointer-style path to the matched value, e.g.\n * `attributes.\"llm.input_messages\"[2].content`. */\n attribute_path: string\n matched_text: string\n context_before: string\n context_after: string\n match_offset: number\n}\n\nexport interface SearchTraceResult {\n trace_id: string\n hits: SpanMatchRecord[]\n has_more: boolean\n}\n\nexport interface SearchSpanResult {\n trace_id: string\n span_id: string\n hits: SpanMatchRecord[]\n has_more: boolean\n}\n\n/** Tunable byte budgets for bounded RLM tool output. */\nexport interface TraceAnalystByteBudgets {\n /** Max bytes any single tool response may emit. Hard ceiling enforced\n * by the store; oversized → summary. Default 150_000. */\n perCallByteCeiling: number\n /** Per-attribute string truncation cap on `viewTrace` (discovery scan).\n * Default 4096. */\n perAttributeViewBudget: number\n /** Per-attribute string truncation cap on `viewSpans` (surgical reads).\n * Default 16384. */\n perAttributeSpanBudget: number\n /** Per-attribute cap on a single match record's `matched_text` and\n * context window. Default 1024. */\n perMatchTextBudget: number\n}\n\nexport const DEFAULT_TRACE_ANALYST_BUDGETS: TraceAnalystByteBudgets = {\n perCallByteCeiling: 150_000,\n perAttributeViewBudget: 4_096,\n perAttributeSpanBudget: 16_384,\n perMatchTextBudget: 1_024,\n}\n\n/** Marker substituted in place of truncated string payloads. Callers\n * parsing tool output can detect it deterministically. */\nexport const TRACE_ANALYST_TRUNCATION_MARKER_PREFIX = '[trace-analyst truncated:'\n","import { RE2JS } from 're2js'\n\nimport {\n TraceAnalysisLimitError,\n TraceAnalysisStoreContractError,\n TraceAnalysisValidationError,\n} from './errors'\nimport { TRACE_ANALYSIS_LIMITS } from './store-contract'\nimport type {\n DatasetOverview,\n QueryTracesPage,\n SearchSpanResult,\n SearchTraceResult,\n SpanMatchRecord,\n TraceAnalystByteBudgets,\n TraceAnalystSpan,\n ViewSpansResult,\n ViewTraceOversized,\n ViewTraceResult,\n} from './types'\nimport { DEFAULT_TRACE_ANALYST_BUDGETS } from './types'\n\nexport function resolveTraceBudgets(\n overrides: Partial<TraceAnalystByteBudgets> | undefined,\n): TraceAnalystByteBudgets {\n const budgets = { ...DEFAULT_TRACE_ANALYST_BUDGETS, ...overrides }\n validateInteger(budgets.perCallByteCeiling, 'perCallByteCeiling', 1)\n for (const name of [\n 'perAttributeViewBudget',\n 'perAttributeSpanBudget',\n 'perMatchTextBudget',\n ] as const) {\n validateInteger(budgets[name], name, TRACE_ANALYSIS_LIMITS.minimumTextBudget)\n }\n return budgets\n}\n\nexport function boundOverview(result: DatasetOverview, byteCeiling: number): DatasetOverview {\n if (result.sample_trace_ids.length > result.total_traces) {\n throw contractError('getOverview', 'sample_trace_ids contains more entries than total_traces')\n }\n if (result.errors.trace_count > result.total_traces) {\n throw contractError('getOverview', 'errors.trace_count exceeds total_traces')\n }\n return withinByteCeiling('getOverview', result, byteCeiling)\n}\n\nexport function boundTracePage(\n result: QueryTracesPage,\n input: { limit: number; offset: number },\n byteCeiling: number,\n): QueryTracesPage {\n if (result.traces.length > input.limit) {\n throw contractError(\n 'queryTraces',\n `store returned ${result.traces.length} traces for limit ${input.limit}`,\n )\n }\n if (result.total < input.offset + result.traces.length) {\n throw contractError(\n 'queryTraces',\n `total ${result.total} is smaller than the returned page ending at ${\n input.offset + result.traces.length\n }`,\n )\n }\n if (result.has_more !== input.offset + result.traces.length < result.total) {\n throw contractError(\n 'queryTraces',\n 'has_more does not match the returned page position and total',\n )\n }\n if (result.has_more && result.traces.length === 0) {\n throw contractError('queryTraces', 'store reported more traces without returning any progress')\n }\n\n const traces: QueryTracesPage['traces'] = []\n for (const trace of result.traces) {\n const candidate = { traces: [...traces, trace], total: result.total, has_more: true }\n if (encodedBytes('queryTraces', candidate) > byteCeiling) break\n traces.push(trace)\n }\n if (result.traces.length > 0 && traces.length === 0) {\n throw responseItemTooLarge(\n 'queryTraces',\n { traces: [result.traces[0]], total: result.total, has_more: true },\n byteCeiling,\n )\n }\n return withinByteCeiling(\n 'queryTraces',\n {\n traces,\n total: result.total,\n has_more: result.has_more || traces.length < result.traces.length,\n },\n byteCeiling,\n )\n}\n\nexport function boundTraceView(\n result: ViewTraceResult,\n expectedTraceId: string,\n perAttributeCap: number,\n byteCeiling: number,\n): ViewTraceResult {\n requireEqual('viewTrace', 'trace_id', result.trace_id, expectedTraceId)\n if (result.oversized) {\n return withinByteCeiling('viewTrace', result, byteCeiling)\n }\n\n const spans = result.spans!.map((span) => {\n requireEqual('viewTrace', 'span.trace_id', span.trace_id, expectedTraceId)\n return truncateSpanAttributes('viewTrace', span, perAttributeCap).span\n })\n const full = { trace_id: expectedTraceId, spans }\n if (encodedBytes('viewTrace', full) <= byteCeiling) return full\n return withinByteCeiling(\n 'viewTrace',\n { trace_id: expectedTraceId, oversized: oversizedFromSpans(spans) },\n byteCeiling,\n )\n}\n\nexport function boundSpansView(\n result: ViewSpansResult,\n expectedTraceId: string,\n requested: readonly string[],\n existingSpanIds: ReadonlySet<string>,\n perAttributeCap: number,\n byteCeiling: number,\n): ViewSpansResult {\n requireEqual('viewSpans', 'trace_id', result.trace_id, expectedTraceId)\n const requestedSet = new Set(requested)\n const missing = checkedAccountingIds('missing_span_ids', result.missing_span_ids, requestedSet)\n const omitted = checkedAccountingIds('omitted_span_ids', result.omitted_span_ids, requestedSet)\n const missingSet = new Set(missing)\n const omittedSet = new Set(omitted)\n const expectedMissing = requested.filter((id) => !existingSpanIds.has(id))\n if (\n expectedMissing.length !== missing.length ||\n expectedMissing.some((id) => !missingSet.has(id))\n ) {\n throw contractError('viewSpans', 'missing_span_ids does not match the store existence checks')\n }\n if (result.has_more !== omitted.length > 0) {\n throw contractError(\n 'viewSpans',\n 'has_more must be true exactly when omitted_span_ids is non-empty',\n )\n }\n if (\n result.spans.length === 0 &&\n requested.some((id) => existingSpanIds.has(id) && omittedSet.has(id))\n ) {\n throw contractError(\n 'viewSpans',\n 'store omitted every existing requested span instead of returning progress or throwing a size error',\n )\n }\n\n const projected = new Map<string, { span: TraceAnalystSpan; truncations: number }>()\n for (const span of result.spans) {\n requireEqual('viewSpans', 'span.trace_id', span.trace_id, expectedTraceId)\n if (!requestedSet.has(span.span_id)) {\n throw contractError(\n 'viewSpans',\n `store returned unrequested span ${JSON.stringify(span.span_id)}`,\n )\n }\n if (missingSet.has(span.span_id) || omittedSet.has(span.span_id)) {\n throw contractError(\n 'viewSpans',\n `span ${JSON.stringify(span.span_id)} is both returned and unavailable`,\n )\n }\n if (projected.has(span.span_id)) {\n throw contractError(\n 'viewSpans',\n `store returned duplicate span ${JSON.stringify(span.span_id)}`,\n )\n }\n projected.set(span.span_id, truncateSpanAttributes('viewSpans', span, perAttributeCap))\n }\n for (const id of requested) {\n if (!missingSet.has(id) && !omittedSet.has(id) && !projected.has(id)) {\n throw contractError(\n 'viewSpans',\n `store did not account for requested span ${JSON.stringify(id)}`,\n )\n }\n }\n\n const spans: TraceAnalystSpan[] = []\n let addedTruncations = 0\n const build = (): ViewSpansResult => ({\n trace_id: expectedTraceId,\n spans,\n missing_span_ids: requested.filter((id) => missingSet.has(id)),\n omitted_span_ids: requested.filter((id) => omittedSet.has(id)),\n has_more: omittedSet.size > 0,\n truncated_attribute_count: result.truncated_attribute_count + addedTruncations,\n })\n withinByteCeiling('viewSpans', build(), byteCeiling)\n for (const id of requested) {\n const item = projected.get(id)\n if (!item) continue\n spans.push(item.span)\n omittedSet.delete(id)\n addedTruncations += item.truncations\n if (encodedBytes('viewSpans', build()) <= byteCeiling) continue\n spans.pop()\n omittedSet.add(id)\n addedTruncations -= item.truncations\n }\n if (projected.size > 0 && spans.length === 0) {\n const first = projected.values().next().value\n if (first) {\n throw responseItemTooLarge(\n 'viewSpans',\n {\n trace_id: expectedTraceId,\n spans: [first.span],\n missing_span_ids: [],\n omitted_span_ids: [],\n has_more: false,\n truncated_attribute_count: result.truncated_attribute_count + first.truncations,\n },\n byteCeiling,\n )\n }\n }\n return withinByteCeiling('viewSpans', build(), byteCeiling)\n}\n\nexport function boundTraceSearch(\n result: SearchTraceResult,\n expectedTraceId: string,\n maxMatches: number,\n budgets: TraceAnalystByteBudgets,\n): SearchTraceResult {\n requireEqual('searchTrace', 'trace_id', result.trace_id, expectedTraceId)\n const bounded = boundSearchHits('searchTrace', result, maxMatches, budgets, (hit) => {\n requireEqual('searchTrace', 'hit.trace_id', hit.trace_id, expectedTraceId)\n })\n return { trace_id: expectedTraceId, ...bounded }\n}\n\nexport function boundSpanSearch(\n result: SearchSpanResult,\n expectedTraceId: string,\n expectedSpanId: string,\n maxMatches: number,\n budgets: TraceAnalystByteBudgets,\n): SearchSpanResult {\n requireEqual('searchSpan', 'trace_id', result.trace_id, expectedTraceId)\n requireEqual('searchSpan', 'span_id', result.span_id, expectedSpanId)\n const bounded = boundSearchHits('searchSpan', result, maxMatches, budgets, (hit) => {\n requireEqual('searchSpan', 'hit.trace_id', hit.trace_id, expectedTraceId)\n requireEqual('searchSpan', 'hit.span_id', hit.span_id, expectedSpanId)\n })\n return { trace_id: expectedTraceId, span_id: expectedSpanId, ...bounded }\n}\n\nfunction boundSearchHits(\n operation: 'searchTrace' | 'searchSpan',\n result: Pick<SearchTraceResult, 'hits' | 'has_more'>,\n maxMatches: number,\n budgets: TraceAnalystByteBudgets,\n validateHit: (hit: SpanMatchRecord) => void,\n): Pick<SearchTraceResult, 'hits' | 'has_more'> {\n if (result.hits.length > maxMatches) {\n throw contractError(\n operation,\n `store returned ${result.hits.length} hits for max_matches ${maxMatches}`,\n )\n }\n if (result.has_more && result.hits.length === 0) {\n throw contractError(operation, 'store reported more matches without returning any progress')\n }\n\n const hits: SpanMatchRecord[] = []\n for (const raw of result.hits) {\n validateHit(raw)\n const hit = truncateMatchRecord(raw, budgets.perMatchTextBudget)\n const candidate = {\n hits: [...hits, hit],\n has_more: true,\n }\n if (encodedBytes(operation, candidate) > budgets.perCallByteCeiling) break\n hits.push(hit)\n }\n if (result.hits.length > 0 && hits.length === 0) {\n throw responseItemTooLarge(\n operation,\n {\n hits: [truncateMatchRecord(result.hits[0]!, budgets.perMatchTextBudget)],\n has_more: true,\n },\n budgets.perCallByteCeiling,\n )\n }\n return withinByteCeiling(\n operation,\n {\n hits,\n has_more: result.has_more || hits.length < result.hits.length,\n },\n budgets.perCallByteCeiling,\n )\n}\n\nfunction checkedAccountingIds(\n label: string,\n ids: readonly string[],\n requested: ReadonlySet<string>,\n): string[] {\n const seen = new Set<string>()\n for (const id of ids) {\n if (!requested.has(id)) {\n throw contractError('viewSpans', `${label} contains unrequested id ${JSON.stringify(id)}`)\n }\n if (seen.has(id)) {\n throw contractError('viewSpans', `${label} contains duplicate id ${JSON.stringify(id)}`)\n }\n seen.add(id)\n }\n return [...ids]\n}\n\nfunction truncateMatchRecord(record: SpanMatchRecord, cap: number): SpanMatchRecord {\n return {\n ...record,\n span_name: truncateForBudget(record.span_name, cap),\n attribute_path: truncateForBudget(record.attribute_path, cap),\n matched_text: truncateForBudget(record.matched_text, cap),\n context_before: truncateForBudget(record.context_before, cap),\n context_after: truncateForBudget(record.context_after, cap),\n }\n}\n\nfunction truncateSpanAttributes(\n operation: string,\n span: TraceAnalystSpan,\n cap: number,\n): { span: TraceAnalystSpan; truncations: number } {\n const attributes: Record<string, unknown> = {}\n let truncations = 0\n for (const [key, value] of Object.entries(span.attributes)) {\n if (typeof value === 'string') {\n const truncated = truncateForBudget(value, cap)\n if (truncated !== value) truncations += 1\n attributes[key] = truncated\n continue\n }\n if (value !== null && typeof value === 'object') {\n let json: string\n try {\n json = JSON.stringify(value)\n } catch (cause) {\n throw new TraceAnalysisStoreContractError(\n operation,\n `span attribute ${JSON.stringify(key)} is not JSON-serializable`,\n { cause },\n )\n }\n const truncated = truncateForBudget(json, cap)\n if (truncated !== json) {\n truncations += 1\n attributes[key] = truncated\n } else {\n attributes[key] = value\n }\n continue\n }\n attributes[key] = value\n }\n return { span: { ...span, attributes }, truncations }\n}\n\nfunction oversizedFromSpans(spans: readonly TraceAnalystSpan[]): ViewTraceOversized {\n const names = new Map<string, number>()\n let maxBytes = 0\n let errors = 0\n for (const span of spans) {\n names.set(span.name, (names.get(span.name) ?? 0) + 1)\n maxBytes = Math.max(maxBytes, encodedBytes('viewTrace', span))\n if (span.status === 'ERROR') errors += 1\n }\n return {\n span_count: spans.length,\n top_span_names: [...names.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, 20),\n span_response_bytes_max: maxBytes,\n error_span_count: errors,\n }\n}\n\nexport function compileSearchRegex(pattern: string): RE2JS {\n if (typeof pattern !== 'string' || pattern.length === 0) {\n throw new TraceAnalysisValidationError('regex_pattern must be a non-empty string')\n }\n let source = pattern\n let flags = RE2JS.MULTILINE\n if (source.startsWith('(?i)')) {\n source = source.slice(4)\n flags |= RE2JS.CASE_INSENSITIVE\n }\n try {\n return RE2JS.compile(source, flags)\n } catch (cause) {\n throw new TraceAnalysisValidationError(\n `regex_pattern is invalid: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause },\n )\n }\n}\n\nexport function truncateForBudget(value: string, byteCap: number): string {\n validateInteger(byteCap, 'byteCap', TRACE_ANALYSIS_LIMITS.minimumTextBudget)\n const original = Buffer.byteLength(value, 'utf8')\n if (original <= byteCap) return value\n\n const marker = `\\n[trace-analyst truncated: original ${original} bytes]`\n const contentCap = byteCap - Buffer.byteLength(marker, 'utf8')\n let cut = Math.max(0, Math.floor((value.length * contentCap) / original))\n while (cut > 0 && Buffer.byteLength(value.slice(0, cut), 'utf8') > contentCap) cut -= 1\n return `${value.slice(0, cut)}${marker}`\n}\n\nexport function validateInteger(\n value: unknown,\n label: string,\n minimum: number,\n maximum = Number.MAX_SAFE_INTEGER,\n): number {\n if (\n typeof value !== 'number' ||\n !Number.isSafeInteger(value) ||\n value < minimum ||\n value > maximum\n ) {\n throw new TraceAnalysisValidationError(\n `${label} must be an integer ${minimum}..${maximum}, got ${String(value)}`,\n )\n }\n return value\n}\n\nfunction requireEqual(operation: string, label: string, actual: string, expected: string): void {\n if (actual !== expected) {\n throw contractError(\n operation,\n `${label} ${JSON.stringify(actual)} does not match ${JSON.stringify(expected)}`,\n )\n }\n}\n\nfunction encodedBytes(operation: string, value: unknown): number {\n try {\n const encoded = JSON.stringify(value)\n if (encoded === undefined) throw new TypeError('JSON.stringify returned undefined')\n return Buffer.byteLength(encoded, 'utf8')\n } catch (cause) {\n if (cause instanceof TraceAnalysisStoreContractError) throw cause\n throw new TraceAnalysisStoreContractError(operation, 'store result is not JSON-serializable', {\n cause,\n })\n }\n}\n\nfunction withinByteCeiling<T>(operation: string, value: T, ceiling: number): T {\n const actual = encodedBytes(operation, value)\n if (actual > ceiling) {\n throw new TraceAnalysisLimitError(\n operation,\n actual,\n ceiling,\n `${operation} metadata requires ${actual} bytes, over the ${ceiling}-byte response limit`,\n )\n }\n return value\n}\n\nfunction responseItemTooLarge(\n operation: string,\n value: unknown,\n ceiling: number,\n): TraceAnalysisLimitError {\n const actual = encodedBytes(operation, value)\n return new TraceAnalysisLimitError(\n operation,\n actual,\n ceiling,\n `${operation} cannot fit one result item in the ${ceiling}-byte response limit`,\n )\n}\n\nfunction contractError(operation: string, message: string): TraceAnalysisStoreContractError {\n return new TraceAnalysisStoreContractError(operation, message)\n}\n","import { z } from 'zod'\nimport { TraceAnalysisStoreContractError, TraceAnalysisValidationError } from './errors'\nimport { TRACE_ANALYSIS_LIMITS } from './store-contract'\n\nconst identifier = z.string().min(1).max(TRACE_ANALYSIS_LIMITS.identifierCharacters)\nconst timestamp = z.iso.datetime({ offset: true })\nconst nonNegativeInteger = z.number().int().nonnegative()\nconst nonNegativeNumber = z.number().nonnegative()\nconst nullableString = z.string().nullable()\nconst nullableIdentifier = identifier.nullable()\nconst stringArray = z.array(z.string())\nconst filterValues = z.array(identifier).max(TRACE_ANALYSIS_LIMITS.filterValues)\n\nexport const traceFiltersSchema = z\n .object({\n has_errors: z.boolean().optional(),\n service_names: filterValues.optional(),\n agent_names: filterValues.optional(),\n model_names: filterValues.optional(),\n tool_names: filterValues.optional(),\n start_time_after: timestamp.optional(),\n start_time_before: timestamp.optional(),\n regex_pattern: z.string().min(1).max(TRACE_ANALYSIS_LIMITS.regexCharacters).optional(),\n })\n .strict()\n\nconst byteCap = z.number().int().min(TRACE_ANALYSIS_LIMITS.minimumTextBudget)\nconst searchPattern = z.string().min(1).max(TRACE_ANALYSIS_LIMITS.regexCharacters)\n\nexport const traceStoreInputSchemas = {\n hasTrace: z.object({ trace_id: identifier }).strict(),\n hasSpans: z\n .object({\n trace_id: identifier,\n span_ids: z.array(identifier).min(1).max(TRACE_ANALYSIS_LIMITS.viewSpans),\n })\n .strict(),\n getOverview: z.object({ filters: traceFiltersSchema.optional() }).strict(),\n queryTraces: z\n .object({\n filters: traceFiltersSchema.optional(),\n limit: z.number().int().min(1).max(TRACE_ANALYSIS_LIMITS.queryTraces),\n offset: z.number().int().nonnegative().optional(),\n })\n .strict(),\n countTraces: z.object({ filters: traceFiltersSchema.optional() }).strict(),\n viewTrace: z\n .object({\n trace_id: identifier,\n per_attribute_byte_cap: byteCap.optional(),\n })\n .strict(),\n viewSpans: z\n .object({\n trace_id: identifier,\n span_ids: z.array(identifier).min(1).max(TRACE_ANALYSIS_LIMITS.viewSpans),\n per_attribute_byte_cap: byteCap.optional(),\n })\n .strict(),\n searchTrace: z\n .object({\n trace_id: identifier,\n regex_pattern: searchPattern,\n max_matches: z.number().int().min(1).max(TRACE_ANALYSIS_LIMITS.searchMatches).default(50),\n })\n .strict(),\n searchSpan: z\n .object({\n trace_id: identifier,\n span_id: identifier,\n regex_pattern: searchPattern,\n max_matches: z.number().int().min(1).max(TRACE_ANALYSIS_LIMITS.searchMatches).default(50),\n })\n .strict(),\n} as const\n\nconst spanKind = z.enum([\n 'AGENT',\n 'LLM',\n 'TOOL',\n 'CHAIN',\n 'EVALUATOR',\n 'GUARDRAIL',\n 'SPAN',\n 'UNKNOWN',\n])\nconst spanStatus = z.enum(['OK', 'ERROR', 'UNSET'])\n\nconst traceSpan = z\n .object({\n trace_id: identifier,\n span_id: identifier,\n parent_span_id: nullableIdentifier,\n name: z.string(),\n kind: spanKind,\n start_time: timestamp,\n end_time: timestamp,\n duration_ms: nonNegativeNumber,\n status: spanStatus,\n status_message: z.string().optional(),\n service_name: nullableString,\n agent_name: nullableString,\n model_name: nullableString,\n tool_name: nullableString,\n attributes: z.record(z.string(), z.json()),\n })\n .strict()\n\nconst traceSummary = z\n .object({\n trace_id: identifier,\n service_name: nullableString,\n agent_name: nullableString,\n span_count: nonNegativeInteger,\n has_errors: z.boolean(),\n start_time: timestamp,\n end_time: timestamp,\n duration_ms: nonNegativeNumber,\n raw_jsonl_bytes: nonNegativeInteger,\n models: stringArray,\n tools: stringArray,\n })\n .strict()\n\nconst errorCluster = z\n .object({\n signature: z.string(),\n status_message_sample: z.string(),\n span_name: nullableString,\n tool_name: nullableString,\n trace_count: nonNegativeInteger,\n span_count: nonNegativeInteger,\n prevalence: z.number().min(0).max(1),\n exemplar_trace_ids: z.array(identifier),\n exemplar_span_ids: z.array(identifier),\n })\n .strict()\n\nconst overview = z\n .object({\n total_traces: nonNegativeInteger,\n raw_jsonl_bytes: nonNegativeInteger,\n services: stringArray,\n agents: stringArray,\n models: stringArray,\n tool_names: stringArray,\n sample_trace_ids: z.array(identifier).max(TRACE_ANALYSIS_LIMITS.sampleTraceIds),\n errors: z\n .object({\n trace_count: nonNegativeInteger,\n span_count: nonNegativeInteger,\n })\n .strict(),\n error_clusters: z.array(errorCluster),\n time_range: z\n .object({\n earliest: timestamp,\n latest: timestamp,\n })\n .strict()\n .nullable(),\n })\n .strict()\n\nconst tracePage = z\n .object({\n traces: z.array(traceSummary),\n total: nonNegativeInteger,\n has_more: z.boolean(),\n })\n .strict()\n\nconst oversizedTrace = z\n .object({\n span_count: nonNegativeInteger,\n top_span_names: z.array(z.tuple([z.string(), nonNegativeInteger])).max(20),\n span_response_bytes_max: nonNegativeInteger,\n error_span_count: nonNegativeInteger,\n })\n .strict()\n\nconst traceView = z\n .object({\n trace_id: identifier,\n spans: z.array(traceSpan).optional(),\n oversized: oversizedTrace.optional(),\n })\n .strict()\n .refine((value) => (value.spans === undefined) !== (value.oversized === undefined), {\n message: 'exactly one of spans or oversized is required',\n })\n\nconst spansView = z\n .object({\n trace_id: identifier,\n spans: z.array(traceSpan),\n missing_span_ids: z.array(identifier),\n omitted_span_ids: z.array(identifier),\n has_more: z.boolean(),\n truncated_attribute_count: nonNegativeInteger,\n })\n .strict()\n\nconst matchRecord = z\n .object({\n trace_id: identifier,\n span_id: identifier,\n span_name: z.string(),\n span_kind: spanKind,\n attribute_path: z.string(),\n matched_text: z.string(),\n context_before: z.string(),\n context_after: z.string(),\n match_offset: nonNegativeInteger,\n })\n .strict()\n\nconst traceSearch = z\n .object({\n trace_id: identifier,\n hits: z.array(matchRecord),\n has_more: z.boolean(),\n })\n .strict()\n\nconst spanSearch = traceSearch\n .extend({\n span_id: identifier,\n })\n .strict()\n\nexport const traceStoreOutputSchemas = {\n hasTrace: z.boolean(),\n hasSpans: z.array(identifier).max(TRACE_ANALYSIS_LIMITS.viewSpans),\n getOverview: overview,\n queryTraces: tracePage,\n countTraces: nonNegativeInteger,\n viewTrace: traceView,\n viewSpans: spansView,\n searchTrace: traceSearch,\n searchSpan: spanSearch,\n} as const\n\nexport function parseTraceInput<T extends z.ZodType>(\n operation: string,\n schema: T,\n value: unknown,\n): z.output<T> {\n try {\n return schema.parse(value)\n } catch (cause) {\n const detail = cause instanceof z.ZodError ? z.prettifyError(cause) : String(cause)\n throw new TraceAnalysisValidationError(`${operation}: invalid arguments: ${detail}`, { cause })\n }\n}\n\nexport function parseStoreOutput<T extends z.ZodType>(\n operation: string,\n schema: T,\n value: unknown,\n): z.output<T> {\n try {\n return schema.parse(value)\n } catch (cause) {\n const detail = cause instanceof z.ZodError ? z.prettifyError(cause) : String(cause)\n throw new TraceAnalysisStoreContractError(operation, `invalid store result: ${detail}`, {\n cause,\n })\n }\n}\n\nexport function toTraceJsonSchema(schema: z.ZodType): Record<string, unknown> {\n return z.toJSONSchema(schema, { target: 'draft-7' }) as Record<string, unknown>\n}\n","import {\n SpanNotFoundError,\n TraceAnalysisStoreContractError,\n TraceAnalysisValidationError,\n TraceNotFoundError,\n} from './errors'\nimport {\n boundOverview,\n boundSpanSearch,\n boundSpansView,\n boundTracePage,\n boundTraceSearch,\n boundTraceView,\n compileSearchRegex,\n resolveTraceBudgets,\n} from './store-bounds'\nimport type {\n BoundedTraceAnalysisStoreOptions,\n TraceAnalysisStore,\n TraceAnalysisStoreContext,\n} from './store-contract'\nimport {\n parseStoreOutput,\n parseTraceInput,\n traceStoreInputSchemas,\n traceStoreOutputSchemas,\n} from './store-schemas'\n\n/** Apply the public validation, cancellation, not-found, and size rules to any adapter. */\nexport function createBoundedTraceAnalysisStore(\n source: TraceAnalysisStore,\n options: BoundedTraceAnalysisStoreOptions = {},\n): TraceAnalysisStore {\n const budgets = resolveTraceBudgets(options.budgets)\n\n return {\n async hasTrace(traceId, context) {\n throwIfAborted(context)\n const { trace_id } = parseTraceInput('hasTrace', traceStoreInputSchemas.hasTrace, {\n trace_id: traceId,\n })\n const result = await source.hasTrace(trace_id, context)\n throwIfAborted(context)\n return parseStoreOutput('hasTrace', traceStoreOutputSchemas.hasTrace, result)\n },\n\n async hasSpans(input, context) {\n throwIfAborted(context)\n const parsed = parseTraceInput('hasSpans', traceStoreInputSchemas.hasSpans, input)\n assertUniqueIds(parsed.span_ids, 'hasSpans.span_ids')\n const result = await source.hasSpans(parsed, context)\n throwIfAborted(context)\n return validateExistingSpanIds(\n parseStoreOutput('hasSpans', traceStoreOutputSchemas.hasSpans, result),\n parsed.span_ids,\n )\n },\n\n async getOverview(filters, context) {\n throwIfAborted(context)\n const input = parseTraceInput('getOverview', traceStoreInputSchemas.getOverview, { filters })\n const result = await source.getOverview(input.filters, context)\n throwIfAborted(context)\n return boundOverview(\n parseStoreOutput('getOverview', traceStoreOutputSchemas.getOverview, result),\n budgets.perCallByteCeiling,\n )\n },\n\n async queryTraces(input, context) {\n throwIfAborted(context)\n const parsed = parseTraceInput('queryTraces', traceStoreInputSchemas.queryTraces, input)\n const offset = parsed.offset ?? 0\n const result = await source.queryTraces({ ...parsed, offset }, context)\n throwIfAborted(context)\n return boundTracePage(\n parseStoreOutput('queryTraces', traceStoreOutputSchemas.queryTraces, result),\n { limit: parsed.limit, offset },\n budgets.perCallByteCeiling,\n )\n },\n\n async countTraces(filters, context) {\n throwIfAborted(context)\n const input = parseTraceInput('countTraces', traceStoreInputSchemas.countTraces, { filters })\n const result = await source.countTraces(input.filters, context)\n throwIfAborted(context)\n return parseStoreOutput('countTraces', traceStoreOutputSchemas.countTraces, result)\n },\n\n async viewTrace(input, context) {\n throwIfAborted(context)\n const parsed = parseTraceInput('viewTrace', traceStoreInputSchemas.viewTrace, input)\n await requireTrace(source, parsed.trace_id, context)\n const perAttributeCap = parsed.per_attribute_byte_cap ?? budgets.perAttributeViewBudget\n const result = await source.viewTrace(\n { ...parsed, per_attribute_byte_cap: perAttributeCap },\n context,\n )\n throwIfAborted(context)\n return boundTraceView(\n parseStoreOutput('viewTrace', traceStoreOutputSchemas.viewTrace, result),\n parsed.trace_id,\n perAttributeCap,\n budgets.perCallByteCeiling,\n )\n },\n\n async viewSpans(input, context) {\n throwIfAborted(context)\n const parsed = parseTraceInput('viewSpans', traceStoreInputSchemas.viewSpans, input)\n assertUniqueIds(parsed.span_ids, 'viewSpans.span_ids')\n await requireTrace(source, parsed.trace_id, context)\n const existingSpanIds = new Set(\n validateExistingSpanIds(\n parseStoreOutput(\n 'hasSpans',\n traceStoreOutputSchemas.hasSpans,\n await source.hasSpans(\n { trace_id: parsed.trace_id, span_ids: parsed.span_ids },\n context,\n ),\n ),\n parsed.span_ids,\n ),\n )\n throwIfAborted(context)\n const perAttributeCap = parsed.per_attribute_byte_cap ?? budgets.perAttributeSpanBudget\n const result = await source.viewSpans(\n { ...parsed, per_attribute_byte_cap: perAttributeCap },\n context,\n )\n throwIfAborted(context)\n return boundSpansView(\n parseStoreOutput('viewSpans', traceStoreOutputSchemas.viewSpans, result),\n parsed.trace_id,\n parsed.span_ids,\n existingSpanIds,\n perAttributeCap,\n budgets.perCallByteCeiling,\n )\n },\n\n async searchTrace(input, context) {\n throwIfAborted(context)\n const parsed = parseTraceInput('searchTrace', traceStoreInputSchemas.searchTrace, input)\n compileSearchRegex(parsed.regex_pattern)\n await requireTrace(source, parsed.trace_id, context)\n const result = await source.searchTrace(parsed, context)\n throwIfAborted(context)\n return boundTraceSearch(\n parseStoreOutput('searchTrace', traceStoreOutputSchemas.searchTrace, result),\n parsed.trace_id,\n parsed.max_matches,\n budgets,\n )\n },\n\n async searchSpan(input, context) {\n throwIfAborted(context)\n const parsed = parseTraceInput('searchSpan', traceStoreInputSchemas.searchSpan, input)\n compileSearchRegex(parsed.regex_pattern)\n await requireTrace(source, parsed.trace_id, context)\n await requireSpan(source, parsed.trace_id, parsed.span_id, context)\n const result = await source.searchSpan(parsed, context)\n throwIfAborted(context)\n return boundSpanSearch(\n parseStoreOutput('searchSpan', traceStoreOutputSchemas.searchSpan, result),\n parsed.trace_id,\n parsed.span_id,\n parsed.max_matches,\n budgets,\n )\n },\n }\n}\n\nasync function requireTrace(\n source: TraceAnalysisStore,\n traceId: string,\n context: TraceAnalysisStoreContext | undefined,\n): Promise<void> {\n throwIfAborted(context)\n const exists = await source.hasTrace(traceId, context)\n throwIfAborted(context)\n if (!parseStoreOutput('hasTrace', traceStoreOutputSchemas.hasTrace, exists)) {\n throw new TraceNotFoundError(traceId)\n }\n}\n\nasync function requireSpan(\n source: TraceAnalysisStore,\n traceId: string,\n spanId: string,\n context: TraceAnalysisStoreContext | undefined,\n): Promise<void> {\n throwIfAborted(context)\n const existing = await source.hasSpans({ trace_id: traceId, span_ids: [spanId] }, context)\n throwIfAborted(context)\n const found = validateExistingSpanIds(\n parseStoreOutput('hasSpans', traceStoreOutputSchemas.hasSpans, existing),\n [spanId],\n )\n if (found.length === 0) {\n throw new SpanNotFoundError(traceId, spanId)\n }\n}\n\nfunction validateExistingSpanIds(found: readonly string[], requested: readonly string[]): string[] {\n const requestedSet = new Set(requested)\n const seen = new Set<string>()\n for (const id of found) {\n if (!requestedSet.has(id)) {\n throw new TraceAnalysisStoreContractError(\n 'hasSpans',\n `hasSpans returned unrequested span id ${JSON.stringify(id)}`,\n )\n }\n if (seen.has(id)) {\n throw new TraceAnalysisStoreContractError(\n 'hasSpans',\n `hasSpans returned duplicate span id ${JSON.stringify(id)}`,\n )\n }\n seen.add(id)\n }\n return [...found]\n}\n\nfunction assertUniqueIds(ids: readonly string[], label: string): void {\n if (new Set(ids).size !== ids.length) {\n throw new TraceAnalysisValidationError(`${label} must not contain duplicates`)\n }\n}\n\nfunction throwIfAborted(context: TraceAnalysisStoreContext | undefined): void {\n context?.signal?.throwIfAborted()\n}\n","/**\n * `OtlpFileTraceStore` — read-only OTLP-JSONL trace store for the\n * trace-analyst.\n *\n * Wire shape. Each line of the input file is one OTLP-shaped span. The\n * store understands flattened OTLP JSONL plus the OpenInference vocab.\n * We project upstream's full\n * span shape down to `TraceAnalystSpan` lazily — full materialisation\n * only happens for the spans the agent actually requests.\n *\n * Indexing. On first read the store builds an in-memory index keyed\n * by `trace_id` carrying:\n * - byte offsets + lengths for each span line (for surgical reads\n * without re-parsing the whole file)\n * - a `TraceAnalystTraceSummary` rollup\n * - sets of services / agents / models / tools / has_errors\n * - byte size of the trace's JSONL slab\n *\n * Memory bound. The index keeps span metadata only — names, kinds,\n * offsets, status. Attribute payloads stay on disk until requested.\n * For a 50MB JSONL with 50k spans, the index is ~5MB.\n *\n * Concurrency. The store builds the index once on first read and\n * caches it. Subsequent reads reuse the index. The file is opened on\n * each read; we never hold a long-lived FD.\n */\n\nimport { readFile, stat } from 'node:fs/promises'\nimport type { RE2JS } from 're2js'\nimport { CaptureIntegrityError } from '../errors'\nimport {\n SpanNotFoundError,\n TraceAnalysisLimitError,\n TraceAnalysisValidationError,\n TraceFileMalformedError,\n TraceFileMissingError,\n TraceFileTooLargeError,\n TraceNotFoundError,\n} from './errors'\nimport {\n compareSpanTime,\n extractOtlpAttributes,\n projectOtlpFlatLine,\n spanEpochMillis,\n} from './otlp-span'\nimport {\n createSharedAbortableTask,\n type SharedAbortableTask,\n waitForSharedTask,\n} from './shared-abortable-task'\nimport {\n compileSearchRegex,\n TRACE_ANALYSIS_LIMITS,\n type TraceAnalysisStore,\n type TraceAnalysisStoreContext,\n truncateForBudget,\n validateInteger,\n} from './store'\nimport {\n type DatasetOverview,\n DEFAULT_TRACE_ANALYST_BUDGETS,\n type ErrorCluster,\n type QueryTracesPage,\n type SearchSpanResult,\n type SearchTraceResult,\n type SpanMatchRecord,\n type TraceAnalystFilters,\n type TraceAnalystSpan,\n type TraceAnalystSpanKind,\n type TraceAnalystSpanStatus,\n type TraceAnalystTraceSummary,\n type ViewSpansResult,\n type ViewTraceOversized,\n type ViewTraceResult,\n} from './types'\n\n/** Lines indexed between event-loop yields. Bounded synchronous work per\n * tick keeps the index build from starving other tasks on large files\n * while staying coarse enough that the yields are cheap. */\nconst INDEX_YIELD_LINES = 5000\nconst SCAN_YIELD_ITEMS = 500\n\n/** Hand control back to the event loop without busy-waiting. */\nfunction yieldToEventLoop(): Promise<void> {\n return new Promise((resolve) => setImmediate(resolve))\n}\n\nasync function scanCheckpoint(signal: AbortSignal | undefined, item: number): Promise<void> {\n signal?.throwIfAborted()\n if (item > 0 && item % SCAN_YIELD_ITEMS === 0) {\n await yieldToEventLoop()\n signal?.throwIfAborted()\n }\n}\n\ninterface SpanIndexEntry {\n span_id: string\n parent_span_id: string | null\n name: string\n kind: TraceAnalystSpanKind\n start_time: string\n end_time: string\n duration_ms: number\n status: TraceAnalystSpanStatus\n status_message: string | undefined\n service_name: string | null\n agent_name: string | null\n model_name: string | null\n tool_name: string | null\n /** Byte offset in the raw JSONL file to the start of this span's line. */\n line_byte_offset: number\n /** Length of this line in bytes (excluding the trailing newline). */\n line_byte_length: number\n}\n\ninterface TraceIndexEntry {\n trace_id: string\n service_name: string | null\n agent_name: string | null\n span_count: number\n has_errors: boolean\n start_time: string\n end_time: string\n duration_ms: number\n raw_jsonl_bytes: number\n models: Set<string>\n tools: Set<string>\n spans: SpanIndexEntry[]\n /** Sorted by line offset for stable iteration. */\n}\n\ninterface DatasetIndex {\n byTrace: Map<string, TraceIndexEntry>\n totalRawBytes: number\n // Pre-computed sorted trace_ids for sample/query stability.\n sortedTraceIds: string[]\n}\n\nexport interface ToolSpansToTraceAnalysisStoreOptions {\n /** Override the discovery (`viewTrace`) per-attribute byte cap. */\n perAttributeViewBudget?: number\n /** Override the surgical (`viewSpans`) per-attribute byte cap. */\n perAttributeSpanBudget?: number\n /** Override the per-call ceiling that triggers oversized summaries. */\n perCallByteCeiling?: number\n /** Override the per-match text budget. */\n perMatchTextBudget?: number\n}\n\ntype BufferedOtlpTraceStoreOptions = ToolSpansToTraceAnalysisStoreOptions\n\nexport interface OtlpFileTraceStoreOptions extends BufferedOtlpTraceStoreOptions {\n /** Path to the OTLP-JSONL file. */\n path: string\n /**\n * Hard ceiling on the trace file size in bytes. The store reads the\n * whole file into one Buffer and indexes it in memory, so an\n * unbounded file OOMs the process. Above this size the store fails\n * loud with `TraceFileTooLargeError` instead of degrading silently.\n * Default 256 MiB.\n */\n maxFileBytes?: number\n}\n\n/** Default ceiling for {@link OtlpFileTraceStoreOptions.maxFileBytes}. */\nexport const DEFAULT_MAX_TRACE_FILE_BYTES = 256 * 1024 * 1024\n\nabstract class BufferedOtlpTraceStore implements TraceAnalysisStore {\n private readonly perAttributeViewBudget: number\n private readonly perAttributeSpanBudget: number\n private readonly perCallByteCeiling: number\n private readonly perMatchTextBudget: number\n private indexValue?: DatasetIndex\n private indexTask?: SharedAbortableTask<DatasetIndex>\n private bufferValue?: Buffer\n private bufferTask?: SharedAbortableTask<Buffer>\n\n constructor(opts: BufferedOtlpTraceStoreOptions) {\n this.perAttributeViewBudget = validateInteger(\n opts.perAttributeViewBudget ?? DEFAULT_TRACE_ANALYST_BUDGETS.perAttributeViewBudget,\n 'perAttributeViewBudget',\n TRACE_ANALYSIS_LIMITS.minimumTextBudget,\n )\n this.perAttributeSpanBudget = validateInteger(\n opts.perAttributeSpanBudget ?? DEFAULT_TRACE_ANALYST_BUDGETS.perAttributeSpanBudget,\n 'perAttributeSpanBudget',\n TRACE_ANALYSIS_LIMITS.minimumTextBudget,\n )\n this.perCallByteCeiling = validateInteger(\n opts.perCallByteCeiling ?? DEFAULT_TRACE_ANALYST_BUDGETS.perCallByteCeiling,\n 'perCallByteCeiling',\n 1,\n )\n this.perMatchTextBudget = validateInteger(\n opts.perMatchTextBudget ?? DEFAULT_TRACE_ANALYST_BUDGETS.perMatchTextBudget,\n 'perMatchTextBudget',\n TRACE_ANALYSIS_LIMITS.minimumTextBudget,\n )\n }\n\n // ─── Public API ────────────────────────────────────────────────────\n\n async hasTrace(trace_id: string, context?: TraceAnalysisStoreContext): Promise<boolean> {\n context?.signal?.throwIfAborted()\n const idx = await this.index(context)\n context?.signal?.throwIfAborted()\n return idx.byTrace.has(trace_id)\n }\n\n async hasSpans(\n opts: { trace_id: string; span_ids: readonly string[] },\n context?: TraceAnalysisStoreContext,\n ): Promise<string[]> {\n context?.signal?.throwIfAborted()\n const idx = await this.index(context)\n const trace = idx.byTrace.get(opts.trace_id)\n if (!trace) return []\n const requested = new Set(opts.span_ids)\n const found: string[] = []\n for (let index = 0; index < trace.spans.length; index += 1) {\n await scanCheckpoint(context?.signal, index)\n const spanId = trace.spans[index]!.span_id\n if (requested.has(spanId)) found.push(spanId)\n }\n return found\n }\n\n async getOverview(\n filters?: TraceAnalystFilters,\n context?: TraceAnalysisStoreContext,\n ): Promise<DatasetOverview> {\n const idx = await this.index(context)\n const matched = await this.matchedTraces(idx, filters, context)\n\n const services = new Set<string>()\n const agents = new Set<string>()\n const models = new Set<string>()\n const tools = new Set<string>()\n let rawBytes = 0\n let earliest: string | null = null\n let latest: string | null = null\n let errorTraceCount = 0\n let errorSpanCount = 0\n const clusters = new Map<string, ErrorClusterAccumulator>()\n\n let traceIndex = 0\n for (const t of matched) {\n await scanCheckpoint(context?.signal, traceIndex++)\n if (t.service_name) services.add(t.service_name)\n if (t.agent_name) agents.add(t.agent_name)\n for (const m of t.models) models.add(m)\n for (const tn of t.tools) tools.add(tn)\n rawBytes += t.raw_jsonl_bytes\n if (!earliest || compareSpanTime(t.start_time, earliest) < 0) earliest = t.start_time\n if (!latest || compareSpanTime(t.end_time, latest) > 0) latest = t.end_time\n if (t.has_errors) {\n errorTraceCount += 1\n let spanIndex = 0\n for (const s of t.spans) {\n await scanCheckpoint(context?.signal, spanIndex++)\n if (s.status !== 'ERROR') continue\n errorSpanCount += 1\n accumulateErrorCluster(clusters, t.trace_id, s)\n }\n }\n }\n\n const sample_trace_ids = matched.slice(0, 20).map((t) => t.trace_id)\n return {\n total_traces: matched.length,\n raw_jsonl_bytes: rawBytes,\n services: [...services].sort(),\n agents: [...agents].sort(),\n models: [...models].sort(),\n tool_names: [...tools].sort(),\n sample_trace_ids,\n errors: { trace_count: errorTraceCount, span_count: errorSpanCount },\n error_clusters: finalizeErrorClusters(clusters, errorTraceCount),\n time_range: earliest && latest ? { earliest, latest } : null,\n }\n }\n\n async queryTraces(\n opts: { filters?: TraceAnalystFilters; limit: number; offset?: number },\n context?: TraceAnalysisStoreContext,\n ): Promise<QueryTracesPage> {\n const limit = validateInteger(\n opts.limit,\n 'queryTraces.limit',\n 1,\n TRACE_ANALYSIS_LIMITS.queryTraces,\n )\n const offset = validateInteger(opts.offset ?? 0, 'queryTraces.offset', 0)\n\n const idx = await this.index(context)\n const matched = await this.matchedTraces(idx, opts.filters, context)\n const slice = matched.slice(offset, offset + limit)\n return {\n traces: slice.map((t) => this.toSummary(t)),\n total: matched.length,\n has_more: offset + slice.length < matched.length,\n }\n }\n\n async countTraces(\n filters?: TraceAnalystFilters,\n context?: TraceAnalysisStoreContext,\n ): Promise<number> {\n const idx = await this.index(context)\n const matched = await this.matchedTraces(idx, filters, context)\n return matched.length\n }\n\n async viewTrace(\n opts: { trace_id: string; per_attribute_byte_cap?: number },\n context?: TraceAnalysisStoreContext,\n ): Promise<ViewTraceResult> {\n context?.signal?.throwIfAborted()\n const idx = await this.index(context)\n const trace = idx.byTrace.get(opts.trace_id)\n if (!trace) {\n throw new TraceNotFoundError(opts.trace_id)\n }\n const cap = validateInteger(\n opts.per_attribute_byte_cap ?? this.perAttributeViewBudget,\n 'viewTrace.per_attribute_byte_cap',\n 1,\n )\n\n // Probe size first — if the materialised payload would exceed\n // the per-call ceiling we return an oversized summary rather than\n // blowing the agent's context.\n const buf = await this.buffer(context)\n const spans: TraceAnalystSpan[] = []\n let runningBytes = 0\n let span_response_bytes_max = 0\n const counter: TruncationCounter = { value: 0 }\n let spanIndex = 0\n for (const s of trace.spans) {\n await scanCheckpoint(context?.signal, spanIndex++)\n const projected = this.projectSpan(buf, trace.trace_id, s, cap, counter)\n const bytes = Buffer.byteLength(JSON.stringify(projected), 'utf8')\n span_response_bytes_max = Math.max(span_response_bytes_max, bytes)\n runningBytes += bytes\n if (runningBytes > this.perCallByteCeiling) {\n return {\n trace_id: trace.trace_id,\n oversized: this.buildOversizedSummary(trace, span_response_bytes_max),\n }\n }\n spans.push(projected)\n }\n return { trace_id: trace.trace_id, spans }\n }\n\n async viewSpans(\n opts: { trace_id: string; span_ids: readonly string[]; per_attribute_byte_cap?: number },\n context?: TraceAnalysisStoreContext,\n ): Promise<ViewSpansResult> {\n context?.signal?.throwIfAborted()\n const idx = await this.index(context)\n const trace = idx.byTrace.get(opts.trace_id)\n if (!trace) throw new TraceNotFoundError(opts.trace_id)\n if (opts.span_ids.length < 1 || opts.span_ids.length > TRACE_ANALYSIS_LIMITS.viewSpans) {\n throw new TraceAnalysisValidationError(\n `viewSpans.span_ids must contain 1..${TRACE_ANALYSIS_LIMITS.viewSpans} ids, got ${opts.span_ids.length}`,\n )\n }\n const cap = validateInteger(\n opts.per_attribute_byte_cap ?? this.perAttributeSpanBudget,\n 'viewSpans.per_attribute_byte_cap',\n 1,\n )\n\n const requested = [...new Set(opts.span_ids)]\n const wantSet = new Set(requested)\n const foundById = new Map<string, SpanIndexEntry>()\n for (let index = 0; index < trace.spans.length; index += 1) {\n await scanCheckpoint(context?.signal, index)\n const span = trace.spans[index]!\n if (wantSet.has(span.span_id)) foundById.set(span.span_id, span)\n }\n const missing = requested.filter((id) => !foundById.has(id))\n\n const buf = await this.buffer(context)\n const spans: TraceAnalystSpan[] = []\n let truncatedAttributeCount = 0\n const omitted = new Set(requested.filter((id) => foundById.has(id)))\n const buildResult = (): ViewSpansResult => ({\n trace_id: trace.trace_id,\n spans,\n missing_span_ids: missing,\n omitted_span_ids: requested.filter((id) => omitted.has(id)),\n has_more: omitted.size > 0,\n truncated_attribute_count: truncatedAttributeCount,\n })\n const metadataBytes = Buffer.byteLength(JSON.stringify(buildResult()), 'utf8')\n if (metadataBytes > this.perCallByteCeiling) {\n throw new TraceAnalysisLimitError(\n 'viewSpans',\n metadataBytes,\n this.perCallByteCeiling,\n `viewSpans accounting requires ${metadataBytes} bytes, over the ${this.perCallByteCeiling}-byte response limit`,\n )\n }\n let spanIndex = 0\n let smallestRejectedBytes = Number.POSITIVE_INFINITY\n for (const id of requested) {\n await scanCheckpoint(context?.signal, spanIndex++)\n const s = foundById.get(id)\n if (!s) continue\n const counter: TruncationCounter = { value: 0 }\n const projected = this.projectSpan(buf, trace.trace_id, s, cap, counter)\n spans.push(projected)\n omitted.delete(id)\n truncatedAttributeCount += counter.value\n const responseBytes = Buffer.byteLength(JSON.stringify(buildResult()), 'utf8')\n if (responseBytes <= this.perCallByteCeiling) {\n continue\n }\n smallestRejectedBytes = Math.min(smallestRejectedBytes, responseBytes)\n if (requested.length === 1) {\n throw new TraceAnalysisLimitError(\n 'viewSpans',\n responseBytes,\n this.perCallByteCeiling,\n `viewSpans cannot fit span ${JSON.stringify(id)} in the ${this.perCallByteCeiling}-byte response limit`,\n )\n }\n spans.pop()\n omitted.add(id)\n truncatedAttributeCount -= counter.value\n }\n if (foundById.size > 0 && spans.length === 0) {\n throw new TraceAnalysisLimitError(\n 'viewSpans',\n smallestRejectedBytes,\n this.perCallByteCeiling,\n `viewSpans cannot fit one requested span in the ${this.perCallByteCeiling}-byte response limit`,\n )\n }\n return buildResult()\n }\n\n async searchTrace(\n opts: { trace_id: string; regex_pattern: string; max_matches?: number },\n context?: TraceAnalysisStoreContext,\n ): Promise<SearchTraceResult> {\n const max_matches = validateInteger(\n opts.max_matches ?? 50,\n 'searchTrace.max_matches',\n 1,\n TRACE_ANALYSIS_LIMITS.searchMatches,\n )\n const idx = await this.index(context)\n const trace = idx.byTrace.get(opts.trace_id)\n if (!trace) throw new TraceNotFoundError(opts.trace_id)\n const re = compileSearchRegex(opts.regex_pattern)\n\n const buf = await this.buffer(context)\n const hits: SpanMatchRecord[] = []\n let hasMore = false\n let spanIndex = 0\n for (const s of trace.spans) {\n await scanCheckpoint(context?.signal, spanIndex++)\n const remaining = max_matches - hits.length\n const localHits = await this.scanSpanForMatches(\n buf,\n trace.trace_id,\n s,\n re,\n this.perMatchTextBudget,\n remaining,\n context,\n )\n for (const h of localHits.records) {\n if (hits.length >= max_matches) break\n hits.push(h)\n }\n if (localHits.hasMore) {\n hasMore = true\n break\n }\n }\n return {\n trace_id: trace.trace_id,\n hits,\n has_more: hasMore,\n }\n }\n\n async searchSpan(\n opts: { trace_id: string; span_id: string; regex_pattern: string; max_matches?: number },\n context?: TraceAnalysisStoreContext,\n ): Promise<SearchSpanResult> {\n const max_matches = validateInteger(\n opts.max_matches ?? 50,\n 'searchSpan.max_matches',\n 1,\n TRACE_ANALYSIS_LIMITS.searchMatches,\n )\n const idx = await this.index(context)\n const trace = idx.byTrace.get(opts.trace_id)\n if (!trace) throw new TraceNotFoundError(opts.trace_id)\n let span: SpanIndexEntry | undefined\n for (let index = 0; index < trace.spans.length; index += 1) {\n await scanCheckpoint(context?.signal, index)\n const candidate = trace.spans[index]!\n if (candidate.span_id === opts.span_id) {\n span = candidate\n break\n }\n }\n if (!span) {\n throw new SpanNotFoundError(opts.trace_id, opts.span_id)\n }\n const re = compileSearchRegex(opts.regex_pattern)\n const buf = await this.buffer(context)\n const localHits = await this.scanSpanForMatches(\n buf,\n trace.trace_id,\n span,\n re,\n this.perMatchTextBudget,\n max_matches,\n context,\n )\n return {\n trace_id: trace.trace_id,\n span_id: span.span_id,\n hits: localHits.records,\n has_more: localHits.hasMore,\n }\n }\n\n // ─── Index building ────────────────────────────────────────────────\n\n /** Force the index to materialise. Useful to amortise startup cost\n * before the first agent call. */\n async ensureIndexed(context?: TraceAnalysisStoreContext): Promise<void> {\n await this.index(context)\n }\n\n private async buffer(context?: TraceAnalysisStoreContext): Promise<Buffer> {\n context?.signal?.throwIfAborted()\n if (this.bufferValue) return this.bufferValue\n if (!this.bufferTask) {\n const task = createSharedAbortableTask((signal) => this.readBuffer(signal))\n this.bufferTask = task\n void task.promise.then(\n (value) => {\n this.bufferValue = value\n if (this.bufferTask === task) this.bufferTask = undefined\n },\n () => {\n if (this.bufferTask === task) this.bufferTask = undefined\n },\n )\n }\n return waitForSharedTask(this.bufferTask, context?.signal)\n }\n\n protected abstract readBuffer(signal?: AbortSignal): Promise<Buffer>\n\n protected abstract sourcePath(): string\n\n private async index(context?: TraceAnalysisStoreContext): Promise<DatasetIndex> {\n context?.signal?.throwIfAborted()\n if (this.indexValue) return this.indexValue\n if (!this.indexTask) {\n const task = createSharedAbortableTask((signal) => this.buildIndex(signal))\n this.indexTask = task\n void task.promise.then(\n (value) => {\n this.indexValue = value\n if (this.indexTask === task) this.indexTask = undefined\n },\n () => {\n if (this.indexTask === task) this.indexTask = undefined\n },\n )\n }\n return waitForSharedTask(this.indexTask, context?.signal)\n }\n\n private async buildIndex(signal?: AbortSignal): Promise<DatasetIndex> {\n // readGuarded surfaces missing/oversized files as typed errors.\n const buf = await this.buffer({ signal })\n signal?.throwIfAborted()\n\n const byTrace = new Map<string, TraceIndexEntry>()\n let cursor = 0\n let lineNumber = 0\n let sinceYield = 0\n while (cursor < buf.length) {\n lineNumber += 1\n // Yield to the event loop every INDEX_YIELD_LINES lines so a huge\n // file doesn't monopolise the thread for the whole index build.\n if (++sinceYield >= INDEX_YIELD_LINES) {\n sinceYield = 0\n await yieldToEventLoop()\n signal?.throwIfAborted()\n }\n const newlineIndex = buf.indexOf(0x0a, cursor) // \\n\n const lineEnd = newlineIndex === -1 ? buf.length : newlineIndex\n const lineLength = lineEnd - cursor\n if (lineLength === 0) {\n cursor = lineEnd + 1\n continue\n }\n const lineSlice = buf.subarray(cursor, lineEnd).toString('utf8')\n const lineOffset = cursor\n cursor = lineEnd + 1\n\n let parsed: unknown\n try {\n parsed = JSON.parse(lineSlice)\n } catch (cause) {\n throw new TraceFileMalformedError(this.sourcePath(), lineNumber, lineOffset, cause)\n }\n if (!parsed || typeof parsed !== 'object') {\n throw new TraceFileMalformedError(this.sourcePath(), lineNumber, lineOffset)\n }\n const span = projectOtlpFlatLine(parsed as Record<string, unknown>)\n if (!span) {\n throw new TraceFileMalformedError(this.sourcePath(), lineNumber, lineOffset)\n }\n\n let entry = byTrace.get(span.trace_id)\n if (!entry) {\n entry = {\n trace_id: span.trace_id,\n service_name: span.service_name,\n agent_name: span.agent_name,\n span_count: 0,\n has_errors: false,\n start_time: span.start_time,\n end_time: span.end_time,\n duration_ms: 0,\n raw_jsonl_bytes: 0,\n models: new Set(),\n tools: new Set(),\n spans: [],\n }\n byTrace.set(span.trace_id, entry)\n } else {\n // Pin the trace's service/agent to the first AGENT span we\n // Prefer the first agent/service fields that appear in the trace.\n if (!entry.service_name && span.service_name) entry.service_name = span.service_name\n if (!entry.agent_name && span.agent_name) entry.agent_name = span.agent_name\n }\n\n const indexEntry: SpanIndexEntry = {\n span_id: span.span_id,\n parent_span_id: span.parent_span_id,\n name: span.name,\n kind: span.kind,\n start_time: span.start_time,\n end_time: span.end_time,\n duration_ms: span.duration_ms,\n status: span.status,\n status_message: span.status_message,\n service_name: span.service_name,\n agent_name: span.agent_name,\n model_name: span.model_name,\n tool_name: span.tool_name,\n line_byte_offset: lineOffset,\n line_byte_length: lineLength,\n }\n entry.spans.push(indexEntry)\n entry.span_count += 1\n entry.raw_jsonl_bytes += lineLength + 1 // +1 newline byte\n if (span.status === 'ERROR') entry.has_errors = true\n if (compareSpanTime(span.start_time, entry.start_time) < 0) entry.start_time = span.start_time\n if (compareSpanTime(span.end_time, entry.end_time) > 0) entry.end_time = span.end_time\n if (span.model_name) entry.models.add(span.model_name)\n if (span.tool_name) entry.tools.add(span.tool_name)\n }\n\n // Compute trace duration once, sort spans by start time for\n // stable iteration.\n let totalRawBytes = 0\n for (const t of byTrace.values()) {\n signal?.throwIfAborted()\n totalRawBytes += t.raw_jsonl_bytes\n t.spans.sort(\n (a, b) =>\n compareSpanTime(a.start_time, b.start_time) || a.line_byte_offset - b.line_byte_offset,\n )\n // Duration is 0 unless BOTH bounds parse — a missing/garbage timestamp\n // yields 0, never a NaN (→ null in JSON) or a bogus epoch-from-zero span.\n const startMs = spanEpochMillis(t.start_time)\n const endMs = spanEpochMillis(t.end_time)\n t.duration_ms = startMs === null || endMs === null ? 0 : Math.max(0, endMs - startMs)\n }\n const sortedTraceIds = [...byTrace.keys()].sort()\n signal?.throwIfAborted()\n\n return { byTrace, totalRawBytes, sortedTraceIds }\n }\n\n // ─── Filter pipeline ───────────────────────────────────────────────\n\n private async matchedTraces(\n idx: DatasetIndex,\n filters: TraceAnalystFilters | undefined,\n context?: TraceAnalysisStoreContext,\n ): Promise<TraceIndexEntry[]> {\n context?.signal?.throwIfAborted()\n const traces: TraceIndexEntry[] = []\n for (let index = 0; index < idx.sortedTraceIds.length; index += 1) {\n await scanCheckpoint(context?.signal, index)\n const trace = idx.byTrace.get(idx.sortedTraceIds[index]!)\n if (trace) traces.push(trace)\n }\n if (!filters) return traces\n\n const indexedFiltered: TraceIndexEntry[] = []\n for (let index = 0; index < traces.length; index += 1) {\n await scanCheckpoint(context?.signal, index)\n const t = traces[index]!\n if (filters.has_errors !== undefined && t.has_errors !== filters.has_errors) continue\n if (filters.service_names && filters.service_names.length > 0) {\n if (!t.service_name || !filters.service_names.includes(t.service_name)) continue\n }\n if (filters.agent_names && filters.agent_names.length > 0) {\n if (!t.agent_name || !filters.agent_names.includes(t.agent_name)) continue\n }\n if (filters.model_names && filters.model_names.length > 0) {\n if (![...t.models].some((m) => filters.model_names!.includes(m))) continue\n }\n if (filters.tool_names && filters.tool_names.length > 0) {\n if (![...t.tools].some((tn) => filters.tool_names!.includes(tn))) continue\n }\n if (filters.start_time_after && t.start_time < filters.start_time_after) continue\n if (filters.start_time_before && t.start_time > filters.start_time_before) continue\n indexedFiltered.push(t)\n }\n\n if (!filters.regex_pattern) return indexedFiltered\n\n // Opt-in raw-bytes scan — only over the already-narrowed set.\n const re = compileSearchRegex(filters.regex_pattern)\n const buf = await this.buffer(context)\n const out: TraceIndexEntry[] = []\n let traceIndex = 0\n for (const t of indexedFiltered) {\n await scanCheckpoint(context?.signal, traceIndex++)\n let matched = false\n let spanIndex = 0\n for (const s of t.spans) {\n await scanCheckpoint(context?.signal, spanIndex++)\n const slice = buf.subarray(s.line_byte_offset, s.line_byte_offset + s.line_byte_length)\n // Buffer.toString allocates; tolerate it because regex_pattern\n // is opt-in. Future optimisation: byte-level fast-path for\n // ASCII-only patterns.\n if (re.test(slice.toString('utf8'))) {\n matched = true\n break\n }\n }\n if (matched) out.push(t)\n }\n return out\n }\n\n private toSummary(t: TraceIndexEntry): TraceAnalystTraceSummary {\n return {\n trace_id: t.trace_id,\n service_name: t.service_name,\n agent_name: t.agent_name,\n span_count: t.span_count,\n has_errors: t.has_errors,\n start_time: t.start_time,\n end_time: t.end_time,\n duration_ms: t.duration_ms,\n raw_jsonl_bytes: t.raw_jsonl_bytes,\n models: [...t.models].sort(),\n tools: [...t.tools].sort(),\n }\n }\n\n // ─── Span projection (lazy attribute reads) ────────────────────────\n\n private projectSpan(\n buf: Buffer,\n trace_id: string,\n s: SpanIndexEntry,\n perAttrCap: number,\n counter: TruncationCounter,\n ): TraceAnalystSpan {\n const slice = buf\n .subarray(s.line_byte_offset, s.line_byte_offset + s.line_byte_length)\n .toString('utf8')\n let raw: Record<string, unknown> = {}\n try {\n const parsed = JSON.parse(slice)\n if (parsed && typeof parsed === 'object') raw = parsed as Record<string, unknown>\n } catch {\n // Should not happen — index pre-validated.\n }\n const attrs = extractOtlpAttributes(raw)\n const projected: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(attrs)) {\n if (typeof v === 'string') {\n const trunc = truncateForBudget(v, perAttrCap)\n if (trunc !== v) counter.value += 1\n projected[k] = trunc\n } else if (Array.isArray(v) || (v && typeof v === 'object')) {\n const json = JSON.stringify(v)\n const trunc = truncateForBudget(json, perAttrCap)\n if (trunc !== json) {\n counter.value += 1\n projected[k] = trunc\n } else {\n projected[k] = v\n }\n } else {\n projected[k] = v\n }\n }\n return {\n trace_id,\n span_id: s.span_id,\n parent_span_id: s.parent_span_id,\n name: s.name,\n kind: s.kind,\n start_time: s.start_time,\n end_time: s.end_time,\n duration_ms: s.duration_ms,\n status: s.status,\n status_message: s.status_message,\n service_name: s.service_name,\n agent_name: s.agent_name,\n model_name: s.model_name,\n tool_name: s.tool_name,\n attributes: projected,\n }\n }\n\n private buildOversizedSummary(\n t: TraceIndexEntry,\n span_response_bytes_max: number,\n ): ViewTraceOversized {\n const counts = new Map<string, number>()\n let errorCount = 0\n for (const s of t.spans) {\n counts.set(s.name, (counts.get(s.name) ?? 0) + 1)\n if (s.status === 'ERROR') errorCount += 1\n }\n const top = [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 20)\n return {\n span_count: t.span_count,\n top_span_names: top,\n span_response_bytes_max,\n error_span_count: errorCount,\n }\n }\n\n private async scanSpanForMatches(\n buf: Buffer,\n trace_id: string,\n s: SpanIndexEntry,\n re: RE2JS,\n textBudget: number,\n recordCap: number,\n context?: TraceAnalysisStoreContext,\n ): Promise<{ records: SpanMatchRecord[]; hasMore: boolean }> {\n // We scan against the original raw JSONL slice for each span and\n // record byte positions; the matched_text + context window is\n // truncated to `textBudget` bytes per record so total tool output\n // stays bounded even if hits cluster.\n const slice = buf\n .subarray(s.line_byte_offset, s.line_byte_offset + s.line_byte_length)\n .toString('utf8')\n const records: SpanMatchRecord[] = []\n let hasMore = false\n let matchIndex = 0\n for (const match of re.matchAll(slice)) {\n await scanCheckpoint(context?.signal, matchIndex++)\n if (records.length >= recordCap) {\n hasMore = true\n break\n }\n const offset = match.index ?? 0\n const before = slice.slice(Math.max(0, offset - textBudget / 2), offset)\n const after = slice.slice(\n offset + match[0].length,\n offset + match[0].length + Math.floor(textBudget / 2),\n )\n records.push({\n trace_id,\n span_id: s.span_id,\n span_name: s.name,\n span_kind: s.kind,\n attribute_path: bestAttributePathForOffset(slice, offset) ?? 'span.raw',\n matched_text: truncateForBudget(match[0], textBudget),\n context_before: truncateForBudget(before, textBudget),\n context_after: truncateForBudget(after, textBudget),\n match_offset: offset,\n })\n }\n return { records, hasMore }\n }\n}\n\nexport class OtlpFileTraceStore extends BufferedOtlpTraceStore {\n private readonly path: string\n private readonly maxFileBytes: number\n\n constructor(opts: OtlpFileTraceStoreOptions) {\n super(opts)\n this.path = opts.path\n this.maxFileBytes = validateInteger(\n opts.maxFileBytes ?? DEFAULT_MAX_TRACE_FILE_BYTES,\n 'maxFileBytes',\n 1,\n )\n }\n\n /** Stat-then-read so an oversized file fails loud before allocating the\n * source buffer. Missing files remain distinct from malformed traces. */\n protected async readBuffer(signal?: AbortSignal): Promise<Buffer> {\n signal?.throwIfAborted()\n let stats: Awaited<ReturnType<typeof stat>>\n try {\n stats = await stat(this.path)\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === 'ENOENT') {\n throw new TraceFileMissingError(this.path)\n }\n throw err\n }\n if (stats.size > this.maxFileBytes) {\n throw new TraceFileTooLargeError(this.path, stats.size, this.maxFileBytes)\n }\n signal?.throwIfAborted()\n return readFile(this.path, { signal })\n }\n\n protected sourcePath(): string {\n return this.path\n }\n}\n\nclass OtlpBufferTraceStore extends BufferedOtlpTraceStore {\n constructor(\n private readonly source: Buffer,\n opts: BufferedOtlpTraceStoreOptions,\n ) {\n super(opts)\n }\n\n protected async readBuffer(signal?: AbortSignal): Promise<Buffer> {\n signal?.throwIfAborted()\n return this.source\n }\n\n protected sourcePath(): string {\n return '<memory>'\n }\n}\n\n/** Build the bounded trace store directly from OpenInference JSONL text. */\nexport function otlpTextToTraceAnalysisStore(\n text: string,\n opts: ToolSpansToTraceAnalysisStoreOptions = {},\n): TraceAnalysisStore {\n if (!text.trim()) throw new CaptureIntegrityError('OTLP trace text must not be empty')\n return new OtlpBufferTraceStore(Buffer.from(text, 'utf8'), opts)\n}\n\nexport function createOtlpBufferTraceStore(\n source: Buffer,\n options: ToolSpansToTraceAnalysisStoreOptions = {},\n): TraceAnalysisStore {\n return new OtlpBufferTraceStore(source, options)\n}\n\nexport {\n SpanNotFoundError,\n TraceFileMalformedError,\n TraceFileMissingError,\n TraceFileTooLargeError,\n TraceNotFoundError,\n} from './errors'\n\n// ─── OTLP shape readers ──────────────────────────────────────────────\n//\n// The per-line projection lives in `./otlp-span` so the index here and\n// `otlpToRunRecords` read the same vocabulary off the same parser.\n\n// Per-call truncation counter. Each public read that projects spans\n// owns one of these and threads it through projectSpan; a store-keyed\n// counter would let two concurrent reads on the same store report each\n// other's truncation counts.\ninterface TruncationCounter {\n value: number\n}\n\n/** A `\"` at `idx` is a real JSON delimiter only when the run of `\\`\n * immediately preceding it is even-length; an odd run means the quote\n * is escaped (`\\\"`) and is part of a string value, not a boundary. */\nfunction isUnescapedQuote(slice: string, idx: number): boolean {\n if (slice[idx] !== '\"') return false\n let backslashes = 0\n let b = idx - 1\n while (b >= 0 && slice[b] === '\\\\') {\n backslashes += 1\n b -= 1\n }\n return backslashes % 2 === 0\n}\n\n/** Scan backwards from `from` (inclusive) for the nearest UNescaped `\"`.\n * Returns its index, or -1 when none is found. */\nfunction prevUnescapedQuote(slice: string, from: number): number {\n for (let i = from; i >= 0; i -= 1) {\n if (slice[i] === '\"' && isUnescapedQuote(slice, i)) return i\n }\n return -1\n}\n\n/**\n * Best-effort: locate the JSON path for the substring at `offset` in\n * a single span's JSONL slice. The slice is '...,\"key\":\"value...\"' — we\n * walk back from `offset` to the value-opening quote, past the `:`, to\n * the key's closing then opening quote, skipping `\\\"`-escaped quotes that\n * live inside string values. Returns `null` when the offset doesn't fall\n * inside a recognisable string field.\n */\nfunction bestAttributePathForOffset(slice: string, offset: number): string | null {\n // Value-opening quote: nearest unescaped '\"' at or before the offset.\n const valueQuote = prevUnescapedQuote(slice, Math.min(offset, slice.length - 1))\n if (valueQuote < 1) return null\n // The ':' separating key and value sits before the value quote.\n let j = valueQuote - 1\n while (j >= 0 && slice[j] !== ':') j -= 1\n if (j < 1) return null\n // Key closing quote, then key opening quote — both unescaped.\n const keyClose = prevUnescapedQuote(slice, j - 1)\n if (keyClose < 1) return null\n const keyOpen = prevUnescapedQuote(slice, keyClose - 1)\n if (keyOpen < 0) return null\n return slice.slice(keyOpen + 1, keyClose)\n}\n\n// ─── Error-cluster extraction ────────────────────────────────────────\n//\n// Deterministic failure-coverage population. The error-span loop in\n// getOverview already visits every ERROR span; bucketing them by a\n// normalized status_message signature turns \"N error spans\" into \"K\n// distinct failure modes\" — the checklist an analyst must close. No LLM.\n\nconst ERROR_CLUSTER_EXEMPLARS = 5\n\ninterface ErrorClusterAccumulator {\n signature: string\n sample: string\n traceIds: Set<string>\n spanIds: string[]\n spanCount: number\n spanNames: Map<string, number>\n toolNames: Map<string, number>\n}\n\n/** Collapse volatile tokens so semantically identical failures share a key:\n * hex/uuid ids → <id>, numbers → #, quoted/abs paths → <path>, durations →\n * <dur>, whitespace collapsed. Empty/absent messages fall back to the span\n * name so a no-message error still forms a real cluster. */\nfunction normalizeErrorSignature(message: string | undefined, spanName: string): string {\n const raw = (message ?? '').trim()\n const base = raw.length > 0 ? raw : `(${spanName || 'error'} — no message)`\n const norm = base\n .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '<id>')\n .replace(/\\b[0-9a-f]{12,}\\b/gi, '<id>')\n .replace(/(?:\\/[\\w.\\-@]+){2,}/g, '<path>')\n .replace(/\\b\\d+(?:\\.\\d+)?(ms|s|m|h|kb|mb|gb)?\\b/gi, (_m, u) => (u ? `#${u}` : '#'))\n .replace(/\\s+/g, ' ')\n .trim()\n return norm\n}\n\nfunction bump(map: Map<string, number>, key: string | null): void {\n if (!key) return\n map.set(key, (map.get(key) ?? 0) + 1)\n}\n\nfunction topKey(map: Map<string, number>): string | null {\n let best: string | null = null\n let bestN = 0\n for (const [k, n] of map)\n if (n > bestN) {\n best = k\n bestN = n\n }\n return best\n}\n\nfunction accumulateErrorCluster(\n clusters: Map<string, ErrorClusterAccumulator>,\n traceId: string,\n span: SpanIndexEntry,\n): void {\n const signature = normalizeErrorSignature(span.status_message, span.name)\n let acc = clusters.get(signature)\n if (!acc) {\n acc = {\n signature,\n sample: span.status_message ?? span.name ?? '',\n traceIds: new Set(),\n spanIds: [],\n spanCount: 0,\n spanNames: new Map(),\n toolNames: new Map(),\n }\n clusters.set(signature, acc)\n }\n acc.traceIds.add(traceId)\n acc.spanCount += 1\n if (acc.spanIds.length < ERROR_CLUSTER_EXEMPLARS && !acc.spanIds.includes(span.span_id)) {\n acc.spanIds.push(span.span_id)\n }\n bump(acc.spanNames, span.name)\n bump(acc.toolNames, span.tool_name)\n}\n\nfunction finalizeErrorClusters(\n clusters: Map<string, ErrorClusterAccumulator>,\n errorTraceCount: number,\n): ErrorCluster[] {\n const out = [...clusters.values()].map(\n (acc): ErrorCluster => ({\n signature: acc.signature,\n status_message_sample: acc.sample,\n span_name: topKey(acc.spanNames),\n tool_name: topKey(acc.toolNames),\n trace_count: acc.traceIds.size,\n span_count: acc.spanCount,\n prevalence: errorTraceCount > 0 ? acc.traceIds.size / errorTraceCount : 0,\n exemplar_trace_ids: [...acc.traceIds].slice(0, ERROR_CLUSTER_EXEMPLARS),\n exemplar_span_ids: acc.spanIds.slice(0, ERROR_CLUSTER_EXEMPLARS),\n }),\n )\n out.sort((a, b) => b.trace_count - a.trace_count || b.span_count - a.span_count)\n return out\n}\n","import {\n type AxAgentActorTurnCallback,\n type AxAIService,\n type AxFunction,\n AxJSRuntime,\n agent,\n} from '@ax-llm/ax'\nimport { TraceFileMissingError } from './store-otlp'\n\nexport const TRACE_ANALYSIS_FINAL_TASK = 'Submit the completed trace analysis.'\n\nconst TRACE_ANALYSIS_COMPLETION_INSTRUCTION = `This host consumes your executor result directly; there is no downstream responder for this run. Ignore generic executor guidance that says a responder will format the answer. You must produce the final report and findings yourself.\n\nReturn exactly one executable JavaScript program per turn. Never emit multiple JavaScript or code fences; put every tool call and the final call in that one program.\n\nWhen the analysis is complete, call \\`await final(${JSON.stringify(TRACE_ANALYSIS_FINAL_TASK)}, { report, findings })\\` exactly once. Do not return a one-argument string from \\`final(...)\\`.`\n\nexport class TraceAnalysisTurnLimitError extends Error {\n readonly analystId: string\n readonly maxTurns: number\n\n constructor(analystId: string, maxTurns: number, cause: unknown) {\n super(\n `Trace analyst '${analystId}' reached maxTurns=${maxTurns} without a structured final result`,\n { cause },\n )\n this.name = 'TraceAnalysisTurnLimitError'\n this.analystId = analystId\n this.maxTurns = maxTurns\n }\n}\n\nexport interface TraceAnalysisLoopResult<TFinding> {\n report: string\n findings: TFinding[]\n usage: readonly unknown[]\n chatLog: readonly unknown[]\n turnCount: number\n}\n\ninterface TraceAnalysisLoopOptions {\n id: string\n description: string\n prompt: string\n question: string\n ai: AxAIService\n model?: string\n tools: readonly AxFunction[]\n maxSubqueries: number\n maxParallelSubqueries: number\n maxTurns: number\n maxRuntimeChars: number\n signal?: AbortSignal\n onTurn?: AxAgentActorTurnCallback\n}\n\nexport function runTraceAnalysisLoop(\n options: TraceAnalysisLoopOptions & { findingType: 'string' },\n): Promise<TraceAnalysisLoopResult<string>>\nexport function runTraceAnalysisLoop(\n options: TraceAnalysisLoopOptions & { findingType: 'object' },\n): Promise<TraceAnalysisLoopResult<Record<string, unknown>>>\nexport async function runTraceAnalysisLoop(\n options: TraceAnalysisLoopOptions & { findingType: 'string' | 'object' },\n): Promise<TraceAnalysisLoopResult<string | Record<string, unknown>>> {\n validateLoopLimits(options)\n\n const config = {\n agentIdentity: { name: options.id, description: options.description },\n contextFields: [] as const,\n runtime: new AxJSRuntime({\n permissions: [],\n blockDynamicImport: true,\n allowedModules: [],\n freezeIntrinsics: true,\n blockShadowRealm: true,\n preventGlobalThisExtensions: false,\n }),\n maxSubAgentCalls: options.maxSubqueries,\n maxTurns: options.maxTurns,\n maxRuntimeChars: options.maxRuntimeChars,\n maxBatchedLlmQueryConcurrency: options.maxParallelSubqueries,\n promptLevel: 'detailed' as const,\n contextPolicy: { preset: 'full' as const, budget: 'balanced' as const },\n functions: options.tools,\n executorOptions: {\n description: `${options.prompt.trim()}\\n\\n${TRACE_ANALYSIS_COMPLETION_INSTRUCTION}`,\n ...(options.model ? { model: options.model } : {}),\n showThoughts: false,\n thinkingTokenBudget: 'none' as const,\n },\n ...(options.onTurn ? { actorTurnCallback: options.onTurn } : {}),\n bubbleErrors: [TraceFileMissingError],\n }\n const analyst =\n options.findingType === 'string'\n ? agent('question:string -> report:string, findings:string[]', config)\n : agent('question:string -> report:string, findings:json[]', config)\n\n const state = await analyst.executor.run(\n options.ai,\n { question: options.question },\n options.signal ? { abortSignal: options.signal } : undefined,\n )\n\n let completed: CompletedTraceAnalysis<string | Record<string, unknown>>\n try {\n completed =\n options.findingType === 'string'\n ? readTraceAnalysisCompletion(state.executorResult, 'string')\n : readTraceAnalysisCompletion(state.executorResult, 'object')\n } catch (error) {\n if (state.turnCount >= options.maxTurns) {\n throw new TraceAnalysisTurnLimitError(options.id, options.maxTurns, error)\n }\n throw new Error(`Trace analyst '${options.id}' stopped without a structured final result`, {\n cause: error,\n })\n }\n\n return {\n ...completed,\n usage: analyst.executor.getUsage(),\n chatLog: analyst.executor.getChatLog(),\n turnCount: state.turnCount,\n }\n}\n\ninterface CompletedTraceAnalysis<TFinding> {\n report: string\n findings: TFinding[]\n}\n\nexport function readTraceAnalysisCompletion(\n value: unknown,\n findingType: 'string',\n): CompletedTraceAnalysis<string>\nexport function readTraceAnalysisCompletion(\n value: unknown,\n findingType: 'object',\n): CompletedTraceAnalysis<Record<string, unknown>>\nexport function readTraceAnalysisCompletion(\n value: unknown,\n findingType: 'string' | 'object',\n): CompletedTraceAnalysis<string | Record<string, unknown>> {\n if (!value || typeof value !== 'object') {\n throw new Error('Trace analyst did not return a structured final result')\n }\n const completion = value as { type?: unknown; args?: unknown }\n if (\n completion.type !== 'final' ||\n !Array.isArray(completion.args) ||\n completion.args.length !== 2 ||\n completion.args[0] !== TRACE_ANALYSIS_FINAL_TASK\n ) {\n throw new Error('Trace analyst did not return a structured final result')\n }\n\n const payload = completion.args[1]\n if (!payload || typeof payload !== 'object') {\n throw new Error('Trace analyst final result must contain report and findings')\n }\n const { report, findings } = payload as { report?: unknown; findings?: unknown }\n if (typeof report !== 'string' || !Array.isArray(findings)) {\n throw new Error('Trace analyst final result must contain report and findings')\n }\n if (findingType === 'string') {\n if (findings.some((finding) => typeof finding !== 'string')) {\n throw new Error('Trace analyst final result must contain string findings')\n }\n return { report, findings: findings as string[] }\n }\n if (\n findings.some((finding) => !finding || typeof finding !== 'object' || Array.isArray(finding))\n ) {\n throw new Error('Trace analyst final result must contain object findings')\n }\n return { report, findings: findings as Record<string, unknown>[] }\n}\n\nfunction validateLoopLimits(options: TraceAnalysisLoopOptions): void {\n if (!Number.isSafeInteger(options.maxSubqueries) || options.maxSubqueries < 0) {\n throw new TypeError('maxSubqueries must be a non-negative integer')\n }\n if (!Number.isSafeInteger(options.maxParallelSubqueries) || options.maxParallelSubqueries < 1) {\n throw new TypeError('maxParallelSubqueries must be a positive integer')\n }\n}\n","/**\n * Canonical transport-neutral trace tools plus the Ax adapter used by the\n * built-in analyst. Schemas and handlers originate here; provider adapters\n * only translate descriptor fields and cancellation context.\n */\n\nimport type { AxFunction } from '@ax-llm/ax'\n\nimport type { EvalToolDef } from '../eval-tools'\nimport {\n type BoundedTraceAnalysisStoreOptions,\n createBoundedTraceAnalysisStore,\n TRACE_ANALYSIS_LIMITS,\n type TraceAnalysisStore,\n} from './store'\nimport { parseTraceInput, toTraceJsonSchema, traceStoreInputSchemas } from './store-schemas'\n\nexport const TRACE_ANALYST_TOOL_NAMESPACE = 'traces' as const\n\nexport interface BuildTraceAnalysisToolsOptions extends BoundedTraceAnalysisStoreOptions {\n store: TraceAnalysisStore\n}\n\nexport interface TraceAnalysisToolDescriptor extends EvalToolDef {\n namespace: typeof TRACE_ANALYST_TOOL_NAMESPACE\n}\n\n/** Bind all seven trace reads without exposing an agent framework type. */\nexport function buildTraceAnalysisToolDescriptors(\n options: BuildTraceAnalysisToolsOptions,\n): TraceAnalysisToolDescriptor[] {\n const store = createBoundedTraceAnalysisStore(options.store, { budgets: options.budgets })\n\n return [\n {\n namespace: TRACE_ANALYST_TOOL_NAMESPACE,\n name: 'getDatasetOverview',\n description:\n 'Dataset rollup: total traces, raw_jsonl_bytes, services, agents, models, tools, ' +\n 'and sample_trace_ids. Always call this first without a regex_pattern.',\n parameters: toTraceJsonSchema(traceStoreInputSchemas.getOverview),\n handler: async (args, context) => {\n const { filters } = parseTraceInput(\n 'getDatasetOverview',\n traceStoreInputSchemas.getOverview,\n args ?? {},\n )\n return store.getOverview(filters, context)\n },\n },\n {\n namespace: TRACE_ANALYST_TOOL_NAMESPACE,\n name: 'queryTraces',\n description:\n `Paginated trace summaries, at most ${TRACE_ANALYSIS_LIMITS.queryTraces} per call. ` +\n 'Each summary carries raw_jsonl_bytes; narrow with indexed filters before regex_pattern.',\n parameters: toTraceJsonSchema(traceStoreInputSchemas.queryTraces),\n handler: async (args, context) => {\n const input = parseTraceInput('queryTraces', traceStoreInputSchemas.queryTraces, args)\n return store.queryTraces(input, context)\n },\n },\n {\n namespace: TRACE_ANALYST_TOOL_NAMESPACE,\n name: 'countTraces',\n description:\n 'Count traces matching filters. Use as a cheap pre-flight before a regex_pattern scan.',\n parameters: toTraceJsonSchema(traceStoreInputSchemas.countTraces),\n handler: async (args, context) => {\n const { filters } = parseTraceInput(\n 'countTraces',\n traceStoreInputSchemas.countTraces,\n args ?? {},\n )\n return store.countTraces(filters, context)\n },\n },\n {\n namespace: TRACE_ANALYST_TOOL_NAMESPACE,\n name: 'viewTrace',\n description:\n 'Return all spans for one trace with bounded attributes. Oversized responses carry ' +\n 'an oversized summary instead of spans; continue with searchTrace or viewSpans.',\n parameters: toTraceJsonSchema(\n traceStoreInputSchemas.viewTrace.omit({\n per_attribute_byte_cap: true,\n }),\n ),\n handler: async (args, context) => {\n const input = parseTraceInput(\n 'viewTrace',\n traceStoreInputSchemas.viewTrace.omit({ per_attribute_byte_cap: true }),\n args,\n )\n return store.viewTrace(input, context)\n },\n },\n {\n namespace: TRACE_ANALYST_TOOL_NAMESPACE,\n name: 'viewSpans',\n description:\n `Read 1..${TRACE_ANALYSIS_LIMITS.viewSpans} specific spans. Every requested id is ` +\n 'accounted for in spans, missing_span_ids, or omitted_span_ids; retry omitted ids.',\n parameters: toTraceJsonSchema(\n traceStoreInputSchemas.viewSpans.omit({\n per_attribute_byte_cap: true,\n }),\n ),\n handler: async (args, context) => {\n const input = parseTraceInput(\n 'viewSpans',\n traceStoreInputSchemas.viewSpans.omit({ per_attribute_byte_cap: true }),\n args,\n )\n return store.viewSpans(input, context)\n },\n },\n {\n namespace: TRACE_ANALYST_TOOL_NAMESPACE,\n name: 'searchTrace',\n description:\n `Regex search across one trace, bounded to ${TRACE_ANALYSIS_LIMITS.searchMatches} hits. ` +\n 'When has_more is true, refine the regex instead of treating the result as complete.',\n parameters: toTraceJsonSchema(traceStoreInputSchemas.searchTrace),\n handler: async (args, context) => {\n const input = parseTraceInput('searchTrace', traceStoreInputSchemas.searchTrace, args)\n return store.searchTrace(input, context)\n },\n },\n {\n namespace: TRACE_ANALYST_TOOL_NAMESPACE,\n name: 'searchSpan',\n description:\n `Regex search inside one span, bounded to ${TRACE_ANALYSIS_LIMITS.searchMatches} hits. ` +\n 'Use after viewSpans omits or truncates a large span payload.',\n parameters: toTraceJsonSchema(traceStoreInputSchemas.searchSpan),\n handler: async (args, context) => {\n const input = parseTraceInput('searchSpan', traceStoreInputSchemas.searchSpan, args)\n return store.searchSpan(input, context)\n },\n },\n ]\n}\n\n/** Adapt the canonical descriptors into Ax functions used by the built-in analyst. */\nexport function buildTraceAnalystTools(options: BuildTraceAnalysisToolsOptions): AxFunction[] {\n return buildTraceAnalysisToolDescriptors(options).map((descriptor) => ({\n namespace: descriptor.namespace,\n name: descriptor.name,\n description: descriptor.description,\n parameters: descriptor.parameters as AxFunction['parameters'],\n func: (args, extra) =>\n descriptor.handler(args, extra?.abortSignal ? { signal: extra.abortSignal } : undefined),\n }))\n}\n\nexport function traceAnalystFunctionGroup(options: BuildTraceAnalysisToolsOptions): {\n namespace: string\n title: string\n selectionCriteria: string\n description: string\n functions: AxFunction[]\n} {\n return {\n namespace: TRACE_ANALYST_TOOL_NAMESPACE,\n title: 'Trace Analysis',\n selectionCriteria: 'Use for any inspection of OTLP-shaped trace data.',\n description:\n 'Discovery, narrowing, and bounded deep reads over a JSONL trace dataset. ' +\n 'Always call getDatasetOverview first.',\n functions: buildTraceAnalystTools(options),\n }\n}\n"],"mappings":"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"}