zidane 7.2.4 → 8.0.4

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 (376) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -6
  3. package/dist/{acp-D-tVyUjw.js → acp-DQDhi2dj.js} +230 -77
  4. package/dist/acp-DQDhi2dj.js.map +1 -0
  5. package/dist/acp-cli.d.ts +1 -1
  6. package/dist/acp-cli.js +9 -66
  7. package/dist/acp-cli.js.map +1 -1
  8. package/dist/acp.d.ts +10 -590
  9. package/dist/acp.d.ts.map +1 -1
  10. package/dist/acp.js +3 -3
  11. package/dist/{agent-D0zZnGbt.js → agent-DSLNmBp0.js} +14401 -13214
  12. package/dist/agent-DSLNmBp0.js.map +1 -0
  13. package/dist/agent.d.ts +1 -1
  14. package/dist/agent.js +3 -2
  15. package/dist/aliasing-lVFbm81n.js +217 -0
  16. package/dist/aliasing-lVFbm81n.js.map +1 -0
  17. package/dist/{anthropic-C2aole0G.js → anthropic-CD00LhUP.js} +1442 -1264
  18. package/dist/anthropic-CD00LhUP.js.map +1 -0
  19. package/dist/artifacts-CV2hUKnL.js.map +1 -1
  20. package/dist/{atomic-write-B7zr1ddF.js → atomic-write-Ijgf2Mhc.js} +13 -3
  21. package/dist/atomic-write-Ijgf2Mhc.js.map +1 -0
  22. package/dist/call-tool-dHlbGOIY.js +70 -0
  23. package/dist/call-tool-dHlbGOIY.js.map +1 -0
  24. package/dist/chat/pure.d.ts +372 -6
  25. package/dist/chat/pure.d.ts.map +1 -1
  26. package/dist/chat/pure.js +35 -244
  27. package/dist/chat/pure.js.map +1 -1
  28. package/dist/{approvals-DKaJZYlm.js → chat-JPJJ8uu5.js} +15879 -14631
  29. package/dist/chat-JPJJ8uu5.js.map +1 -0
  30. package/dist/chat.d.ts +4 -6
  31. package/dist/chat.js +23 -12
  32. package/dist/cli-shared-C-YCaglL.js +159 -0
  33. package/dist/cli-shared-C-YCaglL.js.map +1 -0
  34. package/dist/client-core-BQSyDALT.d.ts +2115 -0
  35. package/dist/client-core-BQSyDALT.d.ts.map +1 -0
  36. package/dist/codemode-worker.d.ts +1 -0
  37. package/dist/codemode-worker.js +155 -0
  38. package/dist/codemode-worker.js.map +1 -0
  39. package/dist/codemode.d.ts +352 -0
  40. package/dist/codemode.d.ts.map +1 -0
  41. package/dist/codemode.js +5 -0
  42. package/dist/connection-Dr-Js4yZ.d.ts +28 -0
  43. package/dist/connection-Dr-Js4yZ.d.ts.map +1 -0
  44. package/dist/connection-loop-gdh22LTI.js +112 -0
  45. package/dist/connection-loop-gdh22LTI.js.map +1 -0
  46. package/dist/context-segments-BHKlagL6.js +1016 -0
  47. package/dist/context-segments-BHKlagL6.js.map +1 -0
  48. package/dist/{context-transport-T_6AYIvy.js → context-transport-DSMTUsK1.js} +3 -3
  49. package/dist/{context-transport-T_6AYIvy.js.map → context-transport-DSMTUsK1.js.map} +1 -1
  50. package/dist/contexts/daytona.d.ts +19 -8
  51. package/dist/contexts/daytona.d.ts.map +1 -1
  52. package/dist/contexts/daytona.js +1 -440
  53. package/dist/contexts/docker.d.ts +36 -7
  54. package/dist/contexts/docker.d.ts.map +1 -1
  55. package/dist/contexts/docker.js +1 -456
  56. package/dist/contexts/e2b.d.ts +68 -13
  57. package/dist/contexts/e2b.d.ts.map +1 -1
  58. package/dist/contexts/e2b.js +1 -382
  59. package/dist/contexts/sandbox.d.ts +1 -1
  60. package/dist/contexts/sandbox.js +5 -0
  61. package/dist/contexts/sandbox.js.map +1 -1
  62. package/dist/{contexts-CRE9pw07.js → contexts-d7UolYot.js} +1059 -524
  63. package/dist/contexts-d7UolYot.js.map +1 -0
  64. package/dist/contexts.d.ts +3 -3
  65. package/dist/contexts.js +1 -1
  66. package/dist/cred-keys-GpBg71cP.js +105 -0
  67. package/dist/cred-keys-GpBg71cP.js.map +1 -0
  68. package/dist/{auth-BG2rVKSt.js → credentials-JttEuRON.js} +55 -206
  69. package/dist/credentials-JttEuRON.js.map +1 -0
  70. package/dist/{cursor-iojRXHF9.js → cursor-CdjaQTBW.js} +3 -3
  71. package/dist/{cursor-iojRXHF9.js.map → cursor-CdjaQTBW.js.map} +1 -1
  72. package/dist/daemon-cli.d.ts +1 -1
  73. package/dist/daemon-cli.js +3 -2
  74. package/dist/daemon-cli.js.map +1 -1
  75. package/dist/daytona-DG3omipZ.js +513 -0
  76. package/dist/daytona-DG3omipZ.js.map +1 -0
  77. package/dist/defaults-Cx3zvDOV.js +23 -0
  78. package/dist/defaults-Cx3zvDOV.js.map +1 -0
  79. package/dist/dispatcher-BMlu2BmZ.js +4941 -0
  80. package/dist/dispatcher-BMlu2BmZ.js.map +1 -0
  81. package/dist/docker-BZhMMJUp.js +727 -0
  82. package/dist/docker-BZhMMJUp.js.map +1 -0
  83. package/dist/e2b-CEVOdRib.js +480 -0
  84. package/dist/e2b-CEVOdRib.js.map +1 -0
  85. package/dist/edit-utils-EGosADZq.js +234 -0
  86. package/dist/edit-utils-EGosADZq.js.map +1 -0
  87. package/dist/environment-8wsKE2Ln.js +214 -0
  88. package/dist/environment-8wsKE2Ln.js.map +1 -0
  89. package/dist/eval-BNcvle_J.js +1595 -0
  90. package/dist/eval-BNcvle_J.js.map +1 -0
  91. package/dist/eval.d.ts +2 -2
  92. package/dist/eval.js +1 -1489
  93. package/dist/executor-Cx5-8yqi.js +621 -0
  94. package/dist/executor-Cx5-8yqi.js.map +1 -0
  95. package/dist/extension-authoring-DyGGmq9V.js +385 -0
  96. package/dist/extension-authoring-DyGGmq9V.js.map +1 -0
  97. package/dist/extensions.d.ts +2 -2
  98. package/dist/extensions.js +3 -3
  99. package/dist/{fetch-url-DX75gpL0.js → fetch-url-Ct2TjDWt.js} +4 -4
  100. package/dist/{fetch-url-DX75gpL0.js.map → fetch-url-Ct2TjDWt.js.map} +1 -1
  101. package/dist/{format-BF745pLL.js → format-C2NQEVUH.js} +39 -2
  102. package/dist/format-C2NQEVUH.js.map +1 -0
  103. package/dist/format-bytes-C7tfc3Zm.js +55 -0
  104. package/dist/format-bytes-C7tfc3Zm.js.map +1 -0
  105. package/dist/headless-C_rNUuYC.js +960 -0
  106. package/dist/headless-C_rNUuYC.js.map +1 -0
  107. package/dist/headless.d.ts +1 -1
  108. package/dist/headless.js +1 -413
  109. package/dist/{history-search-C4bk1Wz_.js → history-search-CcYzF8-0.js} +7 -3
  110. package/dist/history-search-CcYzF8-0.js.map +1 -0
  111. package/dist/history-search-worker.d.ts +1 -1
  112. package/dist/history-search-worker.js +1 -1
  113. package/dist/host-D7NrI03V.js +378 -0
  114. package/dist/host-D7NrI03V.js.map +1 -0
  115. package/dist/host-signals-BcP5QKUD.js +118 -0
  116. package/dist/host-signals-BcP5QKUD.js.map +1 -0
  117. package/dist/identity-CwfO8K-t.js +26 -0
  118. package/dist/identity-CwfO8K-t.js.map +1 -0
  119. package/dist/{index-BgN1T3lk.d.ts → index-BGe1fQT7.d.ts} +10987 -9320
  120. package/dist/index-BGe1fQT7.d.ts.map +1 -0
  121. package/dist/index-BVQsIKGn.d.ts +448 -0
  122. package/dist/index-BVQsIKGn.d.ts.map +1 -0
  123. package/dist/{index-C6NEd5y_.d.ts → index-CHABJd-L.d.ts} +3386 -502
  124. package/dist/index-CHABJd-L.d.ts.map +1 -0
  125. package/dist/{index-C37_ppWv.d.ts → index-D6a7qXpg.d.ts} +2 -3
  126. package/dist/index-D6a7qXpg.d.ts.map +1 -0
  127. package/dist/index.d.ts +6 -6
  128. package/dist/index.js +27 -23
  129. package/dist/{completion-core-BRo86R_L.js → inline-ghost-BVRQeGoL.js} +50 -2
  130. package/dist/inline-ghost-BVRQeGoL.js.map +1 -0
  131. package/dist/ipc/remote.d.ts +313 -0
  132. package/dist/ipc/remote.d.ts.map +1 -0
  133. package/dist/ipc/remote.js +4 -0
  134. package/dist/ipc.d.ts +6 -964
  135. package/dist/ipc.js +403 -4
  136. package/dist/ipc.js.map +1 -0
  137. package/dist/{isolation-Kfoof0MM.d.ts → isolation-D9L650W5.d.ts} +100 -15
  138. package/dist/isolation-D9L650W5.d.ts.map +1 -0
  139. package/dist/json-rpc--HXQti1E.js +350 -0
  140. package/dist/json-rpc--HXQti1E.js.map +1 -0
  141. package/dist/links-j8rED1sR.js +603 -0
  142. package/dist/links-j8rED1sR.js.map +1 -0
  143. package/dist/local-terminal-D8QThwo_.js +252 -0
  144. package/dist/local-terminal-D8QThwo_.js.map +1 -0
  145. package/dist/{logger--C1VQjwJ.js → logger-Gtqlayx8.js} +199 -173
  146. package/dist/logger-Gtqlayx8.js.map +1 -0
  147. package/dist/logs-view-CWG8aUAG.js.map +1 -1
  148. package/dist/{mcp-CgNd-f3F.js → mcp-_wecH9Qe.js} +608 -562
  149. package/dist/mcp-_wecH9Qe.js.map +1 -0
  150. package/dist/mcp.d.ts +2 -2
  151. package/dist/mcp.js +2 -2
  152. package/dist/media-sniff-UKijEaiQ.js.map +1 -1
  153. package/dist/{messages-2jcOA_5R.js → messages-BqiwcD2Q.js} +1017 -1014
  154. package/dist/messages-BqiwcD2Q.js.map +1 -0
  155. package/dist/{oauth-DxHO17JE.js → oauth-Px_pBB9W.js} +5 -5
  156. package/dist/{oauth-DxHO17JE.js.map → oauth-Px_pBB9W.js.map} +1 -1
  157. package/dist/{openai-compat-Dy56weK8.js → openai-compat-CFrpH7uq.js} +432 -589
  158. package/dist/openai-compat-CFrpH7uq.js.map +1 -0
  159. package/dist/orchestration-BCGmB8Ps.js +511 -0
  160. package/dist/orchestration-BCGmB8Ps.js.map +1 -0
  161. package/dist/output/stream-json.d.ts +1 -2
  162. package/dist/output/stream-json.d.ts.map +1 -1
  163. package/dist/output/stream-json.js +1 -1
  164. package/dist/output/terminal.d.ts +1 -2
  165. package/dist/output/terminal.d.ts.map +1 -1
  166. package/dist/output/terminal.js +13 -7
  167. package/dist/output/terminal.js.map +1 -1
  168. package/dist/{plugins-gbI7SBA6.js → plugins-DS7mahzZ.js} +20 -101
  169. package/dist/plugins-DS7mahzZ.js.map +1 -0
  170. package/dist/plugins.d.ts +1 -1
  171. package/dist/plugins.js +1 -2
  172. package/dist/prelude-Cxo4t74B.js +517 -0
  173. package/dist/prelude-Cxo4t74B.js.map +1 -0
  174. package/dist/presets.d.ts +1 -1
  175. package/dist/presets.js +1 -2
  176. package/dist/project-root-B8zADr4o.js +167 -0
  177. package/dist/project-root-B8zADr4o.js.map +1 -0
  178. package/dist/project-user-paths-BSgtrRxl.js +58 -0
  179. package/dist/project-user-paths-BSgtrRxl.js.map +1 -0
  180. package/dist/{prompts-Pqc3JdW_.d.ts → prompts-DYcvqShf.d.ts} +14 -11
  181. package/dist/prompts-DYcvqShf.d.ts.map +1 -0
  182. package/dist/protocol-DnhqqSmE.js +13 -0
  183. package/dist/protocol-DnhqqSmE.js.map +1 -0
  184. package/dist/providers/anthropic.d.ts +2 -2
  185. package/dist/providers/anthropic.js +1 -2
  186. package/dist/providers/arcee.d.ts +1 -1
  187. package/dist/providers/arcee.js +1 -1
  188. package/dist/providers/baseten.d.ts +1 -1
  189. package/dist/providers/baseten.js +1 -1
  190. package/dist/providers/cerebras.d.ts +1 -1
  191. package/dist/providers/cerebras.js +3 -2
  192. package/dist/providers/cerebras.js.map +1 -1
  193. package/dist/providers/local.d.ts +1 -1
  194. package/dist/providers/local.js +1 -1
  195. package/dist/providers/openai-compat.d.ts +1 -1
  196. package/dist/providers/openai-compat.js +1 -2
  197. package/dist/providers/openai.d.ts +1 -1
  198. package/dist/providers/openai.js +15 -12
  199. package/dist/providers/openai.js.map +1 -1
  200. package/dist/providers/openrouter.d.ts +1 -1
  201. package/dist/providers/openrouter.js +3 -2
  202. package/dist/providers/openrouter.js.map +1 -1
  203. package/dist/providers/xai.d.ts +1 -1
  204. package/dist/providers/xai.js +3 -3
  205. package/dist/{providers-BVhnFyiY.js → providers-XUR7F4Hi.js} +4 -4
  206. package/dist/{providers-BVhnFyiY.js.map → providers-XUR7F4Hi.js.map} +1 -1
  207. package/dist/providers.d.ts +1 -1
  208. package/dist/providers.js +4 -4
  209. package/dist/registry-D6ShBWJU.js +5234 -0
  210. package/dist/registry-D6ShBWJU.js.map +1 -0
  211. package/dist/remote-hosts-BtA_9ZGp.js +97 -0
  212. package/dist/remote-hosts-BtA_9ZGp.js.map +1 -0
  213. package/dist/restate.d.ts +2 -3
  214. package/dist/restate.d.ts.map +1 -1
  215. package/dist/restate.js +631 -572
  216. package/dist/restate.js.map +1 -1
  217. package/dist/run-summary-CklLiZ4y.js +288 -0
  218. package/dist/run-summary-CklLiZ4y.js.map +1 -0
  219. package/dist/{sandbox-BH0WQkXn.d.ts → sandbox-C5dR5DwQ.d.ts} +6 -3
  220. package/dist/sandbox-C5dR5DwQ.d.ts.map +1 -0
  221. package/dist/session/sqlite.d.ts +1 -2
  222. package/dist/session/sqlite.d.ts.map +1 -1
  223. package/dist/session/sqlite.js +1 -616
  224. package/dist/session-factory-BUGY5P40.js +1576 -0
  225. package/dist/session-factory-BUGY5P40.js.map +1 -0
  226. package/dist/{session-BqRP1hS7.js → session-xh9JXu6i.js} +94 -52
  227. package/dist/session-xh9JXu6i.js.map +1 -0
  228. package/dist/session.d.ts +1 -1
  229. package/dist/session.js +2 -2
  230. package/dist/settings-keys-Ckf29NeM.js +677 -0
  231. package/dist/settings-keys-Ckf29NeM.js.map +1 -0
  232. package/dist/shell-path-Dqaoow2J.js +412 -0
  233. package/dist/shell-path-Dqaoow2J.js.map +1 -0
  234. package/dist/{skills-BC3dodWp.js → skills-DKqZJm4X.js} +430 -470
  235. package/dist/skills-DKqZJm4X.js.map +1 -0
  236. package/dist/skills.d.ts +2 -2
  237. package/dist/skills.js +1 -2
  238. package/dist/source-mPExaUm8.js +381 -0
  239. package/dist/source-mPExaUm8.js.map +1 -0
  240. package/dist/sqlite-DV1DQzN2.js +698 -0
  241. package/dist/sqlite-DV1DQzN2.js.map +1 -0
  242. package/dist/{src-CkNQKFKr.js → src-BRMYRJib.js} +903 -1121
  243. package/dist/src-BRMYRJib.js.map +1 -0
  244. package/dist/{stdio-DPpBDPx5.js → stdio-C6YyoW3I.js} +4 -4
  245. package/dist/{stdio-DPpBDPx5.js.map → stdio-C6YyoW3I.js.map} +1 -1
  246. package/dist/{stdio-loader-Bbx19dMZ.js → stdio-loader-C830Vg-Z.js} +4 -4
  247. package/dist/{stdio-loader-Bbx19dMZ.js.map → stdio-loader-C830Vg-Z.js.map} +1 -1
  248. package/dist/system-prompt-MNVHatSD.d.ts.map +1 -1
  249. package/dist/timeout-DEaqslLO.d.ts.map +1 -1
  250. package/dist/todo-edits-Dn251YUP.js +1790 -0
  251. package/dist/todo-edits-Dn251YUP.js.map +1 -0
  252. package/dist/{turn-operations-DrbJlpq9.js → tool-formatters-IQFDrdrs.js} +1456 -2120
  253. package/dist/tool-formatters-IQFDrdrs.js.map +1 -0
  254. package/dist/tool-state-Dku6YqAB.js +989 -0
  255. package/dist/tool-state-Dku6YqAB.js.map +1 -0
  256. package/dist/tools/fetch-url.d.ts +1 -2
  257. package/dist/tools/fetch-url.d.ts.map +1 -1
  258. package/dist/tools/fetch-url.js +1 -2
  259. package/dist/tools/prompts.d.ts +1 -1
  260. package/dist/tools/prompts.js +7 -7
  261. package/dist/tools/prompts.js.map +1 -1
  262. package/dist/tools/web-search.d.ts +1 -2
  263. package/dist/tools/web-search.d.ts.map +1 -1
  264. package/dist/tools/web-search.js +2 -2
  265. package/dist/tools/web-search.js.map +1 -1
  266. package/dist/tools-_DnT3AGM.js +578 -0
  267. package/dist/tools-_DnT3AGM.js.map +1 -0
  268. package/dist/tools.d.ts +3 -3
  269. package/dist/tools.js +4 -2
  270. package/dist/tui.d.ts +534 -517
  271. package/dist/tui.d.ts.map +1 -1
  272. package/dist/tui.js +34933 -27242
  273. package/dist/tui.js.map +1 -1
  274. package/dist/turn-operations-B8sokwi5.js +333 -0
  275. package/dist/turn-operations-B8sokwi5.js.map +1 -0
  276. package/dist/turn-operations-DQX5ZZni.d.ts +3089 -0
  277. package/dist/turn-operations-DQX5ZZni.d.ts.map +1 -0
  278. package/dist/types-C7ZFOztE.d.ts +132 -0
  279. package/dist/types-C7ZFOztE.d.ts.map +1 -0
  280. package/dist/types-CH5XpIHw.js +114 -0
  281. package/dist/types-CH5XpIHw.js.map +1 -0
  282. package/dist/{types-CWgENVLY.js → types-Cu0ZGDu9.js} +10 -6
  283. package/dist/types-Cu0ZGDu9.js.map +1 -0
  284. package/dist/types-IqegbJEE.d.ts +624 -0
  285. package/dist/types-IqegbJEE.d.ts.map +1 -0
  286. package/dist/types.d.ts +4 -4
  287. package/dist/types.js +1 -1
  288. package/dist/url-D8HCl65b.js +1259 -0
  289. package/dist/url-D8HCl65b.js.map +1 -0
  290. package/dist/wasm-BVT-j5cl.js +33 -0
  291. package/dist/wasm-BVT-j5cl.js.map +1 -0
  292. package/dist/workspace-exec-stream-SV2R9d5S.js +355 -0
  293. package/dist/workspace-exec-stream-SV2R9d5S.js.map +1 -0
  294. package/dist/ws-CIHMvlSh.js +952 -0
  295. package/dist/ws-CIHMvlSh.js.map +1 -0
  296. package/dist/ws-client-N7NxzvQp.js +230 -0
  297. package/dist/ws-client-N7NxzvQp.js.map +1 -0
  298. package/dist/{xai-CazjStOK.js → xai-CvJTeLrI.js} +165 -5
  299. package/dist/xai-CvJTeLrI.js.map +1 -0
  300. package/dist/xdg-zweed0-t.js +117 -0
  301. package/dist/xdg-zweed0-t.js.map +1 -0
  302. package/docs/ACP.md +52 -0
  303. package/docs/ARCHITECTURE.md +103 -6
  304. package/docs/ARTIFACTS.md +8 -4
  305. package/docs/CHAT.md +165 -14
  306. package/docs/EXECUTION_CONTEXT.md +8 -0
  307. package/docs/EXTENSIONS.md +123 -2
  308. package/docs/HEADLESS.md +2 -0
  309. package/docs/IPC.md +775 -64
  310. package/docs/MACHINES.md +456 -0
  311. package/docs/PANELS.md +3 -0
  312. package/docs/README.md +4 -0
  313. package/docs/RESTATE.md +3 -2
  314. package/docs/RUN_IN_BACKGROUND.md +10 -2
  315. package/docs/SERVER.md +1085 -0
  316. package/docs/SKILL.md +6 -1
  317. package/docs/TERMINAL.md +75 -0
  318. package/docs/TUI.md +65 -14
  319. package/package.json +58 -26
  320. package/scripts/eval.ts +4 -0
  321. package/dist/acp-D-tVyUjw.js.map +0 -1
  322. package/dist/agent-D0zZnGbt.js.map +0 -1
  323. package/dist/anthropic-C2aole0G.js.map +0 -1
  324. package/dist/approvals-DKaJZYlm.js.map +0 -1
  325. package/dist/atomic-write-B7zr1ddF.js.map +0 -1
  326. package/dist/auth-BG2rVKSt.js.map +0 -1
  327. package/dist/completion-core-BRo86R_L.js.map +0 -1
  328. package/dist/contexts/daytona.js.map +0 -1
  329. package/dist/contexts/docker.js.map +0 -1
  330. package/dist/contexts/e2b.js.map +0 -1
  331. package/dist/contexts-CRE9pw07.js.map +0 -1
  332. package/dist/eval.js.map +0 -1
  333. package/dist/format-BF745pLL.js.map +0 -1
  334. package/dist/glob-DluQFSw1.js +0 -270
  335. package/dist/glob-DluQFSw1.js.map +0 -1
  336. package/dist/headless.js.map +0 -1
  337. package/dist/history-search-C4bk1Wz_.js.map +0 -1
  338. package/dist/index-BgN1T3lk.d.ts.map +0 -1
  339. package/dist/index-C37_ppWv.d.ts.map +0 -1
  340. package/dist/index-C6NEd5y_.d.ts.map +0 -1
  341. package/dist/ipc-zVSyo6K1.js +0 -331
  342. package/dist/ipc-zVSyo6K1.js.map +0 -1
  343. package/dist/ipc.d.ts.map +0 -1
  344. package/dist/isolation-Kfoof0MM.d.ts.map +0 -1
  345. package/dist/json-rpc-rSWMUh9b.js +0 -192
  346. package/dist/json-rpc-rSWMUh9b.js.map +0 -1
  347. package/dist/logger--C1VQjwJ.js.map +0 -1
  348. package/dist/mcp-CgNd-f3F.js.map +0 -1
  349. package/dist/messages-2jcOA_5R.js.map +0 -1
  350. package/dist/openai-compat-Dy56weK8.js.map +0 -1
  351. package/dist/output-cap-C9zukcCj.js +0 -100
  352. package/dist/output-cap-C9zukcCj.js.map +0 -1
  353. package/dist/panels-B6gRk4bf.js +0 -789
  354. package/dist/panels-B6gRk4bf.js.map +0 -1
  355. package/dist/plugins-gbI7SBA6.js.map +0 -1
  356. package/dist/prompts-Pqc3JdW_.d.ts.map +0 -1
  357. package/dist/run-summary-BU_NgwUT.js +0 -269
  358. package/dist/run-summary-BU_NgwUT.js.map +0 -1
  359. package/dist/sandbox-BH0WQkXn.d.ts.map +0 -1
  360. package/dist/session/sqlite.js.map +0 -1
  361. package/dist/session-BqRP1hS7.js.map +0 -1
  362. package/dist/shell-path-h5czzllR.js +0 -1549
  363. package/dist/shell-path-h5czzllR.js.map +0 -1
  364. package/dist/skills-BC3dodWp.js.map +0 -1
  365. package/dist/src-CkNQKFKr.js.map +0 -1
  366. package/dist/todo-edits-UOwgxGKu.js +0 -528
  367. package/dist/todo-edits-UOwgxGKu.js.map +0 -1
  368. package/dist/tool-formatters-DoRLnfuD.d.ts +0 -759
  369. package/dist/tool-formatters-DoRLnfuD.d.ts.map +0 -1
  370. package/dist/transcript-anchors-BeudMbXx.d.ts +0 -1762
  371. package/dist/transcript-anchors-BeudMbXx.d.ts.map +0 -1
  372. package/dist/turn-operations-C8bMBDl_.d.ts +0 -1258
  373. package/dist/turn-operations-C8bMBDl_.d.ts.map +0 -1
  374. package/dist/turn-operations-DrbJlpq9.js.map +0 -1
  375. package/dist/types-CWgENVLY.js.map +0 -1
  376. package/dist/xai-CazjStOK.js.map +0 -1
@@ -0,0 +1,1595 @@
1
+ import { t as alwaysQuote } from "./shell-quote-BmnhZmdM.js";
2
+ import { d as createMemoryStore, t as createSession } from "./session-xh9JXu6i.js";
3
+ import { t as createProcessContext } from "./contexts-d7UolYot.js";
4
+ import { a as headlessEventToJsonl, c as runHeadless } from "./headless-C_rNUuYC.js";
5
+ import { join, relative, resolve } from "node:path";
6
+ import { tmpdir } from "node:os";
7
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
8
+ import chalk from "chalk";
9
+ //#region src/eval-artifacts.ts
10
+ async function writeEvalArtifacts(dir, result) {
11
+ await mkdir(dir, { recursive: true });
12
+ const resultPath = join(dir, "result.json");
13
+ const eventsPath = join(dir, "events.jsonl");
14
+ const transcriptPath = join(dir, "transcript.json");
15
+ const workspacePath = result.workspace ? join(dir, "workspace.json") : void 0;
16
+ await writeFile(resultPath, `${JSON.stringify(result, null, 2)}\n`);
17
+ await writeFile(eventsPath, result.events.map(headlessEventToJsonl).join(""));
18
+ await writeFile(transcriptPath, `${JSON.stringify(result.result.transcript, null, 2)}\n`);
19
+ if (workspacePath) await writeFile(workspacePath, `${JSON.stringify(result.workspace, null, 2)}\n`);
20
+ return {
21
+ dir,
22
+ result: resultPath,
23
+ events: eventsPath,
24
+ transcript: transcriptPath,
25
+ ...workspacePath ? { workspace: workspacePath } : {}
26
+ };
27
+ }
28
+ function safeSegment(value) {
29
+ const sanitized = value.replace(/[^\w.-]+/g, "-").replace(/^-+|-+$/g, "");
30
+ if (sanitized === value && sanitized.length > 0) return sanitized;
31
+ return `${sanitized || "eval"}-${shortHash(value)}`;
32
+ }
33
+ function shortHash(value) {
34
+ let hash = 2166136261;
35
+ for (let i = 0; i < value.length; i++) {
36
+ hash ^= value.charCodeAt(i);
37
+ hash = Math.imul(hash, 16777619);
38
+ }
39
+ return (hash >>> 0).toString(36).padStart(7, "0").slice(0, 7);
40
+ }
41
+ function artifactPath(root, result) {
42
+ return resolve(root, safeSegment(result.suite ?? "eval"), safeSegment(result.id));
43
+ }
44
+ function relativeArtifactPath(root, path) {
45
+ return relative(root, path);
46
+ }
47
+ //#endregion
48
+ //#region src/eval-metrics.ts
49
+ /**
50
+ * Declare an eval's metric set. Returns the same map, typed; pass it to
51
+ * `EvalCaseOptions.metrics`. Declared metrics that are not emitted are recorded
52
+ * as missing with a normalized score of 0; emitting an undeclared metric is an
53
+ * authoring error and throws.
54
+ */
55
+ function defineMetrics(spec) {
56
+ return spec;
57
+ }
58
+ /** Always-available efficiency metrics derived from `HeadlessResult`. */
59
+ const EFFICIENCY_METRICS = {
60
+ "execution-time": {
61
+ min: 0,
62
+ max: 3e5,
63
+ direction: "lower-is-better",
64
+ tags: ["@efficiency"],
65
+ description: "Wall-clock run time (ms)."
66
+ },
67
+ "provider-tokens": {
68
+ min: 0,
69
+ max: 2e5,
70
+ direction: "lower-is-better",
71
+ tags: ["@efficiency"],
72
+ description: "Input + output tokens."
73
+ },
74
+ "cache-read-rate": {
75
+ min: 0,
76
+ max: 1,
77
+ direction: "higher-is-better",
78
+ tags: ["@efficiency"],
79
+ description: "Cache-read tokens / input tokens."
80
+ }
81
+ };
82
+ function normalizeMetric(raw, spec) {
83
+ const span = spec.max - spec.min;
84
+ if (span === 0) return 1;
85
+ const normalized = (Math.min(spec.max, Math.max(spec.min, raw)) - spec.min) / span;
86
+ return spec.direction === "lower-is-better" ? 1 - normalized : normalized;
87
+ }
88
+ /**
89
+ * Thrown by `runEvalCase` when a scorer emits a metric id that was not declared
90
+ * in `defineMetrics`. This is an authoring error (a typo'd or stale metric id),
91
+ * not a low score — it fails the eval test rather than being recorded as a
92
+ * failed scorer. Exported so downstream harnesses can type-narrow on it.
93
+ */
94
+ var EvalMetricError = class extends Error {
95
+ constructor(message) {
96
+ super(message);
97
+ this.name = "EvalMetricError";
98
+ }
99
+ };
100
+ function efficiencyMetricValues(result) {
101
+ const u = result.usage;
102
+ const readTotal = u.input + u.cacheRead;
103
+ return {
104
+ "execution-time": result.durationMs,
105
+ "provider-tokens": u.input + u.output,
106
+ "cache-read-rate": readTotal > 0 ? u.cacheRead / readTotal : 0
107
+ };
108
+ }
109
+ function emitEfficiencyMetrics(emit, result) {
110
+ const values = efficiencyMetricValues(result);
111
+ for (const [id, raw] of Object.entries(values)) emit(id, raw);
112
+ }
113
+ function finalizeEvalMetrics(specs, raw) {
114
+ return Object.entries(specs).map(([metricId, spec]) => {
115
+ const emitted = raw.has(metricId);
116
+ const value = emitted ? raw.get(metricId) : spec.min;
117
+ return {
118
+ id: metricId,
119
+ raw: emitted ? value : 0,
120
+ normalized: emitted ? normalizeMetric(value, spec) : 0,
121
+ direction: spec.direction,
122
+ min: spec.min,
123
+ max: spec.max,
124
+ tags: spec.tags ?? [],
125
+ ...spec.description ? { description: spec.description } : {},
126
+ ...emitted ? {} : { missing: true }
127
+ };
128
+ });
129
+ }
130
+ function computeEvalTagScores(metrics) {
131
+ const byTag = /* @__PURE__ */ new Map();
132
+ for (const metric of metrics) for (const tag of metric.tags) {
133
+ const list = byTag.get(tag) ?? [];
134
+ list.push(metric.normalized);
135
+ byTag.set(tag, list);
136
+ }
137
+ const out = {};
138
+ for (const [tag, values] of byTag) out[tag] = mean(values);
139
+ return out;
140
+ }
141
+ function meanNormalized(metrics) {
142
+ return metrics.length === 0 ? 0 : mean(metrics.map((m) => m.normalized));
143
+ }
144
+ function mean(values) {
145
+ return values.length === 0 ? 0 : values.reduce((a, b) => a + b, 0) / values.length;
146
+ }
147
+ //#endregion
148
+ //#region src/eval-summary.ts
149
+ /** Stable ordering by `variant`, then `suite/id`, so parallel completion order doesn't shuffle output. */
150
+ function sortCases(results) {
151
+ return [...results].sort((a, b) => {
152
+ const va = a.variant ?? "";
153
+ const vb = b.variant ?? "";
154
+ if (va !== vb) return va.localeCompare(vb);
155
+ const ka = `${a.suite ?? ""}/${a.id}`;
156
+ const kb = `${b.suite ?? ""}/${b.id}`;
157
+ return ka.localeCompare(kb);
158
+ });
159
+ }
160
+ /** Distinct variant labels across results, in sorted order. */
161
+ function distinctVariants(results) {
162
+ return [...new Set(results.map((r) => r.variant).filter((v) => Boolean(v)))].sort();
163
+ }
164
+ function buildEvalRunSummary(input) {
165
+ const results = sortCases(input);
166
+ const usage = results.reduce((acc, result) => {
167
+ acc.input += result.result.usage.input;
168
+ acc.output += result.result.usage.output;
169
+ acc.cacheRead += result.result.usage.cacheRead;
170
+ acc.cacheCreation += result.result.usage.cacheCreation;
171
+ acc.cost += result.result.usage.cost ?? 0;
172
+ return acc;
173
+ }, {
174
+ input: 0,
175
+ output: 0,
176
+ cacheRead: 0,
177
+ cacheCreation: 0,
178
+ cost: 0
179
+ });
180
+ const totalScore = results.reduce((sum, result) => sum + result.score, 0);
181
+ return {
182
+ count: results.length,
183
+ passed: results.filter((result) => result.passed).length,
184
+ score: results.length > 0 ? totalScore / results.length : 0,
185
+ durationMs: results.reduce((sum, result) => sum + result.result.durationMs, 0),
186
+ usage,
187
+ cases: results.map((result) => ({
188
+ id: result.id,
189
+ ...result.suite ? { suite: result.suite } : {},
190
+ ...result.variant ? { variant: result.variant } : {},
191
+ passed: result.passed,
192
+ score: result.score,
193
+ status: result.result.status,
194
+ durationMs: result.result.durationMs,
195
+ scores: result.scores,
196
+ metrics: result.metrics,
197
+ tagScores: result.tagScores,
198
+ trajectory: result.trajectory
199
+ })),
200
+ metrics: aggregateMetrics(results),
201
+ tagScores: aggregateTagScores(results),
202
+ ...distinctVariants(results).length > 0 ? { variants: aggregateVariants(results) } : {}
203
+ };
204
+ }
205
+ function aggregateVariants(results) {
206
+ return distinctVariants(results).map((variant) => {
207
+ const group = results.filter((r) => r.variant === variant);
208
+ const usage = group.reduce((acc, result) => {
209
+ acc.input += result.result.usage.input;
210
+ acc.output += result.result.usage.output;
211
+ acc.cacheRead += result.result.usage.cacheRead;
212
+ acc.cacheCreation += result.result.usage.cacheCreation;
213
+ acc.cost += result.result.usage.cost ?? 0;
214
+ return acc;
215
+ }, {
216
+ input: 0,
217
+ output: 0,
218
+ cacheRead: 0,
219
+ cacheCreation: 0,
220
+ cost: 0
221
+ });
222
+ return {
223
+ variant,
224
+ count: group.length,
225
+ passed: group.filter((r) => r.passed).length,
226
+ score: mean(group.map((r) => r.score)),
227
+ durationMs: group.reduce((sum, r) => sum + r.result.durationMs, 0),
228
+ usage,
229
+ turns: group.reduce((sum, r) => sum + r.result.turns, 0),
230
+ toolCalls: group.reduce((sum, r) => sum + r.result.numToolCalls, 0)
231
+ };
232
+ });
233
+ }
234
+ function aggregateMetrics(results) {
235
+ const byId = /* @__PURE__ */ new Map();
236
+ for (const result of results) for (const metric of result.metrics) {
237
+ const list = byId.get(metric.id) ?? [];
238
+ list.push(metric);
239
+ byId.set(metric.id, list);
240
+ }
241
+ return [...byId.entries()].map(([id, metrics]) => ({
242
+ id,
243
+ direction: metrics[0].direction,
244
+ tags: metrics[0].tags,
245
+ raw: metricStats(metrics.map((m) => m.raw)),
246
+ normalized: metricStats(metrics.map((m) => m.normalized))
247
+ }));
248
+ }
249
+ function aggregateTagScores(results) {
250
+ const byTag = /* @__PURE__ */ new Map();
251
+ for (const result of results) for (const [tag, value] of Object.entries(result.tagScores)) {
252
+ const list = byTag.get(tag) ?? [];
253
+ list.push(value);
254
+ byTag.set(tag, list);
255
+ }
256
+ const out = {};
257
+ for (const [tag, values] of byTag) out[tag] = mean(values);
258
+ return out;
259
+ }
260
+ function metricStats(values) {
261
+ const sorted = [...values].sort((a, b) => a - b);
262
+ return {
263
+ mean: mean(values),
264
+ min: sorted[0] ?? 0,
265
+ max: sorted[sorted.length - 1] ?? 0,
266
+ p50: percentile(sorted, .5),
267
+ p90: percentile(sorted, .9),
268
+ zeroCount: values.filter((v) => v === 0).length,
269
+ values
270
+ };
271
+ }
272
+ function percentile(sorted, q) {
273
+ if (sorted.length === 0) return 0;
274
+ return sorted[Math.min(sorted.length - 1, Math.max(0, Math.ceil(q * sorted.length) - 1))];
275
+ }
276
+ //#endregion
277
+ //#region src/eval-report.ts
278
+ function formatEvalCaseSummary(result) {
279
+ const lines = [
280
+ `Eval ${result.suite ? `${result.suite}/` : ""}${result.id}`,
281
+ ...result.variant ? [`variant: ${result.variant}`] : [],
282
+ `status: ${result.result.status}`,
283
+ `passed: ${result.passed}`,
284
+ `score: ${result.score.toFixed(2)}`,
285
+ `duration: ${result.result.durationMs}ms`,
286
+ `turns: ${result.result.turns}`,
287
+ `tool calls: ${result.result.numToolCalls}`,
288
+ `usage: input=${result.result.usage.input} output=${result.result.usage.output} cacheRead=${result.result.usage.cacheRead} cacheCreation=${result.result.usage.cacheCreation}${result.result.usage.cost !== void 0 ? ` cost=$${result.result.usage.cost.toFixed(6)}` : ""}`
289
+ ];
290
+ if (result.workspace) lines.push(`workspace files: ${result.workspace.files.length}`);
291
+ if (result.workspaceError) lines.push(`workspace error: ${result.workspaceError}`);
292
+ if (result.artifacts) lines.push(`artifacts: ${result.artifacts.dir}`);
293
+ if (result.scores.length > 0) {
294
+ lines.push("scores:");
295
+ for (const score of result.scores) {
296
+ const value = score.score !== void 0 ? score.score.toFixed(2) : score.passed ? "1.00" : "0.00";
297
+ lines.push(` - ${score.name}: ${value} ${score.passed ? "pass" : "fail"}`);
298
+ if (typeof score.details === "string" && score.details.length > 0) lines.push(` ${score.details}`);
299
+ else if (isRecord(score.details) && typeof score.details.reasoning === "string") lines.push(` ${score.details.reasoning}`);
300
+ }
301
+ }
302
+ return lines.join("\n");
303
+ }
304
+ function formatEvalRunSummary(results) {
305
+ return formatEvalRunSummaryWithOptions(results);
306
+ }
307
+ function formatEvalRunSummaryWithOptions(input, options = {}) {
308
+ const results = sortCases(input);
309
+ const color = createEvalColors(options.color);
310
+ if (results.length === 0) return `${color.heading("Eval run summary")}\n${color.muted("no evals ran")}`;
311
+ const summary = buildEvalRunSummary(results);
312
+ const out = [];
313
+ const variants = distinctVariants(results);
314
+ out.push(color.heading("Eval run summary"));
315
+ if (variants.length > 1) {
316
+ out.push(renderComparisonTable(results, variants, color));
317
+ for (const variant of variants) {
318
+ const group = results.filter((r) => r.variant === variant);
319
+ out.push("");
320
+ out.push(color.heading(variant));
321
+ out.push(renderResultsTable(group, buildEvalRunSummary(group), color));
322
+ }
323
+ } else out.push(renderResultsTable(results, summary, color));
324
+ const tagTable = renderTagTable(summary.tagScores, color);
325
+ if (tagTable) {
326
+ out.push("");
327
+ out.push(tagTable);
328
+ }
329
+ out.push("");
330
+ const hyperlinks = options.color !== false;
331
+ const linkText = (target) => {
332
+ const abs = absPath(target);
333
+ return hyperlinks ? oscLink(abs, abs) : abs;
334
+ };
335
+ for (const result of results) {
336
+ const caseLabel = `${result.suite ? `${result.suite}/` : ""}${result.id}`;
337
+ const label = result.variant ? `[${result.variant}] ${caseLabel}` : caseLabel;
338
+ out.push(`${color.dot(result.passed)} ${color.caseStatus(result.passed, label)}`);
339
+ out.push(`${color.muted("score")} ${color.score(result.score)}`);
340
+ const tagEntries = Object.entries(result.tagScores);
341
+ if (tagEntries.length > 0) out.push(`${color.muted("tags:")} ${tagEntries.map(([tag, value]) => `${color.tag(tag)} ${color.score(value)}`).join(" ")}`);
342
+ for (const metric of result.metrics) {
343
+ const note = metric.missing ? color.fail(" (not emitted)") : color.muted(` (${formatMetricRaw(metric)})`);
344
+ out.push(`${color.muted(padEnd(metric.id, 28))} ${color.score(metric.normalized)}${note}`);
345
+ }
346
+ for (const score of result.scores) {
347
+ const detail = scoreDetailLine(score);
348
+ if (!score.passed && detail) out.push(`${color.dot(score.passed)} ${color.muted(`${score.name}: ${truncate(detail, 140)}`)}`);
349
+ }
350
+ if (result.sourceFile) out.push(`${color.muted("case:")} ${color.muted(linkText(result.sourceFile))}`);
351
+ const resultTarget = caseLinkTarget(result);
352
+ if (resultTarget) out.push(`${color.muted("result:")} ${color.muted(linkText(resultTarget))}`);
353
+ if (result.trajectory.steps.length > 0) out.push(`${color.muted(`turns: ${result.trajectory.totalBlocks}`)} ${formatTrajectoryColored(result.trajectory, color)}`);
354
+ out.push("");
355
+ }
356
+ return out.join("\n").replace(/\n+$/, "");
357
+ }
358
+ function renderTagTable(tagScores, color) {
359
+ const entries = Object.entries(tagScores);
360
+ if (entries.length === 0) return void 0;
361
+ const tagWidth = Math.max(3, ...entries.map(([tag]) => tag.length));
362
+ const top = `┌${"─".repeat(tagWidth + 2)}┬${"─".repeat(9)}┐`;
363
+ const mid = `├${"─".repeat(tagWidth + 2)}┼${"─".repeat(9)}┤`;
364
+ const bot = `└${"─".repeat(tagWidth + 2)}┴${"─".repeat(9)}┘`;
365
+ return [
366
+ top,
367
+ `│ ${color.heading(padEnd("TAG", tagWidth))} │ ${color.heading("SCORE")} │`,
368
+ mid,
369
+ ...entries.map(([tag, value]) => `│ ${color.muted(padEnd(tag, tagWidth))} │ ${color.score(value)} │`),
370
+ bot
371
+ ].join("\n");
372
+ }
373
+ function formatMetricRaw(metric) {
374
+ return `raw ${Number.isInteger(metric.raw) ? formatInt(metric.raw) : metric.raw.toFixed(3)} ${metric.direction === "lower-is-better" ? "↓" : "↑"}`;
375
+ }
376
+ /**
377
+ * Resolve a filesystem target to link an eval case to. Prefers the written
378
+ * artifact (`result.json` → its dir), so the link opens the case's output.
379
+ * Returns `undefined` when no artifacts were written.
380
+ */
381
+ function caseLinkTarget(result) {
382
+ return result.artifacts?.result ?? result.artifacts?.dir;
383
+ }
384
+ /** Wrap text in an OSC 8 terminal hyperlink to a local path or URL. */
385
+ function oscLink(target, text) {
386
+ const url = /^(?:file|https?):\/\//.test(target) ? target : `file://${resolve(target)}`;
387
+ const OSC = "\x1B]8;;";
388
+ const ST = "\x1B\\";
389
+ return `${OSC}${url}${ST}${text}${OSC}${ST}`;
390
+ }
391
+ /** Absolute filesystem path (strips any `file://` prefix, resolves relatives). */
392
+ function absPath(target) {
393
+ const clean = target.replace(/^file:\/\//, "");
394
+ return resolve(clean);
395
+ }
396
+ /**
397
+ * Case key used to line up the same eval across variants in the comparison
398
+ * matrix. Strips the `-repeat-N` suffix `registerEvalTests` appends so a
399
+ * repeated case aggregates into one row (mean score, x/y passed).
400
+ */
401
+ function comparisonCaseKey(result) {
402
+ const id = result.id.replace(/-repeat-\d+$/, "");
403
+ return `${result.suite ? `${result.suite}/` : ""}${id}`;
404
+ }
405
+ /**
406
+ * Cross-variant comparison matrix: one row per eval case, one column per
407
+ * variant (provider/model target), plus rollup rows (score / passed / cost /
408
+ * time) so two models can be read side by side at a glance.
409
+ */
410
+ function renderComparisonTable(input, variants, color) {
411
+ const results = sortCases(input);
412
+ const caseKeys = [...new Set(results.map(comparisonCaseKey))].sort();
413
+ const byCell = /* @__PURE__ */ new Map();
414
+ for (const result of results) {
415
+ const key = `${comparisonCaseKey(result)}\u0000${result.variant ?? ""}`;
416
+ const list = byCell.get(key) ?? [];
417
+ list.push(result);
418
+ byCell.set(key, list);
419
+ }
420
+ const cellFor = (caseKey, variant) => {
421
+ const group = byCell.get(`${caseKey}\u0000${variant}`);
422
+ if (!group || group.length === 0) return { text: "-" };
423
+ const score = mean(group.map((r) => r.score));
424
+ const passedCount = group.filter((r) => r.passed).length;
425
+ const allPassed = passedCount === group.length;
426
+ const status = group.length > 1 ? `${passedCount}/${group.length}` : allPassed ? "pass" : "fail";
427
+ return {
428
+ text: `${score.toFixed(2)} ${status}`,
429
+ score,
430
+ passed: allPassed
431
+ };
432
+ };
433
+ const variantSummaries = aggregateVariants(results);
434
+ const summaryOf = (variant) => variantSummaries.find((s) => s.variant === variant);
435
+ const pair = variants.length === 2;
436
+ const header = [
437
+ "EVAL",
438
+ ...variants,
439
+ ...pair ? [`Δ ${variants[1]}`] : []
440
+ ];
441
+ const rows = caseKeys.map((key) => {
442
+ const cells = variants.map((variant) => cellFor(key, variant));
443
+ if (pair) cells.push(deltaCell(cells[0]?.score, cells[1]?.score, "higher", "points"));
444
+ return {
445
+ label: key,
446
+ cells
447
+ };
448
+ });
449
+ const rollups = [
450
+ {
451
+ label: "SCORE",
452
+ value: (s) => s.score,
453
+ format: (v) => v.toFixed(2),
454
+ better: "higher",
455
+ delta: "points",
456
+ paint: (s) => ({ score: s.score })
457
+ },
458
+ {
459
+ label: "PASSED",
460
+ value: (s) => s.passed,
461
+ format: (v, s) => `${v}/${s.count}`,
462
+ better: "higher",
463
+ delta: "points",
464
+ paint: (s) => ({ passed: s.passed === s.count })
465
+ },
466
+ {
467
+ label: "COST",
468
+ value: (s) => s.usage.cost,
469
+ format: (v) => formatCost(v),
470
+ better: "lower",
471
+ delta: "percent"
472
+ },
473
+ {
474
+ label: "TIME",
475
+ value: (s) => s.durationMs,
476
+ format: (v) => formatDuration(v),
477
+ better: "lower",
478
+ delta: "percent"
479
+ },
480
+ {
481
+ label: "TOKENS",
482
+ value: (s) => s.usage.input + s.usage.output,
483
+ format: (v) => formatInt(v),
484
+ better: "lower",
485
+ delta: "percent"
486
+ },
487
+ {
488
+ label: "CACHE R",
489
+ value: (s) => s.usage.cacheRead,
490
+ format: (v) => formatInt(v),
491
+ better: "lower",
492
+ delta: "percent"
493
+ },
494
+ {
495
+ label: "TURNS",
496
+ value: (s) => s.turns,
497
+ format: (v) => String(v),
498
+ better: "lower",
499
+ delta: "percent"
500
+ },
501
+ {
502
+ label: "TOOL CALLS",
503
+ value: (s) => s.toolCalls,
504
+ format: (v) => String(v),
505
+ better: "lower",
506
+ delta: "percent"
507
+ }
508
+ ].map((def) => {
509
+ const summaries = variants.map(summaryOf);
510
+ const cells = summaries.map((s) => s ? {
511
+ text: def.format(def.value(s), s),
512
+ ...def.paint?.(s)
513
+ } : { text: "-" });
514
+ if (pair) {
515
+ const [a, b] = summaries;
516
+ cells.push(deltaCell(a ? def.value(a) : void 0, b ? def.value(b) : void 0, def.better, def.delta));
517
+ }
518
+ return {
519
+ label: def.label,
520
+ cells,
521
+ rollup: true
522
+ };
523
+ });
524
+ const allRows = [...rows, ...rollups];
525
+ const widths = header.map((h, i) => Math.max(h.length, ...allRows.map((row) => (i === 0 ? row.label : row.cells[i - 1].text).length)));
526
+ const top = `┌${widths.map((w) => "─".repeat(w + 2)).join("┬")}┐`;
527
+ const mid = `├${widths.map((w) => "─".repeat(w + 2)).join("┼")}┤`;
528
+ const bot = `└${widths.map((w) => "─".repeat(w + 2)).join("┴")}┘`;
529
+ const paintComparisonCell = (cell, padded) => {
530
+ if (cell.score === void 0 && cell.passed === void 0) return color.muted(padded);
531
+ if (cell.score !== void 0) {
532
+ const scoreText = cell.score.toFixed(2);
533
+ const rest = cell.text.slice(scoreText.length);
534
+ const coloredRest = cell.passed === void 0 ? color.muted(rest) : cell.passed ? color.pass(rest) : color.fail(rest);
535
+ return padded.replace(cell.text, `${color.score(cell.score)}${coloredRest}`);
536
+ }
537
+ return padded.replace(cell.text, cell.passed ? color.pass(cell.text) : color.fail(cell.text));
538
+ };
539
+ const renderRow = (row) => {
540
+ const labelPadded = padEnd(row.label, widths[0]);
541
+ return `│ ${row.rollup ? color.heading(labelPadded) : color.muted(labelPadded)} │${row.cells.map((cell, i) => {
542
+ const padded = padStart(cell.text, widths[i + 1]);
543
+ return ` ${paintComparisonCell(cell, padded)} `;
544
+ }).join("│")}│`;
545
+ };
546
+ return [
547
+ top,
548
+ `│ ${color.heading(padEnd(header[0], widths[0]))} │${header.slice(1).map((v, i) => ` ${color.heading(padStart(v, widths[i + 1]))} `).join("│")}│`,
549
+ mid,
550
+ ...rows.map(renderRow),
551
+ mid,
552
+ ...rollups.map(renderRow),
553
+ bot
554
+ ].join("\n");
555
+ }
556
+ /**
557
+ * The Δ cell of a two-variant comparison: `b` against `a`, as an absolute
558
+ * difference (`points`, for scores and counts of passes) or a relative one
559
+ * (`percent`). Painted pass/fail by whether the change goes the `better` way;
560
+ * unchanged values and missing sides stay muted.
561
+ */
562
+ function deltaCell(a, b, better, kind) {
563
+ if (a === void 0 || b === void 0) return { text: "-" };
564
+ const diff = b - a;
565
+ if (Math.abs(diff) < 1e-9) return { text: "=" };
566
+ const sign = diff > 0 ? "+" : "−";
567
+ const improved = better === "higher" ? diff > 0 : diff < 0;
568
+ if (kind === "points") {
569
+ const magnitude = Math.abs(diff);
570
+ return {
571
+ text: `${sign}${Number.isInteger(magnitude) ? magnitude : magnitude.toFixed(2)}`,
572
+ passed: improved
573
+ };
574
+ }
575
+ if (a === 0) return {
576
+ text: `${sign}∞`,
577
+ passed: improved
578
+ };
579
+ return {
580
+ text: `${sign}${Math.round(Math.abs(diff / a) * 100)}%`,
581
+ passed: improved
582
+ };
583
+ }
584
+ function renderResultsTable(results, summary, color) {
585
+ const header = [
586
+ "EVAL",
587
+ "STATUS",
588
+ "SCORE",
589
+ "IN",
590
+ "OUT",
591
+ "CACHE R",
592
+ "CACHE W",
593
+ "COST",
594
+ "TIME"
595
+ ];
596
+ const rows = results.map((result) => {
597
+ const label = `${result.suite ? `${result.suite}/` : ""}${result.id}`;
598
+ const u = result.result.usage;
599
+ return {
600
+ passed: result.passed,
601
+ cells: [
602
+ label,
603
+ result.passed ? "pass" : "fail",
604
+ result.score.toFixed(2),
605
+ formatInt(u.input),
606
+ formatInt(u.output),
607
+ formatInt(u.cacheRead),
608
+ formatInt(u.cacheCreation),
609
+ formatCost(u.cost ?? 0),
610
+ formatDuration(result.result.durationMs)
611
+ ],
612
+ score: result.score
613
+ };
614
+ });
615
+ const totals = {
616
+ cells: [
617
+ `TOTAL (${summary.passed}/${summary.count})`,
618
+ summary.passed === summary.count ? "pass" : "fail",
619
+ summary.score.toFixed(2),
620
+ formatInt(summary.usage.input),
621
+ formatInt(summary.usage.output),
622
+ formatInt(summary.usage.cacheRead),
623
+ formatInt(summary.usage.cacheCreation),
624
+ formatCost(summary.usage.cost),
625
+ formatDuration(summary.durationMs)
626
+ ],
627
+ passed: summary.passed === summary.count,
628
+ score: summary.score
629
+ };
630
+ const aligns = [
631
+ "left",
632
+ "left",
633
+ "right",
634
+ "right",
635
+ "right",
636
+ "right",
637
+ "right",
638
+ "right",
639
+ "right"
640
+ ];
641
+ const widths = header.map((h, i) => Math.max(h.length, ...rows.map((r) => r.cells[i].length), totals.cells[i].length));
642
+ const top = `┌${widths.map((w) => "─".repeat(w + 2)).join("┬")}┐`;
643
+ const mid = `├${widths.map((w) => "─".repeat(w + 2)).join("┼")}┤`;
644
+ const bot = `└${widths.map((w) => "─".repeat(w + 2)).join("┴")}┘`;
645
+ const renderRow = (cells, paint) => {
646
+ return `│${cells.map((cell, i) => {
647
+ const padded = aligns[i] === "right" ? padStart(cell, widths[i]) : padEnd(cell, widths[i]);
648
+ return ` ${paint ? paint(i, cell, padded) : padded} `;
649
+ }).join("│")}│`;
650
+ };
651
+ return [
652
+ top,
653
+ renderRow(header, (_i, _raw, padded) => color.heading(padded)),
654
+ mid,
655
+ ...rows.map((r) => renderRow(r.cells, (i, raw, padded) => paintCell(i, raw, padded, r.passed, r.score, color))),
656
+ mid,
657
+ renderRow(totals.cells, (i, raw, padded) => paintCell(i, raw, padded, totals.passed, totals.score, color, true)),
658
+ bot
659
+ ].join("\n");
660
+ }
661
+ function paintCell(col, raw, padded, passed, score, color, bold = false) {
662
+ if (col === 0) return bold ? color.heading(padded) : color.caseStatus(passed, padded);
663
+ if (col === 1) return padded.replace(raw, color.status(passed));
664
+ if (col === 2) return padded.replace(raw, color.score(score));
665
+ if (col === 7) return color.cost(padded);
666
+ return color.muted(padded);
667
+ }
668
+ function scoreDetailLine(score) {
669
+ if (typeof score.details === "string") return score.details;
670
+ if (isRecord(score.details) && typeof score.details.reasoning === "string") return score.details.reasoning;
671
+ }
672
+ function formatInt(value) {
673
+ return value.toLocaleString("en-US");
674
+ }
675
+ function formatCost(value) {
676
+ return value > 0 ? `$${value.toFixed(4)}` : "-";
677
+ }
678
+ function formatDuration(ms) {
679
+ const rounded = Math.round(ms);
680
+ if (rounded < 1e3) return `${rounded}ms`;
681
+ const s = rounded / 1e3;
682
+ return `${Number.isInteger(s) ? s : s.toFixed(1)}s`;
683
+ }
684
+ function padEnd(value, width) {
685
+ return value.length >= width ? value : value + " ".repeat(width - value.length);
686
+ }
687
+ function padStart(value, width) {
688
+ return value.length >= width ? value : " ".repeat(width - value.length) + value;
689
+ }
690
+ function truncate(value, max) {
691
+ const oneLine = value.replace(/\s+/g, " ").trim();
692
+ return oneLine.length > max ? `${oneLine.slice(0, max - 1)}…` : oneLine;
693
+ }
694
+ function isRecord(value) {
695
+ return typeof value === "object" && value !== null;
696
+ }
697
+ function createEvalColors(enabled = shouldUseColor()) {
698
+ if (!enabled) return {
699
+ heading: (value) => value,
700
+ pass: (value) => value,
701
+ fail: (value) => value,
702
+ muted: (value) => value,
703
+ cost: (value) => value,
704
+ status: (passed) => passed ? "pass" : "fail",
705
+ score: (value) => value.toFixed(2),
706
+ caseStatus: (_passed, value) => value,
707
+ dot: (passed) => passed ? "+" : "x",
708
+ tag: (value) => value,
709
+ step: (_kind, value) => value
710
+ };
711
+ return {
712
+ heading: (value) => chalk.bold(value),
713
+ pass: (value) => chalk.green(value),
714
+ fail: (value) => chalk.red(value),
715
+ muted: (value) => chalk.gray(value),
716
+ cost: (value) => chalk.cyan(value),
717
+ status: (passed) => passed ? chalk.green("pass") : chalk.red("fail"),
718
+ score: (value) => value >= .9 ? chalk.green(value.toFixed(2)) : value >= .7 ? chalk.yellow(value.toFixed(2)) : chalk.red(value.toFixed(2)),
719
+ caseStatus: (passed, value) => passed ? chalk.green(value) : chalk.red(value),
720
+ dot: (passed) => passed ? chalk.green("●") : chalk.red("●"),
721
+ tag: (value) => chalk.bold(chalk.whiteBright(value)),
722
+ step: (kind, value) => paintStep(kind, value)
723
+ };
724
+ }
725
+ /** Per-kind trajectory colors: think=magenta, text=blue, tools by family. */
726
+ function paintStep(kind, value) {
727
+ if (kind === "think") return chalk.magenta(value);
728
+ if (kind === "text") return chalk.blue(value);
729
+ if (/write|edit|create/.test(value)) return chalk.green(value);
730
+ if (/read|list|glob|grep|search/.test(value)) return chalk.cyan(value);
731
+ if (/shell|bash|exec|run/.test(value)) return chalk.yellow(value);
732
+ if (/spawn|task|agent/.test(value)) return chalk.magentaBright(value);
733
+ return chalk.white(value);
734
+ }
735
+ function formatTrajectoryColored(trajectory, color) {
736
+ return trajectory.steps.map((step) => {
737
+ const base = step.kind === "tool" ? step.name ?? "tool" : step.kind;
738
+ const labelWithCount = step.count > 1 ? `${base} ×${step.count}` : base;
739
+ const painted = color.step(step.kind, labelWithCount);
740
+ const timing = step.durationMs && step.durationMs >= 100 ? color.muted(`(${formatDuration(step.durationMs)})`) : "";
741
+ return timing ? `${painted} ${timing}` : painted;
742
+ }).join(color.muted(" → "));
743
+ }
744
+ function shouldUseColor() {
745
+ return Boolean(process.stdout.isTTY && !process.env.NO_COLOR);
746
+ }
747
+ //#endregion
748
+ //#region src/eval-scorers.ts
749
+ function statusCompleted(name = "status.completed") {
750
+ return ({ result }) => ({
751
+ name,
752
+ passed: result.status === "completed",
753
+ score: result.status === "completed" ? 1 : 0,
754
+ details: result.status === "completed" ? void 0 : {
755
+ status: result.status,
756
+ error: result.error
757
+ }
758
+ });
759
+ }
760
+ function fileExists(path, name = `file.exists:${path}`) {
761
+ return ({ workspace }) => {
762
+ const found = workspace?.files.some((file) => file.path === path) ?? false;
763
+ return {
764
+ name,
765
+ passed: found,
766
+ score: found ? 1 : 0,
767
+ details: found ? void 0 : `Missing ${path}`
768
+ };
769
+ };
770
+ }
771
+ function fileExistsOneOf(paths, name = `file.existsOneOf:${paths.join("|")}`) {
772
+ return ({ workspace }) => {
773
+ const found = paths.find((path) => workspace?.files.some((file) => file.path === path));
774
+ return {
775
+ name,
776
+ passed: Boolean(found),
777
+ score: found ? 1 : 0,
778
+ details: found ? void 0 : `Missing one of: ${paths.join(", ")}`
779
+ };
780
+ };
781
+ }
782
+ function fileContains(path, expected, name = `file.contains:${path}`) {
783
+ return ({ workspace }) => {
784
+ const file = workspace?.files.find((file) => file.path === path);
785
+ const content = file?.content ?? "";
786
+ const passed = typeof expected === "string" ? content.includes(expected) : expected.test(content);
787
+ return {
788
+ name,
789
+ passed,
790
+ score: passed ? 1 : 0,
791
+ details: passed ? void 0 : file ? `Expected ${path} to contain ${String(expected)}` : `Missing ${path}`
792
+ };
793
+ };
794
+ }
795
+ function fileContentQuality(path, expected, name = `file.quality:${path}`) {
796
+ return ({ workspace }) => {
797
+ const content = (workspace?.files.find((file) => file.path === path))?.content;
798
+ if (content === void 0) return {
799
+ name,
800
+ passed: false,
801
+ score: 0,
802
+ details: `Missing ${path}`
803
+ };
804
+ const normalized = content.trim();
805
+ const expectedNormalized = expected.trim();
806
+ const score = normalized === expectedNormalized ? 1 : normalized.includes(expectedNormalized) ? .75 : content.includes(expected) ? .5 : 0;
807
+ return {
808
+ name,
809
+ passed: score >= .75,
810
+ score,
811
+ details: score >= .75 ? void 0 : `Expected ${path} to closely match ${JSON.stringify(expectedNormalized)}`
812
+ };
813
+ };
814
+ }
815
+ /**
816
+ * Aggregate a group of boolean scorers into a single `0..1` functionality
817
+ * metric (fraction passed) and emit it. Useful for "N of M files present".
818
+ */
819
+ function functionalityMetric(metricId, scorers, name = metricId) {
820
+ return async (ctx) => {
821
+ const results = await runScorers(ctx, scorers);
822
+ const passed = results.filter((r) => r.passed).length;
823
+ const fraction = results.length === 0 ? 1 : passed / results.length;
824
+ ctx.metric(metricId, fraction);
825
+ return {
826
+ name,
827
+ passed: passed === results.length,
828
+ score: fraction,
829
+ details: {
830
+ passed,
831
+ total: results.length,
832
+ checks: results.map((r) => ({
833
+ name: r.name,
834
+ passed: r.passed
835
+ }))
836
+ }
837
+ };
838
+ };
839
+ }
840
+ async function runScorers(ctx, scorers) {
841
+ const scores = [];
842
+ for (const scorer of scorers) try {
843
+ scores.push(await scorer(ctx));
844
+ } catch (err) {
845
+ if (err instanceof EvalMetricError) throw err;
846
+ scores.push({
847
+ name: scorer.name || "anonymous-scorer",
848
+ passed: false,
849
+ score: 0,
850
+ details: err instanceof Error ? err.message : String(err)
851
+ });
852
+ }
853
+ return scores;
854
+ }
855
+ function aggregateScore(scores) {
856
+ if (scores.length === 0) return 1;
857
+ return scores.reduce((sum, score) => sum + (score.score ?? (score.passed ? 1 : 0)), 0) / scores.length;
858
+ }
859
+ //#endregion
860
+ //#region src/eval-trajectory.ts
861
+ /**
862
+ * Build an ordered, grouped trajectory from a transcript. Walks assistant
863
+ * turns in order, emitting `think` / `text` / `tool:<name>` steps, grouping
864
+ * only consecutive identical kinds. Per-step duration is approximated from the
865
+ * owning turn's `createdAt` delta to the next turn.
866
+ */
867
+ function buildTrajectory(transcript) {
868
+ const steps = [];
869
+ let total = 0;
870
+ const push = (kind, name, durationMs) => {
871
+ total++;
872
+ const last = steps[steps.length - 1];
873
+ if (last && last.kind === kind && last.name === name) {
874
+ last.count++;
875
+ if (durationMs > 0) last.durationMs = (last.durationMs ?? 0) + durationMs;
876
+ return;
877
+ }
878
+ steps.push({
879
+ kind,
880
+ ...name ? { name } : {},
881
+ count: 1,
882
+ ...durationMs > 0 ? { durationMs } : {}
883
+ });
884
+ };
885
+ for (let i = 0; i < transcript.length; i++) {
886
+ const turn = transcript[i];
887
+ if (turn.role !== "assistant") continue;
888
+ const next = transcript[i + 1];
889
+ const turnDuration = next ? Math.max(0, next.createdAt - turn.createdAt) : 0;
890
+ const blocks = turn.content.filter((b) => b.type === "thinking" || b.type === "redacted_thinking" || b.type === "text" || b.type === "tool_call");
891
+ const toolBlocks = blocks.filter((b) => b.type === "tool_call").length;
892
+ const perTool = toolBlocks > 0 ? Math.round(turnDuration / toolBlocks) : 0;
893
+ for (const block of blocks) if (block.type === "thinking" || block.type === "redacted_thinking") push("think", void 0, 0);
894
+ else if (block.type === "text") push("text", void 0, 0);
895
+ else if (block.type === "tool_call") push("tool", block.name, perTool);
896
+ }
897
+ return {
898
+ steps,
899
+ totalBlocks: total
900
+ };
901
+ }
902
+ /** Render a trajectory as a one-line timeline string (no color). */
903
+ function formatTrajectoryLine(trajectory) {
904
+ return trajectory.steps.map(stepLabel).join(" → ");
905
+ }
906
+ function stepLabel(step) {
907
+ const base = step.kind === "tool" ? step.name ?? "tool" : step.kind;
908
+ return step.count > 1 ? `${base} ×${step.count}` : base;
909
+ }
910
+ //#endregion
911
+ //#region src/eval-workspace.ts
912
+ async function prepareWorkspace(execution, workspace) {
913
+ if (!workspace) return {
914
+ snapshot: () => void 0,
915
+ error: () => void 0,
916
+ cleanup: async () => {}
917
+ };
918
+ let tempDir;
919
+ let baseExecution = execution;
920
+ if (!baseExecution) {
921
+ const cwd = workspace.cwd ?? await mkdtemp(join(tmpdir(), "zidane-eval-"));
922
+ if (!workspace.cwd) tempDir = cwd;
923
+ baseExecution = createProcessContext({ cwd });
924
+ }
925
+ const captured = {};
926
+ return {
927
+ execution: withWorkspaceLifecycle(baseExecution, workspace, captured),
928
+ snapshot: () => captured.snapshot,
929
+ error: () => captured.error,
930
+ cleanup: async () => {
931
+ if (tempDir && !workspace.retain) await rm(tempDir, {
932
+ recursive: true,
933
+ force: true
934
+ });
935
+ }
936
+ };
937
+ }
938
+ function withWorkspaceLifecycle(execution, workspace, captured) {
939
+ return {
940
+ ...execution,
941
+ async spawn(config) {
942
+ const handle = await execution.spawn({
943
+ ...config,
944
+ ...workspace.cwd && !config?.cwd ? { cwd: workspace.cwd } : {}
945
+ });
946
+ if (workspace.seedDir) await seedWorkspace(execution, handle, workspace);
947
+ return handle;
948
+ },
949
+ async destroy(handle) {
950
+ try {
951
+ captured.snapshot = await captureWorkspace(execution, handle, workspace);
952
+ } catch (err) {
953
+ captured.error = err instanceof Error ? err.message : String(err);
954
+ } finally {
955
+ await execution.destroy(handle);
956
+ }
957
+ }
958
+ };
959
+ }
960
+ async function seedWorkspace(execution, handle, workspace) {
961
+ const target = workspace.seedTarget ?? ".";
962
+ const result = await execution.exec(handle, `mkdir -p ${alwaysQuote(target)} && cp -R ${alwaysQuote(`${workspace.seedDir}/.`)} ${alwaysQuote(target)}`);
963
+ if (result.exitCode !== 0) throw new Error(`Failed to seed eval workspace: ${result.stderr || result.stdout}`);
964
+ }
965
+ async function captureWorkspace(execution, handle, workspace) {
966
+ const capturePaths = workspace.capture?.length ? workspace.capture : ["."];
967
+ const command = [
968
+ `cd ${alwaysQuote(handle.cwd)}`,
969
+ "&&",
970
+ "for p in",
971
+ capturePaths.map(alwaysQuote).join(" "),
972
+ "; do",
973
+ "if [ -e \"$p\" ]; then",
974
+ "find \"$p\" \\( -path \"*/node_modules/*\" -o -path \"*/.git/*\" \\) -prune -o -type f -print0",
975
+ "; fi",
976
+ "done"
977
+ ].join(" ");
978
+ const listed = await execution.exec(handle, command);
979
+ if (listed.exitCode !== 0) throw new Error(`Failed to list eval workspace: ${listed.stderr || listed.stdout}`);
980
+ const maxFileChars = workspace.maxFileChars ?? 262144;
981
+ const files = [];
982
+ const seen = /* @__PURE__ */ new Set();
983
+ for (const rawPath of listed.stdout.split("\0").filter(Boolean)) {
984
+ const path = normalizeSnapshotPath(rawPath);
985
+ if (seen.has(path)) continue;
986
+ seen.add(path);
987
+ const content = await execution.readFile(handle, path);
988
+ const binary = content.includes("\0");
989
+ const truncated = content.length > maxFileChars;
990
+ files.push({
991
+ path,
992
+ size: content.length,
993
+ ...binary ? { binary: true } : { content: truncated ? content.slice(0, maxFileChars) : content },
994
+ ...truncated ? { truncated: true } : {}
995
+ });
996
+ }
997
+ return {
998
+ cwd: handle.cwd,
999
+ files
1000
+ };
1001
+ }
1002
+ function normalizeSnapshotPath(path) {
1003
+ const normalized = path.startsWith("./") ? path.slice(2) : path;
1004
+ return normalized === "" ? "." : normalized;
1005
+ }
1006
+ //#endregion
1007
+ //#region src/eval-execution.ts
1008
+ /**
1009
+ * Wrap an execution context so repeated agent runs share one handle until the
1010
+ * caller disposes it. This is useful for eval fixtures that want per-test
1011
+ * Docker/process lifetime while still using `runHeadless()` per turn.
1012
+ */
1013
+ function createReusableExecutionContext(base) {
1014
+ let handle;
1015
+ let spawnPromise;
1016
+ let disposed = false;
1017
+ let disposePromise;
1018
+ const ensureHandle = (config) => {
1019
+ if (disposed) throw new Error("Reusable execution context has been disposed");
1020
+ if (handle) return Promise.resolve(handle);
1021
+ spawnPromise ??= base.spawn(config).then((next) => {
1022
+ handle = next;
1023
+ return next;
1024
+ }, (err) => {
1025
+ spawnPromise = void 0;
1026
+ throw err;
1027
+ });
1028
+ return spawnPromise;
1029
+ };
1030
+ return {
1031
+ execution: {
1032
+ ...base,
1033
+ async spawn(config) {
1034
+ return ensureHandle(config);
1035
+ },
1036
+ async destroy() {}
1037
+ },
1038
+ dispose() {
1039
+ disposePromise ??= (async () => {
1040
+ disposed = true;
1041
+ const active = handle ?? await spawnPromise?.catch(() => void 0);
1042
+ handle = void 0;
1043
+ spawnPromise = void 0;
1044
+ if (active) await base.destroy(active);
1045
+ })();
1046
+ return disposePromise;
1047
+ },
1048
+ handle: () => handle
1049
+ };
1050
+ }
1051
+ //#endregion
1052
+ //#region src/eval-agent.ts
1053
+ /**
1054
+ * Multi-turn eval agent over the low-level headless runner. It keeps session
1055
+ * and execution lifetime outside any Playwright-specific fixture layer,
1056
+ * so downstream platforms can wrap it with their own `agent.run(...)` shape.
1057
+ */
1058
+ function createEvalAgent(options) {
1059
+ const { cwd, execution, session: initialSession, store: initialStore, mcpServers: baseMcpServers, onEvent: baseOnEvent, ...headlessDefaults } = options;
1060
+ const executionOwner = createReusableExecutionContext(execution ?? createProcessContext({ cwd }));
1061
+ const store = initialStore ?? createMemoryStore();
1062
+ let sessionPromise = initialSession ? Promise.resolve(initialSession) : void 0;
1063
+ let disposed = false;
1064
+ let runInFlight = false;
1065
+ let disposePromise;
1066
+ const stats = {
1067
+ runs: 0,
1068
+ input: 0,
1069
+ output: 0,
1070
+ cacheRead: 0,
1071
+ cacheCreation: 0,
1072
+ cost: 0,
1073
+ turns: 0,
1074
+ toolCalls: 0,
1075
+ durationMs: 0
1076
+ };
1077
+ async function getSession() {
1078
+ if (disposed) throw new Error("Eval agent has been disposed");
1079
+ sessionPromise ??= createSession({ store });
1080
+ return sessionPromise;
1081
+ }
1082
+ async function resolveMcpServers(runServers) {
1083
+ const merged = [...(typeof baseMcpServers === "function" ? await baseMcpServers() : baseMcpServers) ?? [], ...runServers ?? []];
1084
+ return merged.length > 0 ? [...merged] : void 0;
1085
+ }
1086
+ async function run(runOptions) {
1087
+ if (runInFlight) throw new Error("Eval agent already has a run in progress");
1088
+ runInFlight = true;
1089
+ try {
1090
+ const session = await getSession();
1091
+ const { mcpServers: runMcpServers, onEvent: runOnEvent, ...restRunOptions } = runOptions;
1092
+ const mcpServers = await resolveMcpServers(runMcpServers);
1093
+ const result = await runHeadless({
1094
+ ...headlessDefaults,
1095
+ ...restRunOptions,
1096
+ session,
1097
+ execution: executionOwner.execution,
1098
+ ...mcpServers ? { mcpServers } : {},
1099
+ onEvent(event) {
1100
+ baseOnEvent?.(event);
1101
+ runOnEvent?.(event);
1102
+ }
1103
+ });
1104
+ const newTranscript = result.transcript.slice();
1105
+ const runStats = {
1106
+ input: result.usage.input,
1107
+ output: result.usage.output,
1108
+ cacheRead: result.usage.cacheRead,
1109
+ cacheCreation: result.usage.cacheCreation,
1110
+ cost: result.usage.cost ?? 0,
1111
+ durationMs: result.durationMs,
1112
+ turns: result.turns,
1113
+ toolCalls: countToolCallsInTurns(newTranscript)
1114
+ };
1115
+ accumulateEvalAgentStats(stats, runStats);
1116
+ return {
1117
+ result,
1118
+ stats: runStats,
1119
+ newTranscript
1120
+ };
1121
+ } finally {
1122
+ runInFlight = false;
1123
+ }
1124
+ }
1125
+ function dispose() {
1126
+ disposePromise ??= (async () => {
1127
+ disposed = true;
1128
+ await executionOwner.dispose();
1129
+ })();
1130
+ return disposePromise;
1131
+ }
1132
+ return {
1133
+ run,
1134
+ stats,
1135
+ session: getSession,
1136
+ dispose,
1137
+ [Symbol.asyncDispose]: dispose
1138
+ };
1139
+ }
1140
+ function accumulateEvalAgentStats(acc, turn) {
1141
+ acc.runs += 1;
1142
+ acc.input += turn.input;
1143
+ acc.output += turn.output;
1144
+ acc.cacheRead += turn.cacheRead;
1145
+ acc.cacheCreation += turn.cacheCreation;
1146
+ acc.cost += turn.cost;
1147
+ acc.turns += turn.turns;
1148
+ acc.toolCalls += turn.toolCalls;
1149
+ acc.durationMs += turn.durationMs;
1150
+ }
1151
+ function countToolCallsInTurns(turns) {
1152
+ let count = 0;
1153
+ for (const turn of turns) {
1154
+ if (turn.role !== "assistant") continue;
1155
+ count += turn.content.filter((block) => block.type === "tool_call").length;
1156
+ }
1157
+ return count;
1158
+ }
1159
+ const UNPARSEABLE_REASONING = "Judge did not return a parseable score.";
1160
+ const DEFAULT_JUDGE_SYSTEM = [
1161
+ "You are a strict software eval judge.",
1162
+ "Grade only the supplied output against the rubric.",
1163
+ "Call the `submit_grade` tool with your score and reasoning.",
1164
+ "The score must be between 0 and 1."
1165
+ ].join("\n");
1166
+ /** Forced-output tool the judge must call — the schema-enforcement path. */
1167
+ const JUDGE_TOOL = {
1168
+ name: "submit_grade",
1169
+ description: "Submit the grade for the output under evaluation.",
1170
+ inputSchema: {
1171
+ type: "object",
1172
+ properties: {
1173
+ score: {
1174
+ type: "number",
1175
+ minimum: 0,
1176
+ maximum: 1,
1177
+ description: "Quality score from 0 (worst) to 1 (best)."
1178
+ },
1179
+ reasoning: {
1180
+ type: "string",
1181
+ description: "Brief justification for the score."
1182
+ },
1183
+ feedback: {
1184
+ type: "string",
1185
+ description: "Optional actionable feedback."
1186
+ }
1187
+ },
1188
+ required: ["score", "reasoning"],
1189
+ additionalProperties: false
1190
+ }
1191
+ };
1192
+ function llmJudge(options) {
1193
+ const name = options.name ?? "llm.judge";
1194
+ const model = options.model ?? options.provider.meta.defaultModel;
1195
+ return async (ctx) => {
1196
+ const userMessage = options.provider.userMessage(renderJudgePrompt({
1197
+ rubric: options.rubric,
1198
+ input: options.input?.(ctx) ?? defaultJudgeInput(ctx)
1199
+ }));
1200
+ let text = "";
1201
+ const controller = new AbortController();
1202
+ const timeoutMs = options.timeoutMs ?? 6e4;
1203
+ let timedOut = false;
1204
+ const timer = timeoutMs > 0 ? setTimeout(() => {
1205
+ timedOut = true;
1206
+ controller.abort(/* @__PURE__ */ new Error(`LLM judge timed out after ${timeoutMs}ms`));
1207
+ }, timeoutMs) : void 0;
1208
+ const timeoutPromise = timeoutMs > 0 ? new Promise((_resolve, reject) => {
1209
+ controller.signal.addEventListener("abort", () => {
1210
+ if (timedOut) reject(/* @__PURE__ */ new Error(`LLM judge timed out after ${timeoutMs}ms`));
1211
+ }, { once: true });
1212
+ }) : void 0;
1213
+ timeoutPromise?.catch(() => {});
1214
+ const grade = async (maxTokens) => {
1215
+ text = "";
1216
+ const streamPromise = options.provider.stream({
1217
+ model,
1218
+ system: options.system ?? DEFAULT_JUDGE_SYSTEM,
1219
+ tools: options.provider.formatTools([JUDGE_TOOL]),
1220
+ messages: [userMessage],
1221
+ maxTokens,
1222
+ cache: false,
1223
+ signal: controller.signal,
1224
+ toolChoice: {
1225
+ type: "tool",
1226
+ name: JUDGE_TOOL.name
1227
+ }
1228
+ }, { onText(delta) {
1229
+ text += delta;
1230
+ } });
1231
+ return timeoutPromise ? await Promise.race([streamPromise, timeoutPromise]) : await streamPromise;
1232
+ };
1233
+ try {
1234
+ const budget = options.maxTokens ?? 4e3;
1235
+ let result = await grade(budget);
1236
+ const submitted = (r) => r.toolCalls.some((tc) => tc.name === JUDGE_TOOL.name);
1237
+ if (!submitted(result) && result.usage.finishReason === "length") result = await grade(budget * 2);
1238
+ const parsed = readJudgeResult(result.toolCalls, text || result.text);
1239
+ if (!submitted(result) && parsed.reasoning === UNPARSEABLE_REASONING && result.usage.finishReason) parsed.reasoning = `${UNPARSEABLE_REASONING} (finish reason: ${result.usage.finishReason})`;
1240
+ if (options.metric) ctx.metric(options.metric, parsed.score);
1241
+ return {
1242
+ name,
1243
+ passed: parsed.score >= .7,
1244
+ score: parsed.score,
1245
+ details: {
1246
+ reasoning: parsed.reasoning,
1247
+ ...parsed.feedback ? { feedback: parsed.feedback } : {},
1248
+ ...parsed.raw ? { raw: parsed.raw } : {},
1249
+ usage: result.usage
1250
+ }
1251
+ };
1252
+ } finally {
1253
+ if (timer) clearTimeout(timer);
1254
+ }
1255
+ };
1256
+ }
1257
+ function readJudgeResult(toolCalls, fallbackText) {
1258
+ const call = toolCalls.find((tc) => tc.name === JUDGE_TOOL.name);
1259
+ if (call) {
1260
+ const input = call.input;
1261
+ return {
1262
+ score: clampScore(input.score),
1263
+ reasoning: typeof input.reasoning === "string" ? input.reasoning : "",
1264
+ ...typeof input.feedback === "string" ? { feedback: input.feedback } : {}
1265
+ };
1266
+ }
1267
+ return parseJudgeOutput(fallbackText);
1268
+ }
1269
+ function renderJudgePrompt(input) {
1270
+ return [
1271
+ "Rubric:",
1272
+ input.rubric,
1273
+ "",
1274
+ "Output to grade:",
1275
+ input.input,
1276
+ "",
1277
+ "Return JSON only."
1278
+ ].join("\n");
1279
+ }
1280
+ function defaultJudgeInput(ctx) {
1281
+ const chunks = [`Final answer:\n${ctx.result.finalText}`];
1282
+ if (ctx.workspace) chunks.push(`Workspace files:\n${ctx.workspace.files.map((file) => [`--- ${file.path}${file.truncated ? " (truncated)" : ""} ---`, file.binary ? "[binary omitted]" : file.content ?? ""].join("\n")).join("\n")}`);
1283
+ return chunks.join("\n\n");
1284
+ }
1285
+ function parseJudgeOutput(raw) {
1286
+ const trimmed = stripCodeFences(raw.trim());
1287
+ const jsonText = extractJsonObject(trimmed);
1288
+ if (jsonText) try {
1289
+ const parsed = JSON.parse(jsonText);
1290
+ if (parsed.score !== void 0 || parsed.reasoning !== void 0) return {
1291
+ score: clampScore(parsed.score),
1292
+ reasoning: typeof parsed.reasoning === "string" ? parsed.reasoning : "",
1293
+ ...typeof parsed.feedback === "string" ? { feedback: parsed.feedback } : {},
1294
+ ...jsonText === trimmed ? {} : { raw: trimmed }
1295
+ };
1296
+ } catch {}
1297
+ const scoreFragment = trimmed.match(/score["']?\s*[:=]\s*(-?\d+(?:\.\d+)?)/i);
1298
+ if (scoreFragment) return {
1299
+ score: clampScore(Number(scoreFragment[1])),
1300
+ reasoning: trimmed.slice(0, 500),
1301
+ raw: trimmed
1302
+ };
1303
+ const bareFraction = trimmed.match(/^(-?\d+(?:\.\d+)?)\s*\/\s*(\d+(?:\.\d+)?)$/);
1304
+ if (bareFraction) {
1305
+ const denom = Number(bareFraction[2]);
1306
+ return {
1307
+ score: clampScore(denom === 0 ? 0 : Number(bareFraction[1]) / denom),
1308
+ reasoning: trimmed,
1309
+ raw: trimmed
1310
+ };
1311
+ }
1312
+ if (trimmed.match(/^-?\d+(?:\.\d+)?$/)) return {
1313
+ score: clampScore(Number(trimmed)),
1314
+ reasoning: "",
1315
+ raw: trimmed
1316
+ };
1317
+ return {
1318
+ score: 0,
1319
+ reasoning: UNPARSEABLE_REASONING,
1320
+ raw: trimmed
1321
+ };
1322
+ }
1323
+ /** Strip a leading/trailing markdown code fence (``` or ```json). */
1324
+ function stripCodeFences(text) {
1325
+ const fence = text.match(/^```(?:json)?[ \t]*\n([\s\S]*?)\n```$/i);
1326
+ return fence ? fence[1].trim() : text;
1327
+ }
1328
+ /** Extract the first balanced `{...}` object, ignoring braces inside strings. */
1329
+ function extractJsonObject(text) {
1330
+ const start = text.indexOf("{");
1331
+ if (start === -1) return void 0;
1332
+ let depth = 0;
1333
+ let inString = false;
1334
+ let escaped = false;
1335
+ for (let i = start; i < text.length; i++) {
1336
+ const ch = text[i];
1337
+ if (inString) {
1338
+ if (escaped) escaped = false;
1339
+ else if (ch === "\\") escaped = true;
1340
+ else if (ch === "\"") inString = false;
1341
+ continue;
1342
+ }
1343
+ if (ch === "\"") inString = true;
1344
+ else if (ch === "{") depth++;
1345
+ else if (ch === "}") {
1346
+ depth--;
1347
+ if (depth === 0) return text.slice(start, i + 1);
1348
+ }
1349
+ }
1350
+ }
1351
+ function clampScore(value) {
1352
+ const n = typeof value === "number" ? value : Number(value);
1353
+ if (!Number.isFinite(n)) return 0;
1354
+ return Math.max(0, Math.min(1, n));
1355
+ }
1356
+ //#endregion
1357
+ //#region src/eval-registry.ts
1358
+ const evalRegistry = [];
1359
+ const STUB_PROVIDER = {
1360
+ name: "stub",
1361
+ meta: { defaultModel: "stub" },
1362
+ formatTools: (tools) => tools,
1363
+ userMessage: () => ({
1364
+ role: "user",
1365
+ content: []
1366
+ }),
1367
+ assistantMessage: () => ({
1368
+ role: "assistant",
1369
+ content: []
1370
+ }),
1371
+ toolResultsMessage: () => ({
1372
+ role: "user",
1373
+ content: []
1374
+ }),
1375
+ stream: async () => {
1376
+ throw new Error("stub provider is not runnable");
1377
+ }
1378
+ };
1379
+ /**
1380
+ * Register an eval definition. Eval files call this at module load; the harness
1381
+ * (`buildRegisteredEvals`) materializes them with a provider at run time. The
1382
+ * factory keeps definitions lazy so a single registry serves any provider/judge
1383
+ * pairing without re-importing eval files.
1384
+ *
1385
+ * Returns the same factory so a file can also `export default` it for direct,
1386
+ * registry-free use (e.g. hermetic unit tests).
1387
+ */
1388
+ function defineEval(define) {
1389
+ const id = safeRegistryId(define);
1390
+ if (!evalRegistry.some((entry) => entry.id === id)) evalRegistry.push({
1391
+ id,
1392
+ define
1393
+ });
1394
+ return define;
1395
+ }
1396
+ /** Snapshot of every registered eval, materialized for one provider/judge pair. */
1397
+ function buildRegisteredEvals(ctx) {
1398
+ return evalRegistry.map((entry) => entry.define(ctx));
1399
+ }
1400
+ /** Drop every registered eval — test isolation helper. */
1401
+ function clearRegisteredEvals() {
1402
+ evalRegistry.length = 0;
1403
+ }
1404
+ function safeRegistryId(define) {
1405
+ try {
1406
+ const stub = define({
1407
+ provider: STUB_PROVIDER,
1408
+ judge: STUB_PROVIDER
1409
+ });
1410
+ return `${stub.suite ?? "eval"}/${stub.id}`;
1411
+ } catch {
1412
+ return `eval/${evalRegistry.length}`;
1413
+ }
1414
+ }
1415
+ //#endregion
1416
+ //#region src/eval.ts
1417
+ async function runEvalCase(options) {
1418
+ const { id, suite, variant, tags = [], artifactDir, workspace, scorers = [], onEvent, ...headless } = options;
1419
+ const { metrics: declaredMetrics, sourceFile, ...headlessRest } = headless;
1420
+ const events = [];
1421
+ const caseArtifactDir = artifactDir ? join(artifactDir, ...variant ? [safeSegment(variant)] : [], safeSegment(suite ?? "eval"), safeSegment(id)) : void 0;
1422
+ const workspaceState = await prepareWorkspace(headlessRest.execution, workspace);
1423
+ const caseMetricIds = new Set(Object.keys(declaredMetrics ?? {}));
1424
+ const hasCaseMetrics = caseMetricIds.size > 0;
1425
+ const metricSpecs = {
1426
+ ...EFFICIENCY_METRICS,
1427
+ ...declaredMetrics
1428
+ };
1429
+ const rawMetrics = /* @__PURE__ */ new Map();
1430
+ const emitMetric = (metricId, raw) => {
1431
+ if (!(metricId in metricSpecs)) throw new EvalMetricError(`Eval ${id}: metric "${metricId}" emitted but not declared in defineMetrics`);
1432
+ if (!Number.isFinite(raw)) throw new EvalMetricError(`Eval ${id}: metric "${metricId}" emitted a non-finite value (${raw}); scores require finite numbers`);
1433
+ rawMetrics.set(metricId, raw);
1434
+ };
1435
+ try {
1436
+ const result = await runHeadless({
1437
+ ...headlessRest,
1438
+ ...workspaceState.execution ? { execution: workspaceState.execution } : {},
1439
+ onEvent(event) {
1440
+ events.push(event);
1441
+ onEvent?.(event);
1442
+ }
1443
+ });
1444
+ emitEfficiencyMetrics(emitMetric, result);
1445
+ const workspaceSnapshot = workspaceState.snapshot();
1446
+ const workspaceError = workspaceState.error();
1447
+ const scores = await runScorers({
1448
+ id,
1449
+ ...suite ? { suite } : {},
1450
+ tags,
1451
+ result,
1452
+ events,
1453
+ metric: emitMetric,
1454
+ ...workspaceSnapshot ? { workspace: workspaceSnapshot } : {},
1455
+ ...caseArtifactDir ? { artifactDir: caseArtifactDir } : {}
1456
+ }, scorers);
1457
+ const metrics = finalizeEvalMetrics(metricSpecs, rawMetrics);
1458
+ const tagScores = computeEvalTagScores(metrics);
1459
+ const caseMetrics = metrics.filter((metric) => caseMetricIds.has(metric.id));
1460
+ const score = hasCaseMetrics && caseMetrics.length > 0 ? meanNormalized(caseMetrics) : aggregateScore(scores);
1461
+ const evalResult = {
1462
+ id,
1463
+ ...suite ? { suite } : {},
1464
+ ...variant ? { variant } : {},
1465
+ tags,
1466
+ result,
1467
+ score,
1468
+ passed: result.status === "completed" && scores.every((score) => score.passed),
1469
+ scores,
1470
+ metrics,
1471
+ tagScores,
1472
+ trajectory: buildTrajectory(result.transcript),
1473
+ events,
1474
+ ...sourceFile ? { sourceFile } : {},
1475
+ ...workspaceSnapshot ? { workspace: workspaceSnapshot } : {},
1476
+ ...workspaceError ? { workspaceError } : {}
1477
+ };
1478
+ const artifacts = caseArtifactDir ? await writeEvalArtifacts(caseArtifactDir, evalResult) : void 0;
1479
+ return {
1480
+ ...evalResult,
1481
+ ...artifacts ? { artifacts } : {}
1482
+ };
1483
+ } finally {
1484
+ await workspaceState.cleanup();
1485
+ }
1486
+ }
1487
+ /**
1488
+ * Register one test per eval case against a test runner, funnel every result
1489
+ * into a shared reporter, and print the aggregated summary once after all cases.
1490
+ *
1491
+ * A failing test means the agent run itself broke (provider/tool/timeout). Low
1492
+ * scores are reported, not asserted — see {@link RegisterEvalTestsOptions.failOnIncomplete}.
1493
+ */
1494
+ function registerEvalTests(options) {
1495
+ const reporter = options.reporter ?? createEvalRunReporter();
1496
+ const failOnIncomplete = options.failOnIncomplete ?? true;
1497
+ const printSummary = options.printSummary ?? true;
1498
+ const repeat = Math.max(1, options.repeat ?? 1);
1499
+ const concurrency = Math.max(1, options.concurrency ?? 1);
1500
+ options.runner.afterAll(async () => {
1501
+ await reporter.flush();
1502
+ if (printSummary) console.log(`\n${reporter.format()}\n`);
1503
+ if (options.dispose) await options.dispose();
1504
+ });
1505
+ const work = [];
1506
+ for (const evalCase of options.cases) {
1507
+ const caseLabel = `${evalCase.suite ? `${evalCase.suite}/` : ""}${evalCase.id}`;
1508
+ const baseLabel = evalCase.variant ? `[${evalCase.variant}] ${caseLabel}` : caseLabel;
1509
+ for (let run = 1; run <= repeat; run++) {
1510
+ const label = repeat > 1 ? `${baseLabel} #${run}` : baseLabel;
1511
+ const caseId = repeat > 1 ? `${evalCase.id}-repeat-${run}` : evalCase.id;
1512
+ work.push({
1513
+ label,
1514
+ run: () => runEvalCase({
1515
+ ...evalCase,
1516
+ id: caseId,
1517
+ ...options.artifactDir ? { artifactDir: options.artifactDir } : {}
1518
+ })
1519
+ });
1520
+ }
1521
+ }
1522
+ const schedule = createLazyPool(concurrency);
1523
+ work.forEach((w) => {
1524
+ options.runner.it(w.label, async () => {
1525
+ const result = await schedule(w.run);
1526
+ await reporter.record(result);
1527
+ if (failOnIncomplete && result.result.status !== "completed") throw new Error(`Eval ${w.label} did not complete: ${JSON.stringify(result.result.error ?? { status: result.result.status }, null, 2)}`);
1528
+ });
1529
+ });
1530
+ return reporter;
1531
+ }
1532
+ /**
1533
+ * Lazily run tasks with a bounded concurrency `limit`. Nothing starts until a
1534
+ * runner invokes the corresponding test callback, so filtered/skipped tests do
1535
+ * not leak model or Docker work in the background.
1536
+ */
1537
+ function createLazyPool(limit) {
1538
+ const queue = [];
1539
+ let active = 0;
1540
+ const drain = () => {
1541
+ const available = Math.min(limit - active, queue.length);
1542
+ for (let i = 0; i < available; i++) queue.shift()?.();
1543
+ };
1544
+ return (task) => new Promise((resolve, reject) => {
1545
+ const run = async () => {
1546
+ active++;
1547
+ try {
1548
+ resolve(await task());
1549
+ } catch (err) {
1550
+ reject(err);
1551
+ } finally {
1552
+ active--;
1553
+ drain();
1554
+ }
1555
+ };
1556
+ queue.push(() => void run());
1557
+ drain();
1558
+ });
1559
+ }
1560
+ function createEvalRunReporter(options = {}) {
1561
+ const results = [];
1562
+ return {
1563
+ get results() {
1564
+ return results;
1565
+ },
1566
+ async record(result) {
1567
+ results.push(result);
1568
+ if (options.outputDir) {
1569
+ const segments = [
1570
+ ...result.variant ? [safeSegment(result.variant)] : [],
1571
+ safeSegment(result.suite ?? "eval"),
1572
+ safeSegment(result.id)
1573
+ ];
1574
+ const casePath = join(options.outputDir, "cases", `${segments.join("--")}.json`);
1575
+ await mkdir(join(options.outputDir, "cases"), { recursive: true });
1576
+ await writeFile(casePath, `${JSON.stringify(result, null, 2)}\n`);
1577
+ }
1578
+ },
1579
+ async flush() {
1580
+ const summary = buildEvalRunSummary(results);
1581
+ if (options.outputDir) {
1582
+ await mkdir(options.outputDir, { recursive: true });
1583
+ await writeFile(join(options.outputDir, "run-summary.json"), `${JSON.stringify(summary, null, 2)}\n`);
1584
+ }
1585
+ return summary;
1586
+ },
1587
+ format() {
1588
+ return formatEvalRunSummaryWithOptions(results, { color: options.color });
1589
+ }
1590
+ };
1591
+ }
1592
+ //#endregion
1593
+ export { relativeArtifactPath as A, computeEvalTagScores as C, finalizeEvalMetrics as D, emitEfficiencyMetrics as E, normalizeMetric as O, EvalMetricError as S, efficiencyMetricValues as T, statusCompleted as _, clearRegisteredEvals as a, buildEvalRunSummary as b, createEvalAgent as c, formatTrajectoryLine as d, fileContains as f, functionalityMetric as g, fileExistsOneOf as h, buildRegisteredEvals as i, artifactPath as k, createReusableExecutionContext as l, fileExists as m, registerEvalTests as n, defineEval as o, fileContentQuality as p, runEvalCase as r, llmJudge as s, createEvalRunReporter as t, buildTrajectory as u, formatEvalCaseSummary as v, defineMetrics as w, EFFICIENCY_METRICS as x, formatEvalRunSummary as y };
1594
+
1595
+ //# sourceMappingURL=eval-BNcvle_J.js.map