@recombine-ai/bosun 0.1.9 → 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.
- package/bin/bosun.js +9 -8
- package/build/academy/academy.ts +584 -0
- package/build/academy/csv/index.ts +155 -0
- package/build/academy/data.ts +299 -0
- package/build/academy/emulate-agents.ts +129 -0
- package/build/academy/google-sheets/index.ts +187 -0
- package/build/academy/runPromptTests.cli.ts +99 -0
- package/build/academy/suite.ts +99 -0
- package/build/client/_app/immutable/assets/0.3Ve1RxLg.css +1 -0
- package/build/client/_app/immutable/assets/0.3Ve1RxLg.css.br +0 -0
- package/build/client/_app/immutable/assets/0.3Ve1RxLg.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.C7pCuiHL.css +1 -0
- package/build/client/_app/immutable/assets/3.C7pCuiHL.css.br +0 -0
- package/build/client/_app/immutable/assets/3.C7pCuiHL.css.gz +0 -0
- package/build/client/_app/immutable/assets/4.Baezuvdj.css +1 -0
- package/build/client/_app/immutable/assets/4.Baezuvdj.css.br +0 -0
- package/build/client/_app/immutable/assets/4.Baezuvdj.css.gz +0 -0
- package/build/client/_app/immutable/assets/6.CebW_jOJ.css +1 -0
- package/build/client/_app/immutable/assets/6.CebW_jOJ.css.br +0 -0
- package/build/client/_app/immutable/assets/6.CebW_jOJ.css.gz +0 -0
- package/build/client/_app/immutable/assets/8.f3T7i0UW.css +1 -0
- package/build/client/_app/immutable/assets/8.f3T7i0UW.css.br +0 -0
- package/build/client/_app/immutable/assets/8.f3T7i0UW.css.gz +0 -0
- package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css +1 -0
- package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css.br +0 -0
- package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css.gz +0 -0
- package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css +1 -0
- package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css.br +1 -0
- package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css.gz +0 -0
- package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css +1 -0
- package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css.br +0 -0
- package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css.gz +0 -0
- package/build/client/_app/immutable/chunks/B6Eu_a6G.js +8 -0
- package/build/client/_app/immutable/chunks/B6Eu_a6G.js.br +0 -0
- package/build/client/_app/immutable/chunks/B6Eu_a6G.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B946i1vX.js +1 -0
- package/build/client/_app/immutable/chunks/B946i1vX.js.br +0 -0
- package/build/client/_app/immutable/chunks/B946i1vX.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BDr6IUDE.js +1 -0
- package/build/client/_app/immutable/chunks/BDr6IUDE.js.br +0 -0
- package/build/client/_app/immutable/chunks/BDr6IUDE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BJ0PAzRz.js +1 -0
- package/build/client/_app/immutable/chunks/BJ0PAzRz.js.br +0 -0
- package/build/client/_app/immutable/chunks/BJ0PAzRz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BQsXEsya.js +2 -0
- package/build/client/_app/immutable/chunks/BQsXEsya.js.br +0 -0
- package/build/client/_app/immutable/chunks/BQsXEsya.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BVH8cl8Q.js +1 -0
- package/build/client/_app/immutable/chunks/BVH8cl8Q.js.br +0 -0
- package/build/client/_app/immutable/chunks/BVH8cl8Q.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bckf35or.js +1 -0
- package/build/client/_app/immutable/chunks/Bckf35or.js.br +1 -0
- package/build/client/_app/immutable/chunks/Bckf35or.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BcyK4bvI.js +1 -0
- package/build/client/_app/immutable/chunks/BcyK4bvI.js.br +0 -0
- package/build/client/_app/immutable/chunks/BcyK4bvI.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BpsvkpCa.js +1 -0
- package/build/client/_app/immutable/chunks/BpsvkpCa.js.br +0 -0
- package/build/client/_app/immutable/chunks/BpsvkpCa.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C7b8kjFl.js +33 -0
- package/build/client/_app/immutable/chunks/C7b8kjFl.js.br +0 -0
- package/build/client/_app/immutable/chunks/C7b8kjFl.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{D5O98MXA.js → C9ihsQgF.js} +2 -2
- package/build/client/_app/immutable/chunks/C9ihsQgF.js.br +6 -0
- package/build/client/_app/immutable/chunks/C9ihsQgF.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CEHtmspK.js +1 -0
- package/build/client/_app/immutable/chunks/CEHtmspK.js.br +0 -0
- package/build/client/_app/immutable/chunks/CEHtmspK.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CHop8m-3.js +1 -0
- package/build/client/_app/immutable/chunks/CHop8m-3.js.br +0 -0
- package/build/client/_app/immutable/chunks/CHop8m-3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CUWa2xqt.js +1 -0
- package/build/client/_app/immutable/chunks/CUWa2xqt.js.br +0 -0
- package/build/client/_app/immutable/chunks/CUWa2xqt.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ClfaR3Y2.js +1 -0
- package/build/client/_app/immutable/chunks/ClfaR3Y2.js.br +0 -0
- package/build/client/_app/immutable/chunks/ClfaR3Y2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DAgYAbDT.js +3 -0
- package/build/client/_app/immutable/chunks/DAgYAbDT.js.br +0 -0
- package/build/client/_app/immutable/chunks/DAgYAbDT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DBCXNg0T.js +1 -0
- package/build/client/_app/immutable/chunks/DBCXNg0T.js.br +0 -0
- package/build/client/_app/immutable/chunks/DBCXNg0T.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DDncCuU5.js +1 -0
- package/build/client/_app/immutable/chunks/DDncCuU5.js.br +2 -0
- package/build/client/_app/immutable/chunks/DDncCuU5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DHQ8_yIz.js +1 -0
- package/build/client/_app/immutable/chunks/DHQ8_yIz.js.br +0 -0
- package/build/client/_app/immutable/chunks/DHQ8_yIz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Deb2U3a-.js +1 -0
- package/build/client/_app/immutable/chunks/Deb2U3a-.js.br +0 -0
- package/build/client/_app/immutable/chunks/Deb2U3a-.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{B8bx6-qu.js → DgNsppMf.js} +1 -1
- package/build/client/_app/immutable/chunks/DgNsppMf.js.br +0 -0
- package/build/client/_app/immutable/chunks/DgNsppMf.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DgSSnt2u.js +1 -0
- package/build/client/_app/immutable/chunks/DgSSnt2u.js.br +0 -0
- package/build/client/_app/immutable/chunks/DgSSnt2u.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dr0H-PA9.js +1 -0
- package/build/client/_app/immutable/chunks/Dr0H-PA9.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dr0H-PA9.js.gz +0 -0
- package/build/client/_app/immutable/chunks/HA3qddzj.js +1 -0
- package/build/client/_app/immutable/chunks/HA3qddzj.js.br +0 -0
- package/build/client/_app/immutable/chunks/HA3qddzj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/LPKWlFs0.js +1 -0
- package/build/client/_app/immutable/chunks/LPKWlFs0.js.br +3 -0
- package/build/client/_app/immutable/chunks/LPKWlFs0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/VpPuF4LW.js +3 -0
- package/build/client/_app/immutable/chunks/VpPuF4LW.js.br +0 -0
- package/build/client/_app/immutable/chunks/VpPuF4LW.js.gz +0 -0
- package/build/client/_app/immutable/chunks/XyRovF4A.js +1 -0
- package/build/client/_app/immutable/chunks/XyRovF4A.js.br +0 -0
- package/build/client/_app/immutable/chunks/XyRovF4A.js.gz +0 -0
- package/build/client/_app/immutable/chunks/mRVZsLQ4.js +1 -0
- package/build/client/_app/immutable/chunks/mRVZsLQ4.js.br +2 -0
- package/build/client/_app/immutable/chunks/mRVZsLQ4.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CVDHq7dN.js +2 -0
- package/build/client/_app/immutable/entry/app.CVDHq7dN.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CVDHq7dN.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.a4wXr-rh.js +1 -0
- package/build/client/_app/immutable/entry/start.a4wXr-rh.js.br +2 -0
- package/build/client/_app/immutable/entry/start.a4wXr-rh.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.q5P1PqkU.js +3 -0
- package/build/client/_app/immutable/nodes/0.q5P1PqkU.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.q5P1PqkU.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.TfmDsqd-.js +1 -0
- package/build/client/_app/immutable/nodes/1.TfmDsqd-.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.TfmDsqd-.js.gz +0 -0
- package/build/client/_app/immutable/nodes/10.BpXsBlTN.js +1 -0
- package/build/client/_app/immutable/nodes/10.BpXsBlTN.js.br +0 -0
- package/build/client/_app/immutable/nodes/10.BpXsBlTN.js.gz +0 -0
- package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js +1 -0
- package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js.br +0 -0
- package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.BWtLQzzv.js +3 -0
- package/build/client/_app/immutable/nodes/2.BWtLQzzv.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BWtLQzzv.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.BlYIVobe.js +1 -0
- package/build/client/_app/immutable/nodes/3.BlYIVobe.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.BlYIVobe.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.DMboagHp.js +38 -0
- package/build/client/_app/immutable/nodes/4.DMboagHp.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.DMboagHp.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.DJDEfbU1.js +1 -0
- package/build/client/_app/immutable/nodes/5.DJDEfbU1.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.DJDEfbU1.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.Co1n7leD.js +12 -0
- package/build/client/_app/immutable/nodes/6.Co1n7leD.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.Co1n7leD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.3clSez0f.js +1 -0
- package/build/client/_app/immutable/nodes/7.3clSez0f.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.3clSez0f.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.D4xImLsM.js +1 -0
- package/build/client/_app/immutable/nodes/8.D4xImLsM.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.D4xImLsM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.C1KWPSTf.js +1 -0
- package/build/client/_app/immutable/nodes/9.C1KWPSTf.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.C1KWPSTf.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/0-CgyQG-Vf.js +9 -0
- package/build/server/chunks/0-CgyQG-Vf.js.map +1 -0
- package/build/server/chunks/1-DACiLfsu.js +9 -0
- package/build/server/chunks/{1-Cwk3hpe9.js.map → 1-DACiLfsu.js.map} +1 -1
- package/build/server/chunks/10-zMqY0bCj.js +9 -0
- package/build/server/chunks/10-zMqY0bCj.js.map +1 -0
- package/build/server/chunks/11-B7cPB4ip.js +9 -0
- package/build/server/chunks/11-B7cPB4ip.js.map +1 -0
- package/build/server/chunks/2-uTf78dNT.js +9 -0
- package/build/server/chunks/2-uTf78dNT.js.map +1 -0
- package/build/server/chunks/3-DOOLRXaZ.js +9 -0
- package/build/server/chunks/3-DOOLRXaZ.js.map +1 -0
- package/build/server/chunks/4-CLK_BxY0.js +9 -0
- package/build/server/chunks/4-CLK_BxY0.js.map +1 -0
- package/build/server/chunks/5-DfZ6yJrz.js +9 -0
- package/build/server/chunks/5-DfZ6yJrz.js.map +1 -0
- package/build/server/chunks/6-B2BoZUr6.js +22 -0
- package/build/server/chunks/6-B2BoZUr6.js.map +1 -0
- package/build/server/chunks/{5-p3BDfNc2.js → 7-DmgY6drC.js} +6 -6
- package/build/server/chunks/7-DmgY6drC.js.map +1 -0
- package/build/server/chunks/8-Bku8n4Ko.js +9 -0
- package/build/server/chunks/8-Bku8n4Ko.js.map +1 -0
- package/build/server/chunks/{7-C_AGqUAU.js → 9-nwlpMH7t.js} +5 -5
- package/build/server/chunks/9-nwlpMH7t.js.map +1 -0
- package/build/server/chunks/AgentSidebar-CZIBBsSh.js +141 -0
- package/build/server/chunks/AgentSidebar-CZIBBsSh.js.map +1 -0
- package/build/server/chunks/Button-OUO_MioZ.js +44 -0
- package/build/server/chunks/Button-OUO_MioZ.js.map +1 -0
- package/build/server/chunks/ContextEditor-stz14-2o.js +48 -0
- package/build/server/chunks/ContextEditor-stz14-2o.js.map +1 -0
- package/build/server/chunks/{Dropdown-B-UCol1v.js → Dropdown-BTr_XiAm.js} +2 -2
- package/build/server/chunks/Dropdown-BTr_XiAm.js.map +1 -0
- package/build/server/chunks/{Input-DLAEH36y.js → Input-B_jIG2tD.js} +2 -2
- package/build/server/chunks/Input-B_jIG2tD.js.map +1 -0
- package/build/server/chunks/{Icon-DDJ9D6Sq.js → Link-DaOJVbdB.js} +25 -42
- package/build/server/chunks/Link-DaOJVbdB.js.map +1 -0
- package/build/server/chunks/{Panel-KZDoG3_L.js → Panel-CmvYn6IC.js} +2 -2
- package/build/server/chunks/Panel-CmvYn6IC.js.map +1 -0
- package/build/server/chunks/Tab-n348Mfiq.js +84 -0
- package/build/server/chunks/Tab-n348Mfiq.js.map +1 -0
- package/build/server/chunks/_layout.svelte-CP6tz6DB.js +62 -0
- package/build/server/chunks/_layout.svelte-CP6tz6DB.js.map +1 -0
- package/build/server/chunks/{_layout.svelte-BoAJDYC1.js → _layout.svelte-CvGX8M4U.js} +68 -18
- package/build/server/chunks/_layout.svelte-CvGX8M4U.js.map +1 -0
- package/build/server/chunks/{_page.svelte-CdEfc0bc.js → _page.svelte-AHHrodUG.js} +94 -86
- package/build/server/chunks/_page.svelte-AHHrodUG.js.map +1 -0
- package/build/server/chunks/_page.svelte-Bm-iBjXM.js +80 -0
- package/build/server/chunks/_page.svelte-Bm-iBjXM.js.map +1 -0
- package/build/server/chunks/_page.svelte-D5Xqk3cI.js +52 -0
- package/build/server/chunks/_page.svelte-D5Xqk3cI.js.map +1 -0
- package/build/server/chunks/{_page.svelte-CNhxx79k.js → _page.svelte-DKBFi-JF.js} +202 -240
- package/build/server/chunks/_page.svelte-DKBFi-JF.js.map +1 -0
- package/build/server/chunks/{_page.svelte-DQUdiD4S.js → _page.svelte-DSefP5E9.js} +6 -5
- package/build/server/chunks/_page.svelte-DSefP5E9.js.map +1 -0
- package/build/server/chunks/{_page.svelte-kLLxi8vG.js → _page.svelte-Dldwxu4m.js} +28 -6
- package/build/server/chunks/_page.svelte-Dldwxu4m.js.map +1 -0
- package/build/server/chunks/{_page.svelte-Cc0DAAQW.js → _page.svelte-lU1-SHJj.js} +5 -4
- package/build/server/chunks/_page.svelte-lU1-SHJj.js.map +1 -0
- package/build/server/chunks/{_page.svelte-nsIWq28L.js → _page.svelte-vGR-ltk7.js} +7 -27
- package/build/server/chunks/_page.svelte-vGR-ltk7.js.map +1 -0
- package/build/server/chunks/{_server.ts-d0Tii8aZ.js → _server.ts-3D9tpnMZ.js} +3 -2
- package/build/server/chunks/_server.ts-3D9tpnMZ.js.map +1 -0
- package/build/server/chunks/{_server.ts-BBxm_xV1.js → _server.ts-B56wS_0L.js} +4 -1
- package/build/server/chunks/_server.ts-B56wS_0L.js.map +1 -0
- package/build/server/chunks/{_server.ts-CLKPeFqF.js → _server.ts-BCBY3OIY.js} +3 -2
- package/build/server/chunks/_server.ts-BCBY3OIY.js.map +1 -0
- package/build/server/chunks/{_server.ts-BmZBSYvJ.js → _server.ts-BCfiuZgS.js} +19 -8
- package/build/server/chunks/_server.ts-BCfiuZgS.js.map +1 -0
- package/build/server/chunks/_server.ts-BkL-sSQA.js.map +1 -1
- package/build/server/chunks/{_server.ts-DEHw6op6.js → _server.ts-D0C3cRDU.js} +3 -2
- package/build/server/chunks/_server.ts-D0C3cRDU.js.map +1 -0
- package/build/server/chunks/{_server.ts-BYDdbqNr.js → _server.ts-Dc989xbA.js} +3 -2
- package/build/server/chunks/_server.ts-Dc989xbA.js.map +1 -0
- package/build/server/chunks/_server.ts-Ddto8x_p.js.map +1 -1
- package/build/server/chunks/{_server.ts-BIcKE9RQ.js → _server.ts-I-18L-Sg.js} +3 -2
- package/build/server/chunks/_server.ts-I-18L-Sg.js.map +1 -0
- package/build/server/chunks/_server.ts-iuWHhHZx.js +629 -0
- package/build/server/chunks/_server.ts-iuWHhHZx.js.map +1 -0
- package/build/server/chunks/agents-context-C4MM7lSl.js +6 -0
- package/build/server/chunks/agents-context-C4MM7lSl.js.map +1 -0
- package/build/server/chunks/{client2-tp0-IQU0.js → client-BhnXtftB.js} +6 -29
- package/build/server/chunks/client-BhnXtftB.js.map +1 -0
- package/build/server/chunks/{index2-CVBATI2G.js → context-Dy9MY1Z0.js} +253 -965
- package/build/server/chunks/context-Dy9MY1Z0.js.map +1 -0
- package/build/server/chunks/{data-CbXDDeDB.js → data-BltJc-uF.js} +29 -89
- package/build/server/chunks/data-BltJc-uF.js.map +1 -0
- package/build/server/chunks/error.svelte-Cn6umEWY.js +14 -0
- package/build/server/chunks/error.svelte-Cn6umEWY.js.map +1 -0
- package/build/server/chunks/errors-B8liwVcD.js +17 -0
- package/build/server/chunks/errors-B8liwVcD.js.map +1 -0
- package/build/server/chunks/{events-A18hGvKp.js → events-BFcZEt66.js} +3 -9
- package/build/server/chunks/events-BFcZEt66.js.map +1 -0
- package/build/server/chunks/{index-BoStl4QO.js → index-C0ds_eUO.js} +8 -3
- package/build/server/chunks/index-C0ds_eUO.js.map +1 -0
- package/build/server/chunks/index-server-CMCI3p2Y.js +18 -0
- package/build/server/chunks/index-server-CMCI3p2Y.js.map +1 -0
- package/build/server/chunks/index2-B1rkViAM.js +860 -0
- package/build/server/chunks/index2-B1rkViAM.js.map +1 -0
- package/build/server/chunks/index3-CVYj52gl.js.map +1 -1
- package/build/server/chunks/index4-DSZuWW-A.js +47 -0
- package/build/server/chunks/index4-DSZuWW-A.js.map +1 -0
- package/build/server/chunks/main-DL75vM4l.js +2250 -0
- package/build/server/chunks/main-DL75vM4l.js.map +1 -0
- package/build/server/chunks/{state.svelte-Dze7OxC_.js → state.svelte-CBgyohE1.js} +2 -2
- package/build/server/chunks/state.svelte-CBgyohE1.js.map +1 -0
- package/build/server/chunks/suite-4--Gr0jF.js +60 -0
- package/build/server/chunks/suite-4--Gr0jF.js.map +1 -0
- package/build/server/chunks/ws-client-CyJORDFw.js +98 -0
- package/build/server/chunks/ws-client-CyJORDFw.js.map +1 -0
- package/build/server/index.js +167 -90
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +83 -75
- package/build/server/manifest.js.map +1 -1
- package/package.json +3 -1
- package/src/ws-server/projects.ts +82 -9
- package/build/client/_app/immutable/assets/0.7xdY7TSX.css +0 -1
- package/build/client/_app/immutable/assets/0.7xdY7TSX.css.br +0 -0
- package/build/client/_app/immutable/assets/0.7xdY7TSX.css.gz +0 -0
- package/build/client/_app/immutable/assets/10.C1o6a69m.css +0 -1
- package/build/client/_app/immutable/assets/10.C1o6a69m.css.br +0 -1
- package/build/client/_app/immutable/assets/10.C1o6a69m.css.gz +0 -0
- package/build/client/_app/immutable/assets/4.858mUNwe.css +0 -1
- package/build/client/_app/immutable/assets/4.858mUNwe.css.br +0 -0
- package/build/client/_app/immutable/assets/4.858mUNwe.css.gz +0 -0
- package/build/client/_app/immutable/assets/6.CD1QZ0pt.css +0 -1
- package/build/client/_app/immutable/assets/6.CD1QZ0pt.css.br +0 -0
- package/build/client/_app/immutable/assets/6.CD1QZ0pt.css.gz +0 -0
- package/build/client/_app/immutable/chunks/2PVbuV1X.js +0 -1
- package/build/client/_app/immutable/chunks/2PVbuV1X.js.br +0 -1
- package/build/client/_app/immutable/chunks/2PVbuV1X.js.gz +0 -0
- package/build/client/_app/immutable/chunks/9OGf6H2n.js +0 -1
- package/build/client/_app/immutable/chunks/9OGf6H2n.js.br +0 -2
- package/build/client/_app/immutable/chunks/9OGf6H2n.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B8bx6-qu.js.br +0 -1
- package/build/client/_app/immutable/chunks/B8bx6-qu.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BDTuVTVZ.js +0 -1
- package/build/client/_app/immutable/chunks/BDTuVTVZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/BDTuVTVZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BTGV3Gq0.js +0 -8
- package/build/client/_app/immutable/chunks/BTGV3Gq0.js.br +0 -0
- package/build/client/_app/immutable/chunks/BTGV3Gq0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BUoURvZ_.js +0 -1
- package/build/client/_app/immutable/chunks/BUoURvZ_.js.br +0 -0
- package/build/client/_app/immutable/chunks/BUoURvZ_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BdOqksoz.js +0 -1
- package/build/client/_app/immutable/chunks/BdOqksoz.js.br +0 -0
- package/build/client/_app/immutable/chunks/BdOqksoz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Be371ezp.js +0 -2
- package/build/client/_app/immutable/chunks/Be371ezp.js.br +0 -0
- package/build/client/_app/immutable/chunks/Be371ezp.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bmx4ManB.js +0 -1
- package/build/client/_app/immutable/chunks/Bmx4ManB.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bmx4ManB.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C2Y9UxTx.js +0 -1
- package/build/client/_app/immutable/chunks/C2Y9UxTx.js.br +0 -0
- package/build/client/_app/immutable/chunks/C2Y9UxTx.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C681lv5i.js +0 -3
- package/build/client/_app/immutable/chunks/C681lv5i.js.br +0 -0
- package/build/client/_app/immutable/chunks/C681lv5i.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CYuXdPQc.js +0 -1
- package/build/client/_app/immutable/chunks/CYuXdPQc.js.br +0 -0
- package/build/client/_app/immutable/chunks/CYuXdPQc.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CpZGG0E7.js +0 -1
- package/build/client/_app/immutable/chunks/CpZGG0E7.js.br +0 -0
- package/build/client/_app/immutable/chunks/CpZGG0E7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CpdYAO0i.js +0 -1
- package/build/client/_app/immutable/chunks/CpdYAO0i.js.br +0 -0
- package/build/client/_app/immutable/chunks/CpdYAO0i.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CtpS-ZbM.js +0 -1
- package/build/client/_app/immutable/chunks/CtpS-ZbM.js.br +0 -0
- package/build/client/_app/immutable/chunks/CtpS-ZbM.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D5O98MXA.js.br +0 -0
- package/build/client/_app/immutable/chunks/D5O98MXA.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DIiF2tGe.js +0 -1
- package/build/client/_app/immutable/chunks/DIiF2tGe.js.br +0 -0
- package/build/client/_app/immutable/chunks/DIiF2tGe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D_4dC3JZ.js +0 -1
- package/build/client/_app/immutable/chunks/D_4dC3JZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/D_4dC3JZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DveC87gn.js +0 -33
- package/build/client/_app/immutable/chunks/DveC87gn.js.br +0 -0
- package/build/client/_app/immutable/chunks/DveC87gn.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ISgeSat5.js +0 -1
- package/build/client/_app/immutable/chunks/ISgeSat5.js.br +0 -0
- package/build/client/_app/immutable/chunks/ISgeSat5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/uzczSfVx.js +0 -3
- package/build/client/_app/immutable/chunks/uzczSfVx.js.br +0 -0
- package/build/client/_app/immutable/chunks/uzczSfVx.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CSVt0Fuk.js +0 -2
- package/build/client/_app/immutable/entry/app.CSVt0Fuk.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CSVt0Fuk.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BQnEMq3G.js +0 -1
- package/build/client/_app/immutable/entry/start.BQnEMq3G.js.br +0 -2
- package/build/client/_app/immutable/entry/start.BQnEMq3G.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.BFGm6g4L.js +0 -1
- package/build/client/_app/immutable/nodes/0.BFGm6g4L.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.BFGm6g4L.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.B_l4Mw8E.js +0 -1
- package/build/client/_app/immutable/nodes/1.B_l4Mw8E.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.B_l4Mw8E.js.gz +0 -0
- package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js +0 -1
- package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js.br +0 -0
- package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DPpr5BK7.js +0 -3
- package/build/client/_app/immutable/nodes/2.DPpr5BK7.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DPpr5BK7.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.BokOq116.js +0 -12
- package/build/client/_app/immutable/nodes/4.BokOq116.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.BokOq116.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js +0 -1
- package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.7qo5WmXj.js +0 -38
- package/build/client/_app/immutable/nodes/6.7qo5WmXj.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.7qo5WmXj.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.CvDadi99.js +0 -1
- package/build/client/_app/immutable/nodes/7.CvDadi99.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.CvDadi99.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.CLZUC68b.js +0 -1
- package/build/client/_app/immutable/nodes/8.CLZUC68b.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.CLZUC68b.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.BCC-2Any.js +0 -1
- package/build/client/_app/immutable/nodes/9.BCC-2Any.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.BCC-2Any.js.gz +0 -0
- package/build/server/chunks/0-DMd6Dk79.js +0 -9
- package/build/server/chunks/0-DMd6Dk79.js.map +0 -1
- package/build/server/chunks/1-Cwk3hpe9.js +0 -9
- package/build/server/chunks/10-Ci_AhluU.js +0 -9
- package/build/server/chunks/10-Ci_AhluU.js.map +0 -1
- package/build/server/chunks/2-BLxdw-8l.js +0 -9
- package/build/server/chunks/2-BLxdw-8l.js.map +0 -1
- package/build/server/chunks/3-DGFu_uy6.js +0 -19
- package/build/server/chunks/3-DGFu_uy6.js.map +0 -1
- package/build/server/chunks/4-MwbWFUCO.js +0 -22
- package/build/server/chunks/4-MwbWFUCO.js.map +0 -1
- package/build/server/chunks/5-p3BDfNc2.js.map +0 -1
- package/build/server/chunks/6-CK3NUjnH.js +0 -9
- package/build/server/chunks/6-CK3NUjnH.js.map +0 -1
- package/build/server/chunks/7-C_AGqUAU.js.map +0 -1
- package/build/server/chunks/8-Dr1vf8BH.js +0 -9
- package/build/server/chunks/8-Dr1vf8BH.js.map +0 -1
- package/build/server/chunks/9-DAsQ5XZx.js +0 -9
- package/build/server/chunks/9-DAsQ5XZx.js.map +0 -1
- package/build/server/chunks/AgentDropdown-C3XtwkaV.js +0 -162
- package/build/server/chunks/AgentDropdown-C3XtwkaV.js.map +0 -1
- package/build/server/chunks/Dropdown-B-UCol1v.js.map +0 -1
- package/build/server/chunks/Icon-DDJ9D6Sq.js.map +0 -1
- package/build/server/chunks/Input-DLAEH36y.js.map +0 -1
- package/build/server/chunks/Panel-KZDoG3_L.js.map +0 -1
- package/build/server/chunks/_layout.svelte-22nlfSFq.js +0 -9
- package/build/server/chunks/_layout.svelte-22nlfSFq.js.map +0 -1
- package/build/server/chunks/_layout.svelte-BoAJDYC1.js.map +0 -1
- package/build/server/chunks/_page.svelte-CNhxx79k.js.map +0 -1
- package/build/server/chunks/_page.svelte-Cc0DAAQW.js.map +0 -1
- package/build/server/chunks/_page.svelte-CdEfc0bc.js.map +0 -1
- package/build/server/chunks/_page.svelte-DQUdiD4S.js.map +0 -1
- package/build/server/chunks/_page.svelte-kLLxi8vG.js.map +0 -1
- package/build/server/chunks/_page.svelte-nsIWq28L.js.map +0 -1
- package/build/server/chunks/_server.ts-BBxm_xV1.js.map +0 -1
- package/build/server/chunks/_server.ts-BIcKE9RQ.js.map +0 -1
- package/build/server/chunks/_server.ts-BYDdbqNr.js.map +0 -1
- package/build/server/chunks/_server.ts-BmZBSYvJ.js.map +0 -1
- package/build/server/chunks/_server.ts-CLKPeFqF.js.map +0 -1
- package/build/server/chunks/_server.ts-DEHw6op6.js.map +0 -1
- package/build/server/chunks/_server.ts-DTyPQO2I.js +0 -93
- package/build/server/chunks/_server.ts-DTyPQO2I.js.map +0 -1
- package/build/server/chunks/_server.ts-d0Tii8aZ.js.map +0 -1
- package/build/server/chunks/client-DpkplAAP.js +0 -25
- package/build/server/chunks/client-DpkplAAP.js.map +0 -1
- package/build/server/chunks/client2-tp0-IQU0.js.map +0 -1
- package/build/server/chunks/context-DVQH5kJk.js +0 -113
- package/build/server/chunks/context-DVQH5kJk.js.map +0 -1
- package/build/server/chunks/data-CbXDDeDB.js.map +0 -1
- package/build/server/chunks/error.svelte-DNcHZkvg.js +0 -29
- package/build/server/chunks/error.svelte-DNcHZkvg.js.map +0 -1
- package/build/server/chunks/events-A18hGvKp.js.map +0 -1
- package/build/server/chunks/index-BoStl4QO.js.map +0 -1
- package/build/server/chunks/index2-CVBATI2G.js.map +0 -1
- package/build/server/chunks/state.svelte-Dze7OxC_.js.map +0 -1
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { readFile, writeFile, access } from 'node:fs/promises'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { readdir } from 'node:fs/promises'
|
|
4
|
+
|
|
5
|
+
// CSV functionality removed; this module only handles project paths and config JSON.
|
|
6
|
+
|
|
7
|
+
// Resolve the base path for a given project (folder containing workflows.ts)
|
|
8
|
+
export async function getProjectBasePath(project: string): Promise<string> {
|
|
9
|
+
const projectsDir = 'projects'
|
|
10
|
+
console.log('[academy] getProjectBasePath', { project, cwd: process.cwd(), projectsDir })
|
|
11
|
+
|
|
12
|
+
// Fast path: direct read (works with symlinks)
|
|
13
|
+
const directDir = path.join(projectsDir, project)
|
|
14
|
+
const directPkg = path.join(directDir, 'package.json')
|
|
15
|
+
try {
|
|
16
|
+
const raw = await readFile(directPkg, 'utf8')
|
|
17
|
+
const pkg = JSON.parse(raw)
|
|
18
|
+
const agentsRoot = pkg?.bosun?.root ?? 'src/bosun/workflows.ts'
|
|
19
|
+
const agentsRootPath = path.resolve(directDir, agentsRoot)
|
|
20
|
+
const basePath = path.dirname(agentsRootPath)
|
|
21
|
+
console.log('[academy] basePath (direct)', { directPkg, agentsRoot, basePath })
|
|
22
|
+
return basePath
|
|
23
|
+
} catch (e: any) {
|
|
24
|
+
console.warn('[academy] direct package.json read failed', { directPkg, error: e?.message })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Fallback: scan projects directory (include symlinks)
|
|
28
|
+
let entries: any[] = []
|
|
29
|
+
try {
|
|
30
|
+
entries = await readdir(projectsDir, { withFileTypes: true } as any)
|
|
31
|
+
console.log(
|
|
32
|
+
'[academy] projects entries',
|
|
33
|
+
entries.map((ent: any) => ({
|
|
34
|
+
name: ent.name,
|
|
35
|
+
isDir: ent.isDirectory?.(),
|
|
36
|
+
isLink: ent.isSymbolicLink?.()
|
|
37
|
+
}))
|
|
38
|
+
)
|
|
39
|
+
} catch (err: any) {
|
|
40
|
+
console.warn('[academy] projects folder not found; using CWD as fallback', {
|
|
41
|
+
projectsDir,
|
|
42
|
+
error: err?.message
|
|
43
|
+
})
|
|
44
|
+
// Attempt to derive base path from cwd package.json (if present)
|
|
45
|
+
const cwd = process.cwd()
|
|
46
|
+
const cwdPkg = path.join(cwd, 'package.json')
|
|
47
|
+
try {
|
|
48
|
+
const raw = await readFile(cwdPkg, 'utf8')
|
|
49
|
+
const pkg = JSON.parse(raw)
|
|
50
|
+
const agentsRoot = pkg?.bosun?.root ?? 'src/bosun/workflows.ts'
|
|
51
|
+
const agentsRootPath = path.resolve(cwd, agentsRoot)
|
|
52
|
+
const basePath = path.dirname(agentsRootPath)
|
|
53
|
+
console.log('[academy] basePath (cwd fallback with pkg)', { cwdPkg, agentsRoot, basePath })
|
|
54
|
+
return basePath
|
|
55
|
+
} catch {
|
|
56
|
+
console.log('[academy] returning CWD as basePath (no pkg fallback)')
|
|
57
|
+
return cwd
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const ent of entries) {
|
|
62
|
+
const name = ent.name
|
|
63
|
+
if (name !== project) continue
|
|
64
|
+
const dir = path.join(projectsDir, name)
|
|
65
|
+
const pkgPath = path.join(dir, 'package.json')
|
|
66
|
+
try {
|
|
67
|
+
const raw = await readFile(pkgPath, 'utf8')
|
|
68
|
+
const pkg = JSON.parse(raw)
|
|
69
|
+
const agentsRoot = pkg?.bosun?.root ?? 'src/bosun/workflows.ts'
|
|
70
|
+
const agentsRootPath = path.resolve(dir, agentsRoot)
|
|
71
|
+
const basePath = path.dirname(agentsRootPath)
|
|
72
|
+
console.log('[academy] basePath (scanned)', { pkgPath, agentsRoot, basePath })
|
|
73
|
+
return basePath
|
|
74
|
+
} catch (e: any) {
|
|
75
|
+
console.warn('[academy] failed reading candidate package.json', {
|
|
76
|
+
pkgPath,
|
|
77
|
+
error: e?.message
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
console.error('[academy] project not found (after scan)', { project, projectsDir })
|
|
83
|
+
throw new Error(`Project not found: ${project}`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Resolve the project root directory. Supports two modes:
|
|
87
|
+
// - Bosun dev (projects/<project>)
|
|
88
|
+
// - CLI from inside a project repo (cwd)
|
|
89
|
+
export async function getProjectRootPath(project: string): Promise<string> {
|
|
90
|
+
const projectsDir = 'projects'
|
|
91
|
+
// 1) Direct projects/<project>
|
|
92
|
+
const directDir = path.join(projectsDir, project)
|
|
93
|
+
const directPkg = path.join(directDir, 'package.json')
|
|
94
|
+
try {
|
|
95
|
+
await access(directPkg)
|
|
96
|
+
return directDir
|
|
97
|
+
} catch {}
|
|
98
|
+
|
|
99
|
+
// 2) If projects folder missing or inaccessible, fallback to CWD if it looks like a project
|
|
100
|
+
try {
|
|
101
|
+
const cwd = process.cwd()
|
|
102
|
+
const cwdPkg = path.join(cwd, 'package.json')
|
|
103
|
+
await access(cwdPkg)
|
|
104
|
+
return cwd
|
|
105
|
+
} catch {}
|
|
106
|
+
|
|
107
|
+
// 3) Scan projects folder for named entry
|
|
108
|
+
try {
|
|
109
|
+
const entries = (await readdir(projectsDir, { withFileTypes: true } as any)) as any[]
|
|
110
|
+
for (const ent of entries as any[]) {
|
|
111
|
+
const entryName = (ent as any).name ?? String(ent)
|
|
112
|
+
if (entryName !== project) continue
|
|
113
|
+
const dir = path.join(projectsDir, entryName)
|
|
114
|
+
const pkgPath = path.join(dir, 'package.json')
|
|
115
|
+
try {
|
|
116
|
+
await access(pkgPath)
|
|
117
|
+
return dir
|
|
118
|
+
} catch {}
|
|
119
|
+
}
|
|
120
|
+
} catch {}
|
|
121
|
+
|
|
122
|
+
throw new Error(`Project not found: ${project}`)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Removed: all CSV helpers (read/write)
|
|
126
|
+
|
|
127
|
+
export async function tryReadConfig(
|
|
128
|
+
project: string,
|
|
129
|
+
agent: string
|
|
130
|
+
): Promise<{
|
|
131
|
+
repeats?: number
|
|
132
|
+
concurrency?: number
|
|
133
|
+
} | null> {
|
|
134
|
+
const base = await getProjectBasePath(project)
|
|
135
|
+
const jsonPath = path.join(base, `${agent}.config.json`)
|
|
136
|
+
try {
|
|
137
|
+
await access(jsonPath)
|
|
138
|
+
const raw = await readFile(jsonPath, 'utf8')
|
|
139
|
+
const obj = JSON.parse(raw)
|
|
140
|
+
return obj
|
|
141
|
+
} catch {
|
|
142
|
+
return null
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function writeConfig(
|
|
147
|
+
project: string,
|
|
148
|
+
agent: string,
|
|
149
|
+
config: { repeats?: number; concurrency?: number }
|
|
150
|
+
): Promise<void> {
|
|
151
|
+
const base = await getProjectBasePath(project)
|
|
152
|
+
const jsonPath = path.join(base, `${agent}.config.json`)
|
|
153
|
+
const body = JSON.stringify(config ?? {}, null, 2)
|
|
154
|
+
await writeFile(jsonPath, body, 'utf8')
|
|
155
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { tryReadConfig, writeConfig, getProjectRootPath } from './csv'
|
|
2
|
+
import { readdir, readFile } from 'node:fs/promises'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import {
|
|
5
|
+
readSuite,
|
|
6
|
+
writeSuite,
|
|
7
|
+
getSuiteFilePath,
|
|
8
|
+
upsertSuiteMeta,
|
|
9
|
+
type TestRow as SuiteRow
|
|
10
|
+
} from './suite'
|
|
11
|
+
|
|
12
|
+
export type CsvRow = Record<string, string>
|
|
13
|
+
|
|
14
|
+
export type TestRow = SuiteRow
|
|
15
|
+
|
|
16
|
+
export type RunConfig = {
|
|
17
|
+
repeats?: number
|
|
18
|
+
concurrency?: number
|
|
19
|
+
defaultContext?: Record<string, unknown>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type RunResult = {
|
|
23
|
+
success: boolean
|
|
24
|
+
result: string
|
|
25
|
+
evaluation: string
|
|
26
|
+
rendered_prompt: string
|
|
27
|
+
received_prompt: string
|
|
28
|
+
stringified_conversation: string
|
|
29
|
+
received_context: string
|
|
30
|
+
traces: any[]
|
|
31
|
+
errors: string
|
|
32
|
+
logs: string[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type TestResult = {
|
|
36
|
+
test_id: string
|
|
37
|
+
success_rate_percent?: number
|
|
38
|
+
success_rate?: string
|
|
39
|
+
results: RunResult[]
|
|
40
|
+
report_timestamp: string // ISO
|
|
41
|
+
is_old: boolean
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Utility: ensure each row has an id; persist if any are missing.
|
|
45
|
+
export async function loadTests(
|
|
46
|
+
project: string,
|
|
47
|
+
agent: string
|
|
48
|
+
): Promise<{ rows: TestRow[]; headers: string[] }> {
|
|
49
|
+
const suite = await readSuite(project, agent)
|
|
50
|
+
// Ensure ids exist; write back if any are missing
|
|
51
|
+
let changed = false
|
|
52
|
+
const rows: TestRow[] = suite.tests.map((r) => {
|
|
53
|
+
const id = (r.id || '').trim()
|
|
54
|
+
if (!id) changed = true
|
|
55
|
+
return { ...r, id: id || globalThis.crypto?.randomUUID?.() || randomUUID() }
|
|
56
|
+
})
|
|
57
|
+
if (changed) {
|
|
58
|
+
await writeSuite(project, agent, { ...suite, tests: rows })
|
|
59
|
+
}
|
|
60
|
+
const headers = [
|
|
61
|
+
'id',
|
|
62
|
+
'pinned',
|
|
63
|
+
'scenario',
|
|
64
|
+
'author',
|
|
65
|
+
'category',
|
|
66
|
+
'assertion_type',
|
|
67
|
+
'assertion_value',
|
|
68
|
+
'conversation',
|
|
69
|
+
'expected_output',
|
|
70
|
+
'timeout',
|
|
71
|
+
'similarity_threshold',
|
|
72
|
+
'context'
|
|
73
|
+
]
|
|
74
|
+
return { rows, headers }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Utility: update a single row by id and write the CSV
|
|
78
|
+
export async function patchTest(
|
|
79
|
+
project: string,
|
|
80
|
+
agent: string,
|
|
81
|
+
id: string,
|
|
82
|
+
patch: Partial<TestRow>
|
|
83
|
+
): Promise<TestRow | null> {
|
|
84
|
+
const suite = await readSuite(project, agent)
|
|
85
|
+
const idx = suite.tests.findIndex((r) => r.id === id)
|
|
86
|
+
if (idx < 0) return null
|
|
87
|
+
const current = suite.tests[idx]
|
|
88
|
+
const updated: TestRow = {
|
|
89
|
+
id: id,
|
|
90
|
+
pinned:
|
|
91
|
+
String(patch.pinned ?? current.pinned ?? 'TRUE').toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE',
|
|
92
|
+
scenario: String(patch.scenario ?? current.scenario ?? ''),
|
|
93
|
+
author: String(patch.author ?? (current as any).author ?? ''),
|
|
94
|
+
category: String(patch.category ?? (current as any).category ?? ''),
|
|
95
|
+
assertion_type: String(patch.assertion_type ?? current.assertion_type ?? 'llm-rubric'),
|
|
96
|
+
assertion_value: String(patch.assertion_value ?? current.assertion_value ?? ''),
|
|
97
|
+
conversation: String(patch.conversation ?? current.conversation ?? ''),
|
|
98
|
+
expected_output: String(patch.expected_output ?? current.expected_output ?? ''),
|
|
99
|
+
timeout: String(patch.timeout ?? current.timeout ?? '0'),
|
|
100
|
+
similarity_threshold: String(
|
|
101
|
+
patch.similarity_threshold ?? current.similarity_threshold ?? '60'
|
|
102
|
+
),
|
|
103
|
+
context: typeof patch.context === 'string' ? patch.context : (current.context ?? '')
|
|
104
|
+
}
|
|
105
|
+
const nextRows = suite.tests.map((r, i) => (i === idx ? updated : r))
|
|
106
|
+
await writeSuite(project, agent, { ...suite, tests: nextRows })
|
|
107
|
+
return updated
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Batch update multiple rows in a single read/write to avoid race conditions
|
|
111
|
+
export async function patchTestsBatch(
|
|
112
|
+
project: string,
|
|
113
|
+
agent: string,
|
|
114
|
+
updates: Array<{ id: string; patch: Partial<TestRow> }>
|
|
115
|
+
): Promise<TestRow[]> {
|
|
116
|
+
if (!Array.isArray(updates) || updates.length === 0) return []
|
|
117
|
+
const suite = await readSuite(project, agent)
|
|
118
|
+
const byId = new Map(suite.tests.map((r) => [r.id, r]))
|
|
119
|
+
const updatedRows: TestRow[] = []
|
|
120
|
+
for (const { id, patch } of updates) {
|
|
121
|
+
const current = byId.get(id)
|
|
122
|
+
if (!current) continue
|
|
123
|
+
const updated: TestRow = {
|
|
124
|
+
id: id,
|
|
125
|
+
pinned:
|
|
126
|
+
String(patch.pinned ?? current.pinned ?? 'TRUE').toUpperCase() === 'TRUE'
|
|
127
|
+
? 'TRUE'
|
|
128
|
+
: 'FALSE',
|
|
129
|
+
scenario: String(patch.scenario ?? current.scenario ?? ''),
|
|
130
|
+
author: String(patch.author ?? (current as any).author ?? ''),
|
|
131
|
+
category: String(patch.category ?? (current as any).category ?? ''),
|
|
132
|
+
assertion_type: String(patch.assertion_type ?? current.assertion_type ?? 'llm-rubric'),
|
|
133
|
+
assertion_value: String(patch.assertion_value ?? current.assertion_value ?? ''),
|
|
134
|
+
conversation: String(patch.conversation ?? current.conversation ?? ''),
|
|
135
|
+
expected_output: String(patch.expected_output ?? current.expected_output ?? ''),
|
|
136
|
+
timeout: String(patch.timeout ?? current.timeout ?? '0'),
|
|
137
|
+
similarity_threshold: String(
|
|
138
|
+
patch.similarity_threshold ?? current.similarity_threshold ?? '60'
|
|
139
|
+
),
|
|
140
|
+
context: typeof patch.context === 'string' ? patch.context : (current.context ?? '')
|
|
141
|
+
}
|
|
142
|
+
byId.set(id, updated)
|
|
143
|
+
updatedRows.push(updated)
|
|
144
|
+
}
|
|
145
|
+
const nextRows: TestRow[] = suite.tests.map((r) => byId.get(r.id) ?? r)
|
|
146
|
+
await writeSuite(project, agent, { ...suite, tests: nextRows })
|
|
147
|
+
return updatedRows
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Add a new row at the top
|
|
151
|
+
export async function addTest(
|
|
152
|
+
project: string,
|
|
153
|
+
agent: string,
|
|
154
|
+
seed?: Partial<TestRow>
|
|
155
|
+
): Promise<TestRow> {
|
|
156
|
+
const suite = await readSuite(project, agent).catch(() => ({ version: 1, tests: [] }))
|
|
157
|
+
const id = globalThis.crypto?.randomUUID?.() || randomUUID()
|
|
158
|
+
const row: TestRow = {
|
|
159
|
+
id,
|
|
160
|
+
pinned:
|
|
161
|
+
((seed?.pinned || 'TRUE') as any).toString().toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE',
|
|
162
|
+
scenario: seed?.scenario ?? 'New scenario',
|
|
163
|
+
author: seed?.author ?? '',
|
|
164
|
+
category: seed?.category ?? '',
|
|
165
|
+
assertion_type: seed?.assertion_type ?? 'llm-rubric',
|
|
166
|
+
assertion_value: seed?.assertion_value ?? '',
|
|
167
|
+
conversation: seed?.conversation ?? 'user: ...',
|
|
168
|
+
expected_output: seed?.expected_output ?? '',
|
|
169
|
+
timeout: String((seed as any)?.timeout ?? '0'),
|
|
170
|
+
similarity_threshold: String((seed as any)?.similarity_threshold ?? '60'),
|
|
171
|
+
context: typeof seed?.context === 'string' ? (seed?.context as string) : '{}'
|
|
172
|
+
}
|
|
173
|
+
const nextRows = [row, ...suite.tests]
|
|
174
|
+
await writeSuite(project, agent, { ...(suite as any), tests: nextRows })
|
|
175
|
+
return row
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export async function deleteTest(project: string, agent: string, id: string): Promise<boolean> {
|
|
179
|
+
const suite = await readSuite(project, agent)
|
|
180
|
+
const filtered = suite.tests.filter((r) => r.id !== id)
|
|
181
|
+
if (filtered.length === suite.tests.length) return false
|
|
182
|
+
await writeSuite(project, agent, { ...suite, tests: filtered })
|
|
183
|
+
return true
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export async function reorderTests(project: string, agent: string, order: string[]): Promise<void> {
|
|
187
|
+
const suite = await readSuite(project, agent)
|
|
188
|
+
const map = new Map(suite.tests.map((r) => [r.id, r]))
|
|
189
|
+
const next: TestRow[] = []
|
|
190
|
+
for (const id of order) {
|
|
191
|
+
const r = map.get(id)
|
|
192
|
+
if (r) {
|
|
193
|
+
next.push(r)
|
|
194
|
+
map.delete(id)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Append any rows that were not included in order (safety)
|
|
198
|
+
for (const r of map.values()) next.push(r)
|
|
199
|
+
await writeSuite(project, agent, { ...suite, tests: next })
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export async function loadConfig(project: string, agent: string): Promise<RunConfig> {
|
|
203
|
+
const cfg = (await tryReadConfig(project, agent)) || {}
|
|
204
|
+
// Always source defaultContext from the suite meta, not config
|
|
205
|
+
let defaultContext: Record<string, unknown> = {}
|
|
206
|
+
try {
|
|
207
|
+
const suite = await (await import('./suite')).readSuite(project, agent)
|
|
208
|
+
defaultContext = (suite.meta?.defaultContext as any) || {}
|
|
209
|
+
} catch {
|
|
210
|
+
// ignore
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
repeats: typeof (cfg as any).repeats === 'number' ? (cfg as any).repeats : 1,
|
|
214
|
+
concurrency: typeof (cfg as any).concurrency === 'number' ? (cfg as any).concurrency : 1,
|
|
215
|
+
defaultContext
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export async function saveConfig(project: string, agent: string, cfg: RunConfig): Promise<void> {
|
|
220
|
+
// Merge patch into existing config, persisting only repeats/concurrency
|
|
221
|
+
const current = (await tryReadConfig(project, agent)) || {}
|
|
222
|
+
const next = {
|
|
223
|
+
repeats: typeof cfg.repeats === 'number' ? cfg.repeats : (current as any).repeats,
|
|
224
|
+
concurrency:
|
|
225
|
+
typeof cfg.concurrency === 'number' ? cfg.concurrency : (current as any).concurrency
|
|
226
|
+
}
|
|
227
|
+
await writeConfig(project, agent, next)
|
|
228
|
+
// Persist defaultContext exclusively in the suite meta (do not write to config)
|
|
229
|
+
if (cfg && typeof cfg.defaultContext !== 'undefined') {
|
|
230
|
+
await upsertSuiteMeta(project, agent, { defaultContext: cfg.defaultContext })
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// We no longer migrate legacy reports automatically. Please update old reports manually.
|
|
235
|
+
|
|
236
|
+
export async function loadLatestResultsByTest(
|
|
237
|
+
project: string,
|
|
238
|
+
agent: string
|
|
239
|
+
): Promise<Record<string, TestResult>> {
|
|
240
|
+
const projectRoot = await getProjectRootPath(project)
|
|
241
|
+
const outDir = path.join(projectRoot, 'data', 'test_runs')
|
|
242
|
+
let entries: string[] = []
|
|
243
|
+
try {
|
|
244
|
+
entries = await readdir(outDir)
|
|
245
|
+
} catch {
|
|
246
|
+
return {}
|
|
247
|
+
}
|
|
248
|
+
const prefix = `${agent}.`
|
|
249
|
+
const suffix = `.report.json`
|
|
250
|
+
const files = entries.filter((n) => n.startsWith(prefix) && n.endsWith(suffix)).sort()
|
|
251
|
+
if (!files.length) return {}
|
|
252
|
+
|
|
253
|
+
const latestFile = files[files.length - 1]
|
|
254
|
+
const latestTs = latestFile
|
|
255
|
+
.slice(prefix.length, latestFile.length - suffix.length)
|
|
256
|
+
.replace(/-/g, ':')
|
|
257
|
+
|
|
258
|
+
const results: Record<string, TestResult> = {}
|
|
259
|
+
for (const name of files) {
|
|
260
|
+
const full = path.join(outDir, name)
|
|
261
|
+
const raw = await readFile(full, 'utf8')
|
|
262
|
+
const parsed = JSON.parse(raw) as any
|
|
263
|
+
const rows = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.rows) ? parsed.rows : []
|
|
264
|
+
const ts = name.slice(prefix.length, name.length - suffix.length).replace(/-/g, ':')
|
|
265
|
+
for (const r of rows) {
|
|
266
|
+
const test_id = (r as any).test_id
|
|
267
|
+
if (!test_id) {
|
|
268
|
+
throw new Error(
|
|
269
|
+
`Missing test_id in report ${name}. Please add 'test_id' and provenance columns manually.`
|
|
270
|
+
)
|
|
271
|
+
}
|
|
272
|
+
const par = String((r as any).pinned_at_run ?? 'TRUE').toUpperCase()
|
|
273
|
+
if (par === 'FALSE') continue
|
|
274
|
+
// Always prefer newer timestamp
|
|
275
|
+
const prev = results[test_id]
|
|
276
|
+
const rec: TestResult = {
|
|
277
|
+
test_id,
|
|
278
|
+
success_rate_percent: (r as any).success_rate_percent,
|
|
279
|
+
success_rate: (r as any).success_rate,
|
|
280
|
+
results: Array.isArray((r as any).results) ? ((r as any).results as RunResult[]) : [],
|
|
281
|
+
report_timestamp: ts,
|
|
282
|
+
is_old: ts < latestTs
|
|
283
|
+
}
|
|
284
|
+
if (!prev || prev.report_timestamp < ts) {
|
|
285
|
+
results[test_id] = rec
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return results
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Fallback UUID for Node environments without global crypto
|
|
293
|
+
function randomUUID() {
|
|
294
|
+
const rnd = () =>
|
|
295
|
+
Math.floor(Math.random() * 0xffffffff)
|
|
296
|
+
.toString(16)
|
|
297
|
+
.padStart(8, '0')
|
|
298
|
+
return `${rnd()}-${rnd().slice(0, 4)}-${rnd().slice(0, 4)}-${rnd().slice(0, 4)}-${rnd()}${rnd()}`
|
|
299
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
type Message,
|
|
4
|
+
type TestAgent,
|
|
5
|
+
type TestTextAgent,
|
|
6
|
+
type TestVoiceAgent,
|
|
7
|
+
type StepTracer
|
|
8
|
+
} from '@recombine-ai/engine'
|
|
9
|
+
import { loadProjects } from '../../ws-server/projects'
|
|
10
|
+
|
|
11
|
+
export async function loadAgents(props: {
|
|
12
|
+
agentId: string
|
|
13
|
+
getMessages: () => Message[]
|
|
14
|
+
sendMessage: (message: Message | string) => Promise<void>
|
|
15
|
+
stepTracer: StepTracer
|
|
16
|
+
logger?: {
|
|
17
|
+
log: (...args: any[]) => void
|
|
18
|
+
debug: (...args: any[]) => void
|
|
19
|
+
warn: (...args: any[]) => void
|
|
20
|
+
error: (...args: any[]) => void
|
|
21
|
+
}
|
|
22
|
+
context?: Record<string, any>
|
|
23
|
+
timeoutSeconds: number
|
|
24
|
+
}): Promise<void> {
|
|
25
|
+
const {
|
|
26
|
+
agentId,
|
|
27
|
+
getMessages,
|
|
28
|
+
sendMessage,
|
|
29
|
+
stepTracer: stepTracer,
|
|
30
|
+
logger: providedLogger,
|
|
31
|
+
context,
|
|
32
|
+
timeoutSeconds
|
|
33
|
+
} = props
|
|
34
|
+
const projects = await loadProjects()
|
|
35
|
+
if (!projects.length) throw new Error('No projects found')
|
|
36
|
+
|
|
37
|
+
// Pick target agent
|
|
38
|
+
let proj = projects[0]
|
|
39
|
+
let name = Object.keys(proj.factories)[0]
|
|
40
|
+
if (agentId) {
|
|
41
|
+
if (agentId.includes('/')) {
|
|
42
|
+
const [p, n] = agentId.split('/')
|
|
43
|
+
const found = projects.find((x) => x.project === p)
|
|
44
|
+
if (!found) throw new Error(`Project not found: ${p}`)
|
|
45
|
+
if (!found.factories[n]) throw new Error(`Agent not found: ${agentId}`)
|
|
46
|
+
proj = found
|
|
47
|
+
name = n
|
|
48
|
+
} else {
|
|
49
|
+
if (!proj.factories[agentId])
|
|
50
|
+
throw new Error(`Agent not found in default project: ${agentId}`)
|
|
51
|
+
name = agentId
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const factory = proj.factories[name]
|
|
56
|
+
if (!factory) throw new Error('Factory not found')
|
|
57
|
+
|
|
58
|
+
// Minimal stubs
|
|
59
|
+
const logger = providedLogger || {
|
|
60
|
+
log: () => {},
|
|
61
|
+
debug: () => {},
|
|
62
|
+
error: () => {},
|
|
63
|
+
warn: () => {}
|
|
64
|
+
}
|
|
65
|
+
const scheduler = {
|
|
66
|
+
clearAllPendingActions: async () => {},
|
|
67
|
+
registerAction: () => async () => {},
|
|
68
|
+
triggerAction: async () => {},
|
|
69
|
+
serialize: () => ({}) as any,
|
|
70
|
+
setState: (_: any) => {}
|
|
71
|
+
}
|
|
72
|
+
const ctx = createContext({})
|
|
73
|
+
if (context && typeof context === 'object') {
|
|
74
|
+
// Apply provided context before agent lifecycle
|
|
75
|
+
ctx.swap(context)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Maintain in-run history so sendMessage appends to it, mirroring ws-server behavior
|
|
79
|
+
const history = getMessages()
|
|
80
|
+
const getMessagesWithHistory = () => history
|
|
81
|
+
const sendMessageWithHistory = async (message: Message | string) => {
|
|
82
|
+
const m =
|
|
83
|
+
typeof message === 'string' ? ({ sender: 'agent', text: message } as Message) : message
|
|
84
|
+
try {
|
|
85
|
+
history.push(m)
|
|
86
|
+
} catch {
|
|
87
|
+
// Best-effort: if history is immutable, ignore push errors
|
|
88
|
+
logger.log('Failed to push message to history:', m)
|
|
89
|
+
}
|
|
90
|
+
await sendMessage(m)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const agent = (await factory({
|
|
94
|
+
stepTracer: stepTracer,
|
|
95
|
+
tracer: {
|
|
96
|
+
addStep: (step) => {}
|
|
97
|
+
},
|
|
98
|
+
logger: logger,
|
|
99
|
+
scheduler: scheduler as any,
|
|
100
|
+
getMessages: getMessagesWithHistory,
|
|
101
|
+
sendMessage: sendMessageWithHistory,
|
|
102
|
+
sendAction: async () => {},
|
|
103
|
+
ctx
|
|
104
|
+
})) as TestTextAgent
|
|
105
|
+
|
|
106
|
+
process.on('unhandledRejection', (r) => {
|
|
107
|
+
console.error('UNHANDLED', r)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
await agent.respondToMessage()
|
|
112
|
+
await new Promise((resolve) => setTimeout(resolve, timeoutSeconds * 1000))
|
|
113
|
+
} catch (err) {
|
|
114
|
+
const msg = err instanceof Error ? `${err.name}: ${err.message}` : String(err)
|
|
115
|
+
const stack = err instanceof Error ? err.stack : undefined
|
|
116
|
+
try {
|
|
117
|
+
logger.error('Error in agent.respondToMessage():', msg)
|
|
118
|
+
} catch {
|
|
119
|
+
/* noop */
|
|
120
|
+
}
|
|
121
|
+
if (stack) {
|
|
122
|
+
try {
|
|
123
|
+
logger.error(stack)
|
|
124
|
+
} catch {
|
|
125
|
+
/* noop */
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|