@recombine-ai/bosun 0.1.10 → 0.2.0-draft

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 (439) hide show
  1. package/build/academy/academy.ts +584 -0
  2. package/build/academy/csv/index.ts +155 -0
  3. package/build/academy/data.ts +299 -0
  4. package/build/academy/emulate-agents.ts +129 -0
  5. package/build/academy/google-sheets/index.ts +187 -0
  6. package/build/academy/runPromptTests.cli.ts +99 -0
  7. package/build/academy/suite.ts +99 -0
  8. package/build/client/_app/immutable/assets/0.3Ve1RxLg.css +1 -0
  9. package/build/client/_app/immutable/assets/0.3Ve1RxLg.css.br +0 -0
  10. package/build/client/_app/immutable/assets/0.3Ve1RxLg.css.gz +0 -0
  11. package/build/client/_app/immutable/assets/3.C7pCuiHL.css +1 -0
  12. package/build/client/_app/immutable/assets/3.C7pCuiHL.css.br +0 -0
  13. package/build/client/_app/immutable/assets/3.C7pCuiHL.css.gz +0 -0
  14. package/build/client/_app/immutable/assets/4.Baezuvdj.css +1 -0
  15. package/build/client/_app/immutable/assets/4.Baezuvdj.css.br +0 -0
  16. package/build/client/_app/immutable/assets/4.Baezuvdj.css.gz +0 -0
  17. package/build/client/_app/immutable/assets/6.CebW_jOJ.css +1 -0
  18. package/build/client/_app/immutable/assets/6.CebW_jOJ.css.br +0 -0
  19. package/build/client/_app/immutable/assets/6.CebW_jOJ.css.gz +0 -0
  20. package/build/client/_app/immutable/assets/8.f3T7i0UW.css +1 -0
  21. package/build/client/_app/immutable/assets/8.f3T7i0UW.css.br +0 -0
  22. package/build/client/_app/immutable/assets/8.f3T7i0UW.css.gz +0 -0
  23. package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css +1 -0
  24. package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css.br +0 -0
  25. package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css.gz +0 -0
  26. package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css +1 -0
  27. package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css.br +1 -0
  28. package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css.gz +0 -0
  29. package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css +1 -0
  30. package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css.br +0 -0
  31. package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css.gz +0 -0
  32. package/build/client/_app/immutable/chunks/B6Eu_a6G.js +8 -0
  33. package/build/client/_app/immutable/chunks/B6Eu_a6G.js.br +0 -0
  34. package/build/client/_app/immutable/chunks/B6Eu_a6G.js.gz +0 -0
  35. package/build/client/_app/immutable/chunks/B946i1vX.js +1 -0
  36. package/build/client/_app/immutable/chunks/B946i1vX.js.br +0 -0
  37. package/build/client/_app/immutable/chunks/B946i1vX.js.gz +0 -0
  38. package/build/client/_app/immutable/chunks/BDr6IUDE.js +1 -0
  39. package/build/client/_app/immutable/chunks/BDr6IUDE.js.br +0 -0
  40. package/build/client/_app/immutable/chunks/BDr6IUDE.js.gz +0 -0
  41. package/build/client/_app/immutable/chunks/BJ0PAzRz.js +1 -0
  42. package/build/client/_app/immutable/chunks/BJ0PAzRz.js.br +0 -0
  43. package/build/client/_app/immutable/chunks/BJ0PAzRz.js.gz +0 -0
  44. package/build/client/_app/immutable/chunks/BQsXEsya.js +2 -0
  45. package/build/client/_app/immutable/chunks/BQsXEsya.js.br +0 -0
  46. package/build/client/_app/immutable/chunks/BQsXEsya.js.gz +0 -0
  47. package/build/client/_app/immutable/chunks/BVH8cl8Q.js +1 -0
  48. package/build/client/_app/immutable/chunks/BVH8cl8Q.js.br +0 -0
  49. package/build/client/_app/immutable/chunks/BVH8cl8Q.js.gz +0 -0
  50. package/build/client/_app/immutable/chunks/Bckf35or.js +1 -0
  51. package/build/client/_app/immutable/chunks/Bckf35or.js.br +1 -0
  52. package/build/client/_app/immutable/chunks/Bckf35or.js.gz +0 -0
  53. package/build/client/_app/immutable/chunks/BcyK4bvI.js +1 -0
  54. package/build/client/_app/immutable/chunks/BcyK4bvI.js.br +0 -0
  55. package/build/client/_app/immutable/chunks/BcyK4bvI.js.gz +0 -0
  56. package/build/client/_app/immutable/chunks/BpsvkpCa.js +1 -0
  57. package/build/client/_app/immutable/chunks/BpsvkpCa.js.br +0 -0
  58. package/build/client/_app/immutable/chunks/BpsvkpCa.js.gz +0 -0
  59. package/build/client/_app/immutable/chunks/C7b8kjFl.js +33 -0
  60. package/build/client/_app/immutable/chunks/C7b8kjFl.js.br +0 -0
  61. package/build/client/_app/immutable/chunks/C7b8kjFl.js.gz +0 -0
  62. package/build/client/_app/immutable/chunks/{D5O98MXA.js → C9ihsQgF.js} +2 -2
  63. package/build/client/_app/immutable/chunks/C9ihsQgF.js.br +6 -0
  64. package/build/client/_app/immutable/chunks/C9ihsQgF.js.gz +0 -0
  65. package/build/client/_app/immutable/chunks/CEHtmspK.js +1 -0
  66. package/build/client/_app/immutable/chunks/CEHtmspK.js.br +0 -0
  67. package/build/client/_app/immutable/chunks/CEHtmspK.js.gz +0 -0
  68. package/build/client/_app/immutable/chunks/CHop8m-3.js +1 -0
  69. package/build/client/_app/immutable/chunks/CHop8m-3.js.br +0 -0
  70. package/build/client/_app/immutable/chunks/CHop8m-3.js.gz +0 -0
  71. package/build/client/_app/immutable/chunks/CUWa2xqt.js +1 -0
  72. package/build/client/_app/immutable/chunks/CUWa2xqt.js.br +0 -0
  73. package/build/client/_app/immutable/chunks/CUWa2xqt.js.gz +0 -0
  74. package/build/client/_app/immutable/chunks/ClfaR3Y2.js +1 -0
  75. package/build/client/_app/immutable/chunks/ClfaR3Y2.js.br +0 -0
  76. package/build/client/_app/immutable/chunks/ClfaR3Y2.js.gz +0 -0
  77. package/build/client/_app/immutable/chunks/DAgYAbDT.js +3 -0
  78. package/build/client/_app/immutable/chunks/DAgYAbDT.js.br +0 -0
  79. package/build/client/_app/immutable/chunks/DAgYAbDT.js.gz +0 -0
  80. package/build/client/_app/immutable/chunks/DBCXNg0T.js +1 -0
  81. package/build/client/_app/immutable/chunks/DBCXNg0T.js.br +0 -0
  82. package/build/client/_app/immutable/chunks/DBCXNg0T.js.gz +0 -0
  83. package/build/client/_app/immutable/chunks/DDncCuU5.js +1 -0
  84. package/build/client/_app/immutable/chunks/DDncCuU5.js.br +2 -0
  85. package/build/client/_app/immutable/chunks/DDncCuU5.js.gz +0 -0
  86. package/build/client/_app/immutable/chunks/DHQ8_yIz.js +1 -0
  87. package/build/client/_app/immutable/chunks/DHQ8_yIz.js.br +0 -0
  88. package/build/client/_app/immutable/chunks/DHQ8_yIz.js.gz +0 -0
  89. package/build/client/_app/immutable/chunks/Deb2U3a-.js +1 -0
  90. package/build/client/_app/immutable/chunks/Deb2U3a-.js.br +0 -0
  91. package/build/client/_app/immutable/chunks/Deb2U3a-.js.gz +0 -0
  92. package/build/client/_app/immutable/chunks/{B8bx6-qu.js → DgNsppMf.js} +1 -1
  93. package/build/client/_app/immutable/chunks/DgNsppMf.js.br +0 -0
  94. package/build/client/_app/immutable/chunks/DgNsppMf.js.gz +0 -0
  95. package/build/client/_app/immutable/chunks/DgSSnt2u.js +1 -0
  96. package/build/client/_app/immutable/chunks/DgSSnt2u.js.br +0 -0
  97. package/build/client/_app/immutable/chunks/DgSSnt2u.js.gz +0 -0
  98. package/build/client/_app/immutable/chunks/Dr0H-PA9.js +1 -0
  99. package/build/client/_app/immutable/chunks/Dr0H-PA9.js.br +0 -0
  100. package/build/client/_app/immutable/chunks/Dr0H-PA9.js.gz +0 -0
  101. package/build/client/_app/immutable/chunks/HA3qddzj.js +1 -0
  102. package/build/client/_app/immutable/chunks/HA3qddzj.js.br +0 -0
  103. package/build/client/_app/immutable/chunks/HA3qddzj.js.gz +0 -0
  104. package/build/client/_app/immutable/chunks/LPKWlFs0.js +1 -0
  105. package/build/client/_app/immutable/chunks/LPKWlFs0.js.br +3 -0
  106. package/build/client/_app/immutable/chunks/LPKWlFs0.js.gz +0 -0
  107. package/build/client/_app/immutable/chunks/VpPuF4LW.js +3 -0
  108. package/build/client/_app/immutable/chunks/VpPuF4LW.js.br +0 -0
  109. package/build/client/_app/immutable/chunks/VpPuF4LW.js.gz +0 -0
  110. package/build/client/_app/immutable/chunks/XyRovF4A.js +1 -0
  111. package/build/client/_app/immutable/chunks/XyRovF4A.js.br +0 -0
  112. package/build/client/_app/immutable/chunks/XyRovF4A.js.gz +0 -0
  113. package/build/client/_app/immutable/chunks/mRVZsLQ4.js +1 -0
  114. package/build/client/_app/immutable/chunks/mRVZsLQ4.js.br +2 -0
  115. package/build/client/_app/immutable/chunks/mRVZsLQ4.js.gz +0 -0
  116. package/build/client/_app/immutable/entry/app.CVDHq7dN.js +2 -0
  117. package/build/client/_app/immutable/entry/app.CVDHq7dN.js.br +0 -0
  118. package/build/client/_app/immutable/entry/app.CVDHq7dN.js.gz +0 -0
  119. package/build/client/_app/immutable/entry/start.a4wXr-rh.js +1 -0
  120. package/build/client/_app/immutable/entry/start.a4wXr-rh.js.br +2 -0
  121. package/build/client/_app/immutable/entry/start.a4wXr-rh.js.gz +0 -0
  122. package/build/client/_app/immutable/nodes/0.q5P1PqkU.js +3 -0
  123. package/build/client/_app/immutable/nodes/0.q5P1PqkU.js.br +0 -0
  124. package/build/client/_app/immutable/nodes/0.q5P1PqkU.js.gz +0 -0
  125. package/build/client/_app/immutable/nodes/1.TfmDsqd-.js +1 -0
  126. package/build/client/_app/immutable/nodes/1.TfmDsqd-.js.br +0 -0
  127. package/build/client/_app/immutable/nodes/1.TfmDsqd-.js.gz +0 -0
  128. package/build/client/_app/immutable/nodes/10.BpXsBlTN.js +1 -0
  129. package/build/client/_app/immutable/nodes/10.BpXsBlTN.js.br +0 -0
  130. package/build/client/_app/immutable/nodes/10.BpXsBlTN.js.gz +0 -0
  131. package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js +1 -0
  132. package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js.br +0 -0
  133. package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js.gz +0 -0
  134. package/build/client/_app/immutable/nodes/2.BWtLQzzv.js +3 -0
  135. package/build/client/_app/immutable/nodes/2.BWtLQzzv.js.br +0 -0
  136. package/build/client/_app/immutable/nodes/2.BWtLQzzv.js.gz +0 -0
  137. package/build/client/_app/immutable/nodes/3.BlYIVobe.js +1 -0
  138. package/build/client/_app/immutable/nodes/3.BlYIVobe.js.br +0 -0
  139. package/build/client/_app/immutable/nodes/3.BlYIVobe.js.gz +0 -0
  140. package/build/client/_app/immutable/nodes/4.DMboagHp.js +38 -0
  141. package/build/client/_app/immutable/nodes/4.DMboagHp.js.br +0 -0
  142. package/build/client/_app/immutable/nodes/4.DMboagHp.js.gz +0 -0
  143. package/build/client/_app/immutable/nodes/5.DJDEfbU1.js +1 -0
  144. package/build/client/_app/immutable/nodes/5.DJDEfbU1.js.br +0 -0
  145. package/build/client/_app/immutable/nodes/5.DJDEfbU1.js.gz +0 -0
  146. package/build/client/_app/immutable/nodes/6.Co1n7leD.js +12 -0
  147. package/build/client/_app/immutable/nodes/6.Co1n7leD.js.br +0 -0
  148. package/build/client/_app/immutable/nodes/6.Co1n7leD.js.gz +0 -0
  149. package/build/client/_app/immutable/nodes/7.3clSez0f.js +1 -0
  150. package/build/client/_app/immutable/nodes/7.3clSez0f.js.br +0 -0
  151. package/build/client/_app/immutable/nodes/7.3clSez0f.js.gz +0 -0
  152. package/build/client/_app/immutable/nodes/8.D4xImLsM.js +1 -0
  153. package/build/client/_app/immutable/nodes/8.D4xImLsM.js.br +0 -0
  154. package/build/client/_app/immutable/nodes/8.D4xImLsM.js.gz +0 -0
  155. package/build/client/_app/immutable/nodes/9.C1KWPSTf.js +1 -0
  156. package/build/client/_app/immutable/nodes/9.C1KWPSTf.js.br +0 -0
  157. package/build/client/_app/immutable/nodes/9.C1KWPSTf.js.gz +0 -0
  158. package/build/client/_app/version.json +1 -1
  159. package/build/client/_app/version.json.br +0 -0
  160. package/build/client/_app/version.json.gz +0 -0
  161. package/build/server/chunks/0-CgyQG-Vf.js +9 -0
  162. package/build/server/chunks/0-CgyQG-Vf.js.map +1 -0
  163. package/build/server/chunks/1-DACiLfsu.js +9 -0
  164. package/build/server/chunks/{1-dPD-duO8.js.map → 1-DACiLfsu.js.map} +1 -1
  165. package/build/server/chunks/10-zMqY0bCj.js +9 -0
  166. package/build/server/chunks/10-zMqY0bCj.js.map +1 -0
  167. package/build/server/chunks/11-B7cPB4ip.js +9 -0
  168. package/build/server/chunks/11-B7cPB4ip.js.map +1 -0
  169. package/build/server/chunks/2-uTf78dNT.js +9 -0
  170. package/build/server/chunks/2-uTf78dNT.js.map +1 -0
  171. package/build/server/chunks/3-DOOLRXaZ.js +9 -0
  172. package/build/server/chunks/3-DOOLRXaZ.js.map +1 -0
  173. package/build/server/chunks/4-CLK_BxY0.js +9 -0
  174. package/build/server/chunks/4-CLK_BxY0.js.map +1 -0
  175. package/build/server/chunks/5-DfZ6yJrz.js +9 -0
  176. package/build/server/chunks/5-DfZ6yJrz.js.map +1 -0
  177. package/build/server/chunks/6-B2BoZUr6.js +22 -0
  178. package/build/server/chunks/6-B2BoZUr6.js.map +1 -0
  179. package/build/server/chunks/{5-p3BDfNc2.js → 7-DmgY6drC.js} +6 -6
  180. package/build/server/chunks/7-DmgY6drC.js.map +1 -0
  181. package/build/server/chunks/8-Bku8n4Ko.js +9 -0
  182. package/build/server/chunks/8-Bku8n4Ko.js.map +1 -0
  183. package/build/server/chunks/{7-C_AGqUAU.js → 9-nwlpMH7t.js} +5 -5
  184. package/build/server/chunks/9-nwlpMH7t.js.map +1 -0
  185. package/build/server/chunks/AgentSidebar-CZIBBsSh.js +141 -0
  186. package/build/server/chunks/AgentSidebar-CZIBBsSh.js.map +1 -0
  187. package/build/server/chunks/Button-OUO_MioZ.js +44 -0
  188. package/build/server/chunks/Button-OUO_MioZ.js.map +1 -0
  189. package/build/server/chunks/ContextEditor-stz14-2o.js +48 -0
  190. package/build/server/chunks/ContextEditor-stz14-2o.js.map +1 -0
  191. package/build/server/chunks/{Dropdown-B-UCol1v.js → Dropdown-BTr_XiAm.js} +2 -2
  192. package/build/server/chunks/Dropdown-BTr_XiAm.js.map +1 -0
  193. package/build/server/chunks/{Input-DLAEH36y.js → Input-B_jIG2tD.js} +2 -2
  194. package/build/server/chunks/Input-B_jIG2tD.js.map +1 -0
  195. package/build/server/chunks/{Icon-DDJ9D6Sq.js → Link-DaOJVbdB.js} +25 -42
  196. package/build/server/chunks/Link-DaOJVbdB.js.map +1 -0
  197. package/build/server/chunks/{Panel-KZDoG3_L.js → Panel-CmvYn6IC.js} +2 -2
  198. package/build/server/chunks/Panel-CmvYn6IC.js.map +1 -0
  199. package/build/server/chunks/Tab-n348Mfiq.js +84 -0
  200. package/build/server/chunks/Tab-n348Mfiq.js.map +1 -0
  201. package/build/server/chunks/_layout.svelte-CP6tz6DB.js +62 -0
  202. package/build/server/chunks/_layout.svelte-CP6tz6DB.js.map +1 -0
  203. package/build/server/chunks/{_layout.svelte-BoAJDYC1.js → _layout.svelte-CvGX8M4U.js} +68 -18
  204. package/build/server/chunks/_layout.svelte-CvGX8M4U.js.map +1 -0
  205. package/build/server/chunks/{_page.svelte-CdEfc0bc.js → _page.svelte-AHHrodUG.js} +94 -86
  206. package/build/server/chunks/_page.svelte-AHHrodUG.js.map +1 -0
  207. package/build/server/chunks/_page.svelte-Bm-iBjXM.js +80 -0
  208. package/build/server/chunks/_page.svelte-Bm-iBjXM.js.map +1 -0
  209. package/build/server/chunks/_page.svelte-D5Xqk3cI.js +52 -0
  210. package/build/server/chunks/_page.svelte-D5Xqk3cI.js.map +1 -0
  211. package/build/server/chunks/{_page.svelte-CNhxx79k.js → _page.svelte-DKBFi-JF.js} +202 -240
  212. package/build/server/chunks/_page.svelte-DKBFi-JF.js.map +1 -0
  213. package/build/server/chunks/{_page.svelte-DQUdiD4S.js → _page.svelte-DSefP5E9.js} +6 -5
  214. package/build/server/chunks/_page.svelte-DSefP5E9.js.map +1 -0
  215. package/build/server/chunks/{_page.svelte-kLLxi8vG.js → _page.svelte-Dldwxu4m.js} +28 -6
  216. package/build/server/chunks/_page.svelte-Dldwxu4m.js.map +1 -0
  217. package/build/server/chunks/{_page.svelte-Cc0DAAQW.js → _page.svelte-lU1-SHJj.js} +5 -4
  218. package/build/server/chunks/_page.svelte-lU1-SHJj.js.map +1 -0
  219. package/build/server/chunks/{_page.svelte-nsIWq28L.js → _page.svelte-vGR-ltk7.js} +7 -27
  220. package/build/server/chunks/_page.svelte-vGR-ltk7.js.map +1 -0
  221. package/build/server/chunks/{_server.ts-d0Tii8aZ.js → _server.ts-3D9tpnMZ.js} +3 -2
  222. package/build/server/chunks/_server.ts-3D9tpnMZ.js.map +1 -0
  223. package/build/server/chunks/{_server.ts-BBxm_xV1.js → _server.ts-B56wS_0L.js} +4 -1
  224. package/build/server/chunks/_server.ts-B56wS_0L.js.map +1 -0
  225. package/build/server/chunks/{_server.ts-CLKPeFqF.js → _server.ts-BCBY3OIY.js} +3 -2
  226. package/build/server/chunks/_server.ts-BCBY3OIY.js.map +1 -0
  227. package/build/server/chunks/{_server.ts-BmZBSYvJ.js → _server.ts-BCfiuZgS.js} +19 -8
  228. package/build/server/chunks/_server.ts-BCfiuZgS.js.map +1 -0
  229. package/build/server/chunks/_server.ts-BkL-sSQA.js.map +1 -1
  230. package/build/server/chunks/{_server.ts-DEHw6op6.js → _server.ts-D0C3cRDU.js} +3 -2
  231. package/build/server/chunks/_server.ts-D0C3cRDU.js.map +1 -0
  232. package/build/server/chunks/{_server.ts-BYDdbqNr.js → _server.ts-Dc989xbA.js} +3 -2
  233. package/build/server/chunks/_server.ts-Dc989xbA.js.map +1 -0
  234. package/build/server/chunks/_server.ts-Ddto8x_p.js.map +1 -1
  235. package/build/server/chunks/{_server.ts-BIcKE9RQ.js → _server.ts-I-18L-Sg.js} +3 -2
  236. package/build/server/chunks/_server.ts-I-18L-Sg.js.map +1 -0
  237. package/build/server/chunks/_server.ts-iuWHhHZx.js +629 -0
  238. package/build/server/chunks/_server.ts-iuWHhHZx.js.map +1 -0
  239. package/build/server/chunks/agents-context-C4MM7lSl.js +6 -0
  240. package/build/server/chunks/agents-context-C4MM7lSl.js.map +1 -0
  241. package/build/server/chunks/{client2-tp0-IQU0.js → client-BhnXtftB.js} +6 -29
  242. package/build/server/chunks/client-BhnXtftB.js.map +1 -0
  243. package/build/server/chunks/{index2-CVBATI2G.js → context-Dy9MY1Z0.js} +253 -965
  244. package/build/server/chunks/context-Dy9MY1Z0.js.map +1 -0
  245. package/build/server/chunks/{data-CbXDDeDB.js → data-BltJc-uF.js} +29 -89
  246. package/build/server/chunks/data-BltJc-uF.js.map +1 -0
  247. package/build/server/chunks/error.svelte-Cn6umEWY.js +14 -0
  248. package/build/server/chunks/error.svelte-Cn6umEWY.js.map +1 -0
  249. package/build/server/chunks/errors-B8liwVcD.js +17 -0
  250. package/build/server/chunks/errors-B8liwVcD.js.map +1 -0
  251. package/build/server/chunks/{events-A18hGvKp.js → events-BFcZEt66.js} +3 -9
  252. package/build/server/chunks/events-BFcZEt66.js.map +1 -0
  253. package/build/server/chunks/{index-BoStl4QO.js → index-C0ds_eUO.js} +8 -3
  254. package/build/server/chunks/index-C0ds_eUO.js.map +1 -0
  255. package/build/server/chunks/index-server-CMCI3p2Y.js +18 -0
  256. package/build/server/chunks/index-server-CMCI3p2Y.js.map +1 -0
  257. package/build/server/chunks/index2-B1rkViAM.js +860 -0
  258. package/build/server/chunks/index2-B1rkViAM.js.map +1 -0
  259. package/build/server/chunks/index3-CVYj52gl.js.map +1 -1
  260. package/build/server/chunks/index4-DSZuWW-A.js +47 -0
  261. package/build/server/chunks/index4-DSZuWW-A.js.map +1 -0
  262. package/build/server/chunks/main-DL75vM4l.js +2250 -0
  263. package/build/server/chunks/main-DL75vM4l.js.map +1 -0
  264. package/build/server/chunks/{state.svelte-Dze7OxC_.js → state.svelte-CBgyohE1.js} +2 -2
  265. package/build/server/chunks/state.svelte-CBgyohE1.js.map +1 -0
  266. package/build/server/chunks/suite-4--Gr0jF.js +60 -0
  267. package/build/server/chunks/suite-4--Gr0jF.js.map +1 -0
  268. package/build/server/chunks/ws-client-CyJORDFw.js +98 -0
  269. package/build/server/chunks/ws-client-CyJORDFw.js.map +1 -0
  270. package/build/server/index.js +167 -90
  271. package/build/server/index.js.map +1 -1
  272. package/build/server/manifest.js +83 -75
  273. package/build/server/manifest.js.map +1 -1
  274. package/package.json +3 -1
  275. package/src/ws-server/projects.ts +82 -9
  276. package/build/client/_app/immutable/assets/0.7xdY7TSX.css +0 -1
  277. package/build/client/_app/immutable/assets/0.7xdY7TSX.css.br +0 -0
  278. package/build/client/_app/immutable/assets/0.7xdY7TSX.css.gz +0 -0
  279. package/build/client/_app/immutable/assets/10.C1o6a69m.css +0 -1
  280. package/build/client/_app/immutable/assets/10.C1o6a69m.css.br +0 -1
  281. package/build/client/_app/immutable/assets/10.C1o6a69m.css.gz +0 -0
  282. package/build/client/_app/immutable/assets/4.858mUNwe.css +0 -1
  283. package/build/client/_app/immutable/assets/4.858mUNwe.css.br +0 -0
  284. package/build/client/_app/immutable/assets/4.858mUNwe.css.gz +0 -0
  285. package/build/client/_app/immutable/assets/6.CD1QZ0pt.css +0 -1
  286. package/build/client/_app/immutable/assets/6.CD1QZ0pt.css.br +0 -0
  287. package/build/client/_app/immutable/assets/6.CD1QZ0pt.css.gz +0 -0
  288. package/build/client/_app/immutable/chunks/2PVbuV1X.js +0 -1
  289. package/build/client/_app/immutable/chunks/2PVbuV1X.js.br +0 -1
  290. package/build/client/_app/immutable/chunks/2PVbuV1X.js.gz +0 -0
  291. package/build/client/_app/immutable/chunks/9OGf6H2n.js +0 -1
  292. package/build/client/_app/immutable/chunks/9OGf6H2n.js.br +0 -2
  293. package/build/client/_app/immutable/chunks/9OGf6H2n.js.gz +0 -0
  294. package/build/client/_app/immutable/chunks/B8bx6-qu.js.br +0 -1
  295. package/build/client/_app/immutable/chunks/B8bx6-qu.js.gz +0 -0
  296. package/build/client/_app/immutable/chunks/BDTuVTVZ.js +0 -1
  297. package/build/client/_app/immutable/chunks/BDTuVTVZ.js.br +0 -0
  298. package/build/client/_app/immutable/chunks/BDTuVTVZ.js.gz +0 -0
  299. package/build/client/_app/immutable/chunks/BTGV3Gq0.js +0 -8
  300. package/build/client/_app/immutable/chunks/BTGV3Gq0.js.br +0 -0
  301. package/build/client/_app/immutable/chunks/BTGV3Gq0.js.gz +0 -0
  302. package/build/client/_app/immutable/chunks/BUJtMu79.js +0 -3
  303. package/build/client/_app/immutable/chunks/BUJtMu79.js.br +0 -0
  304. package/build/client/_app/immutable/chunks/BUJtMu79.js.gz +0 -0
  305. package/build/client/_app/immutable/chunks/BUoURvZ_.js +0 -1
  306. package/build/client/_app/immutable/chunks/BUoURvZ_.js.br +0 -0
  307. package/build/client/_app/immutable/chunks/BUoURvZ_.js.gz +0 -0
  308. package/build/client/_app/immutable/chunks/BdOqksoz.js +0 -1
  309. package/build/client/_app/immutable/chunks/BdOqksoz.js.br +0 -0
  310. package/build/client/_app/immutable/chunks/BdOqksoz.js.gz +0 -0
  311. package/build/client/_app/immutable/chunks/Be371ezp.js +0 -2
  312. package/build/client/_app/immutable/chunks/Be371ezp.js.br +0 -0
  313. package/build/client/_app/immutable/chunks/Be371ezp.js.gz +0 -0
  314. package/build/client/_app/immutable/chunks/Bmx4ManB.js +0 -1
  315. package/build/client/_app/immutable/chunks/Bmx4ManB.js.br +0 -0
  316. package/build/client/_app/immutable/chunks/Bmx4ManB.js.gz +0 -0
  317. package/build/client/_app/immutable/chunks/C2Y9UxTx.js +0 -1
  318. package/build/client/_app/immutable/chunks/C2Y9UxTx.js.br +0 -0
  319. package/build/client/_app/immutable/chunks/C2Y9UxTx.js.gz +0 -0
  320. package/build/client/_app/immutable/chunks/CYuXdPQc.js +0 -1
  321. package/build/client/_app/immutable/chunks/CYuXdPQc.js.br +0 -0
  322. package/build/client/_app/immutable/chunks/CYuXdPQc.js.gz +0 -0
  323. package/build/client/_app/immutable/chunks/CpZGG0E7.js +0 -1
  324. package/build/client/_app/immutable/chunks/CpZGG0E7.js.br +0 -0
  325. package/build/client/_app/immutable/chunks/CpZGG0E7.js.gz +0 -0
  326. package/build/client/_app/immutable/chunks/CpdYAO0i.js +0 -1
  327. package/build/client/_app/immutable/chunks/CpdYAO0i.js.br +0 -0
  328. package/build/client/_app/immutable/chunks/CpdYAO0i.js.gz +0 -0
  329. package/build/client/_app/immutable/chunks/CtpS-ZbM.js +0 -1
  330. package/build/client/_app/immutable/chunks/CtpS-ZbM.js.br +0 -0
  331. package/build/client/_app/immutable/chunks/CtpS-ZbM.js.gz +0 -0
  332. package/build/client/_app/immutable/chunks/D5O98MXA.js.br +0 -0
  333. package/build/client/_app/immutable/chunks/D5O98MXA.js.gz +0 -0
  334. package/build/client/_app/immutable/chunks/DIiF2tGe.js +0 -1
  335. package/build/client/_app/immutable/chunks/DIiF2tGe.js.br +0 -0
  336. package/build/client/_app/immutable/chunks/DIiF2tGe.js.gz +0 -0
  337. package/build/client/_app/immutable/chunks/D_4dC3JZ.js +0 -1
  338. package/build/client/_app/immutable/chunks/D_4dC3JZ.js.br +0 -0
  339. package/build/client/_app/immutable/chunks/D_4dC3JZ.js.gz +0 -0
  340. package/build/client/_app/immutable/chunks/DveC87gn.js +0 -33
  341. package/build/client/_app/immutable/chunks/DveC87gn.js.br +0 -0
  342. package/build/client/_app/immutable/chunks/DveC87gn.js.gz +0 -0
  343. package/build/client/_app/immutable/chunks/ISgeSat5.js +0 -1
  344. package/build/client/_app/immutable/chunks/ISgeSat5.js.br +0 -0
  345. package/build/client/_app/immutable/chunks/ISgeSat5.js.gz +0 -0
  346. package/build/client/_app/immutable/chunks/f4SQk-uT.js +0 -3
  347. package/build/client/_app/immutable/chunks/f4SQk-uT.js.br +0 -0
  348. package/build/client/_app/immutable/chunks/f4SQk-uT.js.gz +0 -0
  349. package/build/client/_app/immutable/entry/app.BCqdi-0A.js +0 -2
  350. package/build/client/_app/immutable/entry/app.BCqdi-0A.js.br +0 -0
  351. package/build/client/_app/immutable/entry/app.BCqdi-0A.js.gz +0 -0
  352. package/build/client/_app/immutable/entry/start.FFZ3vuST.js +0 -1
  353. package/build/client/_app/immutable/entry/start.FFZ3vuST.js.br +0 -2
  354. package/build/client/_app/immutable/entry/start.FFZ3vuST.js.gz +0 -0
  355. package/build/client/_app/immutable/nodes/0.BFGm6g4L.js +0 -1
  356. package/build/client/_app/immutable/nodes/0.BFGm6g4L.js.br +0 -0
  357. package/build/client/_app/immutable/nodes/0.BFGm6g4L.js.gz +0 -0
  358. package/build/client/_app/immutable/nodes/1.BldvfsiS.js +0 -1
  359. package/build/client/_app/immutable/nodes/1.BldvfsiS.js.br +0 -0
  360. package/build/client/_app/immutable/nodes/1.BldvfsiS.js.gz +0 -0
  361. package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js +0 -1
  362. package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js.br +0 -0
  363. package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js.gz +0 -0
  364. package/build/client/_app/immutable/nodes/2.c7KihIjN.js +0 -3
  365. package/build/client/_app/immutable/nodes/2.c7KihIjN.js.br +0 -0
  366. package/build/client/_app/immutable/nodes/2.c7KihIjN.js.gz +0 -0
  367. package/build/client/_app/immutable/nodes/4.BokOq116.js +0 -12
  368. package/build/client/_app/immutable/nodes/4.BokOq116.js.br +0 -0
  369. package/build/client/_app/immutable/nodes/4.BokOq116.js.gz +0 -0
  370. package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js +0 -1
  371. package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js.br +0 -0
  372. package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js.gz +0 -0
  373. package/build/client/_app/immutable/nodes/6.CMaZNrkR.js +0 -38
  374. package/build/client/_app/immutable/nodes/6.CMaZNrkR.js.br +0 -0
  375. package/build/client/_app/immutable/nodes/6.CMaZNrkR.js.gz +0 -0
  376. package/build/client/_app/immutable/nodes/7.CvDadi99.js +0 -1
  377. package/build/client/_app/immutable/nodes/7.CvDadi99.js.br +0 -0
  378. package/build/client/_app/immutable/nodes/7.CvDadi99.js.gz +0 -0
  379. package/build/client/_app/immutable/nodes/8.CLZUC68b.js +0 -1
  380. package/build/client/_app/immutable/nodes/8.CLZUC68b.js.br +0 -0
  381. package/build/client/_app/immutable/nodes/8.CLZUC68b.js.gz +0 -0
  382. package/build/client/_app/immutable/nodes/9.BY1rgYUV.js +0 -1
  383. package/build/client/_app/immutable/nodes/9.BY1rgYUV.js.br +0 -0
  384. package/build/client/_app/immutable/nodes/9.BY1rgYUV.js.gz +0 -0
  385. package/build/server/chunks/0-DMd6Dk79.js +0 -9
  386. package/build/server/chunks/0-DMd6Dk79.js.map +0 -1
  387. package/build/server/chunks/1-dPD-duO8.js +0 -9
  388. package/build/server/chunks/10-Ci_AhluU.js +0 -9
  389. package/build/server/chunks/10-Ci_AhluU.js.map +0 -1
  390. package/build/server/chunks/2-C0B7VzbP.js +0 -9
  391. package/build/server/chunks/2-C0B7VzbP.js.map +0 -1
  392. package/build/server/chunks/3-DGFu_uy6.js +0 -19
  393. package/build/server/chunks/3-DGFu_uy6.js.map +0 -1
  394. package/build/server/chunks/4-MwbWFUCO.js +0 -22
  395. package/build/server/chunks/4-MwbWFUCO.js.map +0 -1
  396. package/build/server/chunks/5-p3BDfNc2.js.map +0 -1
  397. package/build/server/chunks/6-B6EVTx8w.js +0 -9
  398. package/build/server/chunks/6-B6EVTx8w.js.map +0 -1
  399. package/build/server/chunks/7-C_AGqUAU.js.map +0 -1
  400. package/build/server/chunks/8-Dr1vf8BH.js +0 -9
  401. package/build/server/chunks/8-Dr1vf8BH.js.map +0 -1
  402. package/build/server/chunks/9-BA8KMX2q.js +0 -9
  403. package/build/server/chunks/9-BA8KMX2q.js.map +0 -1
  404. package/build/server/chunks/AgentDropdown-C3XtwkaV.js +0 -162
  405. package/build/server/chunks/AgentDropdown-C3XtwkaV.js.map +0 -1
  406. package/build/server/chunks/Dropdown-B-UCol1v.js.map +0 -1
  407. package/build/server/chunks/Icon-DDJ9D6Sq.js.map +0 -1
  408. package/build/server/chunks/Input-DLAEH36y.js.map +0 -1
  409. package/build/server/chunks/Panel-KZDoG3_L.js.map +0 -1
  410. package/build/server/chunks/_layout.svelte-22nlfSFq.js +0 -9
  411. package/build/server/chunks/_layout.svelte-22nlfSFq.js.map +0 -1
  412. package/build/server/chunks/_layout.svelte-BoAJDYC1.js.map +0 -1
  413. package/build/server/chunks/_page.svelte-CNhxx79k.js.map +0 -1
  414. package/build/server/chunks/_page.svelte-Cc0DAAQW.js.map +0 -1
  415. package/build/server/chunks/_page.svelte-CdEfc0bc.js.map +0 -1
  416. package/build/server/chunks/_page.svelte-DQUdiD4S.js.map +0 -1
  417. package/build/server/chunks/_page.svelte-kLLxi8vG.js.map +0 -1
  418. package/build/server/chunks/_page.svelte-nsIWq28L.js.map +0 -1
  419. package/build/server/chunks/_server.ts-BBxm_xV1.js.map +0 -1
  420. package/build/server/chunks/_server.ts-BIcKE9RQ.js.map +0 -1
  421. package/build/server/chunks/_server.ts-BYDdbqNr.js.map +0 -1
  422. package/build/server/chunks/_server.ts-BmZBSYvJ.js.map +0 -1
  423. package/build/server/chunks/_server.ts-CLKPeFqF.js.map +0 -1
  424. package/build/server/chunks/_server.ts-DEHw6op6.js.map +0 -1
  425. package/build/server/chunks/_server.ts-DTyPQO2I.js +0 -93
  426. package/build/server/chunks/_server.ts-DTyPQO2I.js.map +0 -1
  427. package/build/server/chunks/_server.ts-d0Tii8aZ.js.map +0 -1
  428. package/build/server/chunks/client-DpkplAAP.js +0 -25
  429. package/build/server/chunks/client-DpkplAAP.js.map +0 -1
  430. package/build/server/chunks/client2-tp0-IQU0.js.map +0 -1
  431. package/build/server/chunks/context-DVQH5kJk.js +0 -113
  432. package/build/server/chunks/context-DVQH5kJk.js.map +0 -1
  433. package/build/server/chunks/data-CbXDDeDB.js.map +0 -1
  434. package/build/server/chunks/error.svelte-DNcHZkvg.js +0 -29
  435. package/build/server/chunks/error.svelte-DNcHZkvg.js.map +0 -1
  436. package/build/server/chunks/events-A18hGvKp.js.map +0 -1
  437. package/build/server/chunks/index-BoStl4QO.js.map +0 -1
  438. package/build/server/chunks/index2-CVBATI2G.js.map +0 -1
  439. package/build/server/chunks/state.svelte-Dze7OxC_.js.map +0 -1
@@ -0,0 +1,584 @@
1
+ import { type ProviderOptions } from 'promptfoo'
2
+ import * as promptfoo from 'promptfoo'
3
+ import { type Message, type StepTrace, type StepTracer } from '@recombine-ai/engine'
4
+ import { loadAgents as defaultLoadAgents } from './emulate-agents'
5
+ import { type Assertion as PFAssertion } from 'promptfoo'
6
+ // Backend: per-project JSON test suites (no CSV)
7
+ import { tryReadConfig, getProjectRootPath } from './csv'
8
+ import { mkdir, writeFile } from 'node:fs/promises'
9
+ import path from 'node:path'
10
+ import { readSuite, getSuiteFilePath } from './suite'
11
+ // Use types derived from promptfoo exports instead of incorrect default type imports
12
+
13
+ import type { ApiProvider, CallApiContextParams, ProviderResponse } from 'promptfoo'
14
+ import deepmerge from 'deepmerge'
15
+
16
+ // ----------------- Type aliases & helpers -----------------
17
+ type Context = { [key: string]: unknown }
18
+
19
+ type Conversation = Message[]
20
+
21
+ type Assertion = PFAssertion
22
+
23
+ type NunjucksCompatibleString = string
24
+
25
+ type Step = {
26
+ name: string
27
+ prompt: { raw: string; model: ModelConfig }
28
+ output: 'string' | 'json_schema'
29
+ }
30
+
31
+ type ModelConfig = ProviderOptions
32
+
33
+ interface CsvRow {
34
+ id?: string
35
+ assertion_type: string
36
+ assertion_value: string
37
+ conversation: string
38
+ expected_output: string
39
+ similarity_threshold: number | string
40
+ pinned: 'TRUE' | 'FALSE'
41
+ context: string
42
+ timeout: string
43
+ scenario?: string
44
+ }
45
+
46
+ export type ResultEntry = {
47
+ success: boolean
48
+ result: string
49
+ evaluation: string
50
+ rendered_prompt: string
51
+ received_prompt: string
52
+ stringified_conversation: string
53
+ received_context: string
54
+ // Raw traces array for this run (sanitized where necessary)
55
+ traces: any[]
56
+ errors: string
57
+ logs: string[]
58
+ }
59
+
60
+ export interface TableRow extends CsvRow {
61
+ // Link to details view for this row
62
+ prompts: string
63
+ success_rate_percent: number
64
+ success_rate: string
65
+ // Per-run results (new format)
66
+ results: ResultEntry[]
67
+ }
68
+
69
+ // Deep merge helper using 'deepmerge' with array replacement semantics
70
+ const mergeContexts = (baseCtx: Record<string, any>, testCtx: Record<string, any>) =>
71
+ deepmerge(baseCtx || {}, testCtx || {}, { arrayMerge: (_d, s, _o) => s })
72
+
73
+ // Parse a multi-line sheet conversation string into engine messages
74
+ function parseConversationFromSheet(conversation: string | undefined | null): Conversation {
75
+ if (!conversation) return []
76
+ return conversation
77
+ .split('\n')
78
+ .filter((l) => l.trim())
79
+ .map((line) => {
80
+ const [sender, ...content] = line.split(': ')
81
+ const lower = (sender || '').toLowerCase()
82
+ // Treat common alias 'assistant' as 'agent' to avoid misclassification
83
+ const role: 'agent' | 'user' | 'system' =
84
+ lower === 'agent' || lower === 'assistant'
85
+ ? 'agent'
86
+ : lower === 'system'
87
+ ? 'system'
88
+ : 'user'
89
+ return { sender: role, text: content.join(': ') }
90
+ })
91
+ .filter((m) => m.sender === 'user' || m.sender === 'agent' || m.sender === 'system')
92
+ }
93
+
94
+ // Map pinned sheet rows to common test inputs
95
+ function toTestInputs(
96
+ rows: (CsvRow & { index: number })[],
97
+ defaultContext?: Record<string, any>,
98
+ scope: 'all' | 'pinned' = 'pinned'
99
+ ) {
100
+ return rows
101
+ .filter((r) => (scope === 'all' ? true : r.pinned === 'TRUE'))
102
+ .map((row) => ({
103
+ id: (row as any).id,
104
+ conversation: parseConversationFromSheet(row.conversation),
105
+ assertions: [
106
+ {
107
+ type: row.assertion_type as PFAssertion['type'],
108
+ value: row.assertion_value
109
+ },
110
+ {
111
+ type: 'similar' as 'similar',
112
+ value: String(row.expected_output),
113
+ threshold: Number(row.similarity_threshold)
114
+ }
115
+ ],
116
+ context: (() => {
117
+ const testCtx = row.context ? JSON.parse(row.context) : {}
118
+ return defaultContext ? mergeContexts(defaultContext, testCtx) : testCtx
119
+ })(),
120
+ timeoutSeconds: (() => {
121
+ const rawValue = (row as any).timeout
122
+ if (rawValue === undefined || rawValue === null || String(rawValue).trim() === '') {
123
+ throw new Error('Timeout value is required')
124
+ }
125
+ const raw = Number(rawValue)
126
+ if (isNaN(raw)) {
127
+ throw new Error(`Invalid timeout value: ${rawValue}`)
128
+ }
129
+ if (raw > 1000) {
130
+ throw new Error(`Timeout value exceeds maximum of 1000: ${raw}`)
131
+ }
132
+ if (raw < 0) {
133
+ throw new Error(`Timeout value must be non-negative: ${raw}`)
134
+ }
135
+ return raw
136
+ })()
137
+ }))
138
+ }
139
+
140
+ type LoadAgentsFn = (props: {
141
+ agentId: string
142
+ getMessages: () => Message[]
143
+ sendMessage: (message: Message | string) => Promise<void>
144
+ stepTracer: StepTracer
145
+ logger?: {
146
+ log: (...args: any[]) => void
147
+ debug: (...args: any[]) => void
148
+ warn: (...args: any[]) => void
149
+ error: (...args: any[]) => void
150
+ }
151
+ context?: Context
152
+ timeoutSeconds: number
153
+ }) => Promise<void>
154
+
155
+ export class RecombineAgentProvider implements ApiProvider {
156
+ protected providerId: string
157
+ public config: Record<string, unknown>
158
+ private runLoadAgents: LoadAgentsFn
159
+
160
+ constructor(options: ProviderOptions & { loadAgents?: LoadAgentsFn } = {}) {
161
+ this.providerId = options.id || 'recombine-agent'
162
+ this.config = options.config || {}
163
+ this.runLoadAgents = options.loadAgents || (defaultLoadAgents as unknown as LoadAgentsFn)
164
+ }
165
+
166
+ id() {
167
+ return this.providerId
168
+ }
169
+
170
+ async callApi(_prompt: string, context?: CallApiContextParams): Promise<ProviderResponse> {
171
+ const vars = (context?.vars || {}) as unknown as {
172
+ project: string
173
+ agent: string
174
+ conversation: Conversation
175
+ context: Context
176
+ timeoutSeconds?: number
177
+ }
178
+
179
+ let captured: string = ''
180
+ const capturedLogs: string[] = []
181
+ const capturedStepTraces: any[] = []
182
+
183
+ // Streaming log writer; initialized after basic validation
184
+ let logStream: any = null
185
+ let logsFilePath = ''
186
+
187
+ // Compute agent id and pre-load state with full conversation history
188
+ const agentCompositeId = `${vars.project}/${vars.agent}`
189
+ // Clone the conversation so parallel runs don't share the same array reference.
190
+ // Shallow-clone each message; messages are simple { sender, text } objects in this flow.
191
+ const conv: Conversation = Array.isArray(vars.conversation)
192
+ ? (vars.conversation as Conversation).map((m) => ({ ...m }))
193
+ : []
194
+ const lastUserIndex = (() => {
195
+ for (let i = conv.length - 1; i >= 0; i--) {
196
+ if (conv[i]?.sender === 'user') return i
197
+ }
198
+ return -1
199
+ })()
200
+ if (lastUserIndex < 0) {
201
+ return { output: '', error: 'No user message found in conversation' }
202
+ }
203
+ const lastUser = conv[lastUserIndex]
204
+
205
+ // Prepare a streaming log writer so logs are written as they occur
206
+ {
207
+ const { createWriteStream } = await import('node:fs')
208
+ const runId = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
209
+ const projectRoot = await getProjectRootPath(vars.project)
210
+ const logsDir = path.join(projectRoot, 'data', 'logs')
211
+ await mkdir(logsDir, { recursive: true })
212
+ logsFilePath = path.join(logsDir, `capturedLogs_${runId}.log`)
213
+ logStream = createWriteStream(logsFilePath, { flags: 'a' })
214
+ }
215
+
216
+ const stepTracer: StepTracer = {
217
+ addStepTrace: (stepTrace: StepTrace) => {
218
+ try {
219
+ console.log(`trace: ${stepTrace.name}`)
220
+ capturedStepTraces.push(stepTrace)
221
+ } catch {
222
+ // best-effort capture; ignore serialization issues
223
+ }
224
+ }
225
+ }
226
+
227
+ const push = (level: 'log' | 'debug' | 'warn' | 'error', args: any[]) => {
228
+ try {
229
+ const raw = args
230
+ .map((a) => {
231
+ try {
232
+ return typeof a === 'string' ? a : JSON.stringify(a)
233
+ } catch {
234
+ return String(a)
235
+ }
236
+ })
237
+ .join(' ')
238
+ const prefix = `[${level.toUpperCase()}] `
239
+ let line = `${prefix}${raw}`
240
+ // Enforce max 5000 chars per entry for logs
241
+ if (line.length > 5000) {
242
+ line = line.slice(0, 5000) + '... [TRUNCATED]'
243
+ }
244
+ capturedLogs.push(line)
245
+ try {
246
+ logStream.write(line + '\n')
247
+ } catch {
248
+ /* best-effort stream write */
249
+ }
250
+ } catch {
251
+ // best-effort capture
252
+ }
253
+ }
254
+ const logger = {
255
+ log: (...args: any[]) => push('log', args),
256
+ debug: (...args: any[]) => push('debug', args),
257
+ warn: (...args: any[]) => push('warn', args),
258
+ error: (...args: any[]) => push('error', args)
259
+ }
260
+
261
+ try {
262
+ // Run the agent via loadAgents using provided conversation
263
+ await this.runLoadAgents({
264
+ agentId: agentCompositeId,
265
+ getMessages: () => conv,
266
+ sendMessage: async (message: Message | string) => {
267
+ const m = typeof message === 'string' ? { sender: 'agent', text: message } : message
268
+ if (m.sender === 'agent') {
269
+ if (true) {
270
+ captured = typeof (m as any).text === 'string' ? (m as any).text : JSON.stringify(m)
271
+ logger.log('Agent message captured:', captured)
272
+ } else {
273
+ logger.log('Agent message ignored, as we already captured a message')
274
+ }
275
+ }
276
+ },
277
+ stepTracer,
278
+ logger,
279
+ context: vars.context || {},
280
+ timeoutSeconds: Number(vars.timeoutSeconds)
281
+ })
282
+
283
+ const fs = await import('fs/promises')
284
+ const projectRoot = await getProjectRootPath(vars.project)
285
+ const logsDir = path.join(projectRoot, 'data', 'logs')
286
+ await mkdir(logsDir, { recursive: true })
287
+ const filePath = path.join(logsDir, `capturedStepTraces_${Date.now()}.json`)
288
+ await fs.writeFile(filePath, JSON.stringify(capturedStepTraces, null, 2))
289
+
290
+ // Prepare sanitized traces for sheet output
291
+ const sanitizeTrace = (t: any): any => {
292
+ try {
293
+ const clone: any = { ...t }
294
+ const isMain = clone?.name === 'main' || clone?.name === 'mainReply'
295
+ // Truncate large prompt fields on non-main steps
296
+ const truncate = (s: any, max = 5000) => {
297
+ if (typeof s !== 'string') return s
298
+ return s.length > max ? s.slice(0, max) + '... [TRUNCATED]' : s
299
+ }
300
+ if (isMain) {
301
+ // Hide main step rendered/received prompts entirely in traces
302
+ if ('renderedPrompt' in clone) delete clone.renderedPrompt
303
+ if ('receivedPrompt' in clone) delete clone.receivedPrompt
304
+ } else {
305
+ if (typeof clone.renderedPrompt !== 'undefined') {
306
+ clone.renderedPrompt = truncate(clone.renderedPrompt)
307
+ }
308
+ if (typeof clone.receivedPrompt !== 'undefined') {
309
+ clone.receivedPrompt = truncate(clone.receivedPrompt)
310
+ }
311
+ }
312
+ return clone
313
+ } catch {
314
+ return t
315
+ }
316
+ }
317
+ const sanitizedStepTraces = Array.isArray(capturedStepTraces)
318
+ ? capturedStepTraces.map(sanitizeTrace)
319
+ : []
320
+
321
+ if (captured && captured.trim()) {
322
+ return {
323
+ output: captured,
324
+ metadata: {
325
+ logs: capturedLogs,
326
+ stepTraces: sanitizedStepTraces,
327
+ rawStepTraces: capturedStepTraces
328
+ }
329
+ }
330
+ }
331
+
332
+ return {
333
+ output: '',
334
+ error: 'No agent reply captured',
335
+ metadata: {
336
+ logs: capturedLogs,
337
+ stepTraces: sanitizedStepTraces,
338
+ rawStepTraces: capturedStepTraces
339
+ }
340
+ }
341
+ } catch (err) {
342
+ const msg = err instanceof Error ? `${err.name}: ${err.message}` : String(err)
343
+ capturedLogs.push(`[ERROR] ${msg}`)
344
+ try {
345
+ logStream.write(`[ERROR] ${msg}\n`)
346
+ } catch {
347
+ /* best-effort */
348
+ }
349
+ return {
350
+ output: '',
351
+ error: msg,
352
+ metadata: { logs: capturedLogs, stepTraces: capturedStepTraces }
353
+ }
354
+ } finally {
355
+ // Ensure the stream flushes all data
356
+ if (logStream) {
357
+ await new Promise<void>((resolve) => {
358
+ try {
359
+ logStream.end(resolve)
360
+ } catch {
361
+ resolve()
362
+ }
363
+ })
364
+ }
365
+ }
366
+ }
367
+ }
368
+
369
+ // ----------------- Helpers -----------------
370
+ // Derive the result type returned inside Eval from promptfoo.evaluate
371
+ type PFEval = Awaited<ReturnType<typeof promptfoo.evaluate>>
372
+ type PFEvalResult = PFEval['results'][number]
373
+
374
+ function buildTableRows(
375
+ evals: Array<Awaited<ReturnType<typeof promptfoo.evaluate>>>,
376
+ csvRows: CsvRow[],
377
+ spreadsheetId: string
378
+ ): TableRow[] {
379
+ const bucket = new Map<string, PFEvalResult[]>()
380
+
381
+ for (const ev of evals) {
382
+ for (const res of ev.results) {
383
+ const testId = String(res.metadata?.testId ?? '')
384
+ ;(bucket.get(testId) ?? bucket.set(testId, []).get(testId)!).push(res)
385
+ }
386
+ }
387
+
388
+ const toStringSafe = (v: unknown): string => {
389
+ if (typeof v === 'string') return v
390
+ try {
391
+ return JSON.stringify(v)
392
+ } catch {
393
+ return String(v)
394
+ }
395
+ }
396
+
397
+ return csvRows.map((row) => {
398
+ const rowId = (row as any).id
399
+ const evalResults = bucket.get(String(rowId)) ?? []
400
+ const passCount = evalResults.filter((r) => r.success).length
401
+ const totalRuns = evalResults.length
402
+ const pct = totalRuns ? Math.round((passCount / totalRuns) * 100) : 0
403
+ const rateStr = `${passCount}/${totalRuns}`
404
+
405
+ const results: ResultEntry[] = evalResults.map((r) => {
406
+ const rawTraces = Array.isArray((r as any).metadata?.rawStepTraces)
407
+ ? ((r as any).metadata?.rawStepTraces as any[])
408
+ : Array.isArray((r as any).metadata?.stepTraces)
409
+ ? ((r as any).metadata?.stepTraces as any[])
410
+ : []
411
+ // Pick the last trace whose name === 'main'
412
+ const lastMain = (() => {
413
+ for (let i = rawTraces.length - 1; i >= 0; i--) {
414
+ const t = rawTraces[i]
415
+ if (t && t.name === 'main') return t
416
+ }
417
+ return undefined
418
+ })()
419
+ const rendered_prompt =
420
+ lastMain && typeof lastMain.renderedPrompt !== 'undefined'
421
+ ? toStringSafe(lastMain.renderedPrompt)
422
+ : 'NO RENDERED PROMPT'
423
+ const received_prompt =
424
+ lastMain && typeof lastMain.receivedPrompt !== 'undefined'
425
+ ? toStringSafe(lastMain.receivedPrompt)
426
+ : 'NO RECEIVED PROMPT'
427
+ const stringified_conversation =
428
+ lastMain && typeof lastMain.stringifiedConversation !== 'undefined'
429
+ ? toStringSafe(lastMain.stringifiedConversation)
430
+ : 'NO STRINGIFIED CONVERSATION'
431
+ const received_context =
432
+ lastMain && typeof lastMain.receivedContext !== 'undefined'
433
+ ? toStringSafe(lastMain.receivedContext)
434
+ : 'NO RECEIVED CONTEXT'
435
+
436
+ const logs = Array.isArray((r as any).metadata?.logs)
437
+ ? ((r as any).metadata?.logs as string[])
438
+ : []
439
+ const traces = Array.isArray((r as any).metadata?.stepTraces)
440
+ ? ((r as any).metadata?.stepTraces as any[])
441
+ : []
442
+ return {
443
+ success: !!r.success,
444
+ result: String(r.response?.output ?? ''),
445
+ evaluation: String(r.gradingResult?.reason ?? ''),
446
+ rendered_prompt,
447
+ received_prompt,
448
+ stringified_conversation,
449
+ received_context,
450
+ traces,
451
+ errors: String(r.error ?? ''),
452
+ logs
453
+ }
454
+ })
455
+
456
+ return {
457
+ ...row,
458
+ prompts: `suite://${spreadsheetId}?testId=${rowId}`,
459
+ success_rate_percent: pct,
460
+ success_rate: rateStr,
461
+ results
462
+ }
463
+ })
464
+ }
465
+
466
+ // legacy viewDetails removed; details are now per-run via /api/view endpoint
467
+ async function runPromptTests(
468
+ project: string,
469
+ agent: string,
470
+ opts?: { scope?: 'all' | 'pinned' },
471
+ deps?: { loadAgents?: LoadAgentsFn }
472
+ ): Promise<void> {
473
+ const backendId = `${project}/${agent}`
474
+ const suite = await readSuite(project, agent)
475
+ const rows = suite.tests as unknown as CsvRow[]
476
+ const cfg = await tryReadConfig(project, agent)
477
+ if (!cfg) {
478
+ const suitePath = await getSuiteFilePath(project, agent)
479
+ const expectedPath = path.join(path.dirname(suitePath), `${agent}.config.json`)
480
+ throw new Error(`Config not found at ${expectedPath}`)
481
+ }
482
+
483
+ const repeats = Number((cfg as any)?.repeats ?? 1)
484
+ const concurrency = Number((cfg as any)?.concurrency ?? 1)
485
+ const baseContext = (suite?.meta?.defaultContext as any) || {}
486
+
487
+ // Add an index field to each row for mapping
488
+ const typedRows = rows as unknown as CsvRow[]
489
+ const indexedRows = typedRows.map((row, index) => ({ ...(row as any), index }))
490
+
491
+ const tests = toTestInputs(indexedRows, baseContext, opts?.scope || 'pinned')
492
+
493
+ // Provider function with stable label
494
+ const providerInstance = new RecombineAgentProvider({
495
+ id: 'recombine-agent',
496
+ loadAgents: deps?.loadAgents
497
+ })
498
+ const providerFn = Object.assign(
499
+ (_promptStr: string, ctx?: CallApiContextParams) => providerInstance.callApi(_promptStr, ctx),
500
+ { label: 'recombine-agent' }
501
+ )
502
+
503
+ const testSuites = tests.map((test) => ({
504
+ prompts: ['agent-run'], // placeholder; provider ignores
505
+ tests: [
506
+ {
507
+ metadata: { testId: test.id },
508
+ assert: test.assertions,
509
+ model: 'not used!',
510
+ vars: {
511
+ project,
512
+ agent,
513
+ context: test.context,
514
+ conversation: test.conversation,
515
+ timeoutSeconds: (test as any).timeoutSeconds
516
+ }
517
+ }
518
+ ],
519
+ providers: [providerFn]
520
+ }))
521
+
522
+ const results: Array<Awaited<ReturnType<typeof promptfoo.evaluate>>> = []
523
+ for (const suite of testSuites) {
524
+ try {
525
+ const ev = await promptfoo.evaluate(suite, {
526
+ repeat: repeats,
527
+ cache: false,
528
+ maxConcurrency: concurrency
529
+ })
530
+ results.push(ev)
531
+ } catch (err) {
532
+ const msg = err instanceof Error ? `${err.name}: ${err.message}` : String(err)
533
+ results.push({
534
+ results: [
535
+ {
536
+ success: false,
537
+ response: { output: '' },
538
+ error: msg,
539
+ metadata: { testId: (suite.tests?.[0] as any)?.metadata?.testId }
540
+ } as any
541
+ ]
542
+ } as any)
543
+ }
544
+ }
545
+
546
+ // Build rows with per-run results, including last-steptrace derived fields.
547
+ const rowsToWrite = buildTableRows(results, typedRows, backendId)
548
+
549
+ const projectRoot = await getProjectRootPath(project)
550
+ const outDir = path.join(projectRoot, 'data', 'test_runs')
551
+ await mkdir(outDir, { recursive: true })
552
+ // Use full ISO timestamp and sanitize ':' for filesystem safety
553
+ const iso = new Date().toISOString()
554
+ const isoFile = iso.replace(/:/g, '-')
555
+ const outPath = path.join(outDir, `${agent}.${isoFile}.report.json`)
556
+ // Attach provenance columns to each row before writing
557
+ const withProvenance = rowsToWrite.map((row, idx) => {
558
+ const test_id = (row as any).id ?? String(idx)
559
+ const pinned_at_run =
560
+ String((row as any).pinned || '').toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE'
561
+ const run_scope = opts?.scope || 'pinned'
562
+ return {
563
+ ...row,
564
+ project,
565
+ agent,
566
+ test_id,
567
+ run_timestamp: iso,
568
+ run_config: JSON.stringify({ repeats, concurrency, defaultContext: baseContext }),
569
+ pinned_at_run,
570
+ run_scope
571
+ } as any
572
+ })
573
+ const body = {
574
+ project,
575
+ agent,
576
+ run_timestamp: iso,
577
+ run_scope: opts?.scope || 'pinned',
578
+ run_config: { repeats, concurrency, defaultContext: baseContext },
579
+ rows: withProvenance
580
+ }
581
+ await writeFile(outPath, JSON.stringify(body, null, 2), 'utf8')
582
+ }
583
+
584
+ export { runPromptTests }