@recombine-ai/bosun 0.3.6 → 0.3.9

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 (468) hide show
  1. package/build/client/_app/immutable/assets/0.XjKA4GPF.css +1 -0
  2. package/build/client/_app/immutable/assets/0.XjKA4GPF.css.br +0 -0
  3. package/build/client/_app/immutable/assets/0.XjKA4GPF.css.gz +0 -0
  4. package/build/client/_app/immutable/assets/2.DOE0DQ6H.css +1 -0
  5. package/build/client/_app/immutable/assets/2.DOE0DQ6H.css.br +0 -0
  6. package/build/client/_app/immutable/assets/2.DOE0DQ6H.css.gz +0 -0
  7. package/build/client/_app/immutable/assets/7.DlSPCZj0.css +1 -0
  8. package/build/client/_app/immutable/assets/7.DlSPCZj0.css.br +0 -0
  9. package/build/client/_app/immutable/assets/7.DlSPCZj0.css.gz +0 -0
  10. package/build/client/_app/immutable/assets/8.DoLA3Mkm.css +1 -0
  11. package/build/client/_app/immutable/assets/8.DoLA3Mkm.css.br +0 -0
  12. package/build/client/_app/immutable/assets/8.DoLA3Mkm.css.gz +0 -0
  13. package/build/client/_app/immutable/assets/ChatStepTrace.NFJFjHv0.css +1 -0
  14. package/build/client/_app/immutable/assets/ChatStepTrace.NFJFjHv0.css.br +0 -0
  15. package/build/client/_app/immutable/assets/ChatStepTrace.NFJFjHv0.css.gz +0 -0
  16. package/build/client/_app/immutable/assets/{Tab.BxaGw9IG.css → Tab.jOjMVh6j.css} +1 -1
  17. package/build/client/_app/immutable/assets/Tab.jOjMVh6j.css.br +0 -0
  18. package/build/client/_app/immutable/assets/Tab.jOjMVh6j.css.gz +0 -0
  19. package/build/client/_app/immutable/chunks/7wcu2ga1.js +1 -0
  20. package/build/client/_app/immutable/chunks/7wcu2ga1.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/7wcu2ga1.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/B3K88SyC.js +1 -0
  23. package/build/client/_app/immutable/chunks/B3K88SyC.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/B3K88SyC.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/{D5fGPlBk.js → BGEE3mf3.js} +1 -1
  26. package/build/client/_app/immutable/chunks/BGEE3mf3.js.br +0 -0
  27. package/build/client/_app/immutable/chunks/BGEE3mf3.js.gz +0 -0
  28. package/build/client/_app/immutable/chunks/{BOQMymse.js → BH7VBnJ7.js} +1 -1
  29. package/build/client/_app/immutable/chunks/BH7VBnJ7.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/BH7VBnJ7.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/BHkx8tAH.js +1 -0
  32. package/build/client/_app/immutable/chunks/BHkx8tAH.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/BHkx8tAH.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/BMwJcaLS.js +1 -0
  35. package/build/client/_app/immutable/chunks/BMwJcaLS.js.br +2 -0
  36. package/build/client/_app/immutable/chunks/BMwJcaLS.js.gz +0 -0
  37. package/build/client/_app/immutable/chunks/{CfKHaDCm.js → BOrnwyTp.js} +1 -1
  38. package/build/client/_app/immutable/chunks/BOrnwyTp.js.br +0 -0
  39. package/build/client/_app/immutable/chunks/BOrnwyTp.js.gz +0 -0
  40. package/build/client/_app/immutable/chunks/BbaH2eDw.js +1 -0
  41. package/build/client/_app/immutable/chunks/BbaH2eDw.js.br +0 -0
  42. package/build/client/_app/immutable/chunks/BbaH2eDw.js.gz +0 -0
  43. package/build/client/_app/immutable/chunks/{C769zFCl.js → Bub2VLj9.js} +1 -1
  44. package/build/client/_app/immutable/chunks/Bub2VLj9.js.br +0 -0
  45. package/build/client/_app/immutable/chunks/Bub2VLj9.js.gz +0 -0
  46. package/build/client/_app/immutable/chunks/{yOR3vtRx.js → ByppsbS-.js} +1 -1
  47. package/build/client/_app/immutable/chunks/ByppsbS-.js.br +0 -0
  48. package/build/client/_app/immutable/chunks/ByppsbS-.js.gz +0 -0
  49. package/build/client/_app/immutable/chunks/C0mQlu7J.js +1 -0
  50. package/build/client/_app/immutable/chunks/C0mQlu7J.js.br +1 -0
  51. package/build/client/_app/immutable/chunks/C0mQlu7J.js.gz +0 -0
  52. package/build/client/_app/immutable/chunks/C0pV4x1v.js +1 -0
  53. package/build/client/_app/immutable/chunks/C0pV4x1v.js.br +2 -0
  54. package/build/client/_app/immutable/chunks/C0pV4x1v.js.gz +0 -0
  55. package/build/client/_app/immutable/chunks/C0sQKHpE.js +1 -0
  56. package/build/client/_app/immutable/chunks/C0sQKHpE.js.br +0 -0
  57. package/build/client/_app/immutable/chunks/C0sQKHpE.js.gz +0 -0
  58. package/build/client/_app/immutable/chunks/{CRlLKhPr.js → CFcfsVkY.js} +1 -1
  59. package/build/client/_app/immutable/chunks/CFcfsVkY.js.br +0 -0
  60. package/build/client/_app/immutable/chunks/CFcfsVkY.js.gz +0 -0
  61. package/build/client/_app/immutable/chunks/{CZJlygAJ.js → CYkx2jgw.js} +1 -1
  62. package/build/client/_app/immutable/chunks/CYkx2jgw.js.br +0 -0
  63. package/build/client/_app/immutable/chunks/CYkx2jgw.js.gz +0 -0
  64. package/build/client/_app/immutable/chunks/CZ6iREyA.js +8 -0
  65. package/build/client/_app/immutable/chunks/CZ6iREyA.js.br +0 -0
  66. package/build/client/_app/immutable/chunks/CZ6iREyA.js.gz +0 -0
  67. package/build/client/_app/immutable/chunks/CbCJfhin.js +1 -0
  68. package/build/client/_app/immutable/chunks/CbCJfhin.js.br +0 -0
  69. package/build/client/_app/immutable/chunks/CbCJfhin.js.gz +0 -0
  70. package/build/client/_app/immutable/chunks/{DaRvw8c-.js → CdTjAjKm.js} +7 -7
  71. package/build/client/_app/immutable/chunks/CdTjAjKm.js.br +0 -0
  72. package/build/client/_app/immutable/chunks/CdTjAjKm.js.gz +0 -0
  73. package/build/client/_app/immutable/chunks/{4PztAao_.js → CmPVG-ki.js} +1 -1
  74. package/build/client/_app/immutable/chunks/CmPVG-ki.js.br +0 -0
  75. package/build/client/_app/immutable/chunks/CmPVG-ki.js.gz +0 -0
  76. package/build/client/_app/immutable/chunks/{DJ_lsF0V.js → Cnr0cZA4.js} +1 -1
  77. package/build/client/_app/immutable/chunks/Cnr0cZA4.js.br +0 -0
  78. package/build/client/_app/immutable/chunks/Cnr0cZA4.js.gz +0 -0
  79. package/build/client/_app/immutable/chunks/CojkI8AD.js +33 -0
  80. package/build/client/_app/immutable/chunks/CojkI8AD.js.br +0 -0
  81. package/build/client/_app/immutable/chunks/CojkI8AD.js.gz +0 -0
  82. package/build/client/_app/immutable/chunks/Cp_hX0eh.js +1 -0
  83. package/build/client/_app/immutable/chunks/Cp_hX0eh.js.br +0 -0
  84. package/build/client/_app/immutable/chunks/Cp_hX0eh.js.gz +0 -0
  85. package/build/client/_app/immutable/chunks/Cv6CwVfk.js +3 -0
  86. package/build/client/_app/immutable/chunks/Cv6CwVfk.js.br +0 -0
  87. package/build/client/_app/immutable/chunks/Cv6CwVfk.js.gz +0 -0
  88. package/build/client/_app/immutable/chunks/{DAfsp-82.js → D8qEOlWC.js} +1 -1
  89. package/build/client/_app/immutable/chunks/D8qEOlWC.js.br +0 -0
  90. package/build/client/_app/immutable/chunks/D8qEOlWC.js.gz +0 -0
  91. package/build/client/_app/immutable/chunks/{Bf1oCG9-.js → DOMF1VtZ.js} +1 -1
  92. package/build/client/_app/immutable/chunks/DOMF1VtZ.js.br +0 -0
  93. package/build/client/_app/immutable/chunks/DOMF1VtZ.js.gz +0 -0
  94. package/build/client/_app/immutable/chunks/{Bd7SZbXQ.js → DRaGXt8e.js} +1 -1
  95. package/build/client/_app/immutable/chunks/DRaGXt8e.js.br +0 -0
  96. package/build/client/_app/immutable/chunks/DRaGXt8e.js.gz +0 -0
  97. package/build/client/_app/immutable/chunks/{Bw2f0Pmg.js → DU-D8S0B.js} +1 -1
  98. package/build/client/_app/immutable/chunks/DU-D8S0B.js.br +0 -0
  99. package/build/client/_app/immutable/chunks/DU-D8S0B.js.gz +0 -0
  100. package/build/client/_app/immutable/chunks/{Culo9hD6.js → DadWvtYR.js} +1 -1
  101. package/build/client/_app/immutable/chunks/DadWvtYR.js.br +0 -0
  102. package/build/client/_app/immutable/chunks/DadWvtYR.js.gz +0 -0
  103. package/build/client/_app/immutable/chunks/{Cx_xzGPa.js → DbYdNz4J.js} +1 -1
  104. package/build/client/_app/immutable/chunks/DbYdNz4J.js.br +0 -0
  105. package/build/client/_app/immutable/chunks/DbYdNz4J.js.gz +0 -0
  106. package/build/client/_app/immutable/chunks/DiFAgw_s.js +1 -0
  107. package/build/client/_app/immutable/chunks/DiFAgw_s.js.br +0 -0
  108. package/build/client/_app/immutable/chunks/DiFAgw_s.js.gz +0 -0
  109. package/build/client/_app/immutable/chunks/DrMdBz9b.js +1 -0
  110. package/build/client/_app/immutable/chunks/DrMdBz9b.js.br +0 -0
  111. package/build/client/_app/immutable/chunks/DrMdBz9b.js.gz +0 -0
  112. package/build/client/_app/immutable/chunks/{qXu78w_4.js → DsvX5v5e.js} +1 -1
  113. package/build/client/_app/immutable/chunks/DsvX5v5e.js.br +0 -0
  114. package/build/client/_app/immutable/chunks/DsvX5v5e.js.gz +0 -0
  115. package/build/client/_app/immutable/chunks/Y0ymTIHd.js +1 -0
  116. package/build/client/_app/immutable/chunks/Y0ymTIHd.js.br +0 -0
  117. package/build/client/_app/immutable/chunks/Y0ymTIHd.js.gz +0 -0
  118. package/build/client/_app/immutable/chunks/_HWrJCgx.js +1 -0
  119. package/build/client/_app/immutable/chunks/_HWrJCgx.js.br +0 -0
  120. package/build/client/_app/immutable/chunks/_HWrJCgx.js.gz +0 -0
  121. package/build/client/_app/immutable/chunks/{CRTtd6by.js → qPgPowuc.js} +1 -1
  122. package/build/client/_app/immutable/chunks/qPgPowuc.js.br +0 -0
  123. package/build/client/_app/immutable/chunks/qPgPowuc.js.gz +0 -0
  124. package/build/client/_app/immutable/chunks/ri5tqg4N.js +1 -0
  125. package/build/client/_app/immutable/chunks/ri5tqg4N.js.br +0 -0
  126. package/build/client/_app/immutable/chunks/ri5tqg4N.js.gz +0 -0
  127. package/build/client/_app/immutable/chunks/{Codln_pl.js → sdLD1XcR.js} +1 -1
  128. package/build/client/_app/immutable/chunks/sdLD1XcR.js.br +0 -0
  129. package/build/client/_app/immutable/chunks/sdLD1XcR.js.gz +0 -0
  130. package/build/client/_app/immutable/chunks/t1v2-usS.js +4 -0
  131. package/build/client/_app/immutable/chunks/t1v2-usS.js.br +0 -0
  132. package/build/client/_app/immutable/chunks/t1v2-usS.js.gz +0 -0
  133. package/build/client/_app/immutable/chunks/tLFXBP7P.js +2 -0
  134. package/build/client/_app/immutable/chunks/tLFXBP7P.js.br +0 -0
  135. package/build/client/_app/immutable/chunks/tLFXBP7P.js.gz +0 -0
  136. package/build/client/_app/immutable/entry/app.jP0Pyfdy.js +2 -0
  137. package/build/client/_app/immutable/entry/app.jP0Pyfdy.js.br +0 -0
  138. package/build/client/_app/immutable/entry/app.jP0Pyfdy.js.gz +0 -0
  139. package/build/client/_app/immutable/entry/start.KD1JZMOT.js +1 -0
  140. package/build/client/_app/immutable/entry/start.KD1JZMOT.js.br +2 -0
  141. package/build/client/_app/immutable/entry/start.KD1JZMOT.js.gz +0 -0
  142. package/build/client/_app/immutable/nodes/0.ByrdmeSo.js +3 -0
  143. package/build/client/_app/immutable/nodes/0.ByrdmeSo.js.br +0 -0
  144. package/build/client/_app/immutable/nodes/0.ByrdmeSo.js.gz +0 -0
  145. package/build/client/_app/immutable/nodes/1.VLeq38lN.js +1 -0
  146. package/build/client/_app/immutable/nodes/1.VLeq38lN.js.br +0 -0
  147. package/build/client/_app/immutable/nodes/1.VLeq38lN.js.gz +0 -0
  148. package/build/client/_app/immutable/nodes/10.BHSGZYEC.js +1 -0
  149. package/build/client/_app/immutable/nodes/10.BHSGZYEC.js.br +0 -0
  150. package/build/client/_app/immutable/nodes/10.BHSGZYEC.js.gz +0 -0
  151. package/build/client/_app/immutable/nodes/11.CZ_7M4AF.js +1 -0
  152. package/build/client/_app/immutable/nodes/11.CZ_7M4AF.js.br +0 -0
  153. package/build/client/_app/immutable/nodes/11.CZ_7M4AF.js.gz +0 -0
  154. package/build/client/_app/immutable/nodes/12.DRr2l3NZ.js +1 -0
  155. package/build/client/_app/immutable/nodes/12.DRr2l3NZ.js.br +2 -0
  156. package/build/client/_app/immutable/nodes/12.DRr2l3NZ.js.gz +0 -0
  157. package/build/client/_app/immutable/nodes/13.DetV1tDO.js +1 -0
  158. package/build/client/_app/immutable/nodes/13.DetV1tDO.js.br +0 -0
  159. package/build/client/_app/immutable/nodes/13.DetV1tDO.js.gz +0 -0
  160. package/build/client/_app/immutable/nodes/14.I-eiMWQu.js +11 -0
  161. package/build/client/_app/immutable/nodes/14.I-eiMWQu.js.br +0 -0
  162. package/build/client/_app/immutable/nodes/14.I-eiMWQu.js.gz +0 -0
  163. package/build/client/_app/immutable/nodes/2.DX9U9zLg.js +35 -0
  164. package/build/client/_app/immutable/nodes/2.DX9U9zLg.js.br +0 -0
  165. package/build/client/_app/immutable/nodes/2.DX9U9zLg.js.gz +0 -0
  166. package/build/client/_app/immutable/nodes/3.Bh8il5iy.js +1 -0
  167. package/build/client/_app/immutable/nodes/3.Bh8il5iy.js.br +0 -0
  168. package/build/client/_app/immutable/nodes/3.Bh8il5iy.js.gz +0 -0
  169. package/build/client/_app/immutable/nodes/{3.C-B1sGi_.js → 4.CtzHYc6x.js} +1 -1
  170. package/build/client/_app/immutable/nodes/4.CtzHYc6x.js.br +0 -0
  171. package/build/client/_app/immutable/nodes/4.CtzHYc6x.js.gz +0 -0
  172. package/build/client/_app/immutable/nodes/5.B4dlomkV.js +1 -0
  173. package/build/client/_app/immutable/nodes/5.B4dlomkV.js.br +0 -0
  174. package/build/client/_app/immutable/nodes/5.B4dlomkV.js.gz +0 -0
  175. package/build/client/_app/immutable/nodes/6.CPYhLc46.js +1 -0
  176. package/build/client/_app/immutable/nodes/6.CPYhLc46.js.br +4 -0
  177. package/build/client/_app/immutable/nodes/6.CPYhLc46.js.gz +0 -0
  178. package/build/client/_app/immutable/nodes/7.CBPrYfFp.js +2 -0
  179. package/build/client/_app/immutable/nodes/7.CBPrYfFp.js.br +0 -0
  180. package/build/client/_app/immutable/nodes/7.CBPrYfFp.js.gz +0 -0
  181. package/build/client/_app/immutable/nodes/8.4NTWYv4c.js +6 -0
  182. package/build/client/_app/immutable/nodes/8.4NTWYv4c.js.br +0 -0
  183. package/build/client/_app/immutable/nodes/8.4NTWYv4c.js.gz +0 -0
  184. package/build/client/_app/immutable/nodes/9.BVI-eEdV.js +1 -0
  185. package/build/client/_app/immutable/nodes/9.BVI-eEdV.js.br +0 -0
  186. package/build/client/_app/immutable/nodes/9.BVI-eEdV.js.gz +0 -0
  187. package/build/client/_app/immutable/workers/css.worker-BRIrhzkG.js +84 -0
  188. package/build/client/_app/immutable/workers/css.worker-BRIrhzkG.js.br +0 -0
  189. package/build/client/_app/immutable/workers/css.worker-BRIrhzkG.js.gz +0 -0
  190. package/build/client/_app/immutable/workers/editor.worker-DX6ApQqM.js +12 -0
  191. package/build/client/_app/immutable/workers/editor.worker-DX6ApQqM.js.br +0 -0
  192. package/build/client/_app/immutable/workers/editor.worker-DX6ApQqM.js.gz +0 -0
  193. package/build/client/_app/immutable/workers/html.worker-CBI4EQBP.js +461 -0
  194. package/build/client/_app/immutable/workers/html.worker-CBI4EQBP.js.br +0 -0
  195. package/build/client/_app/immutable/workers/html.worker-CBI4EQBP.js.gz +0 -0
  196. package/build/client/_app/immutable/workers/json.worker-CIZWV9vN.js +49 -0
  197. package/build/client/_app/immutable/workers/json.worker-CIZWV9vN.js.br +0 -0
  198. package/build/client/_app/immutable/workers/json.worker-CIZWV9vN.js.gz +0 -0
  199. package/build/client/_app/immutable/workers/ts.worker-Ds4I2Msu.js +51334 -0
  200. package/build/client/_app/immutable/workers/ts.worker-Ds4I2Msu.js.br +0 -0
  201. package/build/client/_app/immutable/workers/ts.worker-Ds4I2Msu.js.gz +0 -0
  202. package/build/client/_app/version.json +1 -1
  203. package/build/client/_app/version.json.br +0 -0
  204. package/build/client/_app/version.json.gz +0 -0
  205. package/build/server/chunks/0-CjpeDbMt.js +9 -0
  206. package/build/server/chunks/{0-BjExyGhw.js.map → 0-CjpeDbMt.js.map} +1 -1
  207. package/build/server/chunks/1-M0YzuUQM.js +9 -0
  208. package/build/server/chunks/{1-BwvZ1byr.js.map → 1-M0YzuUQM.js.map} +1 -1
  209. package/build/server/chunks/{7-soEaW5k5.js → 10-C7WLHR92.js} +5 -5
  210. package/build/server/chunks/10-C7WLHR92.js.map +1 -0
  211. package/build/server/chunks/11-CPYwUx-7.js +21 -0
  212. package/build/server/chunks/11-CPYwUx-7.js.map +1 -0
  213. package/build/server/chunks/12-C5OSs5Op.js +20 -0
  214. package/build/server/chunks/12-C5OSs5Op.js.map +1 -0
  215. package/build/server/chunks/13-BQ9R_Ex-.js +9 -0
  216. package/build/server/chunks/13-BQ9R_Ex-.js.map +1 -0
  217. package/build/server/chunks/14-BFsI6u_W.js +9 -0
  218. package/build/server/chunks/14-BFsI6u_W.js.map +1 -0
  219. package/build/server/chunks/2-Cjh0UTU6.js +9 -0
  220. package/build/server/chunks/2-Cjh0UTU6.js.map +1 -0
  221. package/build/server/chunks/3-VrGFs76T.js +9 -0
  222. package/build/server/chunks/3-VrGFs76T.js.map +1 -0
  223. package/build/server/chunks/4-CSgrzh2F.js +9 -0
  224. package/build/server/chunks/4-CSgrzh2F.js.map +1 -0
  225. package/build/server/chunks/5-zKehYil3.js +9 -0
  226. package/build/server/chunks/5-zKehYil3.js.map +1 -0
  227. package/build/server/chunks/6-uS_X9B0s.js +21 -0
  228. package/build/server/chunks/6-uS_X9B0s.js.map +1 -0
  229. package/build/server/chunks/7-DewREBAN.js +9 -0
  230. package/build/server/chunks/7-DewREBAN.js.map +1 -0
  231. package/build/server/chunks/8-Dk3ms3jm.js +9 -0
  232. package/build/server/chunks/8-Dk3ms3jm.js.map +1 -0
  233. package/build/server/chunks/9-W6XYayeK.js +25 -0
  234. package/build/server/chunks/9-W6XYayeK.js.map +1 -0
  235. package/build/server/chunks/{AgentSidebar-C4H-7WxT.js → AgentSidebar-BB_yQ9s0.js} +4 -4
  236. package/build/server/chunks/AgentSidebar-BB_yQ9s0.js.map +1 -0
  237. package/build/server/chunks/{Button-D3mqAVvu.js → Button-Cd4Yzpdy.js} +4 -4
  238. package/build/server/chunks/Button-Cd4Yzpdy.js.map +1 -0
  239. package/build/server/chunks/{ChatStepTrace-dfzN1KEN.js → ChatStepTrace-cq26gF4B.js} +229 -14
  240. package/build/server/chunks/ChatStepTrace-cq26gF4B.js.map +1 -0
  241. package/build/server/chunks/ContextEditor-CfjBPLpI.js +67 -0
  242. package/build/server/chunks/ContextEditor-CfjBPLpI.js.map +1 -0
  243. package/build/server/chunks/{Icon-D0R0X6Hr.js → Icon-BgknHaZs.js} +2 -2
  244. package/build/server/chunks/{Icon-D0R0X6Hr.js.map → Icon-BgknHaZs.js.map} +1 -1
  245. package/build/server/chunks/{Input-C_H479QL.js → Input-BJW36iKz.js} +2 -2
  246. package/build/server/chunks/{Input-C_H479QL.js.map → Input-BJW36iKz.js.map} +1 -1
  247. package/build/server/chunks/{Modal-NTInCBwo.js → Modal-D4tx0Bdo.js} +3 -3
  248. package/build/server/chunks/Modal-D4tx0Bdo.js.map +1 -0
  249. package/build/server/chunks/{Tab-DAuTmew0.js → Tab-DheAG-QC.js} +3 -3
  250. package/build/server/chunks/Tab-DheAG-QC.js.map +1 -0
  251. package/build/server/chunks/{_layout.svelte-DFDvSokt.js → _layout.svelte-BL8XnK1E.js} +23 -28
  252. package/build/server/chunks/_layout.svelte-BL8XnK1E.js.map +1 -0
  253. package/build/server/chunks/_layout.svelte-DHgaGTP_.js +844 -0
  254. package/build/server/chunks/_layout.svelte-DHgaGTP_.js.map +1 -0
  255. package/build/server/chunks/{_layout.svelte-CrT993Da.js → _layout.svelte-Svi5xbzP.js} +1 -14
  256. package/build/server/chunks/_layout.svelte-Svi5xbzP.js.map +1 -0
  257. package/build/server/chunks/{_page.svelte-B3Lu_xzt.js → _page.svelte-39hvC6-Q.js} +4 -4
  258. package/build/server/chunks/{_page.svelte-B3Lu_xzt.js.map → _page.svelte-39hvC6-Q.js.map} +1 -1
  259. package/build/server/chunks/{_page.svelte-5O44TlMG.js → _page.svelte-BpnUXzfh.js} +40 -25
  260. package/build/server/chunks/_page.svelte-BpnUXzfh.js.map +1 -0
  261. package/build/server/chunks/{_page.svelte-N6xQwQzn.js → _page.svelte-C1YaC_Qg.js} +498 -496
  262. package/build/server/chunks/_page.svelte-C1YaC_Qg.js.map +1 -0
  263. package/build/server/chunks/{_page.svelte-D9kg5-lo.js → _page.svelte-CbqAsz26.js} +3 -3
  264. package/build/server/chunks/_page.svelte-CbqAsz26.js.map +1 -0
  265. package/build/server/chunks/{_page.svelte-ClesenAz.js → _page.svelte-CmsDxzfh.js} +19 -27
  266. package/build/server/chunks/_page.svelte-CmsDxzfh.js.map +1 -0
  267. package/build/server/chunks/{_page.svelte-DimeWJh5.js → _page.svelte-DCP-PSh0.js} +293 -433
  268. package/build/server/chunks/_page.svelte-DCP-PSh0.js.map +1 -0
  269. package/build/server/chunks/edit-workspace-context-OTOIRCI0.js +13 -0
  270. package/build/server/chunks/edit-workspace-context-OTOIRCI0.js.map +1 -0
  271. package/build/server/chunks/hooks-BJphIAi-.js +8 -0
  272. package/build/server/chunks/hooks-BJphIAi-.js.map +1 -0
  273. package/build/server/chunks/{Tab.svelte_svelte_type_style_lang-Bmdqxv-M.js → index-server-CefdgakO.js} +2 -2
  274. package/build/server/chunks/index-server-CefdgakO.js.map +1 -0
  275. package/build/server/chunks/{index2-CHZ7ZFLZ.js → index2-BuOY2QE4.js} +2 -2
  276. package/build/server/chunks/{index2-CHZ7ZFLZ.js.map → index2-BuOY2QE4.js.map} +1 -1
  277. package/build/server/chunks/log-content.svelte-B3ZvaoLs.js +20 -0
  278. package/build/server/chunks/log-content.svelte-B3ZvaoLs.js.map +1 -0
  279. package/build/server/index.js +3 -2
  280. package/build/server/index.js.map +1 -1
  281. package/build/server/manifest.js +51 -18
  282. package/build/server/manifest.js.map +1 -1
  283. package/package.json +3 -1
  284. package/src/backend/lib/decode-html-entities.spec.ts +29 -0
  285. package/src/backend/lib/decode-html-entities.ts +25 -0
  286. package/src/backend/roleplay/router.ts +31 -0
  287. package/src/backend/tests/academy.ts +353 -115
  288. package/src/backend/tests/analyze.ts +357 -0
  289. package/src/backend/tests/data.ts +48 -12
  290. package/src/backend/tests/emulate-agents.ts +39 -4
  291. package/src/backend/tests/prompt-issues.ts +204 -0
  292. package/src/backend/tests/router.ts +51 -4
  293. package/build/client/_app/immutable/assets/0.D_OBtTqU.css +0 -1
  294. package/build/client/_app/immutable/assets/0.D_OBtTqU.css.br +0 -0
  295. package/build/client/_app/immutable/assets/0.D_OBtTqU.css.gz +0 -0
  296. package/build/client/_app/immutable/assets/4.sP9PzBp7.css +0 -1
  297. package/build/client/_app/immutable/assets/4.sP9PzBp7.css.br +0 -0
  298. package/build/client/_app/immutable/assets/4.sP9PzBp7.css.gz +0 -0
  299. package/build/client/_app/immutable/assets/6.C4C8vBUW.css +0 -1
  300. package/build/client/_app/immutable/assets/6.C4C8vBUW.css.br +0 -0
  301. package/build/client/_app/immutable/assets/6.C4C8vBUW.css.gz +0 -0
  302. package/build/client/_app/immutable/assets/Tab.BxaGw9IG.css.br +0 -0
  303. package/build/client/_app/immutable/assets/Tab.BxaGw9IG.css.gz +0 -0
  304. package/build/client/_app/immutable/chunks/4PztAao_.js.br +0 -0
  305. package/build/client/_app/immutable/chunks/4PztAao_.js.gz +0 -0
  306. package/build/client/_app/immutable/chunks/B2gGEZTS.js +0 -1
  307. package/build/client/_app/immutable/chunks/B2gGEZTS.js.br +0 -2
  308. package/build/client/_app/immutable/chunks/B2gGEZTS.js.gz +0 -0
  309. package/build/client/_app/immutable/chunks/BFOPpRqC.js +0 -8
  310. package/build/client/_app/immutable/chunks/BFOPpRqC.js.br +0 -0
  311. package/build/client/_app/immutable/chunks/BFOPpRqC.js.gz +0 -0
  312. package/build/client/_app/immutable/chunks/BOQMymse.js.br +0 -0
  313. package/build/client/_app/immutable/chunks/BOQMymse.js.gz +0 -0
  314. package/build/client/_app/immutable/chunks/Bd7SZbXQ.js.br +0 -0
  315. package/build/client/_app/immutable/chunks/Bd7SZbXQ.js.gz +0 -0
  316. package/build/client/_app/immutable/chunks/Bf1oCG9-.js.br +0 -0
  317. package/build/client/_app/immutable/chunks/Bf1oCG9-.js.gz +0 -0
  318. package/build/client/_app/immutable/chunks/BgaIh2D4.js +0 -1
  319. package/build/client/_app/immutable/chunks/BgaIh2D4.js.br +0 -0
  320. package/build/client/_app/immutable/chunks/BgaIh2D4.js.gz +0 -0
  321. package/build/client/_app/immutable/chunks/BrDK8TTs.js +0 -2
  322. package/build/client/_app/immutable/chunks/BrDK8TTs.js.br +0 -0
  323. package/build/client/_app/immutable/chunks/BrDK8TTs.js.gz +0 -0
  324. package/build/client/_app/immutable/chunks/BsKQRAyX.js +0 -1
  325. package/build/client/_app/immutable/chunks/BsKQRAyX.js.br +0 -0
  326. package/build/client/_app/immutable/chunks/BsKQRAyX.js.gz +0 -0
  327. package/build/client/_app/immutable/chunks/Bw2f0Pmg.js.br +0 -0
  328. package/build/client/_app/immutable/chunks/Bw2f0Pmg.js.gz +0 -0
  329. package/build/client/_app/immutable/chunks/C-dTPkQy.js +0 -1
  330. package/build/client/_app/immutable/chunks/C-dTPkQy.js.br +0 -0
  331. package/build/client/_app/immutable/chunks/C-dTPkQy.js.gz +0 -0
  332. package/build/client/_app/immutable/chunks/C769zFCl.js.br +0 -0
  333. package/build/client/_app/immutable/chunks/C769zFCl.js.gz +0 -0
  334. package/build/client/_app/immutable/chunks/CInh9KnU.js +0 -1
  335. package/build/client/_app/immutable/chunks/CInh9KnU.js.br +0 -2
  336. package/build/client/_app/immutable/chunks/CInh9KnU.js.gz +0 -0
  337. package/build/client/_app/immutable/chunks/CRTtd6by.js.br +0 -0
  338. package/build/client/_app/immutable/chunks/CRTtd6by.js.gz +0 -0
  339. package/build/client/_app/immutable/chunks/CRlLKhPr.js.br +0 -0
  340. package/build/client/_app/immutable/chunks/CRlLKhPr.js.gz +0 -0
  341. package/build/client/_app/immutable/chunks/CUfDVPpW.js +0 -1
  342. package/build/client/_app/immutable/chunks/CUfDVPpW.js.br +0 -0
  343. package/build/client/_app/immutable/chunks/CUfDVPpW.js.gz +0 -0
  344. package/build/client/_app/immutable/chunks/CZJlygAJ.js.br +0 -0
  345. package/build/client/_app/immutable/chunks/CZJlygAJ.js.gz +0 -0
  346. package/build/client/_app/immutable/chunks/CfKHaDCm.js.br +0 -0
  347. package/build/client/_app/immutable/chunks/CfKHaDCm.js.gz +0 -0
  348. package/build/client/_app/immutable/chunks/Codln_pl.js.br +0 -0
  349. package/build/client/_app/immutable/chunks/Codln_pl.js.gz +0 -0
  350. package/build/client/_app/immutable/chunks/Culo9hD6.js.br +0 -0
  351. package/build/client/_app/immutable/chunks/Culo9hD6.js.gz +0 -0
  352. package/build/client/_app/immutable/chunks/Cx_xzGPa.js.br +0 -0
  353. package/build/client/_app/immutable/chunks/Cx_xzGPa.js.gz +0 -0
  354. package/build/client/_app/immutable/chunks/D5fGPlBk.js.br +0 -0
  355. package/build/client/_app/immutable/chunks/D5fGPlBk.js.gz +0 -0
  356. package/build/client/_app/immutable/chunks/D8e5qIiS.js +0 -33
  357. package/build/client/_app/immutable/chunks/D8e5qIiS.js.br +0 -0
  358. package/build/client/_app/immutable/chunks/D8e5qIiS.js.gz +0 -0
  359. package/build/client/_app/immutable/chunks/D9h7-Y-f.js +0 -1
  360. package/build/client/_app/immutable/chunks/D9h7-Y-f.js.br +0 -0
  361. package/build/client/_app/immutable/chunks/D9h7-Y-f.js.gz +0 -0
  362. package/build/client/_app/immutable/chunks/DAfsp-82.js.br +0 -0
  363. package/build/client/_app/immutable/chunks/DAfsp-82.js.gz +0 -0
  364. package/build/client/_app/immutable/chunks/DJ_lsF0V.js.br +0 -0
  365. package/build/client/_app/immutable/chunks/DJ_lsF0V.js.gz +0 -0
  366. package/build/client/_app/immutable/chunks/DaRvw8c-.js.br +0 -0
  367. package/build/client/_app/immutable/chunks/DaRvw8c-.js.gz +0 -0
  368. package/build/client/_app/immutable/chunks/Dxv8gtYg.js +0 -1
  369. package/build/client/_app/immutable/chunks/Dxv8gtYg.js.br +0 -0
  370. package/build/client/_app/immutable/chunks/Dxv8gtYg.js.gz +0 -0
  371. package/build/client/_app/immutable/chunks/FawE95CY.js +0 -1
  372. package/build/client/_app/immutable/chunks/FawE95CY.js.br +0 -0
  373. package/build/client/_app/immutable/chunks/FawE95CY.js.gz +0 -0
  374. package/build/client/_app/immutable/chunks/HBgR5qMR.js +0 -3
  375. package/build/client/_app/immutable/chunks/HBgR5qMR.js.br +0 -0
  376. package/build/client/_app/immutable/chunks/HBgR5qMR.js.gz +0 -0
  377. package/build/client/_app/immutable/chunks/I-mny6CH.js +0 -1
  378. package/build/client/_app/immutable/chunks/I-mny6CH.js.br +0 -0
  379. package/build/client/_app/immutable/chunks/I-mny6CH.js.gz +0 -0
  380. package/build/client/_app/immutable/chunks/WkRHaFaq.js +0 -4
  381. package/build/client/_app/immutable/chunks/WkRHaFaq.js.br +0 -0
  382. package/build/client/_app/immutable/chunks/WkRHaFaq.js.gz +0 -0
  383. package/build/client/_app/immutable/chunks/aeuWzujc.js +0 -1
  384. package/build/client/_app/immutable/chunks/aeuWzujc.js.br +0 -2
  385. package/build/client/_app/immutable/chunks/aeuWzujc.js.gz +0 -0
  386. package/build/client/_app/immutable/chunks/qXu78w_4.js.br +0 -0
  387. package/build/client/_app/immutable/chunks/qXu78w_4.js.gz +0 -0
  388. package/build/client/_app/immutable/chunks/yOR3vtRx.js.br +0 -0
  389. package/build/client/_app/immutable/chunks/yOR3vtRx.js.gz +0 -0
  390. package/build/client/_app/immutable/entry/app.Bo6pBzFD.js +0 -2
  391. package/build/client/_app/immutable/entry/app.Bo6pBzFD.js.br +0 -0
  392. package/build/client/_app/immutable/entry/app.Bo6pBzFD.js.gz +0 -0
  393. package/build/client/_app/immutable/entry/start.DvDUBfDS.js +0 -1
  394. package/build/client/_app/immutable/entry/start.DvDUBfDS.js.br +0 -0
  395. package/build/client/_app/immutable/entry/start.DvDUBfDS.js.gz +0 -0
  396. package/build/client/_app/immutable/nodes/0.zcQ-QMcb.js +0 -3
  397. package/build/client/_app/immutable/nodes/0.zcQ-QMcb.js.br +0 -0
  398. package/build/client/_app/immutable/nodes/0.zcQ-QMcb.js.gz +0 -0
  399. package/build/client/_app/immutable/nodes/1.BX821K1d.js +0 -1
  400. package/build/client/_app/immutable/nodes/1.BX821K1d.js.br +0 -0
  401. package/build/client/_app/immutable/nodes/1.BX821K1d.js.gz +0 -0
  402. package/build/client/_app/immutable/nodes/2.4IvNSQft.js +0 -1
  403. package/build/client/_app/immutable/nodes/2.4IvNSQft.js.br +0 -0
  404. package/build/client/_app/immutable/nodes/2.4IvNSQft.js.gz +0 -0
  405. package/build/client/_app/immutable/nodes/3.C-B1sGi_.js.br +0 -0
  406. package/build/client/_app/immutable/nodes/3.C-B1sGi_.js.gz +0 -0
  407. package/build/client/_app/immutable/nodes/4.C6l0CiJD.js +0 -35
  408. package/build/client/_app/immutable/nodes/4.C6l0CiJD.js.br +0 -0
  409. package/build/client/_app/immutable/nodes/4.C6l0CiJD.js.gz +0 -0
  410. package/build/client/_app/immutable/nodes/5.RovJmk8R.js +0 -1
  411. package/build/client/_app/immutable/nodes/5.RovJmk8R.js.br +0 -0
  412. package/build/client/_app/immutable/nodes/5.RovJmk8R.js.gz +0 -0
  413. package/build/client/_app/immutable/nodes/6.vrBdmqTE.js +0 -5
  414. package/build/client/_app/immutable/nodes/6.vrBdmqTE.js.br +0 -0
  415. package/build/client/_app/immutable/nodes/6.vrBdmqTE.js.gz +0 -0
  416. package/build/client/_app/immutable/nodes/7.BLozkJCY.js +0 -1
  417. package/build/client/_app/immutable/nodes/7.BLozkJCY.js.br +0 -0
  418. package/build/client/_app/immutable/nodes/7.BLozkJCY.js.gz +0 -0
  419. package/build/client/_app/immutable/nodes/8.BeHRzquW.js +0 -1
  420. package/build/client/_app/immutable/nodes/8.BeHRzquW.js.br +0 -0
  421. package/build/client/_app/immutable/nodes/8.BeHRzquW.js.gz +0 -0
  422. package/build/client/_app/immutable/nodes/9.tDZ3CQE6.js +0 -11
  423. package/build/client/_app/immutable/nodes/9.tDZ3CQE6.js.br +0 -0
  424. package/build/client/_app/immutable/nodes/9.tDZ3CQE6.js.gz +0 -0
  425. package/build/server/chunks/0-BjExyGhw.js +0 -9
  426. package/build/server/chunks/1-BwvZ1byr.js +0 -9
  427. package/build/server/chunks/2-DLWqn5zk.js +0 -9
  428. package/build/server/chunks/2-DLWqn5zk.js.map +0 -1
  429. package/build/server/chunks/3-Be4gJSbJ.js +0 -9
  430. package/build/server/chunks/3-Be4gJSbJ.js.map +0 -1
  431. package/build/server/chunks/4-BQq4QAnS.js +0 -9
  432. package/build/server/chunks/4-BQq4QAnS.js.map +0 -1
  433. package/build/server/chunks/5-DM_iNIlm.js +0 -9
  434. package/build/server/chunks/5-DM_iNIlm.js.map +0 -1
  435. package/build/server/chunks/6-eSsWX3tm.js +0 -33
  436. package/build/server/chunks/6-eSsWX3tm.js.map +0 -1
  437. package/build/server/chunks/7-soEaW5k5.js.map +0 -1
  438. package/build/server/chunks/8-CA7E96iK.js +0 -9
  439. package/build/server/chunks/8-CA7E96iK.js.map +0 -1
  440. package/build/server/chunks/9-D2SkYOhZ.js +0 -9
  441. package/build/server/chunks/9-D2SkYOhZ.js.map +0 -1
  442. package/build/server/chunks/AgentSidebar-C4H-7WxT.js.map +0 -1
  443. package/build/server/chunks/Button-D3mqAVvu.js.map +0 -1
  444. package/build/server/chunks/ChatStepTrace-dfzN1KEN.js.map +0 -1
  445. package/build/server/chunks/ContextEditor-ySHjHE1w.js +0 -45
  446. package/build/server/chunks/ContextEditor-ySHjHE1w.js.map +0 -1
  447. package/build/server/chunks/Modal-NTInCBwo.js.map +0 -1
  448. package/build/server/chunks/Tab-DAuTmew0.js.map +0 -1
  449. package/build/server/chunks/Tab.svelte_svelte_type_style_lang-Bmdqxv-M.js.map +0 -1
  450. package/build/server/chunks/_layout.svelte-CrT993Da.js.map +0 -1
  451. package/build/server/chunks/_layout.svelte-DFDvSokt.js.map +0 -1
  452. package/build/server/chunks/_page.svelte-5O44TlMG.js.map +0 -1
  453. package/build/server/chunks/_page.svelte-ClesenAz.js.map +0 -1
  454. package/build/server/chunks/_page.svelte-D9kg5-lo.js.map +0 -1
  455. package/build/server/chunks/_page.svelte-DimeWJh5.js.map +0 -1
  456. package/build/server/chunks/_page.svelte-N6xQwQzn.js.map +0 -1
  457. /package/build/client/_app/immutable/assets/{9.C5apk4jm.css → 14.C5apk4jm.css} +0 -0
  458. /package/build/client/_app/immutable/assets/{9.C5apk4jm.css.br → 14.C5apk4jm.css.br} +0 -0
  459. /package/build/client/_app/immutable/assets/{9.C5apk4jm.css.gz → 14.C5apk4jm.css.gz} +0 -0
  460. /package/build/client/_app/immutable/assets/{2.Dzh7_Q8n.css → 3.Dzh7_Q8n.css} +0 -0
  461. /package/build/client/_app/immutable/assets/{2.Dzh7_Q8n.css.br → 3.Dzh7_Q8n.css.br} +0 -0
  462. /package/build/client/_app/immutable/assets/{2.Dzh7_Q8n.css.gz → 3.Dzh7_Q8n.css.gz} +0 -0
  463. /package/build/client/_app/immutable/assets/{3.CZVw96CJ.css → 4.CZVw96CJ.css} +0 -0
  464. /package/build/client/_app/immutable/assets/{3.CZVw96CJ.css.br → 4.CZVw96CJ.css.br} +0 -0
  465. /package/build/client/_app/immutable/assets/{3.CZVw96CJ.css.gz → 4.CZVw96CJ.css.gz} +0 -0
  466. /package/build/client/_app/immutable/assets/{Modal.tn0RQdqM.css → bosun-theme.tn0RQdqM.css} +0 -0
  467. /package/build/client/_app/immutable/assets/{Modal.tn0RQdqM.css.br → bosun-theme.tn0RQdqM.css.br} +0 -0
  468. /package/build/client/_app/immutable/assets/{Modal.tn0RQdqM.css.gz → bosun-theme.tn0RQdqM.css.gz} +0 -0
@@ -6,7 +6,7 @@ import { loadAgents } from './emulate-agents'
6
6
  import { type Assertion as PFAssertion } from 'promptfoo'
7
7
  // Backend: per-project JSON test suites (no CSV)
8
8
  import { tryReadConfig } from './config'
9
- import { mkdir, writeFile } from 'node:fs/promises'
9
+ import { mkdir, rename, unlink, writeFile } from 'node:fs/promises'
10
10
  import path from 'node:path'
11
11
  import { readSuite } from './suite'
12
12
  // Use types derived from promptfoo exports instead of incorrect default type imports
@@ -58,6 +58,58 @@ export interface TableRow extends CsvRow {
58
58
  results: ResultEntry[]
59
59
  }
60
60
 
61
+ export interface WrittenRunReportConfig {
62
+ repeats: number
63
+ concurrency: number
64
+ defaultContext: Record<string, any>
65
+ }
66
+
67
+ export interface WrittenRunReportRow extends TableRow {
68
+ agent: string
69
+ test_id: string
70
+ run_timestamp: string
71
+ run_config: string
72
+ pinned_at_run: 'TRUE' | 'FALSE'
73
+ run_scope: 'all' | 'pinned'
74
+ }
75
+
76
+ export interface WrittenRunReport {
77
+ agent: string
78
+ run_timestamp: string
79
+ run_scope: 'all' | 'pinned'
80
+ run_config: WrittenRunReportConfig
81
+ rows: WrittenRunReportRow[]
82
+ }
83
+
84
+ type PromptTestsScope = 'all' | 'pinned'
85
+
86
+ type PromptTestsSelection = { scope: PromptTestsScope } | { testId: string }
87
+
88
+ const activeRunsByAgent = new Map<string, AbortController>()
89
+
90
+ export function cancelPromptTests(agent: string): boolean {
91
+ const controller = activeRunsByAgent.get(agent)
92
+ if (!controller) return false
93
+ controller.abort()
94
+ return true
95
+ }
96
+
97
+ export async function runPromptTestsManaged(
98
+ agent: string,
99
+ selection: PromptTestsSelection = { scope: 'pinned' }
100
+ ): Promise<WrittenRunReport> {
101
+ if (activeRunsByAgent.has(agent)) {
102
+ throw new Error('Tests already running for this agent')
103
+ }
104
+ const controller = new AbortController()
105
+ activeRunsByAgent.set(agent, controller)
106
+ try {
107
+ return await runPromptTests(agent, selection, { signal: controller.signal })
108
+ } finally {
109
+ activeRunsByAgent.delete(agent)
110
+ }
111
+ }
112
+
61
113
  // Deep merge helper using 'deepmerge' with array replacement semantics
62
114
  const mergeContexts = (baseCtx: Record<string, any>, testCtx: Record<string, any>) =>
63
115
  deepmerge(baseCtx || {}, testCtx || {}, { arrayMerge: (_d, s, _o) => s })
@@ -111,10 +163,13 @@ function parseConversationFromSheet(conversation: string | undefined | null): Co
111
163
  function toTestInputs(
112
164
  rows: (CsvRow & { index: number })[],
113
165
  defaultContext?: Record<string, any>,
114
- scope: 'all' | 'pinned' = 'pinned'
166
+ selection: PromptTestsSelection = { scope: 'pinned' }
115
167
  ) {
116
168
  return rows
117
- .filter((r) => (scope === 'all' ? true : r.pinned === 'TRUE'))
169
+ .filter((r) => {
170
+ if ('testId' in selection) return String(r.id ?? '') === String(selection.testId)
171
+ return selection.scope === 'all' ? true : r.pinned === 'TRUE'
172
+ })
118
173
  .map((row) => ({
119
174
  id: row.id,
120
175
  scenario: row.scenario,
@@ -157,12 +212,17 @@ function toTestInputs(
157
212
  export class RecombineAgentProvider implements ApiProvider {
158
213
  protected providerId: string
159
214
  public config: Record<string, unknown>
215
+ private abortSignal?: AbortSignal
160
216
 
161
217
  constructor(options: ProviderOptions) {
162
218
  this.providerId = options.id || 'recombine-agent'
163
219
  this.config = options.config || {}
164
220
  }
165
221
 
222
+ setAbortSignal(signal: AbortSignal | undefined) {
223
+ this.abortSignal = signal
224
+ }
225
+
166
226
  id() {
167
227
  return this.providerId
168
228
  }
@@ -269,7 +329,8 @@ export class RecombineAgentProvider implements ApiProvider {
269
329
  stepTracer,
270
330
  logger,
271
331
  context: vars.context || {},
272
- timeoutSeconds: Number(vars.timeoutSeconds)
332
+ timeoutSeconds: Number(vars.timeoutSeconds),
333
+ abortSignal: this.abortSignal
273
334
  })
274
335
 
275
336
  const logsDir = path.join(projectRoot, 'data', 'logs')
@@ -361,6 +422,62 @@ export class RecombineAgentProvider implements ApiProvider {
361
422
  type PFEval = Awaited<ReturnType<typeof promptfoo.evaluate>>
362
423
  type PFEvalResult = PFEval['results'][number]
363
424
 
425
+ const toStringSafe = (v: unknown): string => {
426
+ if (typeof v === 'string') return v
427
+ try {
428
+ return JSON.stringify(v)
429
+ } catch {
430
+ return String(v)
431
+ }
432
+ }
433
+
434
+ function toResultEntry(r: any): ResultEntry {
435
+ const rawTraces = Array.isArray(r.metadata?.rawStepTraces)
436
+ ? r.metadata?.rawStepTraces
437
+ : Array.isArray(r.metadata?.stepTraces)
438
+ ? r.metadata?.stepTraces
439
+ : []
440
+ // Pick the last trace whose name === 'main'
441
+ const lastMain = (() => {
442
+ for (let i = rawTraces.length - 1; i >= 0; i--) {
443
+ const t = rawTraces[i]
444
+ if (t && t.name === 'main') return t
445
+ }
446
+ return undefined
447
+ })()
448
+ const rendered_prompt =
449
+ lastMain && typeof lastMain.renderedPrompt !== 'undefined'
450
+ ? toStringSafe(lastMain.renderedPrompt)
451
+ : 'NO RENDERED PROMPT'
452
+ const received_prompt =
453
+ lastMain && typeof lastMain.receivedPrompt !== 'undefined'
454
+ ? toStringSafe(lastMain.receivedPrompt)
455
+ : 'NO RECEIVED PROMPT'
456
+ const stringified_conversation =
457
+ lastMain && typeof lastMain.stringifiedConversation !== 'undefined'
458
+ ? toStringSafe(lastMain.stringifiedConversation)
459
+ : 'NO STRINGIFIED CONVERSATION'
460
+ const received_context =
461
+ lastMain && typeof lastMain.receivedContext !== 'undefined'
462
+ ? toStringSafe(lastMain.receivedContext)
463
+ : 'NO RECEIVED CONTEXT'
464
+
465
+ const logs = Array.isArray(r.metadata?.logs) ? (r.metadata?.logs as string[]) : []
466
+ const traces = Array.isArray(r.metadata?.stepTraces) ? r.metadata?.stepTraces : []
467
+ return {
468
+ success: !!r.success,
469
+ result: String(r.response?.output ?? ''),
470
+ evaluation: String(r.gradingResult?.reason ?? ''),
471
+ rendered_prompt,
472
+ received_prompt,
473
+ stringified_conversation,
474
+ received_context,
475
+ traces,
476
+ errors: String(r.error ?? ''),
477
+ logs
478
+ }
479
+ }
480
+
364
481
  function buildTableRows(
365
482
  evals: Array<Awaited<ReturnType<typeof promptfoo.evaluate>>>,
366
483
  csvRows: CsvRow[],
@@ -375,15 +492,6 @@ function buildTableRows(
375
492
  }
376
493
  }
377
494
 
378
- const toStringSafe = (v: unknown): string => {
379
- if (typeof v === 'string') return v
380
- try {
381
- return JSON.stringify(v)
382
- } catch {
383
- return String(v)
384
- }
385
- }
386
-
387
495
  return csvRows.map((row) => {
388
496
  const rowId = row.id
389
497
  const evalResults = bucket.get(String(rowId)) ?? []
@@ -392,52 +500,7 @@ function buildTableRows(
392
500
  const pct = totalRuns ? Math.round((passCount / totalRuns) * 100) : 0
393
501
  const rateStr = `${passCount}/${totalRuns}`
394
502
 
395
- const results: ResultEntry[] = evalResults.map((r) => {
396
- const rawTraces = Array.isArray(r.metadata?.rawStepTraces)
397
- ? r.metadata?.rawStepTraces
398
- : Array.isArray(r.metadata?.stepTraces)
399
- ? r.metadata?.stepTraces
400
- : []
401
- // Pick the last trace whose name === 'main'
402
- const lastMain = (() => {
403
- for (let i = rawTraces.length - 1; i >= 0; i--) {
404
- const t = rawTraces[i]
405
- if (t && t.name === 'main') return t
406
- }
407
- return undefined
408
- })()
409
- const rendered_prompt =
410
- lastMain && typeof lastMain.renderedPrompt !== 'undefined'
411
- ? toStringSafe(lastMain.renderedPrompt)
412
- : 'NO RENDERED PROMPT'
413
- const received_prompt =
414
- lastMain && typeof lastMain.receivedPrompt !== 'undefined'
415
- ? toStringSafe(lastMain.receivedPrompt)
416
- : 'NO RECEIVED PROMPT'
417
- const stringified_conversation =
418
- lastMain && typeof lastMain.stringifiedConversation !== 'undefined'
419
- ? toStringSafe(lastMain.stringifiedConversation)
420
- : 'NO STRINGIFIED CONVERSATION'
421
- const received_context =
422
- lastMain && typeof lastMain.receivedContext !== 'undefined'
423
- ? toStringSafe(lastMain.receivedContext)
424
- : 'NO RECEIVED CONTEXT'
425
-
426
- const logs = Array.isArray(r.metadata?.logs) ? (r.metadata?.logs as string[]) : []
427
- const traces = Array.isArray(r.metadata?.stepTraces) ? r.metadata?.stepTraces : []
428
- return {
429
- success: !!r.success,
430
- result: String(r.response?.output ?? ''),
431
- evaluation: String(r.gradingResult?.reason ?? ''),
432
- rendered_prompt,
433
- received_prompt,
434
- stringified_conversation,
435
- received_context,
436
- traces,
437
- errors: String(r.error ?? ''),
438
- logs
439
- }
440
- })
503
+ const results: ResultEntry[] = evalResults.map((r) => toResultEntry(r))
441
504
 
442
505
  return {
443
506
  ...row,
@@ -449,7 +512,14 @@ function buildTableRows(
449
512
  })
450
513
  }
451
514
 
452
- export async function runPromptTests(agent: string, scope: 'all' | 'pinned' = 'pinned') {
515
+ export async function runPromptTests(
516
+ agent: string,
517
+ selection: PromptTestsSelection = { scope: 'pinned' },
518
+ opts?: { signal?: AbortSignal }
519
+ ): Promise<WrittenRunReport> {
520
+ const signal = opts?.signal
521
+ const scope = 'scope' in selection ? selection.scope : 'pinned'
522
+ const onlyTestId = 'testId' in selection ? selection.testId : undefined
453
523
  const suite = await readSuite(agent)
454
524
  const rows = suite.tests as unknown as CsvRow[]
455
525
  const cfg = (await tryReadConfig(agent)) || {}
@@ -462,17 +532,30 @@ export async function runPromptTests(agent: string, scope: 'all' | 'pinned' = 'p
462
532
  const typedRows = rows as unknown as CsvRow[]
463
533
  const indexedRows = typedRows.map((row, index) => ({ ...row, index }))
464
534
 
465
- const tests = toTestInputs(indexedRows, baseContext, scope || 'pinned')
535
+ if (onlyTestId && !indexedRows.some((row) => String(row.id ?? '') === String(onlyTestId))) {
536
+ throw new Error(`Test not found: ${onlyTestId}`)
537
+ }
538
+
539
+ const tests = toTestInputs(indexedRows, baseContext, selection)
466
540
 
467
- // Provider function with stable label
468
- const providerInstance = new RecombineAgentProvider({
469
- id: 'recombine-agent'
470
- })
471
- const providerFn = Object.assign(
472
- (_promptStr: string, ctx?: CallApiContextParams) => providerInstance.callApi(_promptStr, ctx),
541
+ // Provider function with stable label
542
+ const providerInstance = new RecombineAgentProvider({
543
+ id: 'recombine-agent'
544
+ })
545
+ providerInstance.setAbortSignal(signal)
546
+ const providerFn = Object.assign(
547
+ (_promptStr: string, ctx?: CallApiContextParams) => {
548
+ if (signal?.aborted) {
549
+ throw new Error('Operation cancelled')
550
+ }
551
+ return providerInstance.callApi(_promptStr, ctx)
552
+ },
473
553
  { label: 'recombine-agent' }
474
554
  )
475
555
 
556
+ const hookKey = `__bosun_promptfoo_hook_${process.pid}_${Date.now()}_${Math.random().toString(16).slice(2)}`
557
+ const extensionCode = `globalThis[${JSON.stringify(hookKey)}]?.(output, context)`
558
+
476
559
  const testSuites = tests.map((test) => ({
477
560
  prompts: ['agent-run'], // placeholder; provider ignores
478
561
  scenario: test.scenario,
@@ -487,68 +570,223 @@ export async function runPromptTests(agent: string, scope: 'all' | 'pinned' = 'p
487
570
  conversation: test.conversation,
488
571
  timeoutSeconds: (test as any).timeoutSeconds
489
572
  }
490
- }
491
- ],
492
- providers: [providerFn]
573
+ }
574
+ ],
575
+ providers: [providerFn],
576
+ extensions: [extensionCode]
493
577
  }))
494
578
 
495
- const results: Array<Awaited<ReturnType<typeof promptfoo.evaluate>>> = []
496
- for (const suite of testSuites) {
497
- try {
498
- console.log(`Running: ${suite.scenario}`)
499
- const ev = await promptfoo.evaluate(suite, {
500
- repeat: repeats,
501
- cache: false,
502
- maxConcurrency: concurrency
503
- })
504
- results.push(ev)
505
- } catch (err) {
506
- const msg = err instanceof Error ? `${err.name}: ${err.message}` : String(err)
507
- results.push({
508
- results: [
509
- {
510
- success: false,
511
- response: { output: '' },
512
- error: msg,
513
- metadata: { testId: (suite.tests?.[0] as any)?.metadata?.testId }
514
- } as any
515
- ]
516
- } as any)
517
- }
518
- }
519
-
520
- // Build rows with per-run results, including last-step trace derived fields.
521
- const rowsToWrite = buildTableRows(results, typedRows, agent)
522
-
523
579
  const projectRoot = path.dirname(await getRootPath())
524
580
  const outDir = path.join(projectRoot, 'data', 'test_runs')
525
581
  await mkdir(outDir, { recursive: true })
582
+
526
583
  // Use full ISO timestamp and sanitize ':' for filesystem safety
527
584
  const iso = new Date().toISOString()
528
585
  const isoFile = iso.replace(/:/g, '-')
529
586
  const outPath = path.join(outDir, `${agent}.${isoFile}.report.json`)
530
- // Attach provenance columns to each row before writing
531
- const withProvenance = rowsToWrite.map((row, idx) => {
532
- const test_id = row.id ?? String(idx)
533
- const pinned = (row.pinned || '').toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE'
534
- return {
535
- ...row,
536
- agent,
537
- test_id,
538
- run_timestamp: iso,
539
- run_config: JSON.stringify({ repeats, concurrency, defaultContext: baseContext }),
540
- pinned_at_run: scope === 'all' ? 'TRUE' : pinned,
541
- run_scope: scope
587
+
588
+ async function writeReport(report: WrittenRunReport) {
589
+ const dir = path.dirname(outPath)
590
+ const base = path.basename(outPath)
591
+ const tmpPath = path.join(
592
+ dir,
593
+ `.${base}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`
594
+ )
595
+ const json = JSON.stringify(report, null, 2)
596
+ await writeFile(tmpPath, json, 'utf8')
597
+ try {
598
+ await rename(tmpPath, outPath)
599
+ } catch (e: any) {
600
+ // Windows doesn't allow atomic rename over an existing file.
601
+ try {
602
+ await unlink(outPath)
603
+ } catch {
604
+ // ignore
605
+ }
606
+ await rename(tmpPath, outPath)
542
607
  }
543
- })
544
- const body = {
608
+ }
609
+
610
+ const runConfig: WrittenRunReportConfig = {
611
+ repeats,
612
+ concurrency,
613
+ defaultContext: baseContext
614
+ }
615
+
616
+ const body: WrittenRunReport = {
545
617
  agent,
546
618
  run_timestamp: iso,
547
619
  run_scope: scope,
548
- run_config: { repeats, concurrency, defaultContext: baseContext },
549
- rows: withProvenance
620
+ run_config: runConfig,
621
+ rows: []
622
+ }
623
+
624
+ // Write an empty report immediately so clients can start polling this run.
625
+ await writeReport(body)
626
+
627
+ const byTestId = new Map<string, WrittenRunReportRow>()
628
+
629
+ const originalRowById = new Map<string, CsvRow>()
630
+ for (const r of typedRows) {
631
+ const id = String((r as any)?.id ?? '').trim()
632
+ if (id) originalRowById.set(id, r)
633
+ }
634
+
635
+ const countsByTestId = new Map<string, { pass: number; total: number }>()
636
+
637
+ let writeTimer: ReturnType<typeof setTimeout> | null = null
638
+ let writePending = false
639
+ let writeChain: Promise<void> = Promise.resolve()
640
+ const enqueueWrite = () => {
641
+ writeChain = writeChain
642
+ .catch(() => {})
643
+ .then(() => writeReport(body))
644
+ return writeChain
550
645
  }
551
- await writeFile(outPath, JSON.stringify(body, null, 2), 'utf8')
646
+ const requestWrite = () => {
647
+ writePending = true
648
+ if (writeTimer) return
649
+ writeTimer = setTimeout(() => {
650
+ writeTimer = null
651
+ if (!writePending) return
652
+ writePending = false
653
+ void enqueueWrite()
654
+ }, 200)
655
+ }
656
+
657
+ ;(globalThis as any)[hookKey] = (hookName: string, ctx: any) => {
658
+ try {
659
+ if (hookName !== 'afterEach') return
660
+ if (signal?.aborted) {
661
+ throw new Error('Operation cancelled')
662
+ }
663
+ const testId = String(ctx?.test?.metadata?.testId ?? '')
664
+ if (!testId) return
665
+ const r = ctx?.result
666
+ if (!r) return
667
+
668
+ const originalRow = originalRowById.get(testId)
669
+ if (!originalRow) return
670
+
671
+ let reportRow = byTestId.get(testId)
672
+ if (!reportRow) {
673
+ const pinned: 'TRUE' | 'FALSE' =
674
+ String((originalRow as any).pinned || '').toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE'
675
+ const nextRow: WrittenRunReportRow = {
676
+ ...(originalRow as any),
677
+ prompts: `suite://${agent}?testId=${testId}`,
678
+ success_rate_percent: 0,
679
+ success_rate: '0/0',
680
+ results: [],
681
+ agent,
682
+ test_id: testId,
683
+ run_timestamp: iso,
684
+ run_config: JSON.stringify(runConfig),
685
+ pinned_at_run: scope === 'all' || !!onlyTestId ? 'TRUE' : pinned,
686
+ run_scope: scope
687
+ }
688
+ reportRow = nextRow
689
+ byTestId.set(testId, nextRow)
690
+ body.rows = Array.from(byTestId.values())
691
+ }
692
+ if (!reportRow) return
693
+
694
+ const entry = toResultEntry(r)
695
+ reportRow.results.push(entry)
696
+
697
+ const counts = countsByTestId.get(testId) ?? { pass: 0, total: 0 }
698
+ counts.total += 1
699
+ if (entry.success) counts.pass += 1
700
+ countsByTestId.set(testId, counts)
701
+
702
+ reportRow.success_rate = `${counts.pass}/${counts.total}`
703
+ reportRow.success_rate_percent = counts.total ? Math.round((counts.pass / counts.total) * 100) : 0
704
+
705
+ requestWrite()
706
+ } catch (err) {
707
+ if (signal?.aborted) throw err
708
+ // ignore
709
+ }
710
+ }
711
+
712
+ try {
713
+ for (const suite of testSuites) {
714
+ if (signal?.aborted) break
715
+ const testId = String((suite.tests?.[0] as any)?.metadata?.testId ?? '')
716
+ const originalRow = testId ? typedRows.find((r) => String(r.id) === testId) : undefined
717
+ try {
718
+ console.log(`Running: ${suite.scenario}`)
719
+ const ev = await promptfoo.evaluate(suite, {
720
+ repeat: repeats,
721
+ cache: false,
722
+ maxConcurrency: concurrency,
723
+ abortSignal: signal
724
+ })
725
+
726
+ if (originalRow && testId) {
727
+ const rowToWrite = buildTableRows([ev], [originalRow], agent)[0]
728
+ const pinned: 'TRUE' | 'FALSE' =
729
+ (rowToWrite.pinned || '').toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE'
730
+ byTestId.set(testId, {
731
+ ...rowToWrite,
732
+ agent,
733
+ test_id: testId,
734
+ run_timestamp: iso,
735
+ run_config: JSON.stringify(runConfig),
736
+ pinned_at_run: scope === 'all' || !!onlyTestId ? 'TRUE' : pinned,
737
+ run_scope: scope
738
+ })
739
+ body.rows = Array.from(byTestId.values())
740
+ await enqueueWrite()
741
+ }
742
+ } catch (err) {
743
+ const cancelled =
744
+ !!signal?.aborted ||
745
+ (err instanceof Error && /operation cancelled/i.test(err.message || ''))
746
+ if (cancelled) {
747
+ break
748
+ }
749
+ const msg = err instanceof Error ? `${err.name}: ${err.message}` : String(err)
750
+ const ev = {
751
+ results: [
752
+ {
753
+ success: false,
754
+ response: { output: '' },
755
+ error: msg,
756
+ metadata: { testId: (suite.tests?.[0] as any)?.metadata?.testId }
757
+ } as any
758
+ ]
759
+ } as any
760
+
761
+ // Persist failure row immediately for real-time UI updates.
762
+ if (originalRow && testId) {
763
+ const rowToWrite = buildTableRows([ev], [originalRow], agent)[0]
764
+ const pinned: 'TRUE' | 'FALSE' =
765
+ (rowToWrite.pinned || '').toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE'
766
+ byTestId.set(testId, {
767
+ ...rowToWrite,
768
+ agent,
769
+ test_id: testId,
770
+ run_timestamp: iso,
771
+ run_config: JSON.stringify(runConfig),
772
+ pinned_at_run: scope === 'all' || !!onlyTestId ? 'TRUE' : pinned,
773
+ run_scope: scope
774
+ })
775
+ body.rows = Array.from(byTestId.values())
776
+ await enqueueWrite()
777
+ }
778
+ }
779
+ }
780
+ } finally {
781
+ if (writeTimer) clearTimeout(writeTimer)
782
+ writeTimer = null
783
+ delete (globalThis as any)[hookKey]
784
+ await writeChain
785
+ }
786
+
787
+ // Ensure the final report is written even if no tests ran (or an update was skipped).
788
+ body.rows = Array.from(byTestId.values())
789
+ await enqueueWrite()
552
790
 
553
791
  return body
554
792
  }