@tangle-network/agent-eval 0.128.2 → 0.130.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 (424) hide show
  1. package/CHANGELOG.md +279 -0
  2. package/README.md +19 -0
  3. package/dist/active-curriculum-C4mk67HP.js +214 -0
  4. package/dist/active-curriculum-C4mk67HP.js.map +1 -0
  5. package/dist/adversarial-smnADNFS.d.ts +21 -0
  6. package/dist/adversarial-smnADNFS.d.ts.map +1 -0
  7. package/dist/analyst/index.d.ts +83 -2932
  8. package/dist/analyst/index.d.ts.map +1 -0
  9. package/dist/analyst/index.js +319 -364
  10. package/dist/analyst/index.js.map +1 -1
  11. package/dist/analyst-BkTS3C58.d.ts +89 -0
  12. package/dist/analyst-BkTS3C58.d.ts.map +1 -0
  13. package/dist/analyst-LsnNpSkm.js +152 -0
  14. package/dist/analyst-LsnNpSkm.js.map +1 -0
  15. package/dist/analyze-runs-C1CavBMk.js +1067 -0
  16. package/dist/analyze-runs-C1CavBMk.js.map +1 -0
  17. package/dist/analyze-runs-FsgYCinh.d.ts +72 -0
  18. package/dist/analyze-runs-FsgYCinh.d.ts.map +1 -0
  19. package/dist/attribute-vocabulary-DLJ6303h.d.ts +54 -0
  20. package/dist/attribute-vocabulary-DLJ6303h.d.ts.map +1 -0
  21. package/dist/authenticity/index.d.ts +81 -79
  22. package/dist/authenticity/index.d.ts.map +1 -0
  23. package/dist/authenticity/index.js +209 -193
  24. package/dist/authenticity/index.js.map +1 -1
  25. package/dist/baseline-HsBvw_dk.js +550 -0
  26. package/dist/baseline-HsBvw_dk.js.map +1 -0
  27. package/dist/baseline-hG3K85h4.d.ts +125 -0
  28. package/dist/baseline-hG3K85h4.d.ts.map +1 -0
  29. package/dist/belief-state/index.d.ts +448 -1205
  30. package/dist/belief-state/index.d.ts.map +1 -0
  31. package/dist/belief-state/index.js +1617 -1710
  32. package/dist/belief-state/index.js.map +1 -1
  33. package/dist/benchmarks/index.d.ts +2 -894
  34. package/dist/benchmarks/index.js +2 -59
  35. package/dist/benchmarks-DviOvUNr.js +754 -0
  36. package/dist/benchmarks-DviOvUNr.js.map +1 -0
  37. package/dist/builder-eval/index.d.ts +150 -662
  38. package/dist/builder-eval/index.d.ts.map +1 -0
  39. package/dist/builder-eval/index.js +356 -345
  40. package/dist/builder-eval/index.js.map +1 -1
  41. package/dist/calibration-CNWWA6K8.js +94 -0
  42. package/dist/calibration-CNWWA6K8.js.map +1 -0
  43. package/dist/campaign/index.d.ts +5 -6390
  44. package/dist/campaign/index.js +3 -212
  45. package/dist/campaign-CBKZvQ1H.js +3885 -0
  46. package/dist/campaign-CBKZvQ1H.js.map +1 -0
  47. package/dist/cli.d.ts +1 -1
  48. package/dist/cli.js +164 -174
  49. package/dist/cli.js.map +1 -1
  50. package/dist/client-C97NMzqi.d.ts +581 -0
  51. package/dist/client-C97NMzqi.d.ts.map +1 -0
  52. package/dist/client-CYzbdJOZ.js +637 -0
  53. package/dist/client-CYzbdJOZ.js.map +1 -0
  54. package/dist/code-agent-session-BjkMTQ7H.js +1390 -0
  55. package/dist/code-agent-session-BjkMTQ7H.js.map +1 -0
  56. package/dist/code-agent-session-DqqgOJaz.d.ts +143 -0
  57. package/dist/code-agent-session-DqqgOJaz.d.ts.map +1 -0
  58. package/dist/concurrency-DIxRZF_J.js +85 -0
  59. package/dist/concurrency-DIxRZF_J.js.map +1 -0
  60. package/dist/contract/index.d.ts +645 -5605
  61. package/dist/contract/index.d.ts.map +1 -0
  62. package/dist/contract/index.js +1730 -1937
  63. package/dist/contract/index.js.map +1 -1
  64. package/dist/control.d.ts +3 -1030
  65. package/dist/control.js +2 -32
  66. package/dist/cost-ledger-DIgQUFZZ.js +801 -0
  67. package/dist/cost-ledger-DIgQUFZZ.js.map +1 -0
  68. package/dist/cost-ledger-Dye6jCgg.d.ts +236 -0
  69. package/dist/cost-ledger-Dye6jCgg.d.ts.map +1 -0
  70. package/dist/dataset-BvtnC8Dc.d.ts +115 -0
  71. package/dist/dataset-BvtnC8Dc.d.ts.map +1 -0
  72. package/dist/default-registry-C-vFCSEc.js +2579 -0
  73. package/dist/default-registry-C-vFCSEc.js.map +1 -0
  74. package/dist/default-registry-CNPo-Vsb.d.ts +540 -0
  75. package/dist/default-registry-CNPo-Vsb.d.ts.map +1 -0
  76. package/dist/emitter-CPBAhxum.js +266 -0
  77. package/dist/emitter-CPBAhxum.js.map +1 -0
  78. package/dist/emitter-DGQGoLyj.d.ts +113 -0
  79. package/dist/emitter-DGQGoLyj.d.ts.map +1 -0
  80. package/dist/errors-8YnH8WlF.js +64 -0
  81. package/dist/errors-8YnH8WlF.js.map +1 -0
  82. package/dist/errors-CEk209JS.d.ts +76 -0
  83. package/dist/errors-CEk209JS.d.ts.map +1 -0
  84. package/dist/eval-campaign-DEm6c8ru.js +349 -0
  85. package/dist/eval-campaign-DEm6c8ru.js.map +1 -0
  86. package/dist/execution-tracks-CpgFPpS5.js +93 -0
  87. package/dist/execution-tracks-CpgFPpS5.js.map +1 -0
  88. package/dist/exporters-q9iL-2Jf.js +148 -0
  89. package/dist/exporters-q9iL-2Jf.js.map +1 -0
  90. package/dist/extract-usage-BrQ8mCLX.js +155 -0
  91. package/dist/extract-usage-BrQ8mCLX.js.map +1 -0
  92. package/dist/failure-cluster-CqcvCcdR.d.ts +59 -0
  93. package/dist/failure-cluster-CqcvCcdR.d.ts.map +1 -0
  94. package/dist/feedback-trajectory-CVaeREXV.d.ts +340 -0
  95. package/dist/feedback-trajectory-CVaeREXV.d.ts.map +1 -0
  96. package/dist/fuzz.d.ts +320 -646
  97. package/dist/fuzz.d.ts.map +1 -0
  98. package/dist/fuzz.js +670 -617
  99. package/dist/fuzz.js.map +1 -1
  100. package/dist/hf-dataset-DBJXXoY1.js +763 -0
  101. package/dist/hf-dataset-DBJXXoY1.js.map +1 -0
  102. package/dist/hosted/index.d.ts +11 -831
  103. package/dist/hosted/index.d.ts.map +1 -0
  104. package/dist/hosted/index.js +2 -37
  105. package/dist/index-2JJSA6-r2.d.ts +926 -0
  106. package/dist/index-2JJSA6-r2.d.ts.map +1 -0
  107. package/dist/index-6N0aYmpW.d.ts +217 -0
  108. package/dist/index-6N0aYmpW.d.ts.map +1 -0
  109. package/dist/index-BAvgST_9.d.ts +131 -0
  110. package/dist/index-BAvgST_9.d.ts.map +1 -0
  111. package/dist/index-BvnJuTGD.d.ts +68 -0
  112. package/dist/index-BvnJuTGD.d.ts.map +1 -0
  113. package/dist/index-C61Wi7yg.d.ts +547 -0
  114. package/dist/index-C61Wi7yg.d.ts.map +1 -0
  115. package/dist/index-CAPUUKaM.d.ts +335 -0
  116. package/dist/index-CAPUUKaM.d.ts.map +1 -0
  117. package/dist/index-DE5fb3EC.d.ts +2244 -0
  118. package/dist/index-DE5fb3EC.d.ts.map +1 -0
  119. package/dist/index-DSC51roc.d.ts +102 -0
  120. package/dist/index-DSC51roc.d.ts.map +1 -0
  121. package/dist/index.d.ts +3776 -15120
  122. package/dist/index.d.ts.map +1 -0
  123. package/dist/index.js +11185 -11191
  124. package/dist/index.js.map +1 -1
  125. package/dist/integrity-BzRbCHzi.js +424 -0
  126. package/dist/integrity-BzRbCHzi.js.map +1 -0
  127. package/dist/integrity-rmVhXWA7.d.ts +61 -0
  128. package/dist/integrity-rmVhXWA7.d.ts.map +1 -0
  129. package/dist/judge-calibration-DFtEMlde.d.ts +146 -0
  130. package/dist/judge-calibration-DFtEMlde.d.ts.map +1 -0
  131. package/dist/ledger-core/index.d.ts +2 -0
  132. package/dist/ledger-core/index.js +2 -0
  133. package/dist/ledger-core-DtZz1RG0.js +388 -0
  134. package/dist/ledger-core-DtZz1RG0.js.map +1 -0
  135. package/dist/llm-client--GR4JbZE.js +687 -0
  136. package/dist/llm-client--GR4JbZE.js.map +1 -0
  137. package/dist/llm-client-B_nIBlYo.d.ts +290 -0
  138. package/dist/llm-client-B_nIBlYo.d.ts.map +1 -0
  139. package/dist/matrix/index.d.ts +3 -155
  140. package/dist/matrix/index.js +2 -8
  141. package/dist/matrix-BzQnu2S6.js +270 -0
  142. package/dist/matrix-BzQnu2S6.js.map +1 -0
  143. package/dist/meta-eval/index.d.ts +4 -1027
  144. package/dist/meta-eval/index.js +393 -390
  145. package/dist/meta-eval/index.js.map +1 -1
  146. package/dist/metrics-C9YY1OcL.js +239 -0
  147. package/dist/metrics-C9YY1OcL.js.map +1 -0
  148. package/dist/mint-yN2M2eh0.js +201 -0
  149. package/dist/mint-yN2M2eh0.js.map +1 -0
  150. package/dist/multi-layer-verifier-BHY1gWAc.d.ts +138 -0
  151. package/dist/multi-layer-verifier-BHY1gWAc.d.ts.map +1 -0
  152. package/dist/multishot/index.d.ts +273 -481
  153. package/dist/multishot/index.d.ts.map +1 -0
  154. package/dist/multishot/index.js +595 -548
  155. package/dist/multishot/index.js.map +1 -1
  156. package/dist/off-policy-DvgzvtIx.js +220 -0
  157. package/dist/off-policy-DvgzvtIx.js.map +1 -0
  158. package/dist/off-policy-mskQw8Mb.d.ts +153 -0
  159. package/dist/off-policy-mskQw8Mb.d.ts.map +1 -0
  160. package/dist/openapi.json +1 -1
  161. package/dist/opencode-sqlite-BGrHeDu3.js +318 -0
  162. package/dist/opencode-sqlite-BGrHeDu3.js.map +1 -0
  163. package/dist/outcome-store-BYHIuO0e.d.ts +65 -0
  164. package/dist/outcome-store-BYHIuO0e.d.ts.map +1 -0
  165. package/dist/outcome-store-ChBKlTd_.js +75 -0
  166. package/dist/outcome-store-ChBKlTd_.js.map +1 -0
  167. package/dist/paired-arms-D9D0wXj2.js +260 -0
  168. package/dist/paired-arms-D9D0wXj2.js.map +1 -0
  169. package/dist/pipelines/index.d.ts +95 -532
  170. package/dist/pipelines/index.d.ts.map +1 -0
  171. package/dist/pipelines/index.js +497 -478
  172. package/dist/pipelines/index.js.map +1 -1
  173. package/dist/pre-registration-DakwTRXk.js +96 -0
  174. package/dist/pre-registration-DakwTRXk.js.map +1 -0
  175. package/dist/propose-review-control-LhIWGzHl.js +1458 -0
  176. package/dist/propose-review-control-LhIWGzHl.js.map +1 -0
  177. package/dist/query-CJ_DX8vl.d.ts +28 -0
  178. package/dist/query-CJ_DX8vl.d.ts.map +1 -0
  179. package/dist/query-Di7eEQ79.js +83 -0
  180. package/dist/query-Di7eEQ79.js.map +1 -0
  181. package/dist/raw-provider-sink-BQd7mzyT.js +201 -0
  182. package/dist/raw-provider-sink-BQd7mzyT.js.map +1 -0
  183. package/dist/raw-provider-sink-BU29Sh8h.d.ts +134 -0
  184. package/dist/raw-provider-sink-BU29Sh8h.d.ts.map +1 -0
  185. package/dist/redact-7Aq1ukl-.js +107 -0
  186. package/dist/redact-7Aq1ukl-.js.map +1 -0
  187. package/dist/release-report-Cz9NKH39.js +603 -0
  188. package/dist/release-report-Cz9NKH39.js.map +1 -0
  189. package/dist/release-report-mvB2G4_J.d.ts +244 -0
  190. package/dist/release-report-mvB2G4_J.d.ts.map +1 -0
  191. package/dist/replay-GnyotH0J.js +1741 -0
  192. package/dist/replay-GnyotH0J.js.map +1 -0
  193. package/dist/replay-OoidtG1E.d.ts +749 -0
  194. package/dist/replay-OoidtG1E.d.ts.map +1 -0
  195. package/dist/reporting.d.ts +6 -1298
  196. package/dist/reporting.js +6 -50
  197. package/dist/researcher-CwTdwXG1.d.ts +314 -0
  198. package/dist/researcher-CwTdwXG1.d.ts.map +1 -0
  199. package/dist/reward-hacking-eAnOsynk.d.ts +224 -0
  200. package/dist/reward-hacking-eAnOsynk.d.ts.map +1 -0
  201. package/dist/reward-hacking-qipEpKvY.js +596 -0
  202. package/dist/reward-hacking-qipEpKvY.js.map +1 -0
  203. package/dist/reward-nw2xZGZG.js +137 -0
  204. package/dist/reward-nw2xZGZG.js.map +1 -0
  205. package/dist/rl.d.ts +916 -3596
  206. package/dist/rl.d.ts.map +1 -0
  207. package/dist/rl.js +2362 -1751
  208. package/dist/rl.js.map +1 -1
  209. package/dist/rolldown-runtime-8H4AJuhK.js +14 -0
  210. package/dist/rollout/index.d.ts +3 -1048
  211. package/dist/rollout/index.js +8 -110
  212. package/dist/rollout-BOYjemfR.js +624 -0
  213. package/dist/rollout-BOYjemfR.js.map +1 -0
  214. package/dist/rubric-predictive-validity-B3xmbmS1.js +141 -0
  215. package/dist/rubric-predictive-validity-B3xmbmS1.js.map +1 -0
  216. package/dist/rubric-predictive-validity-Ku_clp_1.d.ts +74 -0
  217. package/dist/rubric-predictive-validity-Ku_clp_1.d.ts.map +1 -0
  218. package/dist/run-evidence-ClRX_8A9.d.ts +225 -0
  219. package/dist/run-evidence-ClRX_8A9.d.ts.map +1 -0
  220. package/dist/run-record-BuoE80Dq.js +467 -0
  221. package/dist/run-record-BuoE80Dq.js.map +1 -0
  222. package/dist/run-record-CnZu_gjl.d.ts +357 -0
  223. package/dist/run-record-CnZu_gjl.d.ts.map +1 -0
  224. package/dist/run-score-iEEAWiBY.js +41 -0
  225. package/dist/run-score-iEEAWiBY.js.map +1 -0
  226. package/dist/runtime-trajectory-1gyaTOoC.js +93 -0
  227. package/dist/runtime-trajectory-1gyaTOoC.js.map +1 -0
  228. package/dist/runtime-trajectory-BvSZcCHD.d.ts +50 -0
  229. package/dist/runtime-trajectory-BvSZcCHD.d.ts.map +1 -0
  230. package/dist/schema-BtVldJ3T.d.ts +206 -0
  231. package/dist/schema-BtVldJ3T.d.ts.map +1 -0
  232. package/dist/schema-C6DW4ZHR.js +821 -0
  233. package/dist/schema-C6DW4ZHR.js.map +1 -0
  234. package/dist/schema-CRhEY1SO.js +69 -0
  235. package/dist/schema-CRhEY1SO.js.map +1 -0
  236. package/dist/schema-Cef2cFmb.d.ts +408 -0
  237. package/dist/schema-Cef2cFmb.d.ts.map +1 -0
  238. package/dist/semantic-concept-judge-B6cWNJ2K.js +725 -0
  239. package/dist/semantic-concept-judge-B6cWNJ2K.js.map +1 -0
  240. package/dist/sequential-Br0mAPHA.js +148 -0
  241. package/dist/sequential-Br0mAPHA.js.map +1 -0
  242. package/dist/sequential-CYwq6Ff_.d.ts +141 -0
  243. package/dist/sequential-CYwq6Ff_.d.ts.map +1 -0
  244. package/dist/series-convergence-CjO2QdRW.js +43 -0
  245. package/dist/series-convergence-CjO2QdRW.js.map +1 -0
  246. package/dist/series-convergence-ofsqPWhs.d.ts +35 -0
  247. package/dist/series-convergence-ofsqPWhs.d.ts.map +1 -0
  248. package/dist/server-m5D9cvnG.js +1040 -0
  249. package/dist/server-m5D9cvnG.js.map +1 -0
  250. package/dist/skill-usage-C_pXm7lP.d.ts +534 -0
  251. package/dist/skill-usage-C_pXm7lP.d.ts.map +1 -0
  252. package/dist/skillopt-optimization-method-B7wX7XkF.d.ts +1739 -0
  253. package/dist/skillopt-optimization-method-B7wX7XkF.d.ts.map +1 -0
  254. package/dist/skillopt-optimization-method-D4ODwFVV.js +7712 -0
  255. package/dist/skillopt-optimization-method-D4ODwFVV.js.map +1 -0
  256. package/dist/statistics-Cmj6nynr.d.ts +514 -0
  257. package/dist/statistics-Cmj6nynr.d.ts.map +1 -0
  258. package/dist/statistics-CnnxdpOg.js +1437 -0
  259. package/dist/statistics-CnnxdpOg.js.map +1 -0
  260. package/dist/store-CT9YIIve.d.ts +117 -0
  261. package/dist/store-CT9YIIve.d.ts.map +1 -0
  262. package/dist/store-CxJry_cs.d.ts +229 -0
  263. package/dist/store-CxJry_cs.d.ts.map +1 -0
  264. package/dist/storyboard/index.d.ts +84 -203
  265. package/dist/storyboard/index.d.ts.map +1 -0
  266. package/dist/storyboard/index.js +609 -542
  267. package/dist/storyboard/index.js.map +1 -1
  268. package/dist/summary-report-BNs5nmXI.js +862 -0
  269. package/dist/summary-report-BNs5nmXI.js.map +1 -0
  270. package/dist/summary-report-Cj9gdw4i.d.ts +407 -0
  271. package/dist/summary-report-Cj9gdw4i.d.ts.map +1 -0
  272. package/dist/supervisor-run/index.d.ts +2 -849
  273. package/dist/supervisor-run/index.js +2 -64
  274. package/dist/supervisor-run-_lnTLM3z.js +1679 -0
  275. package/dist/supervisor-run-_lnTLM3z.js.map +1 -0
  276. package/dist/task-failure-attributes-CQZlB3et.js +311 -0
  277. package/dist/task-failure-attributes-CQZlB3et.js.map +1 -0
  278. package/dist/test-graded-scenario-BsqWLmPt.js +318 -0
  279. package/dist/test-graded-scenario-BsqWLmPt.js.map +1 -0
  280. package/dist/test-graded-scenario-D1TaI2va.d.ts +141 -0
  281. package/dist/test-graded-scenario-D1TaI2va.d.ts.map +1 -0
  282. package/dist/tools-BmuN627J.js +1085 -0
  283. package/dist/tools-BmuN627J.js.map +1 -0
  284. package/dist/trace-attributes.d.ts +2 -52
  285. package/dist/trace-attributes.js +131 -61
  286. package/dist/trace-attributes.js.map +1 -1
  287. package/dist/traces.d.ts +12 -2365
  288. package/dist/traces.js +12 -251
  289. package/dist/trajectory-D_7rLrvE.js +56 -0
  290. package/dist/trajectory-D_7rLrvE.js.map +1 -0
  291. package/dist/types-DGsxbAEd.d.ts +387 -0
  292. package/dist/types-DGsxbAEd.d.ts.map +1 -0
  293. package/dist/types-k9tZGKUg.d.ts +640 -0
  294. package/dist/types-k9tZGKUg.d.ts.map +1 -0
  295. package/dist/verdict-Dps8_okt.d.ts +37 -0
  296. package/dist/verdict-Dps8_okt.d.ts.map +1 -0
  297. package/dist/wire/index.d.ts +702 -1174
  298. package/dist/wire/index.d.ts.map +1 -0
  299. package/dist/wire/index.js +2 -81
  300. package/docs/feature-guide.md +1 -1
  301. package/docs/rollout.md +116 -2
  302. package/package.json +18 -10
  303. package/dist/benchmarks/index.js.map +0 -1
  304. package/dist/campaign/index.js.map +0 -1
  305. package/dist/chunk-2JX3CFMB.js +0 -695
  306. package/dist/chunk-2JX3CFMB.js.map +0 -1
  307. package/dist/chunk-2MKQIFS4.js +0 -183
  308. package/dist/chunk-2MKQIFS4.js.map +0 -1
  309. package/dist/chunk-3RF76KTD.js +0 -84
  310. package/dist/chunk-3RF76KTD.js.map +0 -1
  311. package/dist/chunk-5DTSBUL2.js +0 -159
  312. package/dist/chunk-5DTSBUL2.js.map +0 -1
  313. package/dist/chunk-7ZZMD7UK.js +0 -386
  314. package/dist/chunk-7ZZMD7UK.js.map +0 -1
  315. package/dist/chunk-BOD4O7OF.js +0 -40
  316. package/dist/chunk-BOD4O7OF.js.map +0 -1
  317. package/dist/chunk-BYT7ELPS.js +0 -1553
  318. package/dist/chunk-BYT7ELPS.js.map +0 -1
  319. package/dist/chunk-DJKY2TSY.js +0 -2428
  320. package/dist/chunk-DJKY2TSY.js.map +0 -1
  321. package/dist/chunk-DPUHNQLN.js +0 -232
  322. package/dist/chunk-DPUHNQLN.js.map +0 -1
  323. package/dist/chunk-DRYIUNWY.js +0 -622
  324. package/dist/chunk-DRYIUNWY.js.map +0 -1
  325. package/dist/chunk-EJGRPCO3.js +0 -617
  326. package/dist/chunk-EJGRPCO3.js.map +0 -1
  327. package/dist/chunk-EOSZT7PL.js +0 -2001
  328. package/dist/chunk-EOSZT7PL.js.map +0 -1
  329. package/dist/chunk-EZJEIH2R.js +0 -1559
  330. package/dist/chunk-EZJEIH2R.js.map +0 -1
  331. package/dist/chunk-GGE4NNQT.js +0 -65
  332. package/dist/chunk-GGE4NNQT.js.map +0 -1
  333. package/dist/chunk-HHWE3POT.js +0 -94
  334. package/dist/chunk-HHWE3POT.js.map +0 -1
  335. package/dist/chunk-IHQDPH7D.js +0 -171
  336. package/dist/chunk-IHQDPH7D.js.map +0 -1
  337. package/dist/chunk-JHCHEVET.js +0 -274
  338. package/dist/chunk-JHCHEVET.js.map +0 -1
  339. package/dist/chunk-K4DBDHLK.js +0 -158
  340. package/dist/chunk-K4DBDHLK.js.map +0 -1
  341. package/dist/chunk-K6N6XJJX.js +0 -306
  342. package/dist/chunk-K6N6XJJX.js.map +0 -1
  343. package/dist/chunk-MA6HLL3S.js +0 -65
  344. package/dist/chunk-MA6HLL3S.js.map +0 -1
  345. package/dist/chunk-MAZ26DC7.js +0 -99
  346. package/dist/chunk-MAZ26DC7.js.map +0 -1
  347. package/dist/chunk-MHELPNRP.js +0 -1212
  348. package/dist/chunk-MHELPNRP.js.map +0 -1
  349. package/dist/chunk-NACAGYSY.js +0 -1040
  350. package/dist/chunk-NACAGYSY.js.map +0 -1
  351. package/dist/chunk-NKAGIDE2.js +0 -7633
  352. package/dist/chunk-NKAGIDE2.js.map +0 -1
  353. package/dist/chunk-NPCTHQIO.js +0 -91
  354. package/dist/chunk-NPCTHQIO.js.map +0 -1
  355. package/dist/chunk-NYLOYM6N.js +0 -332
  356. package/dist/chunk-NYLOYM6N.js.map +0 -1
  357. package/dist/chunk-ONWEPEDO.js +0 -57
  358. package/dist/chunk-ONWEPEDO.js.map +0 -1
  359. package/dist/chunk-P5W7RQKK.js +0 -576
  360. package/dist/chunk-P5W7RQKK.js.map +0 -1
  361. package/dist/chunk-P6FYH6K4.js +0 -1161
  362. package/dist/chunk-P6FYH6K4.js.map +0 -1
  363. package/dist/chunk-PBE2LOSS.js +0 -669
  364. package/dist/chunk-PBE2LOSS.js.map +0 -1
  365. package/dist/chunk-PC4UYEBM.js +0 -166
  366. package/dist/chunk-PC4UYEBM.js.map +0 -1
  367. package/dist/chunk-PXE2VKMX.js +0 -140
  368. package/dist/chunk-PXE2VKMX.js.map +0 -1
  369. package/dist/chunk-PZ5AY32C.js +0 -10
  370. package/dist/chunk-PZ5AY32C.js.map +0 -1
  371. package/dist/chunk-RZTMDUO7.js +0 -49
  372. package/dist/chunk-RZTMDUO7.js.map +0 -1
  373. package/dist/chunk-S5YLIBFX.js +0 -136
  374. package/dist/chunk-S5YLIBFX.js.map +0 -1
  375. package/dist/chunk-SZLVEKMJ.js +0 -1446
  376. package/dist/chunk-SZLVEKMJ.js.map +0 -1
  377. package/dist/chunk-T4SQEITX.js +0 -95
  378. package/dist/chunk-T4SQEITX.js.map +0 -1
  379. package/dist/chunk-TBL77AUT.js +0 -355
  380. package/dist/chunk-TBL77AUT.js.map +0 -1
  381. package/dist/chunk-TSN7JT6D.js +0 -1646
  382. package/dist/chunk-TSN7JT6D.js.map +0 -1
  383. package/dist/chunk-TT4KNT67.js +0 -124
  384. package/dist/chunk-TT4KNT67.js.map +0 -1
  385. package/dist/chunk-UB2LOJ6Q.js +0 -4461
  386. package/dist/chunk-UB2LOJ6Q.js.map +0 -1
  387. package/dist/chunk-UWZZKKU7.js +0 -237
  388. package/dist/chunk-UWZZKKU7.js.map +0 -1
  389. package/dist/chunk-VBQ3CRKH.js +0 -291
  390. package/dist/chunk-VBQ3CRKH.js.map +0 -1
  391. package/dist/chunk-VGRCHJON.js +0 -163
  392. package/dist/chunk-VGRCHJON.js.map +0 -1
  393. package/dist/chunk-VI2UW6B6.js +0 -162
  394. package/dist/chunk-VI2UW6B6.js.map +0 -1
  395. package/dist/chunk-VLOATJQ2.js +0 -908
  396. package/dist/chunk-VLOATJQ2.js.map +0 -1
  397. package/dist/chunk-VQMK5FMP.js +0 -247
  398. package/dist/chunk-VQMK5FMP.js.map +0 -1
  399. package/dist/chunk-VZSRQ272.js +0 -149
  400. package/dist/chunk-VZSRQ272.js.map +0 -1
  401. package/dist/chunk-WGXIEX7P.js +0 -116
  402. package/dist/chunk-WGXIEX7P.js.map +0 -1
  403. package/dist/chunk-WS3NZZQQ.js +0 -929
  404. package/dist/chunk-WS3NZZQQ.js.map +0 -1
  405. package/dist/chunk-XDWDC2MP.js +0 -695
  406. package/dist/chunk-XDWDC2MP.js.map +0 -1
  407. package/dist/chunk-XPRT64IE.js +0 -766
  408. package/dist/chunk-XPRT64IE.js.map +0 -1
  409. package/dist/chunk-YJBNWCAA.js +0 -1056
  410. package/dist/chunk-YJBNWCAA.js.map +0 -1
  411. package/dist/chunk-ZET2UAYW.js +0 -89
  412. package/dist/chunk-ZET2UAYW.js.map +0 -1
  413. package/dist/chunk-ZUUWPZCV.js +0 -752
  414. package/dist/chunk-ZUUWPZCV.js.map +0 -1
  415. package/dist/control.js.map +0 -1
  416. package/dist/hosted/index.js.map +0 -1
  417. package/dist/matrix/index.js.map +0 -1
  418. package/dist/reporting.js.map +0 -1
  419. package/dist/rollout/index.js.map +0 -1
  420. package/dist/run-campaign-ISHFZ7FJ.js +0 -17
  421. package/dist/run-campaign-ISHFZ7FJ.js.map +0 -1
  422. package/dist/supervisor-run/index.js.map +0 -1
  423. package/dist/traces.js.map +0 -1
  424. package/dist/wire/index.js.map +0 -1
@@ -1,2001 +0,0 @@
1
- import {
2
- readTaskFailureLabels,
3
- recordAggregateMeasurements,
4
- summarizeExecutionMeasurements,
5
- summarizeTraceErrors
6
- } from "./chunk-7ZZMD7UK.js";
7
- import {
8
- extractUsage,
9
- extractUsageFromSse
10
- } from "./chunk-PXE2VKMX.js";
11
- import {
12
- analyzeTraces
13
- } from "./chunk-5DTSBUL2.js";
14
- import {
15
- applyToolSpanOtlpAttributes,
16
- classifyOtlpSpanRole,
17
- compareSpanTime,
18
- firstStringAttr,
19
- isOtlpModelCall,
20
- projectOtlpFlatLine,
21
- spanEpochMillis,
22
- traceSpanKindToOpenInferenceKind
23
- } from "./chunk-P6FYH6K4.js";
24
- import {
25
- defaultProviderRedactor,
26
- providerFromBaseUrl
27
- } from "./chunk-PC4UYEBM.js";
28
- import {
29
- canonicalize,
30
- hashJson,
31
- validateRunRecord
32
- } from "./chunk-2JX3CFMB.js";
33
- import {
34
- ReplayError
35
- } from "./chunk-ONWEPEDO.js";
36
- import {
37
- LLM_INPUT_TOKENS,
38
- LLM_MODEL_ATTR_KEYS,
39
- LLM_MODEL_NAME,
40
- LLM_OUTPUT_TOKENS,
41
- OPENINFERENCE_SPAN_KIND,
42
- TOOL_NAME,
43
- applyLlmSpanOtlpAttributes
44
- } from "./chunk-K4DBDHLK.js";
45
-
46
- // src/trace-analyst/hook.ts
47
- var DEFAULT_QUESTION = "Summarise what happened in this run. Surface any failure modes, surprising findings, or evidence that the run's verdict is wrong.";
48
- function traceAnalystOnRunComplete(opts) {
49
- return async (ctx) => {
50
- if (opts.shouldRun && !opts.shouldRun(ctx)) return;
51
- const source = opts.analyze.source;
52
- if (source === void 0) {
53
- await ctx.store.appendEvent({
54
- eventId: `analyst-skip-${ctx.runId}`,
55
- runId: ctx.runId,
56
- kind: "log",
57
- timestamp: Date.now(),
58
- payload: { source: "trace_analyst_hook", reason: "no source configured" }
59
- });
60
- return;
61
- }
62
- const result = await analyzeTraces({ question: opts.question ?? DEFAULT_QUESTION }, {
63
- ...opts.analyze,
64
- source
65
- });
66
- if (opts.save) await opts.save(result, ctx);
67
- if (opts.gateOn && !opts.gateOn(result, ctx)) {
68
- await ctx.store.appendEvent({
69
- eventId: `analyst-gate-${ctx.runId}`,
70
- runId: ctx.runId,
71
- kind: "log",
72
- timestamp: Date.now(),
73
- payload: {
74
- source: "trace_analyst_hook",
75
- reason: "analyst_gate_failed",
76
- findings: result.findings
77
- }
78
- });
79
- }
80
- };
81
- }
82
-
83
- // src/trace-analyst/insights.ts
84
- var DOMAIN_STOP_WORDS = /* @__PURE__ */ new Set([
85
- "and",
86
- "advanced",
87
- "app",
88
- "build",
89
- "create",
90
- "easy",
91
- "expert",
92
- "extreme",
93
- "for",
94
- "from",
95
- "hard",
96
- "implementation",
97
- "integrate",
98
- "medium",
99
- "project",
100
- "task",
101
- "the",
102
- "this",
103
- "with",
104
- "workflow"
105
- ]);
106
- function tokenizeDomainWords(value) {
107
- return [...value.matchAll(/[A-Za-z][A-Za-z0-9.+#-]{2,}/g)].map((match) => match[0].toLowerCase()).filter((word) => !DOMAIN_STOP_WORDS.has(word));
108
- }
109
- function inferDomainKeywords(suite) {
110
- const suiteWords = new Set(tokenizeDomainWords(`${suite.name} ${suite.collectionId ?? ""}`));
111
- const source = [
112
- suite.name,
113
- suite.collectionId ?? "",
114
- ...suite.tasks.flatMap((task) => [
115
- task.id,
116
- task.name,
117
- task.prompt ?? "",
118
- task.difficulty ?? "",
119
- ...task.tags ?? [],
120
- ...task.gaps ?? []
121
- ])
122
- ].join(" ");
123
- const counts = /* @__PURE__ */ new Map();
124
- for (const word of tokenizeDomainWords(source)) counts.set(word, (counts.get(word) ?? 0) + 1);
125
- return [...counts.entries()].filter(([word, count]) => count >= 2 || suiteWords.has(word)).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([word]) => word).slice(0, 18);
126
- }
127
- function domainEvidencePattern(keywords) {
128
- const escaped = keywords.filter((keyword) => keyword.length >= 3).map((keyword) => keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
129
- return escaped.length > 0 ? new RegExp(`(?<![A-Za-z0-9])(?:${escaped.join("|")})(?![A-Za-z0-9])`, "i") : /(?<![A-Za-z0-9])(?:sdk|api|css|dns|xml|provider|client|service|integration|webhook|transaction|auth|oauth|graphql|rest)(?![A-Za-z0-9])/i;
130
- }
131
- function describeTraceInsightScope(suite) {
132
- const taskLabel = suite.tasks.length === 1 ? "1 implementation task" : `${suite.tasks.length} implementation tasks`;
133
- const tags = /* @__PURE__ */ new Map();
134
- for (const task of suite.tasks) {
135
- for (const tag of task.tags ?? []) tags.set(tag, (tags.get(tag) ?? 0) + 1);
136
- }
137
- const topTags = [...tags.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, 8).map(([tag]) => tag);
138
- if (topTags.length > 0) return `${taskLabel} across ${topTags.join(", ")}.`;
139
- const difficulties = [
140
- ...new Set(
141
- suite.tasks.map((task) => task.difficulty).filter((value) => Boolean(value))
142
- )
143
- ].join(", ");
144
- return `${taskLabel} across ${difficulties || "the selected benchmark scope"}.`;
145
- }
146
- function planTraceInsightQuestions(input) {
147
- const hasFailures = input.suite.tasks.some((task) => task.outcome && task.outcome !== "satisfied");
148
- const hasMultipleShots = input.suite.tasks.some(
149
- (task) => (task.gaps ?? []).some((gap) => /shot|review|retry|continue/i.test(gap))
150
- );
151
- const questions = [
152
- {
153
- id: "execution-path",
154
- question: "What did the worker actually do before the first meaningful implementation edit?",
155
- why: "Separates grounded execution from polished but shallow output."
156
- },
157
- {
158
- id: "research-grounding",
159
- question: "Did the worker inspect docs, source, examples, or package references before committing to an implementation path?",
160
- why: "Identifies whether failures came from weak retrieval, weak examples, or premature coding."
161
- },
162
- {
163
- id: "domain-proof",
164
- question: "Which tasks produced executable domain proof versus UI copy, placeholders, or inferred behavior?",
165
- why: "Keeps product-quality claims tied to concrete evidence."
166
- },
167
- {
168
- id: "root-cause",
169
- question: "For each major failure cluster, is the likely root cause prompt/scaffold, docs/examples, SDK/API ergonomics, evaluator, runtime, or model behavior?",
170
- why: "Turns trace observations into actionable ownership."
171
- },
172
- {
173
- id: "evidence-quality",
174
- question: "Which external-facing claims are directly supported by trace ids, span ids, verifier findings, reviewer notes, or generated code?",
175
- why: "Prevents unsupported customer-report conclusions."
176
- }
177
- ];
178
- if (hasMultipleShots) {
179
- questions.push({
180
- id: "reviewer-lift",
181
- question: "Where did reviewer feedback improve score, stall, or regress across shots?",
182
- why: "Shows whether the driver loop is learning or merely repeating work."
183
- });
184
- }
185
- if (hasFailures) {
186
- questions.push({
187
- id: "optimization-targets",
188
- question: "Which prompt, evaluator, scaffold, or workflow changes should feed the next GEPA/autoresearch optimization run?",
189
- why: "Connects benchmark evidence to the optimization loop."
190
- });
191
- }
192
- return questions;
193
- }
194
- function buildTraceInsightContext(input) {
195
- return {
196
- suite: input.suite,
197
- scope: describeTraceInsightScope(input.suite),
198
- keywords: inferDomainKeywords(input.suite),
199
- questions: planTraceInsightQuestions(input),
200
- panel: defaultTraceInsightPanel(),
201
- findings: input.findings ?? [],
202
- agent: input.agent ?? null,
203
- totals: input.totals ?? null
204
- };
205
- }
206
- function scoreTraceInsightReadiness(context) {
207
- const failedTasks = context.suite.tasks.filter(
208
- (task) => task.outcome && task.outcome !== "satisfied"
209
- );
210
- const findingTaskIds = new Set(context.findings.flatMap((finding) => finding.taskIds));
211
- const failedTasksWithFindings = failedTasks.filter((task) => findingTaskIds.has(task.id));
212
- const tasksWithGaps = context.suite.tasks.filter((task) => (task.gaps ?? []).length > 0);
213
- const gates = [
214
- {
215
- id: "domain-context",
216
- label: "Domain context inferred",
217
- passed: context.keywords.length > 0,
218
- severity: "high",
219
- detail: context.keywords.length > 0 ? `${context.keywords.length} domain terms inferred: ${context.keywords.slice(0, 8).join(", ")}` : "No domain terms were inferred from suite, tasks, prompts, tags, or gaps."
220
- },
221
- {
222
- id: "panel-coverage",
223
- label: "Analyst panel planned",
224
- passed: context.panel.length >= 4 && context.questions.length >= 5,
225
- severity: "high",
226
- detail: `${context.panel.length} panel roles and ${context.questions.length} investigation questions planned.`
227
- },
228
- {
229
- id: "failure-coverage",
230
- label: "Failures mapped to findings",
231
- passed: failedTasks.length === 0 || failedTasksWithFindings.length / failedTasks.length >= 0.5,
232
- severity: "critical",
233
- detail: failedTasks.length === 0 ? "No failed tasks in suite." : `${failedTasksWithFindings.length}/${failedTasks.length} failed tasks appear in finding clusters.`
234
- },
235
- {
236
- id: "gap-evidence",
237
- label: "Task gaps captured",
238
- passed: failedTasks.length === 0 || tasksWithGaps.length / failedTasks.length >= 0.5,
239
- severity: "medium",
240
- detail: `${tasksWithGaps.length} tasks include explicit evaluator or analyst gaps.`
241
- }
242
- ];
243
- const penalty = gates.reduce((sum, gate) => {
244
- if (gate.passed) return sum;
245
- if (gate.severity === "critical") return sum + 35;
246
- if (gate.severity === "high") return sum + 20;
247
- if (gate.severity === "medium") return sum + 10;
248
- return sum + 5;
249
- }, 0);
250
- const score = Math.max(0, Math.min(1, 1 - penalty / 100));
251
- return {
252
- score,
253
- grade: score >= 0.9 ? "external-ready" : score >= 0.7 ? "internal-review" : "raw-analysis",
254
- gates
255
- };
256
- }
257
- function defaultTraceInsightPanel() {
258
- return [
259
- {
260
- id: "trace-forensics",
261
- name: "Trace Forensics",
262
- responsibility: "Reconstruct what the worker did in order, including research, edits, reviewer interventions, verifier feedback, and stop reason."
263
- },
264
- {
265
- id: "root-cause",
266
- name: "Root Cause",
267
- responsibility: "Map failures to prompt/scaffold, docs/examples, SDK/API/product ergonomics, evaluator, runtime, or model behavior."
268
- },
269
- {
270
- id: "optimization",
271
- name: "Optimization",
272
- responsibility: "Identify prompt, reviewer, evaluator, scaffold, and GEPA/autoresearch changes that should be tested next."
273
- },
274
- {
275
- id: "external-evidence",
276
- name: "External Evidence",
277
- responsibility: "Separate customer-safe claims from internal harness findings and reject conclusions without task, trace, span, code, reviewer, or verifier evidence."
278
- }
279
- ];
280
- }
281
- function buildTraceInsightPrompt(input) {
282
- const context = buildTraceInsightContext(input);
283
- const maxRepresentativeTraces = input.maxRepresentativeTraces ?? 6;
284
- return `Analyze this benchmark run and produce evidence-backed trace intelligence.
285
-
286
- Audience:
287
- - internal AI/product leadership
288
- - possible customer-facing report for ${input.suite.name}
289
-
290
- Investigation plan:
291
- ${context.questions.map((item, index) => `${index + 1}. ${item.question} (${item.why})`).join("\n")}
292
-
293
- Analyst panel:
294
- ${context.panel.map((role) => `- ${role.name}: ${role.responsibility}`).join("\n")}
295
-
296
- If the task branches are independent, use subagents for the panel roles above and aggregate their findings. Do not run a panel role unless its answer will change the final report.
297
-
298
- Required output:
299
- 1. Executive verdict: what this run proves and does not prove.
300
- 2. The investigation questions you answered and the evidence used.
301
- 3. Failure taxonomy: agent prompting, evaluator/harness, docs/examples, SDK/API/product integration, infra.
302
- 4. Evidence-backed examples with trace ids/task ids and concrete verifier findings.
303
- 5. Highest-ROI fixes for the benchmark harness, prompt/GEPA optimization, and customer-facing product/docs surface.
304
- 6. What is safe for an external report versus what must stay internal.
305
- 7. One rerun plan that would validate lift after optimization.
306
-
307
- Budget:
308
- - Inspect the dataset overview, the failure summary, and at most ${maxRepresentativeTraces} representative traces.
309
- - Prefer traces named in the failure summary over broad exploration.
310
- - Do not do exhaustive trace sweeps.
311
- - Return the final report as soon as the taxonomy and examples are supported.
312
-
313
- Run summary:
314
- ${JSON.stringify(
315
- {
316
- suite: input.suite.name,
317
- scope: context.scope,
318
- inferredKeywords: context.keywords,
319
- agent: context.agent,
320
- totals: context.totals,
321
- findings: context.findings.map((finding) => ({
322
- kind: finding.kind,
323
- severity: finding.severity,
324
- taskCount: finding.taskIds.length,
325
- proposedFixClass: finding.proposedFixClass
326
- })),
327
- failures: input.suite.tasks.filter((task) => task.outcome && task.outcome !== "satisfied").map((task) => ({
328
- task: task.id,
329
- difficulty: task.difficulty,
330
- outcome: task.outcome,
331
- score: task.score,
332
- gaps: task.gaps ?? []
333
- }))
334
- },
335
- null,
336
- 2
337
- )}
338
-
339
- Use the trace tools. Do not invent facts. Cite task ids. Separate customer-facing claims from internal harness/model findings.`;
340
- }
341
-
342
- // src/trace-analyst/otlp-flatten.ts
343
- var DEFAULT_KIND_MAP = {
344
- 0: "SPAN_KIND_UNSPECIFIED",
345
- 1: "SPAN_KIND_INTERNAL",
346
- 2: "SPAN_KIND_SERVER",
347
- 3: "SPAN_KIND_CLIENT",
348
- 4: "SPAN_KIND_PRODUCER",
349
- 5: "SPAN_KIND_CONSUMER"
350
- };
351
- var STATUS_MAP = {
352
- 0: "STATUS_CODE_UNSET",
353
- 1: "STATUS_CODE_OK",
354
- 2: "STATUS_CODE_ERROR"
355
- };
356
- function attrValue(v) {
357
- if (v.stringValue !== void 0) return v.stringValue;
358
- if (v.intValue !== void 0) return Number(v.intValue);
359
- if (v.doubleValue !== void 0) return v.doubleValue;
360
- if (v.boolValue !== void 0) return v.boolValue;
361
- return "";
362
- }
363
- function attrsToRecord(attrs) {
364
- const out = {};
365
- for (const a of attrs) out[a.key] = attrValue(a.value);
366
- return out;
367
- }
368
- function nanoToIso(nano) {
369
- const ms = Number(nano) / 1e6;
370
- return Number.isFinite(ms) ? new Date(ms).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString();
371
- }
372
- function applyOpenInference(attrs) {
373
- if ("llm.model" in attrs && !(LLM_MODEL_NAME in attrs)) {
374
- attrs[LLM_MODEL_NAME] = attrs["llm.model"];
375
- }
376
- if ("llm.input_tokens" in attrs && !(LLM_INPUT_TOKENS in attrs)) {
377
- attrs[LLM_INPUT_TOKENS] = attrs["llm.input_tokens"];
378
- }
379
- if ("inference.llm.input_tokens" in attrs && !(LLM_INPUT_TOKENS in attrs)) {
380
- attrs[LLM_INPUT_TOKENS] = attrs["inference.llm.input_tokens"];
381
- }
382
- if ("llm.output_tokens" in attrs && !(LLM_OUTPUT_TOKENS in attrs)) {
383
- attrs[LLM_OUTPUT_TOKENS] = attrs["llm.output_tokens"];
384
- }
385
- if ("inference.llm.output_tokens" in attrs && !(LLM_OUTPUT_TOKENS in attrs)) {
386
- attrs[LLM_OUTPUT_TOKENS] = attrs["inference.llm.output_tokens"];
387
- }
388
- if (TOOL_NAME in attrs && !("inference.tool.name" in attrs)) {
389
- attrs["inference.tool.name"] = attrs[TOOL_NAME];
390
- }
391
- if ("span.kind" in attrs && !(OPENINFERENCE_SPAN_KIND in attrs)) {
392
- attrs[OPENINFERENCE_SPAN_KIND] = String(attrs["span.kind"]).toUpperCase();
393
- }
394
- }
395
- function flattenOtlpExportToNdjson(otlpExport, opts = {}) {
396
- const vocab = opts.attributeVocabulary ?? "openinference";
397
- const kindMap = { ...DEFAULT_KIND_MAP, ...opts.kindMap };
398
- const lines = [];
399
- for (const rs of otlpExport.resourceSpans ?? []) {
400
- const resource = { attributes: attrsToRecord(rs.resource?.attributes ?? []) };
401
- for (const scope of rs.scopeSpans ?? []) {
402
- for (const span of scope.spans ?? []) {
403
- const attributes = attrsToRecord(span.attributes ?? []);
404
- if (vocab === "openinference") applyOpenInference(attributes);
405
- const line = {
406
- trace_id: span.traceId,
407
- span_id: span.spanId,
408
- parent_span_id: span.parentSpanId ?? null,
409
- name: span.name,
410
- kind: kindMap[span.kind] ?? "SPAN_KIND_UNSPECIFIED",
411
- start_time: nanoToIso(span.startTimeUnixNano),
412
- end_time: nanoToIso(span.endTimeUnixNano),
413
- status: {
414
- code: STATUS_MAP[span.status?.code ?? 0] ?? "STATUS_CODE_UNSET",
415
- ...span.status?.message ? { message: span.status.message } : {}
416
- },
417
- resource,
418
- attributes
419
- };
420
- if (span.events && span.events.length > 0) {
421
- line.events = span.events.map((e) => ({
422
- name: e.name,
423
- timeUnixNano: e.timeUnixNano,
424
- ...e.attributes ? { attributes: attrsToRecord(e.attributes) } : {}
425
- }));
426
- }
427
- lines.push(line);
428
- }
429
- }
430
- }
431
- return lines;
432
- }
433
-
434
- // src/trace-analyst/otlp-to-run-records.ts
435
- function otlpToRunRecords(otlpJsonl, opts) {
436
- return otlpToTraceRunRecords(otlpJsonl, opts).map((r) => r.record);
437
- }
438
- function otlpRowsToRunRecords(rows, opts) {
439
- return otlpRowsToTraceRunRecords(rows, opts).map((row) => row.record);
440
- }
441
- function otlpToTraceRunRecords(otlpJsonl, opts) {
442
- return traceRunRecordsFromSpans(
443
- groupSpansByLogicalRun(groupJsonlSpansByTrace(otlpJsonl), opts.logicalRunIdForTrace),
444
- opts
445
- );
446
- }
447
- function otlpRowsToTraceRunRecords(rows, opts) {
448
- return traceRunRecordsFromSpans(
449
- groupSpansByLogicalRun(groupRowsByTrace(rows), opts.logicalRunIdForTrace),
450
- opts
451
- );
452
- }
453
- function traceRunRecordsFromSpans(byTrace, opts) {
454
- const splitTag = opts.splitTag ?? "holdout";
455
- const commitSha = opts.commitSha ?? "unknown";
456
- const promptHash = opts.promptHash ?? "unknown";
457
- const configHash = opts.configHash ?? "unknown";
458
- const seed = opts.seed ?? 0;
459
- const fallbackModel = opts.fallbackModel ?? "unknown@otlp";
460
- if (byTrace.size === 0) {
461
- throw new Error(
462
- "otlpToRunRecords: OTLP input produced zero valid spans \u2014 every row was empty, malformed, or missing trace_id/span_id"
463
- );
464
- }
465
- const traceIds = [...byTrace.keys()].sort();
466
- const out = [];
467
- for (const traceId of traceIds) {
468
- const spans = byTrace.get(traceId);
469
- const agg = aggregateTrace(traceId, spans, fallbackModel);
470
- const score = resolveScore(opts, traceId, agg);
471
- const { costUsd, costProvenance } = resolveCost(opts, agg);
472
- const raw = {
473
- source_trace_count: agg.sourceTraceCount,
474
- span_count: agg.spanCount,
475
- llm_span_count: agg.llmSpanCount,
476
- tool_span_count: agg.toolSpanCount,
477
- agent_span_count: agg.agentSpanCount,
478
- error_span_count: agg.errorSpanCount,
479
- execution_error_count: agg.executionErrorCount,
480
- process_error_count: agg.processErrorCount,
481
- guardrail_error_count: agg.guardrailErrorCount,
482
- judge_error_count: agg.judgeErrorCount,
483
- propagated_error_count: agg.propagatedErrorCount,
484
- unclassified_error_count: agg.unclassifiedErrorCount,
485
- prompt_tokens: agg.tokenUsage.input,
486
- completion_tokens: agg.tokenUsage.output
487
- };
488
- if (agg.tokenUsage.reasoning !== void 0) raw.reasoning_tokens = agg.tokenUsage.reasoning;
489
- if (agg.tokenUsage.cached !== void 0) raw.cached_tokens = agg.tokenUsage.cached;
490
- if (agg.tokenUsage.cacheWrite !== void 0) {
491
- raw.cache_write_tokens = agg.tokenUsage.cacheWrite;
492
- }
493
- if (agg.costMeasurement.value !== void 0 && !agg.costMeasurement.complete) {
494
- raw.partial_observed_cost_usd = agg.costMeasurement.value;
495
- }
496
- recordAggregateMeasurements(raw, agg.aggregateMeasurement);
497
- if (costProvenance.kind === "uncaptured") raw.cost_unpriced = 1;
498
- const outcome = { raw };
499
- if (score !== void 0) {
500
- if (splitTag === "holdout") outcome.holdoutScore = score;
501
- else outcome.searchScore = score;
502
- }
503
- const { promptText, completionText } = extractPromptCompletion(spans, agg.callSpanIds);
504
- const judgeMetadata = opts.judgeMetadataForTrace?.(traceId);
505
- const taskFailure = readTaskFailureLabels(
506
- spans.filter((span) => span.parent_span_id === null && isTerminalRootCandidate(span)),
507
- `otlpToRunRecords: run '${traceId}'`
508
- );
509
- const record = validateRunRecord({
510
- runId: `otlp:${opts.experimentId}:${opts.candidateId}:${traceId}`,
511
- experimentId: opts.experimentId,
512
- candidateId: opts.candidateId,
513
- seed,
514
- model: ensureSnapshot(agg.model, fallbackModel),
515
- promptHash,
516
- configHash,
517
- commitSha,
518
- wallMs: agg.wallMs,
519
- costUsd,
520
- costProvenance,
521
- tokenUsage: agg.tokenUsage,
522
- terminalOutcome: agg.terminalOutcome,
523
- ...agg.terminalFailureMessage ? { terminalFailureReason: agg.terminalFailureMessage } : {},
524
- ...judgeMetadata ? { judgeMetadata } : {},
525
- outcome,
526
- ...taskFailure,
527
- splitTag,
528
- scenarioId: traceId
529
- });
530
- out.push({
531
- record,
532
- ...promptText !== void 0 ? { promptText } : {},
533
- ...completionText !== void 0 ? { completionText } : {}
534
- });
535
- }
536
- return out;
537
- }
538
- function* yieldJsonlRows(otlpJsonl) {
539
- for (const line of otlpJsonl.split("\n")) {
540
- const trimmed = line.trim();
541
- if (trimmed.length === 0) continue;
542
- let parsed;
543
- try {
544
- parsed = JSON.parse(trimmed);
545
- } catch {
546
- continue;
547
- }
548
- if (parsed && typeof parsed === "object") yield parsed;
549
- }
550
- }
551
- function groupJsonlSpansByTrace(otlpJsonl) {
552
- return groupRowsByTrace(yieldJsonlRows(otlpJsonl));
553
- }
554
- function groupRowsByTrace(rows) {
555
- const byTrace = /* @__PURE__ */ new Map();
556
- for (const row of rows) {
557
- if (!row || typeof row !== "object") continue;
558
- const span = projectOtlpFlatLine(row);
559
- if (!span) continue;
560
- const arr = byTrace.get(span.trace_id);
561
- if (arr) arr.push(span);
562
- else byTrace.set(span.trace_id, [span]);
563
- }
564
- return byTrace;
565
- }
566
- function groupSpansByLogicalRun(byTrace, logicalRunIdForTrace) {
567
- if (!logicalRunIdForTrace) return byTrace;
568
- const byRun = /* @__PURE__ */ new Map();
569
- for (const [traceId, spans] of byTrace) {
570
- const suppliedRunId = logicalRunIdForTrace(traceId);
571
- if (typeof suppliedRunId !== "string" || suppliedRunId.trim().length === 0) {
572
- throw new Error(
573
- `otlpToRunRecords: logicalRunIdForTrace('${traceId}') returned an empty run id`
574
- );
575
- }
576
- const runId = suppliedRunId.trim();
577
- const target = byRun.get(runId) ?? [];
578
- for (const span of spans) {
579
- target.push({
580
- ...span,
581
- span_id: qualifySpanId(traceId, span.span_id),
582
- parent_span_id: span.parent_span_id ? qualifySpanId(traceId, span.parent_span_id) : null
583
- });
584
- }
585
- byRun.set(runId, target);
586
- }
587
- return byRun;
588
- }
589
- function qualifySpanId(traceId, spanId) {
590
- const prefix = `${traceId}:`;
591
- return spanId.startsWith(prefix) ? spanId : `${prefix}${spanId}`;
592
- }
593
- function aggregateTrace(traceId, spans, fallbackModel) {
594
- const ordered = [...spans].sort(
595
- (a2, b2) => compareSpanTime(a2.start_time, b2.start_time) || a2.span_id.localeCompare(b2.span_id)
596
- );
597
- const measurements = summarizeExecutionMeasurements(
598
- ordered.map((span) => ({
599
- id: span.span_id,
600
- ...span.parent_span_id ? { parentId: span.parent_span_id } : {},
601
- attributes: span.attributes,
602
- modelCall: isOtlpModelCall({
603
- kind: span.kind,
604
- name: span.name,
605
- attributes: span.attributes
606
- }),
607
- aggregate: span.kind !== "LLM" && span.kind !== "UNKNOWN"
608
- }))
609
- );
610
- let toolSpanCount = 0;
611
- let agentSpanCount = 0;
612
- let firstErrorMessage;
613
- const modelVotes = /* @__PURE__ */ new Map();
614
- let earliest = ordered[0]?.start_time ?? "";
615
- let latest = ordered[0]?.end_time ?? "";
616
- for (const s of ordered) {
617
- if (s.start_time && (!earliest || compareSpanTime(s.start_time, earliest) < 0))
618
- earliest = s.start_time;
619
- if (s.end_time && (!latest || compareSpanTime(s.end_time, latest) > 0)) latest = s.end_time;
620
- if (s.kind === "TOOL") {
621
- toolSpanCount += 1;
622
- } else if (s.kind === "AGENT") {
623
- agentSpanCount += 1;
624
- }
625
- if (s.status === "ERROR") {
626
- if (firstErrorMessage === void 0) {
627
- firstErrorMessage = (s.status_message ?? `${s.name} \u2014 STATUS_CODE_ERROR`).slice(0, 500);
628
- }
629
- }
630
- }
631
- const callSpanIds = new Set(measurements.callSpanIds);
632
- for (const span of ordered) {
633
- if (!callSpanIds.has(span.span_id)) continue;
634
- const model2 = firstStringAttr(span.attributes, LLM_MODEL_ATTR_KEYS) ?? span.model_name;
635
- if (model2) modelVotes.set(model2, (modelVotes.get(model2) ?? 0) + 1);
636
- }
637
- const model = topVote(modelVotes) ?? firstModelAttr(ordered) ?? fallbackModel;
638
- let wallMs = 0;
639
- const a = spanEpochMillis(earliest);
640
- const b = spanEpochMillis(latest);
641
- if (a !== null && b !== null) wallMs = Math.max(0, b - a);
642
- const sourceTraceIds = [...new Set(spans.map((span) => span.trace_id))].sort();
643
- const terminal = terminalEvidenceFromRoots(ordered);
644
- const errorSummary = summarizeTraceErrors(
645
- ordered.map((span) => ({
646
- id: span.span_id,
647
- ...span.parent_span_id ? { parentId: span.parent_span_id } : {},
648
- role: errorRoleForProjectedSpan(span),
649
- error: span.status === "ERROR",
650
- processRoot: span.parent_span_id === null && isTerminalRootCandidate(span)
651
- }))
652
- );
653
- return {
654
- traceId,
655
- sourceTraceCount: sourceTraceIds.length,
656
- sourceTraceIds,
657
- spanCount: spans.length,
658
- llmSpanCount: measurements.modelCallCount,
659
- toolSpanCount,
660
- agentSpanCount,
661
- errorSpanCount: errorSummary.total,
662
- executionErrorCount: errorSummary.execution,
663
- processErrorCount: errorSummary.process,
664
- guardrailErrorCount: errorSummary.guardrail,
665
- judgeErrorCount: errorSummary.evaluation,
666
- propagatedErrorCount: errorSummary.propagated,
667
- unclassifiedErrorCount: errorSummary.unclassified,
668
- tokenUsage: measurements.tokenUsage,
669
- firstErrorMessage,
670
- model,
671
- startTime: earliest,
672
- endTime: latest,
673
- wallMs,
674
- terminalOutcome: terminal.outcome,
675
- ...terminal.failureMessage ? { terminalFailureMessage: terminal.failureMessage } : {},
676
- callSpanIds: measurements.callSpanIds,
677
- costMeasurement: measurements.cost,
678
- ...measurements.aggregate ? { aggregateMeasurement: measurements.aggregate } : {}
679
- };
680
- }
681
- function terminalEvidenceFromRoots(spans) {
682
- const roots = spans.filter(
683
- (span) => span.parent_span_id === null && isTerminalRootCandidate(span)
684
- );
685
- if (roots.length !== 1) return { outcome: "unknown" };
686
- const root = roots[0];
687
- if (root.status === "ERROR") {
688
- return {
689
- outcome: "failed",
690
- failureMessage: (root.status_message ?? `${root.name} \u2014 STATUS_CODE_ERROR`).slice(0, 500)
691
- };
692
- }
693
- if (root.status === "OK") return { outcome: "succeeded" };
694
- return { outcome: "unknown" };
695
- }
696
- function isTerminalRootCandidate(span) {
697
- const role = errorRoleForProjectedSpan(span);
698
- return role !== "LLM" && role !== "TOOL" && role !== "EVALUATOR" && role !== "GUARDRAIL";
699
- }
700
- function errorRoleForProjectedSpan(span) {
701
- return classifyOtlpSpanRole({
702
- kind: span.kind,
703
- name: span.name,
704
- attributes: span.attributes
705
- });
706
- }
707
- function resolveScore(opts, traceId, agg) {
708
- const supplied = opts.scoreForTrace?.(traceId, agg);
709
- if (supplied !== void 0) {
710
- if (!Number.isFinite(supplied)) {
711
- throw new Error(
712
- `otlpToRunRecords: scoreForTrace('${traceId}') returned non-finite ${supplied}`
713
- );
714
- }
715
- return supplied;
716
- }
717
- return void 0;
718
- }
719
- function resolveCost(opts, agg) {
720
- const observedCost = agg.costMeasurement;
721
- if (observedCost.complete && observedCost.value !== void 0) {
722
- return {
723
- costUsd: observedCost.value,
724
- costProvenance: { kind: "observed", usd: observedCost.value }
725
- };
726
- }
727
- if (agg.aggregateMeasurement?.costUsd !== void 0) {
728
- return {
729
- costUsd: agg.aggregateMeasurement.costUsd,
730
- costProvenance: { kind: "observed", usd: agg.aggregateMeasurement.costUsd }
731
- };
732
- }
733
- if (opts.priceUsdPerToken !== void 0) {
734
- const totalTokens = agg.tokenUsage.input + agg.tokenUsage.output;
735
- const costUsd = totalTokens * opts.priceUsdPerToken;
736
- return { costUsd, costProvenance: { kind: "estimated", usd: costUsd } };
737
- }
738
- return { costUsd: null, costProvenance: { kind: "uncaptured", usd: null } };
739
- }
740
- function extractPromptCompletion(spans, callSpanIds) {
741
- const callIds = new Set(callSpanIds);
742
- const measuredCalls = spans.filter((span) => callIds.has(span.span_id));
743
- const llm = (measuredCalls.length > 0 ? measuredCalls : spans.filter((s) => s.kind === "LLM")).sort(
744
- (a, b) => compareSpanTime(a.start_time, b.start_time) || a.span_id.localeCompare(b.span_id)
745
- );
746
- if (llm.length === 0) return {};
747
- const promptText = firstStringAttr(llm[0].attributes, ["input.value", "llm.input_messages", "gen_ai.prompt"]) ?? void 0;
748
- const last = llm[llm.length - 1];
749
- const completionText = firstStringAttr(last.attributes, [
750
- "output.value",
751
- "llm.output_messages",
752
- "gen_ai.completion"
753
- ]) ?? void 0;
754
- return {
755
- ...promptText !== void 0 ? { promptText } : {},
756
- ...completionText !== void 0 ? { completionText } : {}
757
- };
758
- }
759
- function topVote(votes) {
760
- let best = null;
761
- let bestN = 0;
762
- for (const [k, n] of votes) {
763
- if (n > bestN || n === bestN && best !== null && k < best) {
764
- best = k;
765
- bestN = n;
766
- }
767
- }
768
- return best;
769
- }
770
- function firstModelAttr(spans) {
771
- for (const s of spans) {
772
- const m = firstStringAttr(s.attributes, LLM_MODEL_ATTR_KEYS) ?? s.model_name;
773
- if (m) return m;
774
- }
775
- return null;
776
- }
777
- function ensureSnapshot(model, fallbackModel) {
778
- if (modelHasSnapshot(model)) return model;
779
- const fallbackTag = fallbackModel.includes("@") ? fallbackModel.slice(fallbackModel.indexOf("@")) : "@otlp";
780
- return `${model}${fallbackTag}`;
781
- }
782
- function modelHasSnapshot(model) {
783
- if (model.includes("@")) return true;
784
- if (/-\d{8}$/.test(model)) return true;
785
- if (/-\d{4}-\d{2}-\d{2}$/.test(model)) return true;
786
- if (/:date-/.test(model)) return true;
787
- return false;
788
- }
789
-
790
- // src/trace/store.ts
791
- var InMemoryTraceStore = class {
792
- runs = /* @__PURE__ */ new Map();
793
- allSpans = [];
794
- allEvents = [];
795
- allArtifacts = [];
796
- allBudget = [];
797
- async appendRun(run) {
798
- if (this.runs.has(run.runId)) throw new Error(`run ${run.runId} already exists`);
799
- this.runs.set(run.runId, { ...run });
800
- }
801
- async updateRun(runId, patch) {
802
- const existing = this.runs.get(runId);
803
- if (!existing) throw new Error(`run ${runId} not found`);
804
- this.runs.set(runId, { ...existing, ...patch });
805
- }
806
- async appendSpan(span) {
807
- this.allSpans.push({ ...span });
808
- }
809
- async updateSpan(spanId, patch) {
810
- const idx = this.allSpans.findIndex((s) => s.spanId === spanId);
811
- if (idx < 0) throw new Error(`span ${spanId} not found`);
812
- this.allSpans[idx] = { ...this.allSpans[idx], ...patch };
813
- }
814
- async appendEvent(event) {
815
- this.allEvents.push({ ...event });
816
- }
817
- async appendArtifact(artifact) {
818
- this.allArtifacts.push({ ...artifact });
819
- }
820
- async appendBudgetEntry(entry) {
821
- this.allBudget.push({ ...entry });
822
- }
823
- async getRun(runId) {
824
- const r = this.runs.get(runId);
825
- return r ? { ...r } : void 0;
826
- }
827
- async listRuns(filter = {}) {
828
- return [...this.runs.values()].filter((r) => matchesRun(r, filter));
829
- }
830
- async spans(filter = {}) {
831
- return this.allSpans.filter((s) => matchesSpan(s, filter)).map((s) => ({ ...s }));
832
- }
833
- async events(filter = {}) {
834
- return this.allEvents.filter((e) => matchesEvent(e, filter)).map((e) => ({ ...e }));
835
- }
836
- async budget(runId) {
837
- return this.allBudget.filter((b) => b.runId === runId).map((b) => ({ ...b }));
838
- }
839
- async artifacts(runId) {
840
- return this.allArtifacts.filter((a) => a.runId === runId).map((a) => ({ ...a }));
841
- }
842
- };
843
- function matchesRun(r, f) {
844
- if (f.scenarioId && r.scenarioId !== f.scenarioId) return false;
845
- if (f.variantId && r.variantId !== f.variantId) return false;
846
- if (f.status && r.status !== f.status) return false;
847
- if (f.since !== void 0 && r.startedAt < f.since) return false;
848
- if (f.until !== void 0 && r.startedAt > f.until) return false;
849
- if (f.tag && r.tags?.[f.tag.key] !== f.tag.value) return false;
850
- if (f.parentRunId && r.parentRunId !== f.parentRunId) return false;
851
- if (f.projectId && r.projectId !== f.projectId) return false;
852
- if (f.chatId && r.chatId !== f.chatId) return false;
853
- if (f.layer && r.layer !== f.layer) return false;
854
- return true;
855
- }
856
- function matchesSpan(s, f) {
857
- if (f.runId && s.runId !== f.runId) return false;
858
- if (f.parentSpanId && s.parentSpanId !== f.parentSpanId) return false;
859
- if (f.kind && s.kind !== f.kind) return false;
860
- if (f.name && s.name !== f.name) return false;
861
- if (f.toolName && (s.kind !== "tool" || s.toolName !== f.toolName)) return false;
862
- if (f.judgeId && (s.kind !== "judge" || s.judgeId !== f.judgeId)) return false;
863
- if (f.since !== void 0 && s.startedAt < f.since) return false;
864
- if (f.until !== void 0 && s.startedAt > f.until) return false;
865
- return true;
866
- }
867
- function matchesEvent(e, f) {
868
- if (f.runId && e.runId !== f.runId) return false;
869
- if (f.spanId && e.spanId !== f.spanId) return false;
870
- if (f.kind && e.kind !== f.kind) return false;
871
- if (f.since !== void 0 && e.timestamp < f.since) return false;
872
- if (f.until !== void 0 && e.timestamp > f.until) return false;
873
- return true;
874
- }
875
- var FileSystemTraceStore = class {
876
- dir;
877
- maxBytes;
878
- /** Lazy in-memory index for queries — populated on first read. */
879
- index;
880
- /** Memoized index build — concurrent first reads share one build, and an
881
- * append racing an in-flight load awaits this so its row isn't lost. */
882
- indexPromise;
883
- /** Strictly-increasing rollover stamp. Date.now() alone collides when two
884
- * rollovers land in the same millisecond, overwriting a rolled file. */
885
- lastRolloverStamp = 0;
886
- /**
887
- * Per-file append serialization. stat → conditional-rename → appendFile is a
888
- * read-modify-write on the active file; without a lock two concurrent appends
889
- * to the same `name` can both pass the size check (exceeding maxBytes) or one
890
- * can append to a file the other just renamed away. Each entry chains the
891
- * next append behind the prior one for that file.
892
- */
893
- appendLocks = /* @__PURE__ */ new Map();
894
- constructor(options) {
895
- this.dir = options.dir;
896
- this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024;
897
- }
898
- async ensureDir() {
899
- const fs = await import("fs/promises");
900
- await fs.mkdir(this.dir, { recursive: true });
901
- }
902
- async append(name, record) {
903
- if (this.indexPromise) await this.indexPromise;
904
- const prior = this.appendLocks.get(name) ?? Promise.resolve();
905
- const result = prior.then(() => this.appendLocked(name, record));
906
- const tail = result.then(
907
- () => {
908
- },
909
- () => {
910
- }
911
- );
912
- this.appendLocks.set(name, tail);
913
- try {
914
- await result;
915
- } finally {
916
- if (this.appendLocks.get(name) === tail) this.appendLocks.delete(name);
917
- }
918
- }
919
- async appendLocked(name, record) {
920
- await this.ensureDir();
921
- const fs = await import("fs/promises");
922
- const path = await import("path");
923
- const active = path.join(this.dir, `${name}.ndjson`);
924
- try {
925
- const stat = await fs.stat(active);
926
- if (stat.size >= this.maxBytes) {
927
- const stamp = Math.max(Date.now(), this.lastRolloverStamp + 1);
928
- this.lastRolloverStamp = stamp;
929
- const rolled = path.join(this.dir, `${name}.${stamp}.ndjson`);
930
- await fs.rename(active, rolled);
931
- }
932
- } catch {
933
- }
934
- await fs.appendFile(active, `${JSON.stringify(record)}
935
- `, "utf8");
936
- if (this.index && !record?._update) {
937
- await this.insertInto(name, record);
938
- }
939
- }
940
- async insertInto(name, record) {
941
- if (!this.index) return;
942
- switch (name) {
943
- case "runs":
944
- await this.index.appendRun(record);
945
- break;
946
- case "spans":
947
- await this.index.appendSpan(record);
948
- break;
949
- case "events":
950
- await this.index.appendEvent(record);
951
- break;
952
- case "artifacts":
953
- await this.index.appendArtifact(record);
954
- break;
955
- case "budget":
956
- await this.index.appendBudgetEntry(record);
957
- break;
958
- }
959
- }
960
- load() {
961
- this.indexPromise ??= this.buildIndex();
962
- return this.indexPromise;
963
- }
964
- async buildIndex() {
965
- const fs = await import("fs/promises");
966
- const path = await import("path");
967
- const store = new InMemoryTraceStore();
968
- let entries;
969
- try {
970
- entries = await fs.readdir(this.dir);
971
- } catch {
972
- this.index = store;
973
- return store;
974
- }
975
- entries.sort((a, b) => {
976
- const baseA = a.split(".")[0];
977
- const baseB = b.split(".")[0];
978
- if (baseA !== baseB) return baseA < baseB ? -1 : 1;
979
- const ta = a.match(/^[^.]+\.(\d+)\.ndjson$/);
980
- const tb = b.match(/^[^.]+\.(\d+)\.ndjson$/);
981
- const tsA = ta ? Number(ta[1]) : Number.POSITIVE_INFINITY;
982
- const tsB = tb ? Number(tb[1]) : Number.POSITIVE_INFINITY;
983
- return tsA - tsB;
984
- });
985
- {
986
- const runUpdates = [];
987
- const spanUpdates = [];
988
- for (const file of entries) {
989
- if (!file.endsWith(".ndjson")) continue;
990
- const full = path.join(this.dir, file);
991
- const content = await fs.readFile(full, "utf8");
992
- const base = file.split(".")[0];
993
- const lines = content.split("\n");
994
- for (let ln = 0; ln < lines.length; ln++) {
995
- const line = lines[ln];
996
- if (!line.trim()) continue;
997
- let record;
998
- try {
999
- record = JSON.parse(line);
1000
- } catch (err) {
1001
- throw new Error(
1002
- `FileSystemTraceStore: corrupt NDJSON in ${file} line ${ln + 1}: ${err instanceof Error ? err.message : String(err)} \u2014 ${line.slice(0, 120)}`
1003
- );
1004
- }
1005
- if (base === "runs") {
1006
- if (record?._update) {
1007
- runUpdates.push(record);
1008
- continue;
1009
- }
1010
- try {
1011
- await store.appendRun(record);
1012
- } catch {
1013
- await store.updateRun(record.runId, record);
1014
- }
1015
- } else if (base === "spans") {
1016
- if (record?._update) {
1017
- spanUpdates.push(record);
1018
- continue;
1019
- }
1020
- await store.appendSpan(record);
1021
- } else if (base === "events") {
1022
- await store.appendEvent(record);
1023
- } else if (base === "artifacts") {
1024
- await store.appendArtifact(record);
1025
- } else if (base === "budget") {
1026
- await store.appendBudgetEntry(record);
1027
- }
1028
- }
1029
- }
1030
- for (const record of runUpdates) {
1031
- await store.updateRun(record.runId, record);
1032
- }
1033
- for (const record of spanUpdates) {
1034
- await store.updateSpan(record.spanId, record);
1035
- }
1036
- }
1037
- this.index = store;
1038
- return store;
1039
- }
1040
- async appendRun(run) {
1041
- await this.append("runs", run);
1042
- }
1043
- async updateRun(runId, patch) {
1044
- await this.append("runs", { runId, ...patch, _update: true });
1045
- if (this.index) await this.index.updateRun(runId, patch);
1046
- }
1047
- async appendSpan(span) {
1048
- await this.append("spans", span);
1049
- }
1050
- async updateSpan(spanId, patch) {
1051
- await this.append("spans", { spanId, ...patch, _update: true });
1052
- if (this.index) await this.index.updateSpan(spanId, patch);
1053
- }
1054
- async appendEvent(event) {
1055
- await this.append("events", event);
1056
- }
1057
- async appendArtifact(artifact) {
1058
- await this.append("artifacts", artifact);
1059
- }
1060
- async appendBudgetEntry(entry) {
1061
- await this.append("budget", entry);
1062
- }
1063
- async getRun(runId) {
1064
- return (await this.load()).getRun(runId);
1065
- }
1066
- async listRuns(filter) {
1067
- return (await this.load()).listRuns(filter);
1068
- }
1069
- async spans(filter) {
1070
- return (await this.load()).spans(filter);
1071
- }
1072
- async events(filter) {
1073
- return (await this.load()).events(filter);
1074
- }
1075
- async budget(runId) {
1076
- return (await this.load()).budget(runId);
1077
- }
1078
- async artifacts(runId) {
1079
- return (await this.load()).artifacts(runId);
1080
- }
1081
- };
1082
-
1083
- // src/trace/capture-fetch.ts
1084
- var DEFAULT_BODY_CAP = 2 * 1024 * 1024;
1085
- function headersToRecord(headers) {
1086
- if (!headers) return void 0;
1087
- const out = {};
1088
- headers.forEach((value, key) => {
1089
- out[key.toLowerCase()] = value;
1090
- });
1091
- return Object.keys(out).length > 0 ? out : void 0;
1092
- }
1093
- function parseMaybeJson(text) {
1094
- if (text.length === 0) return void 0;
1095
- try {
1096
- return JSON.parse(text);
1097
- } catch {
1098
- return text;
1099
- }
1100
- }
1101
- async function readRequestBody(input, init) {
1102
- if (typeof init?.body === "string") return parseMaybeJson(init.body);
1103
- if (init?.body != null) return void 0;
1104
- if (input instanceof Request) {
1105
- try {
1106
- return parseMaybeJson(await input.clone().text());
1107
- } catch {
1108
- return void 0;
1109
- }
1110
- }
1111
- return void 0;
1112
- }
1113
- function endpointFromUrl(url, baseUrl) {
1114
- const normalisedBase = baseUrl.replace(/\/+$/, "");
1115
- if (url.startsWith(normalisedBase)) return url.slice(normalisedBase.length) || "/";
1116
- try {
1117
- return new URL(url).pathname;
1118
- } catch {
1119
- return url;
1120
- }
1121
- }
1122
- function captureFetchToRawSink(fetch2, sink, ctx, opts = {}) {
1123
- const provider = ctx.provider ?? providerFromBaseUrl(ctx.baseUrl);
1124
- const redactor = opts.redactor ?? defaultProviderRedactor;
1125
- const bodyCap = opts.responseBodyByteCap ?? DEFAULT_BODY_CAP;
1126
- let warned = false;
1127
- const baseEvent = (direction, endpoint) => ({
1128
- eventId: crypto.randomUUID(),
1129
- runId: ctx.runId,
1130
- spanId: ctx.spanId,
1131
- provider,
1132
- model: ctx.model,
1133
- endpoint,
1134
- baseUrl: ctx.baseUrl,
1135
- attemptIndex: 0,
1136
- // retries are re-invocations one layer up; documented in 0.x
1137
- direction,
1138
- timestamp: Date.now(),
1139
- redactedFields: []
1140
- });
1141
- const record = async (event) => {
1142
- try {
1143
- await sink.record(redactor(event));
1144
- } catch (err) {
1145
- if (opts.failClosed) throw err;
1146
- if (!warned) {
1147
- warned = true;
1148
- console.warn(
1149
- `captureFetchToRawSink: sink.record failed (capture is best-effort) \u2014 ${err instanceof Error ? err.message : String(err)}`
1150
- );
1151
- }
1152
- }
1153
- };
1154
- return async (input, init) => {
1155
- const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
1156
- const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
1157
- const endpoint = endpointFromUrl(url, ctx.baseUrl);
1158
- const reqHeaders = new Headers(
1159
- init?.headers ?? (input instanceof Request ? input.headers : void 0)
1160
- );
1161
- await record({
1162
- ...baseEvent("request", endpoint),
1163
- requestHeaders: { ...headersToRecord(reqHeaders), "x-http-method": method },
1164
- requestBody: await readRequestBody(input, init)
1165
- });
1166
- const start = Date.now();
1167
- let response;
1168
- try {
1169
- response = await fetch2(input, init);
1170
- } catch (err) {
1171
- await record({
1172
- ...baseEvent("error", endpoint),
1173
- durationMs: Date.now() - start,
1174
- errorMessage: err instanceof Error ? err.message : String(err)
1175
- });
1176
- throw err;
1177
- }
1178
- let responseBody;
1179
- let rawText;
1180
- const redactedFields = [];
1181
- try {
1182
- rawText = await response.clone().text();
1183
- if (rawText.length > bodyCap) {
1184
- responseBody = rawText.slice(0, bodyCap);
1185
- redactedFields.push("body_truncated");
1186
- } else {
1187
- responseBody = parseMaybeJson(rawText);
1188
- }
1189
- } catch {
1190
- responseBody = void 0;
1191
- }
1192
- if (opts.onUsage && rawText !== void 0) {
1193
- try {
1194
- const parsedForUsage = parseMaybeJson(rawText);
1195
- const usage = extractUsage(parsedForUsage) ?? (typeof parsedForUsage === "string" ? extractUsageFromSse(rawText, { mode: opts.sseUsageMode }) : null);
1196
- if (usage) opts.onUsage(usage, ctx);
1197
- } catch (err) {
1198
- if (opts.failClosed) throw err;
1199
- }
1200
- }
1201
- await record({
1202
- ...baseEvent("response", endpoint),
1203
- durationMs: Date.now() - start,
1204
- statusCode: response.status,
1205
- responseHeaders: headersToRecord(response.headers),
1206
- responseBody,
1207
- redactedFields
1208
- });
1209
- return response;
1210
- };
1211
- }
1212
-
1213
- // src/trace/otel.ts
1214
- var OTEL_AGENT_EVAL_SCOPE = { name: "@tangle-network/agent-eval", version: "0.3.0" };
1215
- async function exportRunAsOtlp(store, runId, resourceAttrs = {}) {
1216
- const run = await store.getRun(runId);
1217
- if (!run) throw new Error(`run ${runId} not found`);
1218
- const spans = await store.spans({ runId });
1219
- const events = await store.events({ runId });
1220
- const eventsBySpan = /* @__PURE__ */ new Map();
1221
- for (const e of events) {
1222
- if (!e.spanId) continue;
1223
- const arr = eventsBySpan.get(e.spanId) ?? [];
1224
- arr.push(e);
1225
- eventsBySpan.set(e.spanId, arr);
1226
- }
1227
- const traceId = runToTraceId(run);
1228
- const otlpSpans = spans.map(
1229
- (s) => spanToOtlp(s, traceId, eventsBySpan.get(s.spanId) ?? [])
1230
- );
1231
- return {
1232
- resourceSpans: [
1233
- {
1234
- resource: {
1235
- attributes: toAttributes({
1236
- "service.name": "agent-eval",
1237
- "run.id": run.runId,
1238
- "run.scenario_id": run.scenarioId,
1239
- "run.variant_id": run.variantId ?? "",
1240
- "run.dataset_version": run.datasetVersion ?? "",
1241
- "run.code_sha": run.codeSha ?? "",
1242
- "run.model_fingerprint": run.modelFingerprint ?? "",
1243
- ...resourceAttrs
1244
- })
1245
- },
1246
- scopeSpans: [{ scope: OTEL_AGENT_EVAL_SCOPE, spans: otlpSpans }]
1247
- }
1248
- ]
1249
- };
1250
- }
1251
- function spanToOtlp(span, traceId, events) {
1252
- const endedAt = span.endedAt ?? span.startedAt;
1253
- return {
1254
- traceId,
1255
- spanId: padSpanId(span.spanId),
1256
- parentSpanId: span.parentSpanId ? padSpanId(span.parentSpanId) : void 0,
1257
- name: span.name,
1258
- kind: 1,
1259
- // SPAN_KIND_INTERNAL
1260
- startTimeUnixNano: msToNs(span.startedAt),
1261
- endTimeUnixNano: msToNs(endedAt),
1262
- attributes: toAttributes(flattenSpanAttributes(span)),
1263
- events: events.map((e) => ({
1264
- timeUnixNano: msToNs(e.timestamp),
1265
- name: e.kind,
1266
- attributes: toAttributes(flattenPayload(e.payload))
1267
- })),
1268
- status: span.status === "error" ? { code: 2, message: span.error } : { code: 1 }
1269
- };
1270
- }
1271
- function flattenSpanAttributes(span) {
1272
- const base = {};
1273
- if (span.attributes) {
1274
- for (const [k, v] of Object.entries(span.attributes)) {
1275
- if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") base[k] = v;
1276
- }
1277
- }
1278
- base[OPENINFERENCE_SPAN_KIND] = traceSpanKindToOpenInferenceKind(span.kind);
1279
- if (span.kind === "llm") {
1280
- applyLlmSpanOtlpAttributes(base, span);
1281
- } else if (span.kind === "tool") {
1282
- applyToolSpanOtlpAttributes(base, span);
1283
- } else if (span.kind === "retrieval") {
1284
- base["retrieval.query"] = span.query;
1285
- base["retrieval.hits"] = span.hits.length;
1286
- } else if (span.kind === "judge") {
1287
- base["judge.id"] = span.judgeId;
1288
- base["judge.dimension"] = span.dimension;
1289
- base["judge.score"] = span.score;
1290
- base["judge.target_span_id"] = span.targetSpanId;
1291
- } else if (span.kind === "sandbox") {
1292
- if (span.image) base["sandbox.image"] = span.image;
1293
- if (span.exitCode !== void 0) base["sandbox.exit_code"] = span.exitCode;
1294
- if (span.testsPassed !== void 0) base["sandbox.tests_passed"] = span.testsPassed;
1295
- if (span.testsTotal !== void 0) base["sandbox.tests_total"] = span.testsTotal;
1296
- }
1297
- return base;
1298
- }
1299
- function flattenPayload(payload) {
1300
- const out = {};
1301
- for (const [k, v] of Object.entries(payload)) {
1302
- if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") out[k] = v;
1303
- else out[k] = JSON.stringify(v);
1304
- }
1305
- return out;
1306
- }
1307
- function toAttributes(record) {
1308
- return Object.entries(record).map(([key, value]) => ({
1309
- key,
1310
- value: typeof value === "number" ? Number.isInteger(value) ? { intValue: value.toString() } : { doubleValue: value } : typeof value === "boolean" ? { boolValue: value } : { stringValue: value }
1311
- }));
1312
- }
1313
- function msToNs(ms) {
1314
- return (BigInt(Math.floor(ms)) * 1000000n).toString();
1315
- }
1316
- function padSpanId(id) {
1317
- const cleaned = id.replace(/-/g, "");
1318
- return cleaned.slice(0, 16).padEnd(16, "0");
1319
- }
1320
- function runToTraceId(run) {
1321
- const cleaned = run.runId.replace(/-/g, "");
1322
- return cleaned.slice(0, 32).padEnd(32, "0");
1323
- }
1324
-
1325
- // src/trace/otel-bridge.ts
1326
- function otelRunCompleteHook(exporter) {
1327
- return async (ctx) => {
1328
- const spans = await ctx.store.spans({ runId: ctx.runId });
1329
- for (const span of spans) {
1330
- if (span.endedAt) {
1331
- exporter.exportSpan(storeSpanToExportable(span, ctx.runId));
1332
- }
1333
- }
1334
- await exporter.flush();
1335
- };
1336
- }
1337
- function createOtelTracingStore(inner, exporter, traceId) {
1338
- return {
1339
- async appendRun(run) {
1340
- return inner.appendRun(run);
1341
- },
1342
- async updateRun(runId, patch) {
1343
- return inner.updateRun(runId, patch);
1344
- },
1345
- async appendSpan(span) {
1346
- if (span.endedAt) {
1347
- exporter.exportSpan(storeSpanToExportable(span, traceId));
1348
- }
1349
- return inner.appendSpan(span);
1350
- },
1351
- async updateSpan(spanId, patch) {
1352
- await inner.updateSpan(spanId, patch);
1353
- if (patch.endedAt) {
1354
- const spans = await inner.spans({ runId: traceId });
1355
- const found = spans.find((s) => s.spanId === spanId);
1356
- if (found) {
1357
- exporter.exportSpan(storeSpanToExportable(found, traceId));
1358
- }
1359
- }
1360
- },
1361
- async appendEvent(event) {
1362
- return inner.appendEvent(event);
1363
- },
1364
- async appendBudgetEntry(entry) {
1365
- return inner.appendBudgetEntry(entry);
1366
- },
1367
- async appendArtifact(artifact) {
1368
- return inner.appendArtifact(artifact);
1369
- },
1370
- getRun: inner.getRun.bind(inner),
1371
- listRuns: inner.listRuns.bind(inner),
1372
- spans: inner.spans.bind(inner),
1373
- events: inner.events.bind(inner),
1374
- budget: inner.budget.bind(inner),
1375
- artifacts: inner.artifacts.bind(inner)
1376
- };
1377
- }
1378
- function storeSpanToExportable(span, traceId) {
1379
- const llm = span.kind === "llm" ? span : void 0;
1380
- const tool = span.kind === "tool" ? span : void 0;
1381
- return {
1382
- traceId,
1383
- spanId: span.spanId,
1384
- parentSpanId: span.parentSpanId,
1385
- name: span.name,
1386
- kind: span.kind,
1387
- startedAt: span.startedAt,
1388
- endedAt: span.endedAt,
1389
- status: span.status,
1390
- error: span.error,
1391
- model: llm?.model,
1392
- inputTokens: llm?.inputTokens,
1393
- outputTokens: llm?.outputTokens,
1394
- reasoningTokens: llm?.reasoningTokens,
1395
- cachedTokens: llm?.cachedTokens,
1396
- cacheWriteTokens: llm?.cacheWriteTokens,
1397
- costUsd: llm?.costUsd,
1398
- tool: tool ? {
1399
- toolName: tool.toolName,
1400
- args: tool.args,
1401
- argsCaptured: tool.argsCaptured,
1402
- result: tool.result,
1403
- latencyMs: tool.latencyMs
1404
- } : void 0,
1405
- attributes: span.attributes
1406
- };
1407
- }
1408
-
1409
- // src/trace/otel-export.ts
1410
- function createOtelExporter(config) {
1411
- const resolvedEndpoint = config?.endpoint ?? (typeof process !== "undefined" ? process.env.OTEL_EXPORTER_OTLP_ENDPOINT : void 0);
1412
- if (!resolvedEndpoint) return void 0;
1413
- const endpoint = resolvedEndpoint;
1414
- const headers = config?.headers ?? parseHeadersFromEnv();
1415
- const batchSize = config?.batchSize ?? 64;
1416
- const flushIntervalMs = config?.flushIntervalMs ?? 5e3;
1417
- const serviceName = config?.serviceName ?? "agent-eval";
1418
- const resourceAttrs = config?.resourceAttributes ?? {};
1419
- const pending = [];
1420
- let timer;
1421
- let stopped = false;
1422
- const exporter = {
1423
- exportSpan(span) {
1424
- if (stopped) return;
1425
- pending.push(toOtlpSpan(span));
1426
- if (pending.length >= batchSize) {
1427
- void doFlush();
1428
- }
1429
- },
1430
- async flush() {
1431
- await doFlush();
1432
- },
1433
- async shutdown() {
1434
- stopped = true;
1435
- if (timer !== void 0) {
1436
- clearInterval(timer);
1437
- timer = void 0;
1438
- }
1439
- await doFlush();
1440
- }
1441
- };
1442
- timer = setInterval(() => {
1443
- if (pending.length > 0) void doFlush();
1444
- }, flushIntervalMs);
1445
- if (typeof timer === "object" && "unref" in timer) {
1446
- ;
1447
- timer.unref();
1448
- }
1449
- async function doFlush() {
1450
- if (pending.length === 0) return;
1451
- const batch = pending.splice(0);
1452
- const body = {
1453
- resourceSpans: [
1454
- {
1455
- resource: {
1456
- attributes: toAttributes2({
1457
- "service.name": serviceName,
1458
- ...resourceAttrs
1459
- })
1460
- },
1461
- scopeSpans: [{ scope: OTEL_AGENT_EVAL_SCOPE, spans: batch }]
1462
- }
1463
- ]
1464
- };
1465
- const url = `${endpoint.replace(/\/+$/, "")}/v1/traces`;
1466
- try {
1467
- await fetch(url, {
1468
- method: "POST",
1469
- headers: {
1470
- "content-type": "application/json",
1471
- ...headers
1472
- },
1473
- body: JSON.stringify(body)
1474
- });
1475
- } catch {
1476
- }
1477
- }
1478
- return exporter;
1479
- }
1480
- function parseHeadersFromEnv() {
1481
- if (typeof process === "undefined") return {};
1482
- const raw = process.env.OTEL_EXPORTER_OTLP_HEADERS;
1483
- if (!raw) return {};
1484
- const out = {};
1485
- for (const pair of raw.split(",")) {
1486
- const eq = pair.indexOf("=");
1487
- if (eq < 0) continue;
1488
- const key = pair.slice(0, eq).trim();
1489
- const value = pair.slice(eq + 1).trim();
1490
- if (key) out[key] = value;
1491
- }
1492
- return out;
1493
- }
1494
- function toOtlpSpan(span) {
1495
- const endedAt = span.endedAt ?? span.startedAt;
1496
- const attrs = {};
1497
- if (span.attributes) {
1498
- for (const [k, v] of Object.entries(span.attributes)) {
1499
- if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") attrs[k] = v;
1500
- }
1501
- }
1502
- attrs[OPENINFERENCE_SPAN_KIND] = traceSpanKindToOpenInferenceKind(span.kind);
1503
- applyLlmSpanOtlpAttributes(attrs, span);
1504
- if (span.tool) applyToolSpanOtlpAttributes(attrs, span.tool);
1505
- return {
1506
- traceId: padTraceId(span.traceId),
1507
- spanId: padSpanId2(span.spanId),
1508
- parentSpanId: span.parentSpanId ? padSpanId2(span.parentSpanId) : void 0,
1509
- name: span.name,
1510
- kind: 1,
1511
- // SPAN_KIND_INTERNAL
1512
- startTimeUnixNano: msToNs2(span.startedAt),
1513
- endTimeUnixNano: msToNs2(endedAt),
1514
- attributes: toAttributes2(attrs),
1515
- status: span.status === "error" ? { code: 2, message: span.error } : { code: 1 }
1516
- };
1517
- }
1518
- function toAttributes2(record) {
1519
- return Object.entries(record).map(([key, value]) => ({
1520
- key,
1521
- value: typeof value === "number" ? Number.isInteger(value) ? { intValue: value.toString() } : { doubleValue: value } : typeof value === "boolean" ? { boolValue: value } : { stringValue: value }
1522
- }));
1523
- }
1524
- function msToNs2(ms) {
1525
- return (BigInt(Math.floor(ms)) * 1000000n).toString();
1526
- }
1527
- function padSpanId2(id) {
1528
- const cleaned = id.replace(/-/g, "");
1529
- return cleaned.slice(0, 16).padEnd(16, "0");
1530
- }
1531
- function padTraceId(id) {
1532
- const cleaned = id.replace(/-/g, "");
1533
- return cleaned.slice(0, 32).padEnd(32, "0");
1534
- }
1535
-
1536
- // src/trace/store-to-otlp.ts
1537
- import { readdirSync, readFileSync, statSync, writeFileSync } from "fs";
1538
- import { join } from "path";
1539
- function convertTraceStoresToOtlp(source, outPath, opts = {}) {
1540
- const sources = Array.isArray(source) ? [...source] : typeof source === "string" ? [{ root: source, layout: "celled" }] : [source];
1541
- const defaultServiceName = opts.serviceName ?? "agent-eval";
1542
- const resourceAttributes = opts.resourceAttributes ?? (() => ({}));
1543
- const runAttributes = opts.runAttributes ?? (() => ({}));
1544
- const lines = [];
1545
- let spanCount = 0;
1546
- let runCount = 0;
1547
- let cellCount = 0;
1548
- let cellErrorCount = 0;
1549
- for (const src of sources) {
1550
- const serviceName = src.serviceName ?? defaultServiceName;
1551
- const cellDirs = src.layout === "flat" ? [{ label: "<root>", dir: src.root }] : listCells(src.root).map((name) => ({ label: name, dir: join(src.root, name) }));
1552
- for (const cell of cellDirs) {
1553
- try {
1554
- const result = projectCell({
1555
- cellDir: cell.dir,
1556
- serviceName,
1557
- resourceAttributes,
1558
- runAttributes
1559
- });
1560
- for (const line of result.lines) lines.push(line);
1561
- spanCount += result.spanCount;
1562
- runCount += result.runCount;
1563
- cellCount += 1;
1564
- } catch (err) {
1565
- console.warn(
1566
- `[traces-to-otlp] cell ${cell.label} (${cell.dir}) skipped: ${err instanceof Error ? err.message : String(err)}`
1567
- );
1568
- cellErrorCount += 1;
1569
- }
1570
- }
1571
- }
1572
- writeFileSync(outPath, lines.join("\n") + (lines.length > 0 ? "\n" : ""));
1573
- return { spanCount, runCount, cellCount, cellErrorCount };
1574
- }
1575
- function projectCell(args) {
1576
- const { cellDir, serviceName, resourceAttributes, runAttributes } = args;
1577
- const lines = [];
1578
- let runCount = 0;
1579
- let spanCount = 0;
1580
- const runs = readMergedShards(cellDir, "runs", "runId");
1581
- const spans = readMergedShards(cellDir, "spans", "spanId");
1582
- const events = readShards(cellDir, "events");
1583
- const runByRunId = /* @__PURE__ */ new Map();
1584
- for (const r of runs) runByRunId.set(r.runId, r);
1585
- const spanBySpanId = /* @__PURE__ */ new Map();
1586
- for (const s of spans) spanBySpanId.set(s.spanId, s);
1587
- const eventsBySpanId = /* @__PURE__ */ new Map();
1588
- for (const e of events) {
1589
- if (e.kind === "state_mutation" && e.payload && typeof e.payload === "object") {
1590
- const entity = e.payload.entity;
1591
- if (entity === "run") {
1592
- const run = e.payload.run;
1593
- if (run?.runId) runByRunId.set(run.runId, run);
1594
- continue;
1595
- }
1596
- if (entity === "run.update") {
1597
- const patch = e.payload.patch;
1598
- if (patch && e.runId) {
1599
- const prior = runByRunId.get(e.runId);
1600
- if (prior) runByRunId.set(e.runId, { ...prior, ...patch });
1601
- }
1602
- continue;
1603
- }
1604
- if (entity === "span") {
1605
- const span = e.payload.span;
1606
- if (span?.spanId) spanBySpanId.set(span.spanId, span);
1607
- continue;
1608
- }
1609
- if (entity === "span.update") {
1610
- const spanId = e.payload.spanId;
1611
- const patch = e.payload.patch;
1612
- if (spanId && patch) {
1613
- const prior = spanBySpanId.get(spanId);
1614
- if (prior) spanBySpanId.set(spanId, { ...prior, ...patch });
1615
- }
1616
- continue;
1617
- }
1618
- }
1619
- if (!e.spanId) continue;
1620
- const arr = eventsBySpanId.get(e.spanId) ?? [];
1621
- arr.push(e);
1622
- eventsBySpanId.set(e.spanId, arr);
1623
- }
1624
- for (const run of runByRunId.values()) {
1625
- const traceId = padTraceId2(run.runId);
1626
- const agentName = run.variantId ?? run.scenarioId;
1627
- const sharedResource = {
1628
- attributes: {
1629
- "service.name": serviceName,
1630
- "agent.name": agentName,
1631
- "run.id": run.runId,
1632
- "run.status": run.status,
1633
- ...resourceAttributes(run)
1634
- }
1635
- };
1636
- const runSpanId = padSpanId3(`run-${run.runId}`);
1637
- const runStart = msToIso(run.startedAt);
1638
- const runEnd = msToIso(run.endedAt ?? run.startedAt);
1639
- const runStatus = run.outcome?.failureClass && run.outcome.failureClass !== "success" ? "STATUS_CODE_ERROR" : "STATUS_CODE_OK";
1640
- const runAttrs = {
1641
- [OPENINFERENCE_SPAN_KIND]: "AGENT",
1642
- "agent.name": agentName,
1643
- "agent.workflow.name": serviceName,
1644
- ...runAttributes(run)
1645
- };
1646
- lines.push(
1647
- JSON.stringify(
1648
- toLine({
1649
- traceId,
1650
- spanId: runSpanId,
1651
- parentSpanId: "",
1652
- name: `run.${agentName}`,
1653
- kind: "SPAN_KIND_INTERNAL",
1654
- startTime: runStart,
1655
- endTime: runEnd,
1656
- statusCode: runStatus,
1657
- statusMessage: run.outcome?.notes ?? "",
1658
- resource: sharedResource,
1659
- attributes: runAttrs
1660
- })
1661
- )
1662
- );
1663
- runCount += 1;
1664
- for (const span of spanBySpanId.values()) {
1665
- if (span.runId !== run.runId) continue;
1666
- const spanAttrs = spanToAttributes(span, eventsBySpanId.get(span.spanId) ?? []);
1667
- const statusCode = span.status === "error" ? "STATUS_CODE_ERROR" : "STATUS_CODE_OK";
1668
- lines.push(
1669
- JSON.stringify(
1670
- toLine({
1671
- traceId,
1672
- spanId: padSpanId3(span.spanId),
1673
- parentSpanId: span.parentSpanId ? padSpanId3(span.parentSpanId) : runSpanId,
1674
- name: span.name,
1675
- kind: spanKindToOtlpKind(span.kind),
1676
- startTime: msToIso(span.startedAt),
1677
- endTime: msToIso(span.endedAt ?? span.startedAt),
1678
- statusCode,
1679
- statusMessage: span.error ?? "",
1680
- resource: sharedResource,
1681
- attributes: spanAttrs
1682
- })
1683
- )
1684
- );
1685
- spanCount += 1;
1686
- }
1687
- }
1688
- return { lines, runCount, spanCount };
1689
- }
1690
- function listCells(root) {
1691
- try {
1692
- return readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
1693
- } catch {
1694
- return [];
1695
- }
1696
- }
1697
- function readShards(cellDir, name) {
1698
- let entries;
1699
- try {
1700
- entries = readdirSync(cellDir);
1701
- } catch {
1702
- return [];
1703
- }
1704
- const shards = entries.filter((f) => (f === `${name}.ndjson` || f.startsWith(`${name}.`)) && f.endsWith(".ndjson")).map((f) => ({ file: f, path: join(cellDir, f) })).map((s) => {
1705
- let mtime = 0;
1706
- try {
1707
- mtime = statSync(s.path).mtimeMs;
1708
- } catch {
1709
- }
1710
- return { ...s, mtime };
1711
- }).sort((a, b) => a.mtime - b.mtime || a.file.localeCompare(b.file));
1712
- const rows = [];
1713
- for (const shard of shards) {
1714
- let text;
1715
- try {
1716
- text = readFileSync(shard.path, "utf-8");
1717
- } catch {
1718
- continue;
1719
- }
1720
- for (const line of text.split("\n")) {
1721
- const trimmed = line.trim();
1722
- if (!trimmed) continue;
1723
- try {
1724
- rows.push(JSON.parse(trimmed));
1725
- } catch {
1726
- }
1727
- }
1728
- }
1729
- return rows;
1730
- }
1731
- function readMergedShards(cellDir, name, idKey) {
1732
- const rows = readShards(cellDir, name);
1733
- const byId = /* @__PURE__ */ new Map();
1734
- for (const row of rows) {
1735
- const id = row[idKey];
1736
- if (!id) continue;
1737
- const prior = byId.get(id);
1738
- if (prior && row._update) {
1739
- byId.set(id, { ...prior, ...row, _update: void 0 });
1740
- } else {
1741
- byId.set(id, row);
1742
- }
1743
- }
1744
- return [...byId.values()];
1745
- }
1746
- function spanToAttributes(span, events) {
1747
- const attrs = {
1748
- [OPENINFERENCE_SPAN_KIND]: traceSpanKindToOpenInferenceKind(span.kind)
1749
- };
1750
- if (span.kind === "llm") {
1751
- applyLlmSpanOtlpAttributes(attrs, span);
1752
- if (Array.isArray(span.messages)) {
1753
- attrs["llm.input_messages"] = JSON.stringify(span.messages.slice(-6));
1754
- }
1755
- if (typeof span.output === "string") {
1756
- attrs["llm.output_messages"] = JSON.stringify([{ role: "assistant", content: span.output }]);
1757
- }
1758
- } else if (span.kind === "tool") {
1759
- applyToolSpanOtlpAttributes(attrs, span);
1760
- } else if (span.kind === "judge") {
1761
- attrs["judge.id"] = span.judgeId;
1762
- attrs["judge.dimension"] = span.dimension;
1763
- attrs["judge.score"] = span.score;
1764
- attrs["judge.target_span_id"] = span.targetSpanId;
1765
- }
1766
- if (span.attributes) {
1767
- for (const [k, v] of Object.entries(span.attributes)) {
1768
- attrs[`agent_eval.${k}`] = v;
1769
- }
1770
- }
1771
- if (events.length > 0) {
1772
- attrs["agent_eval.event_count"] = events.length;
1773
- attrs["agent_eval.event_kinds"] = JSON.stringify(events.map((e) => e.kind));
1774
- }
1775
- return attrs;
1776
- }
1777
- function spanKindToOtlpKind(kind) {
1778
- switch (kind) {
1779
- case "llm":
1780
- return "SPAN_KIND_CLIENT";
1781
- case "retrieval":
1782
- return "SPAN_KIND_CLIENT";
1783
- default:
1784
- return "SPAN_KIND_INTERNAL";
1785
- }
1786
- }
1787
- function toLine(args) {
1788
- return {
1789
- trace_id: args.traceId,
1790
- span_id: args.spanId,
1791
- parent_span_id: args.parentSpanId,
1792
- name: args.name,
1793
- kind: args.kind,
1794
- start_time: args.startTime,
1795
- end_time: args.endTime,
1796
- status: { code: args.statusCode, message: args.statusMessage },
1797
- resource: args.resource,
1798
- attributes: args.attributes
1799
- };
1800
- }
1801
- function msToIso(ms) {
1802
- if (!Number.isFinite(ms) || ms <= 0) return (/* @__PURE__ */ new Date(0)).toISOString();
1803
- return new Date(ms).toISOString();
1804
- }
1805
- function padSpanId3(id) {
1806
- const cleaned = id.replace(/[^a-f0-9]/gi, "").toLowerCase();
1807
- if (cleaned.length >= 16) return cleaned.slice(0, 16);
1808
- return foldTo16Hex(id);
1809
- }
1810
- function padTraceId2(id) {
1811
- const cleaned = id.replace(/[^a-f0-9]/gi, "").toLowerCase();
1812
- if (cleaned.length >= 32) return cleaned.slice(0, 32);
1813
- return foldTo32Hex(id);
1814
- }
1815
- function foldTo16Hex(s) {
1816
- let h1 = 2166136261;
1817
- for (const ch of s) {
1818
- h1 ^= ch.charCodeAt(0);
1819
- h1 = Math.imul(h1, 16777619) >>> 0;
1820
- }
1821
- const part = h1.toString(16).padStart(8, "0");
1822
- return (part + part).slice(0, 16);
1823
- }
1824
- function foldTo32Hex(s) {
1825
- return foldTo16Hex(s) + foldTo16Hex(`${s}::trace`).slice(0, 16);
1826
- }
1827
-
1828
- // src/replay.ts
1829
- var ReplayCacheMissError = class extends ReplayError {
1830
- constructor(url, requestKey2, message) {
1831
- super(message ?? `replay cache miss for ${url} (key=${requestKey2})`);
1832
- this.url = url;
1833
- this.requestKey = requestKey2;
1834
- }
1835
- url;
1836
- requestKey;
1837
- };
1838
- var ReplayCache = class _ReplayCache {
1839
- byKey = /* @__PURE__ */ new Map();
1840
- orphans = 0;
1841
- byProvider = {};
1842
- byModel = {};
1843
- /**
1844
- * Build a cache from a sink's events. The sink must implement `list()`.
1845
- * Filter by `runId` / `spanId` to scope to a specific replay.
1846
- */
1847
- static async fromSink(sink, filter = {}) {
1848
- if (!sink.list) {
1849
- throw new ReplayError("ReplayCache.fromSink: sink must implement list() to be replayable.");
1850
- }
1851
- const events = await sink.list(filter);
1852
- return _ReplayCache.fromEvents(events);
1853
- }
1854
- /** Build a cache from an in-memory event list. */
1855
- static async fromEvents(events) {
1856
- const cache = new _ReplayCache();
1857
- const groups = /* @__PURE__ */ new Map();
1858
- for (const e of events) {
1859
- const k = `${e.runId ?? ""}::${e.spanId ?? ""}::${e.attemptIndex}`;
1860
- const g = groups.get(k) ?? {};
1861
- if (e.direction === "request") g.req = e;
1862
- else g.res = e;
1863
- groups.set(k, g);
1864
- }
1865
- for (const g of groups.values()) {
1866
- if (!g.req) continue;
1867
- if (!g.res) {
1868
- cache.orphans += 1;
1869
- continue;
1870
- }
1871
- const key = await requestKey(g.req);
1872
- cache.byKey.set(key, { request: g.req, response: g.res });
1873
- cache.byProvider[g.req.provider] = (cache.byProvider[g.req.provider] ?? 0) + 1;
1874
- cache.byModel[g.req.model] = (cache.byModel[g.req.model] ?? 0) + 1;
1875
- }
1876
- return cache;
1877
- }
1878
- /** Number of cacheable (request, response) pairs in the cache. */
1879
- size() {
1880
- return this.byKey.size;
1881
- }
1882
- stats() {
1883
- return {
1884
- total: this.byKey.size,
1885
- byProvider: { ...this.byProvider },
1886
- byModel: { ...this.byModel },
1887
- orphanRequests: this.orphans
1888
- };
1889
- }
1890
- /** Iterate every cached `(request, response)` pair in insertion order. */
1891
- *entries() {
1892
- for (const entry of this.byKey.values()) yield entry;
1893
- }
1894
- /**
1895
- * Look up a cached response by hashing the (model, messages, temperature,
1896
- * maxTokens, response_format) shape. Returns `undefined` on miss; the
1897
- * caller decides whether to throw, fall back to the network, or skip.
1898
- */
1899
- async lookup(requestBody) {
1900
- const key = await keyFromBody(requestBody);
1901
- return this.byKey.get(key);
1902
- }
1903
- };
1904
- function createReplayFetch(cache, opts = {}) {
1905
- const onMiss = opts.onMiss ?? "throw";
1906
- const fallback = opts.fallbackFetch ?? globalThis.fetch?.bind(globalThis);
1907
- return (async (input, init) => {
1908
- const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
1909
- if (!/\/chat\/completions(?:[?#].*)?$/.test(url)) {
1910
- if (!fallback)
1911
- throw new ReplayError(
1912
- `replay fetch: non-completions URL ${url} but no fallbackFetch configured`
1913
- );
1914
- return fallback(input, init);
1915
- }
1916
- let bodyParsed;
1917
- if (init?.body && typeof init.body === "string") {
1918
- try {
1919
- bodyParsed = JSON.parse(init.body);
1920
- } catch {
1921
- }
1922
- }
1923
- const hit = bodyParsed === void 0 ? void 0 : await cache.lookup(bodyParsed);
1924
- if (hit) {
1925
- opts.onHit?.({ url, provider: hit.request.provider, model: hit.request.model });
1926
- const status = hit.response.statusCode ?? 200;
1927
- const headers = new Headers(
1928
- Object.entries(hit.response.responseHeaders ?? { "Content-Type": "application/json" })
1929
- );
1930
- const bodyText = typeof hit.response.responseBody === "string" ? hit.response.responseBody : JSON.stringify(hit.response.responseBody ?? {});
1931
- return new Response(bodyText, { status, headers });
1932
- }
1933
- opts.onMissNotify?.({ url, requestBody: bodyParsed });
1934
- if (onMiss === "throw") {
1935
- const key = bodyParsed === void 0 ? "<unparseable>" : await keyFromBody(bodyParsed);
1936
- throw new ReplayCacheMissError(url, key);
1937
- }
1938
- if (onMiss === "fail-closed") {
1939
- return new Response(JSON.stringify({ error: "replay_cache_miss" }), { status: 599 });
1940
- }
1941
- if (!fallback)
1942
- throw new ReplayError("replay fetch: onMiss=fallback but no fallbackFetch configured");
1943
- return fallback(input, init);
1944
- });
1945
- }
1946
- async function* iterateRawCalls(sink, filter = {}) {
1947
- if (!sink.list) {
1948
- throw new ReplayError("iterateRawCalls: sink must implement list().");
1949
- }
1950
- const events = await sink.list(filter);
1951
- const cache = await ReplayCache.fromEvents(events);
1952
- for (const entry of cache.entries()) yield entry;
1953
- }
1954
- async function requestKey(event) {
1955
- return keyFromBody(event.requestBody);
1956
- }
1957
- async function keyFromBody(body) {
1958
- if (body == null || typeof body !== "object") return hashJson({ raw: String(body) });
1959
- const b = body;
1960
- const reduced = canonicalize({
1961
- model: b.model ?? null,
1962
- messages: b.messages ?? null,
1963
- temperature: b.temperature ?? null,
1964
- max_tokens: b.max_tokens ?? null,
1965
- max_completion_tokens: b.max_completion_tokens ?? null,
1966
- response_format: b.response_format ?? null
1967
- });
1968
- return hashJson(reduced);
1969
- }
1970
-
1971
- export {
1972
- traceAnalystOnRunComplete,
1973
- tokenizeDomainWords,
1974
- inferDomainKeywords,
1975
- domainEvidencePattern,
1976
- describeTraceInsightScope,
1977
- planTraceInsightQuestions,
1978
- buildTraceInsightContext,
1979
- scoreTraceInsightReadiness,
1980
- defaultTraceInsightPanel,
1981
- buildTraceInsightPrompt,
1982
- flattenOtlpExportToNdjson,
1983
- otlpToRunRecords,
1984
- otlpRowsToRunRecords,
1985
- otlpToTraceRunRecords,
1986
- otlpRowsToTraceRunRecords,
1987
- InMemoryTraceStore,
1988
- FileSystemTraceStore,
1989
- captureFetchToRawSink,
1990
- OTEL_AGENT_EVAL_SCOPE,
1991
- exportRunAsOtlp,
1992
- otelRunCompleteHook,
1993
- createOtelTracingStore,
1994
- createOtelExporter,
1995
- convertTraceStoresToOtlp,
1996
- ReplayCacheMissError,
1997
- ReplayCache,
1998
- createReplayFetch,
1999
- iterateRawCalls
2000
- };
2001
- //# sourceMappingURL=chunk-EOSZT7PL.js.map