@tangle-network/agent-eval 0.221.8 → 0.222.1

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 (579) hide show
  1. package/CHANGELOG.md +168 -0
  2. package/dist/adapters/http.d.ts +3 -5
  3. package/dist/adapters/http.d.ts.map +1 -1
  4. package/dist/adapters/http.js +1 -2
  5. package/dist/{adversarial-smnADNFS.d.ts → adversarial-DnQQFqTR.d.ts} +1 -3
  6. package/dist/adversarial-DnQQFqTR.d.ts.map +1 -0
  7. package/dist/{agent-profile-CNmwfaqq.d.ts → agent-profile-CSEQRC9l.d.ts} +4 -10
  8. package/dist/agent-profile-CSEQRC9l.d.ts.map +1 -0
  9. package/dist/agent-profile-Dngk3LZ0.js +153 -0
  10. package/dist/agent-profile-Dngk3LZ0.js.map +1 -0
  11. package/dist/{agent-profile-cell-BcpFbNd5.d.ts → agent-profile-cell-3kYxUsK2.d.ts} +3 -5
  12. package/dist/agent-profile-cell-3kYxUsK2.d.ts.map +1 -0
  13. package/dist/{agent-profile-cell-B1V1gUZs.js → agent-profile-cell-CT5JYueM.js} +5 -7
  14. package/dist/{agent-profile-cell-B1V1gUZs.js.map → agent-profile-cell-CT5JYueM.js.map} +1 -1
  15. package/dist/{agreement-irr-BhAqjluA.js → agreement-irr-BTjDN0i6.js} +4 -5
  16. package/dist/{agreement-irr-BhAqjluA.js.map → agreement-irr-BTjDN0i6.js.map} +1 -1
  17. package/dist/analyst/index.d.ts +95 -159
  18. package/dist/analyst/index.d.ts.map +1 -1
  19. package/dist/analyst/index.js +28 -39
  20. package/dist/analyst/index.js.map +1 -1
  21. package/dist/{analyze-runs-DfX6dHP0.d.ts → analyze-runs-CGLRgZGd.d.ts} +7 -13
  22. package/dist/analyze-runs-CGLRgZGd.d.ts.map +1 -0
  23. package/dist/{analyze-runs-CHmsykNJ.js → analyze-runs-CTheASYV.js} +23 -32
  24. package/dist/{analyze-runs-CHmsykNJ.js.map → analyze-runs-CTheASYV.js.map} +1 -1
  25. package/dist/{attribute-vocabulary-CcXqHODT.d.ts → attribute-vocabulary-5oo8ykIx.d.ts} +2 -4
  26. package/dist/attribute-vocabulary-5oo8ykIx.d.ts.map +1 -0
  27. package/dist/authenticity/index.d.ts +0 -2
  28. package/dist/authenticity/index.d.ts.map +1 -1
  29. package/dist/authenticity/index.js +1 -2
  30. package/dist/{benchmark-command-Cnjfo0Zh.js → benchmark-command-Cr7i7YSX.js} +61 -94
  31. package/dist/benchmark-command-Cr7i7YSX.js.map +1 -0
  32. package/dist/benchmarks/index.d.ts +5 -15
  33. package/dist/benchmarks/index.d.ts.map +1 -1
  34. package/dist/benchmarks/index.js +27 -38
  35. package/dist/benchmarks/index.js.map +1 -1
  36. package/dist/{bounded-process-Cj9YjXbE.js → bounded-process-BZrWXIKW.js} +2 -3
  37. package/dist/{bounded-process-Cj9YjXbE.js.map → bounded-process-BZrWXIKW.js.map} +1 -1
  38. package/dist/builder-eval/index.d.ts +5 -14
  39. package/dist/builder-eval/index.d.ts.map +1 -1
  40. package/dist/builder-eval/index.js +11 -17
  41. package/dist/builder-eval/index.js.map +1 -1
  42. package/dist/{calibration-CTwxpJ-t.js → calibration-6usfVYYo.js} +4 -5
  43. package/dist/{calibration-CTwxpJ-t.js.map → calibration-6usfVYYo.js.map} +1 -1
  44. package/dist/campaign/index.d.ts +9 -9
  45. package/dist/campaign/index.js +15 -14
  46. package/dist/{campaign-uddTlFg5.js → campaign-ddr1N3yD.js} +61 -58
  47. package/dist/campaign-ddr1N3yD.js.map +1 -0
  48. package/dist/{campaign-evidence-DunzcJGv.js → campaign-evidence-DN8rWuBj.js} +20 -322
  49. package/dist/campaign-evidence-DN8rWuBj.js.map +1 -0
  50. package/dist/{canonical-Dq2hOQ8L.js → canonical-CicJlINA.js} +3 -4
  51. package/dist/{canonical-Dq2hOQ8L.js.map → canonical-CicJlINA.js.map} +1 -1
  52. package/dist/{canonical-CFpojCN5.d.ts → canonical-gLeHiqzd.d.ts} +2 -4
  53. package/dist/canonical-gLeHiqzd.d.ts.map +1 -0
  54. package/dist/{cell-spend-DEWR3nj-.js → cell-spend-zxmzg4GH.js} +3 -4
  55. package/dist/{cell-spend-DEWR3nj-.js.map → cell-spend-zxmzg4GH.js.map} +1 -1
  56. package/dist/{chat-client-BNATB3rJ.js → chat-client-CO3uB33i.js} +3 -4
  57. package/dist/{chat-client-BNATB3rJ.js.map → chat-client-CO3uB33i.js.map} +1 -1
  58. package/dist/{chat-json-call-BzWYp18J.js → chat-json-call-8yUv4LFO.js} +4 -5
  59. package/dist/{chat-json-call-BzWYp18J.js.map → chat-json-call-8yUv4LFO.js.map} +1 -1
  60. package/dist/{claim-BPVuyHuy.js → claim-Dod_mjk3.js} +5 -6
  61. package/dist/{claim-BPVuyHuy.js.map → claim-Dod_mjk3.js.map} +1 -1
  62. package/dist/cli.js +179 -23
  63. package/dist/cli.js.map +1 -1
  64. package/dist/{client-hwo3cJjR.d.ts → client-BIFwUg7I.d.ts} +6 -12
  65. package/dist/client-BIFwUg7I.d.ts.map +1 -0
  66. package/dist/{cluster-bootstrap-DEwwhl0C.js → cluster-bootstrap-SbaeM44s.js} +4 -5
  67. package/dist/{cluster-bootstrap-DEwwhl0C.js.map → cluster-bootstrap-SbaeM44s.js.map} +1 -1
  68. package/dist/completion-verifier-7KEfroqx.d.ts +168 -0
  69. package/dist/completion-verifier-7KEfroqx.d.ts.map +1 -0
  70. package/dist/{completion-verifier-asaV1nSj.js → completion-verifier-rqbMh5-4.js} +9 -160
  71. package/dist/completion-verifier-rqbMh5-4.js.map +1 -0
  72. package/dist/contract/index.d.ts +13 -13
  73. package/dist/contract/index.js +41 -60
  74. package/dist/contract/index.js.map +1 -1
  75. package/dist/{cost-ledger-BGZB6yY2.js → cost-ledger-CS8R3IZj.js} +10 -17
  76. package/dist/{cost-ledger-BGZB6yY2.js.map → cost-ledger-CS8R3IZj.js.map} +1 -1
  77. package/dist/{cost-ledger-C1W3ICmP.d.ts → cost-ledger-Czro9wmo.d.ts} +1 -5
  78. package/dist/cost-ledger-Czro9wmo.d.ts.map +1 -0
  79. package/dist/{dataset-DQqhOCPt.d.ts → dataset-DThC1S6G.d.ts} +1 -3
  80. package/dist/dataset-DThC1S6G.d.ts.map +1 -0
  81. package/dist/{decision-point-0nJubuoM.js → decision-point-lhMgODOR.js} +14 -18
  82. package/dist/{decision-point-0nJubuoM.js.map → decision-point-lhMgODOR.js.map} +1 -1
  83. package/dist/{deep-freeze-CurcOQg3.js → deep-freeze-CK8-2W7p.js} +2 -3
  84. package/dist/{deep-freeze-CurcOQg3.js.map → deep-freeze-CK8-2W7p.js.map} +1 -1
  85. package/dist/{default-registry-CLG5YqGS.d.ts → default-registry-1f4ukAIX.d.ts} +53 -61
  86. package/dist/default-registry-1f4ukAIX.d.ts.map +1 -0
  87. package/dist/{default-registry-BBTDgkDM.js → default-registry-C1tPEjZ4.js} +29 -45
  88. package/dist/{default-registry-BBTDgkDM.js.map → default-registry-C1tPEjZ4.js.map} +1 -1
  89. package/dist/{define-agent-eval-CCbT7Kfr.js → define-agent-eval-BLoP4Lf9.js} +15 -18
  90. package/dist/{define-agent-eval-CCbT7Kfr.js.map → define-agent-eval-BLoP4Lf9.js.map} +1 -1
  91. package/dist/{define-agent-eval-JKt3gMQr.d.ts → define-agent-eval-sUYh9BFA.d.ts} +19 -27
  92. package/dist/define-agent-eval-sUYh9BFA.d.ts.map +1 -0
  93. package/dist/{descriptive-CVNy48rR.js → descriptive-cPwITVfy.js} +30 -8
  94. package/dist/descriptive-cPwITVfy.js.map +1 -0
  95. package/dist/diagnosis/index.d.ts +5 -15
  96. package/dist/diagnosis/index.d.ts.map +1 -1
  97. package/dist/diagnosis/index.js +13 -19
  98. package/dist/diagnosis/index.js.map +1 -1
  99. package/dist/{dspy-rlm-engine-DN1p_5jx.js → dspy-rlm-engine-jDiWkul6.js} +7 -10
  100. package/dist/{dspy-rlm-engine-DN1p_5jx.js.map → dspy-rlm-engine-jDiWkul6.js.map} +1 -1
  101. package/dist/{emitter-DbMXUIVP.js → emitter-DhQ65mza.js} +3 -4
  102. package/dist/{emitter-DbMXUIVP.js.map → emitter-DhQ65mza.js.map} +1 -1
  103. package/dist/{emitter-DABYYTcH.d.ts → emitter-mAXC5PSN.d.ts} +3 -5
  104. package/dist/emitter-mAXC5PSN.d.ts.map +1 -0
  105. package/dist/{engine-dtRVeuQs.d.ts → engine-BITiErg-.d.ts} +10 -18
  106. package/dist/engine-BITiErg-.d.ts.map +1 -0
  107. package/dist/{equal-terms-DbPGcVtI.js → equal-terms-K11VHmR3.js} +3 -4
  108. package/dist/{equal-terms-DbPGcVtI.js.map → equal-terms-K11VHmR3.js.map} +1 -1
  109. package/dist/{errors-BcOs5MKW.js → errors-DeEEV9Vx.js} +2 -3
  110. package/dist/{errors-BcOs5MKW.js.map → errors-DeEEV9Vx.js.map} +1 -1
  111. package/dist/{errors-DEE6u6ot.d.ts → errors-E9I2hldP.d.ts} +1 -3
  112. package/dist/errors-E9I2hldP.d.ts.map +1 -0
  113. package/dist/{eval-campaign-DoX5vz3E.js → eval-campaign-Cgixrvf7.js} +8 -9
  114. package/dist/{eval-campaign-DoX5vz3E.js.map → eval-campaign-Cgixrvf7.js.map} +1 -1
  115. package/dist/{evaluation-wdGyZ7jV.js → evaluation-B8H3GYej.js} +4 -6
  116. package/dist/{evaluation-wdGyZ7jV.js.map → evaluation-B8H3GYej.js.map} +1 -1
  117. package/dist/{evaluation-DblGquCB.d.ts → evaluation-Djq7-Ybj.d.ts} +4 -6
  118. package/dist/evaluation-Djq7-Ybj.d.ts.map +1 -0
  119. package/dist/evaluation.d.ts +1 -1
  120. package/dist/evaluation.js +1 -2
  121. package/dist/{exact-types-Do63KoKn.d.ts → exact-types-CndDT_h7.d.ts} +8 -10
  122. package/dist/exact-types-CndDT_h7.d.ts.map +1 -0
  123. package/dist/{exec-CpbtOXVt.js → exec-C0_AkLUv.js} +3 -5
  124. package/dist/{exec-CpbtOXVt.js.map → exec-C0_AkLUv.js.map} +1 -1
  125. package/dist/{execution-tracks-CpgFPpS5.js → execution-tracks-DaDXYwAq.js} +2 -3
  126. package/dist/{execution-tracks-CpgFPpS5.js.map → execution-tracks-DaDXYwAq.js.map} +1 -1
  127. package/dist/experiment/index.d.ts +9 -37
  128. package/dist/experiment/index.d.ts.map +1 -1
  129. package/dist/experiment/index.js +29 -40
  130. package/dist/experiment/index.js.map +1 -1
  131. package/dist/{exporters-Dk3oEbK_.d.ts → exporters-B5Ze_RKh.d.ts} +4 -4
  132. package/dist/exporters-B5Ze_RKh.d.ts.map +1 -0
  133. package/dist/{exporters-DWvM16LE.js → exporters-ByLcILYU.js} +23 -5
  134. package/dist/exporters-ByLcILYU.js.map +1 -0
  135. package/dist/{external-optimizer-process-DEzJ2CGX.js → external-optimizer-process-BRVmaDFe.js} +5 -6
  136. package/dist/{external-optimizer-process-DEzJ2CGX.js.map → external-optimizer-process-BRVmaDFe.js.map} +1 -1
  137. package/dist/{external-optimizer-subprocess-B_ukPtRD.js → external-optimizer-subprocess-U616hV_l.js} +24 -37
  138. package/dist/{external-optimizer-subprocess-B_ukPtRD.js.map → external-optimizer-subprocess-U616hV_l.js.map} +1 -1
  139. package/dist/{extract-usage-BZLU01kR.js → extract-usage-ISFqhfDz.js} +2 -3
  140. package/dist/{extract-usage-BZLU01kR.js.map → extract-usage-ISFqhfDz.js.map} +1 -1
  141. package/dist/{failure-cluster-DN0t63Z0.d.ts → failure-cluster-DOoa7CBg.d.ts} +3 -7
  142. package/dist/failure-cluster-DOoa7CBg.d.ts.map +1 -0
  143. package/dist/{failure-taxonomy-Bx5oWqaW.js → failure-taxonomy-9eQfXKoW.js} +2 -3
  144. package/dist/{failure-taxonomy-Bx5oWqaW.js.map → failure-taxonomy-9eQfXKoW.js.map} +1 -1
  145. package/dist/{feedback-trajectory-CYVJXolG.d.ts → feedback-trajectory-DsHR9krG.d.ts} +7 -13
  146. package/dist/feedback-trajectory-DsHR9krG.d.ts.map +1 -0
  147. package/dist/{finding-composition-8n0fFgVI.js → finding-composition-DlvE1Qul.js} +4 -6
  148. package/dist/{finding-composition-8n0fFgVI.js.map → finding-composition-DlvE1Qul.js.map} +1 -1
  149. package/dist/{findings-store-Bg4sdS-e.js → findings-store-B75Dspaq.js} +11 -14
  150. package/dist/{findings-store-Bg4sdS-e.js.map → findings-store-B75Dspaq.js.map} +1 -1
  151. package/dist/fuzz.d.ts +3 -17
  152. package/dist/fuzz.d.ts.map +1 -1
  153. package/dist/fuzz.js +30 -29
  154. package/dist/fuzz.js.map +1 -1
  155. package/dist/{hf-dataset-CKxIJQba.js → hf-dataset-DPVQXW5n.js} +362 -21
  156. package/dist/hf-dataset-DPVQXW5n.js.map +1 -0
  157. package/dist/hosted/index.d.ts +2 -6
  158. package/dist/hosted/index.d.ts.map +1 -1
  159. package/dist/hosted/index.js +1 -2
  160. package/dist/{index-CalAsXMR.d.ts → index-B1Bm9oJA.d.ts} +3 -15
  161. package/dist/index-B1Bm9oJA.d.ts.map +1 -0
  162. package/dist/{index-D7fmC-1K.d.ts → index-BdKzYYkC.d.ts} +183 -36
  163. package/dist/index-BdKzYYkC.d.ts.map +1 -0
  164. package/dist/{index-CdEVr8-O.d.ts → index-Bdcpx2s8.d.ts} +24 -299
  165. package/dist/index-Bdcpx2s8.d.ts.map +1 -0
  166. package/dist/{index-jnuFLxOs.d.ts → index-Cu12qxJb.d.ts} +11 -39
  167. package/dist/index-Cu12qxJb.d.ts.map +1 -0
  168. package/dist/{index-CfJULcW5.d.ts → index-DAk2quYu.d.ts} +18 -38
  169. package/dist/index-DAk2quYu.d.ts.map +1 -0
  170. package/dist/{index-CHxwfW5g.d.ts → index-DwUGehqX.d.ts} +3 -9
  171. package/dist/index-DwUGehqX.d.ts.map +1 -0
  172. package/dist/{index-CTIRz-AB.d.ts → index-IzWTz5EP.d.ts} +14 -36
  173. package/dist/index-IzWTz5EP.d.ts.map +1 -0
  174. package/dist/index.d.ts +55 -188
  175. package/dist/index.d.ts.map +1 -1
  176. package/dist/index.js +122 -195
  177. package/dist/index.js.map +1 -1
  178. package/dist/{integrity-D-s2iHiT.js → integrity-B1V6klyO.js} +12 -363
  179. package/dist/integrity-B1V6klyO.js.map +1 -0
  180. package/dist/{integrity-D9lBnv_K.d.ts → integrity-BAdVzT8u.d.ts} +4 -6
  181. package/dist/integrity-BAdVzT8u.d.ts.map +1 -0
  182. package/dist/{integrity-W4CADcFc.js → integrity-DOHt1mwU.js} +3 -4
  183. package/dist/{integrity-W4CADcFc.js.map → integrity-DOHt1mwU.js.map} +1 -1
  184. package/dist/{internal-BTK91Bqt.js → internal-v6XfOeJW.js} +6 -8
  185. package/dist/{internal-BTK91Bqt.js.map → internal-v6XfOeJW.js.map} +1 -1
  186. package/dist/{interval-Dq9gt7jx.js → interval-Bd2f4CRT.js} +6 -8
  187. package/dist/{interval-Dq9gt7jx.js.map → interval-Bd2f4CRT.js.map} +1 -1
  188. package/dist/{interval-ohuOJurX.d.ts → interval-CWyxqDpE.d.ts} +1 -5
  189. package/dist/interval-CWyxqDpE.d.ts.map +1 -0
  190. package/dist/{journal-C7om8Gum.js → journal-C1uLJi0w.js} +115 -121
  191. package/dist/{journal-C7om8Gum.js.map → journal-C1uLJi0w.js.map} +1 -1
  192. package/dist/{json-BhdsJaOQ.js → json-DtvZNAU9.js} +4 -6
  193. package/dist/{json-BhdsJaOQ.js.map → json-DtvZNAU9.js.map} +1 -1
  194. package/dist/json-recovery-DK4MDm5r.js +296 -0
  195. package/dist/json-recovery-DK4MDm5r.js.map +1 -0
  196. package/dist/{judge-calibration-BkXMIWA4.js → judge-calibration-DGqlfWW8.js} +5 -6
  197. package/dist/{judge-calibration-BkXMIWA4.js.map → judge-calibration-DGqlfWW8.js.map} +1 -1
  198. package/dist/{judge-calibration-DFtEMlde.d.ts → judge-calibration-DnrbQaXI.d.ts} +1 -3
  199. package/dist/judge-calibration-DnrbQaXI.d.ts.map +1 -0
  200. package/dist/{judge-gate-BVvmP00P.js → judge-gate-C2BCOt-M.js} +8 -12
  201. package/dist/{judge-gate-BVvmP00P.js.map → judge-gate-C2BCOt-M.js.map} +1 -1
  202. package/dist/judges-BLxg5p8E.js +20 -0
  203. package/dist/judges-BLxg5p8E.js.map +1 -0
  204. package/dist/{kind-factory-Dl0PmNQL.js → kind-factory-VKysp1ds.js} +23 -39
  205. package/dist/{kind-factory-Dl0PmNQL.js.map → kind-factory-VKysp1ds.js.map} +1 -1
  206. package/dist/ledger-core/index.d.ts +2 -2
  207. package/dist/ledger-core/index.js +3 -3
  208. package/dist/ledger-core/lock-holder.d.ts +1 -1
  209. package/dist/ledger-core/lock-holder.js +1 -2
  210. package/dist/{ledger-core-CAxUdDk0.js → ledger-core-CfT-FzPf.js} +5 -6
  211. package/dist/{ledger-core-CAxUdDk0.js.map → ledger-core-CfT-FzPf.js.map} +1 -1
  212. package/dist/{llm-client-b1ysZVIU.js → llm-client-kJ9EOqjt.js} +22 -30
  213. package/dist/{llm-client-b1ysZVIU.js.map → llm-client-kJ9EOqjt.js.map} +1 -1
  214. package/dist/{llm-judge-Cybq29bL.js → llm-judge-cgbhTKQp.js} +108 -164
  215. package/dist/llm-judge-cgbhTKQp.js.map +1 -0
  216. package/dist/{lock-holder-DaJbfpci.d.ts → lock-holder-DoxlZFkQ.d.ts} +1 -3
  217. package/dist/lock-holder-DoxlZFkQ.d.ts.map +1 -0
  218. package/dist/matrix/index.d.ts +3 -3
  219. package/dist/matrix/index.js +2 -2
  220. package/dist/{matrix-DtkZLD_3.d.ts → matrix-8X6i5kJ6.d.ts} +4 -12
  221. package/dist/matrix-8X6i5kJ6.d.ts.map +1 -0
  222. package/dist/{matrix-B8l-Nsxd.js → matrix-CgpX8wdm.js} +8 -13
  223. package/dist/matrix-CgpX8wdm.js.map +1 -0
  224. package/dist/{mean-BbA_JCzW.js → mean-CdDYG-us.js} +6 -9
  225. package/dist/{mean-BbA_JCzW.js.map → mean-CdDYG-us.js.map} +1 -1
  226. package/dist/meta-eval/index.d.ts +3 -3
  227. package/dist/meta-eval/index.js +17 -21
  228. package/dist/meta-eval/index.js.map +1 -1
  229. package/dist/{metrics-BKaPBtIG.js → metrics-DNCAUtuB.js} +2 -3
  230. package/dist/{metrics-BKaPBtIG.js.map → metrics-DNCAUtuB.js.map} +1 -1
  231. package/dist/{mint-CbdwjTPW.js → mint-D9ZysYtY.js} +7 -8
  232. package/dist/{mint-CbdwjTPW.js.map → mint-D9ZysYtY.js.map} +1 -1
  233. package/dist/{multi-layer-verifier-DEgMUk6v.d.ts → multi-layer-verifier-lM4aVN78.d.ts} +2 -4
  234. package/dist/multi-layer-verifier-lM4aVN78.d.ts.map +1 -0
  235. package/dist/{multiplicity-Sg0U7h8j.js → multiplicity-DAd4xaDC.js} +3 -4
  236. package/dist/{multiplicity-Sg0U7h8j.js.map → multiplicity-DAd4xaDC.js.map} +1 -1
  237. package/dist/{multiplicity-DIWHvysC.d.ts → multiplicity-D_SEsc5j.d.ts} +1 -3
  238. package/dist/multiplicity-D_SEsc5j.d.ts.map +1 -0
  239. package/dist/multishot/golden/index.d.ts +1 -17
  240. package/dist/multishot/golden/index.d.ts.map +1 -1
  241. package/dist/multishot/golden/index.js +10 -17
  242. package/dist/multishot/golden/index.js.map +1 -1
  243. package/dist/multishot/index.d.ts +2 -10
  244. package/dist/multishot/index.d.ts.map +1 -1
  245. package/dist/multishot/index.js +11 -18
  246. package/dist/multishot/index.js.map +1 -1
  247. package/dist/{nonnegative-number-DvdMxg_f.js → nonnegative-number-lEYbOsuh.js} +2 -3
  248. package/dist/{nonnegative-number-DvdMxg_f.js.map → nonnegative-number-lEYbOsuh.js.map} +1 -1
  249. package/dist/openapi.json +1 -1
  250. package/dist/{otel-spans-64hmQqON.js → otel-spans-BsGzTWIK.js} +5 -6
  251. package/dist/{otel-spans-64hmQqON.js.map → otel-spans-BsGzTWIK.js.map} +1 -1
  252. package/dist/{otlp-attributes-D9ptWaIJ.js → otlp-attributes-Boeb7gtH.js} +2 -3
  253. package/dist/{otlp-attributes-D9ptWaIJ.js.map → otlp-attributes-Boeb7gtH.js.map} +1 -1
  254. package/dist/{outcome-observations-FLmRpgYa.js → outcome-observations-D4snOtUb.js} +4 -5
  255. package/dist/{outcome-observations-FLmRpgYa.js.map → outcome-observations-D4snOtUb.js.map} +1 -1
  256. package/dist/{outcome-store-DUcMj-3D.js → outcome-store-TarrcfHG.js} +2 -3
  257. package/dist/{outcome-store-DUcMj-3D.js.map → outcome-store-TarrcfHG.js.map} +1 -1
  258. package/dist/{package-version-D7lQHt_-.js → package-version-CJl_pY9W.js} +2 -3
  259. package/dist/{package-version-D7lQHt_-.js.map → package-version-CJl_pY9W.js.map} +1 -1
  260. package/dist/{paired-arms-B2ttLc0_.js → paired-arms-D-54hO-k.js} +10 -14
  261. package/dist/{paired-arms-B2ttLc0_.js.map → paired-arms-D-54hO-k.js.map} +1 -1
  262. package/dist/{paired-binary-B_nejA44.js → paired-binary-BR0nwHOA.js} +3 -4
  263. package/dist/{paired-binary-B_nejA44.js.map → paired-binary-BR0nwHOA.js.map} +1 -1
  264. package/dist/{paired-promotion-decision-CQMJ5xGN.d.ts → paired-promotion-decision-BDnqepZ1.d.ts} +1 -5
  265. package/dist/paired-promotion-decision-BDnqepZ1.d.ts.map +1 -0
  266. package/dist/{paired-promotion-decision-D0SHb-ZL.js → paired-promotion-decision-FGvHA4p_.js} +5 -7
  267. package/dist/{paired-promotion-decision-D0SHb-ZL.js.map → paired-promotion-decision-FGvHA4p_.js.map} +1 -1
  268. package/dist/{pareto-BiBnQXAE.js → pareto-B9udAt2i.js} +28 -50
  269. package/dist/pareto-B9udAt2i.js.map +1 -0
  270. package/dist/pipelines/index.d.ts +5 -11
  271. package/dist/pipelines/index.d.ts.map +1 -1
  272. package/dist/pipelines/index.js +6 -8
  273. package/dist/pipelines/index.js.map +1 -1
  274. package/dist/{power-and-mde-CQX-0weG.js → power-and-mde-ClI6RWw4.js} +4 -5
  275. package/dist/{power-and-mde-CQX-0weG.js.map → power-and-mde-ClI6RWw4.js.map} +1 -1
  276. package/dist/{predicate-FdKmElA_.js → predicate-BYHA4MBn.js} +2 -3
  277. package/dist/{predicate-FdKmElA_.js.map → predicate-BYHA4MBn.js.map} +1 -1
  278. package/dist/{prime-bridge-transport-6feEglLf.d.ts → prime-bridge-transport-Cfqir_Im.d.ts} +1 -3
  279. package/dist/prime-bridge-transport-Cfqir_Im.d.ts.map +1 -0
  280. package/dist/{prime-bridge-transport-Z3cpKGoV.js → prime-bridge-transport-Csd5SQg7.js} +2 -3
  281. package/dist/{prime-bridge-transport-Z3cpKGoV.js.map → prime-bridge-transport-Csd5SQg7.js.map} +1 -1
  282. package/dist/{prime-protocol-BGxjfhM4.d.ts → prime-protocol-BpQlTowq.d.ts} +4 -8
  283. package/dist/prime-protocol-BpQlTowq.d.ts.map +1 -0
  284. package/dist/{prime-protocol-BFgGrEMP.js → prime-protocol-CrhpXRz9.js} +4 -6
  285. package/dist/{prime-protocol-BFgGrEMP.js.map → prime-protocol-CrhpXRz9.js.map} +1 -1
  286. package/dist/profile-cell.d.ts +1 -1
  287. package/dist/profile-cell.js +1 -2
  288. package/dist/{promotion-gate-CkVZHagC.d.ts → promotion-gate-CixshGI8.d.ts} +5 -11
  289. package/dist/promotion-gate-CixshGI8.d.ts.map +1 -0
  290. package/dist/{promotion-policy-6A8osGr_.js → promotion-policy-CBYeD4zi.js} +5 -6
  291. package/dist/{promotion-policy-6A8osGr_.js.map → promotion-policy-CBYeD4zi.js.map} +1 -1
  292. package/dist/{proposal-findings-DqLUWsAG.js → proposal-findings-WFQrxnfe.js} +3 -4
  293. package/dist/{proposal-findings-DqLUWsAG.js.map → proposal-findings-WFQrxnfe.js.map} +1 -1
  294. package/dist/{quantile--0yb07pD.js → quantile-CncXP-Ss.js} +2 -3
  295. package/dist/{quantile--0yb07pD.js.map → quantile-CncXP-Ss.js.map} +1 -1
  296. package/dist/{query-B_RZ36an.js → query-CGXzO9d4.js} +5 -6
  297. package/dist/{query-B_RZ36an.js.map → query-CGXzO9d4.js.map} +1 -1
  298. package/dist/{query-Cmv_U8vf.d.ts → query-UD0B08Sb.d.ts} +4 -6
  299. package/dist/query-UD0B08Sb.d.ts.map +1 -0
  300. package/dist/{random-DGEyr3zG.d.ts → random-BN150Q_X.d.ts} +1 -5
  301. package/dist/random-BN150Q_X.d.ts.map +1 -0
  302. package/dist/{random-DDDcC7YU.js → random-DrzcgC7F.js} +3 -4
  303. package/dist/{random-DDDcC7YU.js.map → random-DrzcgC7F.js.map} +1 -1
  304. package/dist/{raw-provider-sink-75w4FWBj.js → raw-provider-sink-DDLkP_eF.js} +3 -4
  305. package/dist/{raw-provider-sink-75w4FWBj.js.map → raw-provider-sink-DDLkP_eF.js.map} +1 -1
  306. package/dist/{record-id-DUgsK5qp.js → record-id-CWZXFh58.js} +2 -3
  307. package/dist/{record-id-DUgsK5qp.js.map → record-id-CWZXFh58.js.map} +1 -1
  308. package/dist/{redact-DXdlFb_U.d.ts → redact-C_wzC4c_.d.ts} +1 -3
  309. package/dist/redact-C_wzC4c_.d.ts.map +1 -0
  310. package/dist/{redact-mtkTiJVk.js → redact-D6APJS1d.js} +3 -5
  311. package/dist/{redact-mtkTiJVk.js.map → redact-D6APJS1d.js.map} +1 -1
  312. package/dist/{registry-BcdJmyoU.d.ts → registry-D9A7Tybn.d.ts} +5 -11
  313. package/dist/registry-D9A7Tybn.d.ts.map +1 -0
  314. package/dist/{release-confidence-CYIFH-fp.js → release-confidence-CTUJz5mM.js} +10 -16
  315. package/dist/release-confidence-CTUJz5mM.js.map +1 -0
  316. package/dist/{render-BhJqXoBH.js → render-pfAZ7IR4.js} +266 -33
  317. package/dist/render-pfAZ7IR4.js.map +1 -0
  318. package/dist/{reporting-html-Kvlc8oMt.js → reporting-html-DMXIjATy.js} +2 -3
  319. package/dist/{reporting-html-Kvlc8oMt.js.map → reporting-html-DMXIjATy.js.map} +1 -1
  320. package/dist/reporting.d.ts +6 -6
  321. package/dist/reporting.js +7 -7
  322. package/dist/{researcher-DKWtoMWk.d.ts → researcher-CLnNJ7Or.d.ts} +8 -12
  323. package/dist/researcher-CLnNJ7Or.d.ts.map +1 -0
  324. package/dist/{reward-nw2xZGZG.js → reward-P0VD_Aft.js} +2 -3
  325. package/dist/{reward-nw2xZGZG.js.map → reward-P0VD_Aft.js.map} +1 -1
  326. package/dist/{reward-BeUgVVC_.d.ts → reward-ST4PXNXF.d.ts} +2 -4
  327. package/dist/reward-ST4PXNXF.d.ts.map +1 -0
  328. package/dist/{reward-hacking-WTxUbtbb.d.ts → reward-hacking-C9hPVT0Q.d.ts} +4 -8
  329. package/dist/reward-hacking-C9hPVT0Q.d.ts.map +1 -0
  330. package/dist/{reward-hacking-ByuETaIb.js → reward-hacking-DZzHZlS1.js} +5 -7
  331. package/dist/{reward-hacking-ByuETaIb.js.map → reward-hacking-DZzHZlS1.js.map} +1 -1
  332. package/dist/rl.d.ts +26 -63
  333. package/dist/rl.d.ts.map +1 -1
  334. package/dist/rl.js +35 -52
  335. package/dist/rl.js.map +1 -1
  336. package/dist/{rolldown-runtime-8H4AJuhK.js → rolldown-runtime-BJohB4LM.js} +1 -2
  337. package/dist/rollout/index.d.ts +6 -6
  338. package/dist/rollout/index.js +7 -7
  339. package/dist/{rollout-Dd1ucT_M.js → rollout-BhkMpAJT.js} +279 -16
  340. package/dist/rollout-BhkMpAJT.js.map +1 -0
  341. package/dist/{terminal-record-CB9BFtjS.js → rollout-nodes-BHR9Q5jP.js} +351 -11
  342. package/dist/rollout-nodes-BHR9Q5jP.js.map +1 -0
  343. package/dist/{round-decimal-COrKglMh.js → round-decimal-ZmjAQPo1.js} +2 -3
  344. package/dist/{round-decimal-COrKglMh.js.map → round-decimal-ZmjAQPo1.js.map} +1 -1
  345. package/dist/{rubric-predictive-validity-Cd5SCtAf.d.ts → rubric-predictive-validity-B3RzbwOx.d.ts} +2 -8
  346. package/dist/rubric-predictive-validity-B3RzbwOx.d.ts.map +1 -0
  347. package/dist/{rubric-predictive-validity-CeKW2GQN.js → rubric-predictive-validity-CQp_M0vy.js} +3 -4
  348. package/dist/{rubric-predictive-validity-CeKW2GQN.js.map → rubric-predictive-validity-CQp_M0vy.js.map} +1 -1
  349. package/dist/{run-record-CysKLB93.js → run-record-CZy4-TnZ.js} +4 -5
  350. package/dist/{run-record-CysKLB93.js.map → run-record-CZy4-TnZ.js.map} +1 -1
  351. package/dist/{run-record-C3awiXPf.d.ts → run-record-D2BFMPGl.d.ts} +5 -7
  352. package/dist/run-record-D2BFMPGl.d.ts.map +1 -0
  353. package/dist/{run-record-DhEJgoPz.js → run-record-DEjx43cI.js} +6 -7
  354. package/dist/{run-record-DhEJgoPz.js.map → run-record-DEjx43cI.js.map} +1 -1
  355. package/dist/{sandbox-harness-BlSOu4LX.d.ts → sandbox-harness-B3Kx1fOA.d.ts} +1 -3
  356. package/dist/sandbox-harness-B3Kx1fOA.d.ts.map +1 -0
  357. package/dist/{schema-D6EVKzTB.d.ts → schema-CkIvnmLU.d.ts} +2 -43
  358. package/dist/schema-CkIvnmLU.d.ts.map +1 -0
  359. package/dist/{schema-Bt2vLFm3.js → schema-D-xu3MU_.js} +2 -3
  360. package/dist/{schema-Bt2vLFm3.js.map → schema-D-xu3MU_.js.map} +1 -1
  361. package/dist/{schema-C-ziyJD7.d.ts → schema-DkFJr3Y8.d.ts} +111 -48
  362. package/dist/schema-DkFJr3Y8.d.ts.map +1 -0
  363. package/dist/{schema-CvhfLjtZ.js → schema-YUIXT8iW.js} +37 -7
  364. package/dist/schema-YUIXT8iW.js.map +1 -0
  365. package/dist/search/index.d.ts +3 -35
  366. package/dist/search/index.d.ts.map +1 -1
  367. package/dist/search/index.js +4 -5
  368. package/dist/{search-kernel-CctpiDd2.d.ts → search-kernel-B77eE7Ac.d.ts} +10 -36
  369. package/dist/search-kernel-B77eE7Ac.d.ts.map +1 -0
  370. package/dist/{search-ledger-CZRqtFbW.js → search-ledger-BsVi-Ngv.js} +17 -26
  371. package/dist/{search-ledger-CZRqtFbW.js.map → search-ledger-BsVi-Ngv.js.map} +1 -1
  372. package/dist/{search-ledger-file-Bd5Tioq6.js → search-ledger-file-DTBD6X-y.js} +6 -8
  373. package/dist/{search-ledger-file-Bd5Tioq6.js.map → search-ledger-file-DTBD6X-y.js.map} +1 -1
  374. package/dist/{search-ledger-types-p2xKfiDJ.d.ts → search-ledger-types-qiYRUo_N.d.ts} +5 -9
  375. package/dist/search-ledger-types-qiYRUo_N.d.ts.map +1 -0
  376. package/dist/{search-shipper-Dn3NLsuH.js → search-shipper-pdg4viK7.js} +8 -13
  377. package/dist/{search-shipper-Dn3NLsuH.js.map → search-shipper-pdg4viK7.js.map} +1 -1
  378. package/dist/{search-summary-D4bwYnAE.js → search-summary-Ct7SrmVc.js} +6 -7
  379. package/dist/{search-summary-D4bwYnAE.js.map → search-summary-Ct7SrmVc.js.map} +1 -1
  380. package/dist/{sequential-CimQrbjv.js → sequential-B1I0tRfL.js} +6 -7
  381. package/dist/{sequential-CimQrbjv.js.map → sequential-B1I0tRfL.js.map} +1 -1
  382. package/dist/{sequential-KwGspfeR.d.ts → sequential-Bb_pdTqG.d.ts} +1 -3
  383. package/dist/sequential-Bb_pdTqG.d.ts.map +1 -0
  384. package/dist/{sequential-BVv1sjsw.js → sequential-Bjs5roiK.js} +2 -3
  385. package/dist/{sequential-BVv1sjsw.js.map → sequential-Bjs5roiK.js.map} +1 -1
  386. package/dist/{sequential-eprocess-DodI6RoF.js → sequential-eprocess-C1YLwFaz.js} +3 -4
  387. package/dist/{sequential-eprocess-DodI6RoF.js.map → sequential-eprocess-C1YLwFaz.js.map} +1 -1
  388. package/dist/{server-ChhXPCgX.js → server-DA6h3co5.js} +11 -17
  389. package/dist/{server-ChhXPCgX.js.map → server-DA6h3co5.js.map} +1 -1
  390. package/dist/{single-run-lock-Dekd8_Wv.js → single-run-lock-BGlW3OSk.js} +3 -4
  391. package/dist/{single-run-lock-Dekd8_Wv.js.map → single-run-lock-BGlW3OSk.js.map} +1 -1
  392. package/dist/{skillopt-optimization-method-sB_-yi1G.js → skillopt-optimization-method-qB1M554K.js} +38 -57
  393. package/dist/{skillopt-optimization-method-sB_-yi1G.js.map → skillopt-optimization-method-qB1M554K.js.map} +1 -1
  394. package/dist/{spans-CVngGij3.d.ts → spans-vZoW__3q.d.ts} +2 -4
  395. package/dist/spans-vZoW__3q.d.ts.map +1 -0
  396. package/dist/{statistical-heldout-BjzSOmLH.d.ts → statistical-heldout-BYxHe3KO.d.ts} +9 -37
  397. package/dist/statistical-heldout-BYxHe3KO.d.ts.map +1 -0
  398. package/dist/{statistical-heldout-Bksv92Th.js → statistical-heldout-TP6ndL0B.js} +4 -5
  399. package/dist/{statistical-heldout-Bksv92Th.js.map → statistical-heldout-TP6ndL0B.js.map} +1 -1
  400. package/dist/{steps-DlepJPwD.d.ts → steps-B8fYY_Vo.d.ts} +1 -3
  401. package/dist/steps-B8fYY_Vo.d.ts.map +1 -0
  402. package/dist/{store-B3nWRy3B.d.ts → store-CMs5wGXP.d.ts} +2 -4
  403. package/dist/store-CMs5wGXP.d.ts.map +1 -0
  404. package/dist/{store-BhNuLdJw.js → store-ZykIyQmy.js} +2 -3
  405. package/dist/{store-BhNuLdJw.js.map → store-ZykIyQmy.js.map} +1 -1
  406. package/dist/{store-otlp-CFf27E8_.js → store-otlp-DmLm65XW.js} +8 -13
  407. package/dist/{store-otlp-CFf27E8_.js.map → store-otlp-DmLm65XW.js.map} +1 -1
  408. package/dist/{store-tool-spans-BK_8FjGG.js → store-tool-spans-C2g8UYm-.js} +17 -41
  409. package/dist/{store-tool-spans-BK_8FjGG.js.map → store-tool-spans-C2g8UYm-.js.map} +1 -1
  410. package/dist/{store-tool-spans-DxsFwtdr.d.ts → store-tool-spans-DMM6wMwB.d.ts} +11 -29
  411. package/dist/store-tool-spans-DMM6wMwB.d.ts.map +1 -0
  412. package/dist/storyboard/index.d.ts +1 -5
  413. package/dist/storyboard/index.d.ts.map +1 -1
  414. package/dist/storyboard/index.js +3 -5
  415. package/dist/storyboard/index.js.map +1 -1
  416. package/dist/{summary-report-C8V49Jt3.d.ts → summary-report-0La5vejY.d.ts} +5 -13
  417. package/dist/summary-report-0La5vejY.d.ts.map +1 -0
  418. package/dist/{summary-report-DHDWxe6p.js → summary-report-CPfsrLac.js} +21 -30
  419. package/dist/summary-report-CPfsrLac.js.map +1 -0
  420. package/dist/supervisor-run/index.d.ts +30 -29
  421. package/dist/supervisor-run/index.d.ts.map +1 -1
  422. package/dist/supervisor-run/index.js +6 -7
  423. package/dist/{systemone-CHnqwmYg.d.ts → systemone-UHbKD6LH.d.ts} +12 -24
  424. package/dist/systemone-UHbKD6LH.d.ts.map +1 -0
  425. package/dist/{systemone-protocol-Bl2EI2KQ.d.ts → systemone-protocol-C4t7JH4Y.d.ts} +1 -3
  426. package/dist/systemone-protocol-C4t7JH4Y.d.ts.map +1 -0
  427. package/dist/systemone-protocol.d.ts +1 -1
  428. package/dist/systemone-protocol.js +2 -3
  429. package/dist/{systemone-review-cQ9acAsb.d.ts → systemone-review-Cn9Uj0xG.d.ts} +8 -10
  430. package/dist/systemone-review-Cn9Uj0xG.d.ts.map +1 -0
  431. package/dist/{systemone-review-DFGtIUcf.js → systemone-review-S49gsy_y.js} +5 -6
  432. package/dist/{systemone-review-DFGtIUcf.js.map → systemone-review-S49gsy_y.js.map} +1 -1
  433. package/dist/systemone.d.ts +4 -4
  434. package/dist/systemone.js +3 -3
  435. package/dist/{task-failure-attributes-oIK3BhCR.js → task-failure-attributes-CC6VuIpk.js} +7 -10
  436. package/dist/{task-failure-attributes-oIK3BhCR.js.map → task-failure-attributes-CC6VuIpk.js.map} +1 -1
  437. package/dist/{tool-groups-b3oU_D88.d.ts → tool-groups-CFWmAGCV.d.ts} +3 -5
  438. package/dist/tool-groups-CFWmAGCV.d.ts.map +1 -0
  439. package/dist/{tool-waste-CkjzWmeY.d.ts → tool-waste-BFG1vwTV.d.ts} +4 -16
  440. package/dist/tool-waste-BFG1vwTV.d.ts.map +1 -0
  441. package/dist/{tool-waste-DLsjS_p-.js → tool-waste-CLJ46AbT.js} +10 -26
  442. package/dist/{tool-waste-DLsjS_p-.js.map → tool-waste-CLJ46AbT.js.map} +1 -1
  443. package/dist/trace-attributes.d.ts +1 -1
  444. package/dist/trace-attributes.js +1 -2
  445. package/dist/{trace-questions-BmT8M6UQ.d.ts → trace-questions-BFCQAzoT.d.ts} +4 -6
  446. package/dist/trace-questions-BFCQAzoT.d.ts.map +1 -0
  447. package/dist/trace-repair/index.d.ts +46 -92
  448. package/dist/trace-repair/index.d.ts.map +1 -1
  449. package/dist/trace-repair/index.js +32 -54
  450. package/dist/trace-repair/index.js.map +1 -1
  451. package/dist/traces.d.ts +13 -29
  452. package/dist/traces.d.ts.map +1 -1
  453. package/dist/traces.js +18 -22
  454. package/dist/traces.js.map +1 -1
  455. package/dist/{trajectory-D_7rLrvE.js → trajectory-O3GDHmev.js} +2 -3
  456. package/dist/{trajectory-D_7rLrvE.js.map → trajectory-O3GDHmev.js.map} +1 -1
  457. package/dist/trajectory-replay/index.d.ts +2 -22
  458. package/dist/trajectory-replay/index.d.ts.map +1 -1
  459. package/dist/trajectory-replay/index.js +19 -30
  460. package/dist/trajectory-replay/index.js.map +1 -1
  461. package/dist/{tree-DSqwJpL9.js → tree-DrIChF4a.js} +39 -68
  462. package/dist/{tree-DSqwJpL9.js.map → tree-DrIChF4a.js.map} +1 -1
  463. package/dist/{types-B_IFcKp5.d.ts → types-0KglnQ9o.d.ts} +3 -15
  464. package/dist/types-0KglnQ9o.d.ts.map +1 -0
  465. package/dist/{types-6Lfdlshp.d.ts → types-BEvjDziM.d.ts} +50 -62
  466. package/dist/types-BEvjDziM.d.ts.map +1 -0
  467. package/dist/{types-CnWmj8NW.js → types-BK0blWhe.js} +3 -4
  468. package/dist/{types-CnWmj8NW.js.map → types-BK0blWhe.js.map} +1 -1
  469. package/dist/{types-CmXY0PQf.d.ts → types-C-aOqgt2.d.ts} +2 -5
  470. package/dist/types-C-aOqgt2.d.ts.map +1 -0
  471. package/dist/{types-BXgASBCL.js → types-DK4vNv5q.js} +2 -3
  472. package/dist/{types-BXgASBCL.js.map → types-DK4vNv5q.js.map} +1 -1
  473. package/dist/{types-DZ0mYVw9.d.ts → types-DUR0dqET.d.ts} +3 -5
  474. package/dist/types-DUR0dqET.d.ts.map +1 -0
  475. package/dist/{types-M6eF9m-r.d.ts → types-e3HGaI7P.d.ts} +84 -24
  476. package/dist/types-e3HGaI7P.d.ts.map +1 -0
  477. package/dist/{verdict-BGQmxQ8A.js → verdict-C8TcdwfD.js} +3 -4
  478. package/dist/{verdict-BGQmxQ8A.js.map → verdict-C8TcdwfD.js.map} +1 -1
  479. package/dist/{verdict-C24NELtN.d.ts → verdict-D_qiBQ6_.d.ts} +1 -5
  480. package/dist/verdict-D_qiBQ6_.d.ts.map +1 -0
  481. package/dist/{verdict-cache-CL_7tePD.js → verdict-cache-BVH-fl18.js} +3 -4
  482. package/dist/{verdict-cache-CL_7tePD.js.map → verdict-cache-BVH-fl18.js.map} +1 -1
  483. package/dist/wire/index.d.ts +43 -51
  484. package/dist/wire/index.d.ts.map +1 -1
  485. package/dist/wire/index.js +1 -2
  486. package/docs/eval-surface-map.md +15 -0
  487. package/docs/rollout.md +132 -6
  488. package/package.json +18 -18
  489. package/dist/adversarial-smnADNFS.d.ts.map +0 -1
  490. package/dist/agent-profile-CNmwfaqq.d.ts.map +0 -1
  491. package/dist/agent-profile-cell-BcpFbNd5.d.ts.map +0 -1
  492. package/dist/analyze-runs-DfX6dHP0.d.ts.map +0 -1
  493. package/dist/attribute-vocabulary-CcXqHODT.d.ts.map +0 -1
  494. package/dist/benchmark-command-Cnjfo0Zh.js.map +0 -1
  495. package/dist/campaign-evidence-DunzcJGv.js.map +0 -1
  496. package/dist/campaign-uddTlFg5.js.map +0 -1
  497. package/dist/canonical-CFpojCN5.d.ts.map +0 -1
  498. package/dist/client-hwo3cJjR.d.ts.map +0 -1
  499. package/dist/completion-verifier-asaV1nSj.js.map +0 -1
  500. package/dist/cost-ledger-C1W3ICmP.d.ts.map +0 -1
  501. package/dist/dataset-DQqhOCPt.d.ts.map +0 -1
  502. package/dist/default-registry-CLG5YqGS.d.ts.map +0 -1
  503. package/dist/define-agent-eval-JKt3gMQr.d.ts.map +0 -1
  504. package/dist/descriptive-B2iPaT9J.d.ts +0 -89
  505. package/dist/descriptive-B2iPaT9J.d.ts.map +0 -1
  506. package/dist/descriptive-CVNy48rR.js.map +0 -1
  507. package/dist/emitter-DABYYTcH.d.ts.map +0 -1
  508. package/dist/engine-dtRVeuQs.d.ts.map +0 -1
  509. package/dist/errors-DEE6u6ot.d.ts.map +0 -1
  510. package/dist/evaluation-DblGquCB.d.ts.map +0 -1
  511. package/dist/exact-types-Do63KoKn.d.ts.map +0 -1
  512. package/dist/exporters-DWvM16LE.js.map +0 -1
  513. package/dist/exporters-Dk3oEbK_.d.ts.map +0 -1
  514. package/dist/failure-cluster-DN0t63Z0.d.ts.map +0 -1
  515. package/dist/feedback-trajectory-CYVJXolG.d.ts.map +0 -1
  516. package/dist/hf-dataset-CKxIJQba.js.map +0 -1
  517. package/dist/index-CHxwfW5g.d.ts.map +0 -1
  518. package/dist/index-CTIRz-AB.d.ts.map +0 -1
  519. package/dist/index-CalAsXMR.d.ts.map +0 -1
  520. package/dist/index-CdEVr8-O.d.ts.map +0 -1
  521. package/dist/index-CfJULcW5.d.ts.map +0 -1
  522. package/dist/index-D7fmC-1K.d.ts.map +0 -1
  523. package/dist/index-jnuFLxOs.d.ts.map +0 -1
  524. package/dist/integrity-D-s2iHiT.js.map +0 -1
  525. package/dist/integrity-D9lBnv_K.d.ts.map +0 -1
  526. package/dist/interval-ohuOJurX.d.ts.map +0 -1
  527. package/dist/judge-calibration-DFtEMlde.d.ts.map +0 -1
  528. package/dist/llm-judge-Cybq29bL.js.map +0 -1
  529. package/dist/lock-holder-DaJbfpci.d.ts.map +0 -1
  530. package/dist/matrix-B8l-Nsxd.js.map +0 -1
  531. package/dist/matrix-DtkZLD_3.d.ts.map +0 -1
  532. package/dist/mint-CkzpVPdz.d.ts +0 -81
  533. package/dist/mint-CkzpVPdz.d.ts.map +0 -1
  534. package/dist/multi-layer-verifier-DEgMUk6v.d.ts.map +0 -1
  535. package/dist/multiplicity-DIWHvysC.d.ts.map +0 -1
  536. package/dist/paired-promotion-decision-CQMJ5xGN.d.ts.map +0 -1
  537. package/dist/pareto-BiBnQXAE.js.map +0 -1
  538. package/dist/prime-bridge-transport-6feEglLf.d.ts.map +0 -1
  539. package/dist/prime-protocol-BGxjfhM4.d.ts.map +0 -1
  540. package/dist/promotion-gate-CkVZHagC.d.ts.map +0 -1
  541. package/dist/query-Cmv_U8vf.d.ts.map +0 -1
  542. package/dist/random-DGEyr3zG.d.ts.map +0 -1
  543. package/dist/redact-DXdlFb_U.d.ts.map +0 -1
  544. package/dist/registry-BcdJmyoU.d.ts.map +0 -1
  545. package/dist/release-confidence-CYIFH-fp.js.map +0 -1
  546. package/dist/render-BhJqXoBH.js.map +0 -1
  547. package/dist/researcher-DKWtoMWk.d.ts.map +0 -1
  548. package/dist/reward-BeUgVVC_.d.ts.map +0 -1
  549. package/dist/reward-hacking-WTxUbtbb.d.ts.map +0 -1
  550. package/dist/rollout-Dd1ucT_M.js.map +0 -1
  551. package/dist/rubric-predictive-validity-Cd5SCtAf.d.ts.map +0 -1
  552. package/dist/run-record-C3awiXPf.d.ts.map +0 -1
  553. package/dist/sandbox-harness-BlSOu4LX.d.ts.map +0 -1
  554. package/dist/schema-C-ziyJD7.d.ts.map +0 -1
  555. package/dist/schema-CvhfLjtZ.js.map +0 -1
  556. package/dist/schema-D6EVKzTB.d.ts.map +0 -1
  557. package/dist/search-kernel-CctpiDd2.d.ts.map +0 -1
  558. package/dist/search-ledger-types-p2xKfiDJ.d.ts.map +0 -1
  559. package/dist/sequential-KwGspfeR.d.ts.map +0 -1
  560. package/dist/spans-CVngGij3.d.ts.map +0 -1
  561. package/dist/statistical-heldout-BjzSOmLH.d.ts.map +0 -1
  562. package/dist/steps-DlepJPwD.d.ts.map +0 -1
  563. package/dist/store-B3nWRy3B.d.ts.map +0 -1
  564. package/dist/store-tool-spans-DxsFwtdr.d.ts.map +0 -1
  565. package/dist/summary-report-C8V49Jt3.d.ts.map +0 -1
  566. package/dist/summary-report-DHDWxe6p.js.map +0 -1
  567. package/dist/systemone-CHnqwmYg.d.ts.map +0 -1
  568. package/dist/systemone-protocol-Bl2EI2KQ.d.ts.map +0 -1
  569. package/dist/systemone-review-cQ9acAsb.d.ts.map +0 -1
  570. package/dist/terminal-record-CB9BFtjS.js.map +0 -1
  571. package/dist/tool-groups-b3oU_D88.d.ts.map +0 -1
  572. package/dist/tool-waste-CkjzWmeY.d.ts.map +0 -1
  573. package/dist/trace-questions-BmT8M6UQ.d.ts.map +0 -1
  574. package/dist/types-6Lfdlshp.d.ts.map +0 -1
  575. package/dist/types-B_IFcKp5.d.ts.map +0 -1
  576. package/dist/types-CmXY0PQf.d.ts.map +0 -1
  577. package/dist/types-DZ0mYVw9.d.ts.map +0 -1
  578. package/dist/types-M6eF9m-r.d.ts.map +0 -1
  579. package/dist/verdict-C24NELtN.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/storyboard/code-edit.ts","../../src/storyboard/index.ts"],"sourcesContent":["/**\n * Code-edit extraction + the \"watch the agent write code\" animation.\n *\n * The base storyboard (./index) compresses a run into scenes but keeps scenes\n * payload-free (title + narration + evidence span ids). To actually SHOW the\n * code an agent wrote, this module pulls the concrete edit (path, diff,\n * before/after, language) out of the raw edit-tool spans and renders a\n * self-contained HTML replay that types each file out, character by character,\n * like an editor recording.\n *\n * Additive on purpose: it reuses the canonical `Span` (trace/schema) and the\n * `Storyboard` IR (./index) without modifying the reducer/compiler — so it\n * composes with the existing pipeline and a Remotion consumer can read the same\n * `CodeEdit[]` to render an MP4.\n */\n\nimport type { Span } from '../trace/schema'\n\n\nconst EDIT_TOOLS =\n /(edit|write|patch|apply|str_replace|create.*file|save|insert|update.*file|multi_edit)/i\n\n/** A concrete code change lifted from a tool span. */\nexport interface CodeEdit {\n /** Span the edit came from — back-reference into the trace. */\n spanId: string\n path: string\n language?: string\n /** Unified diff, when the tool carried one. */\n diff?: string\n /** Full file body before / after, when present — enables true keystroke\n * animation rather than only flashing a diff. */\n before?: string\n after?: string\n additions: number\n deletions: number\n startedAt: number\n}\n\nfunction languageOf(path: string): string | undefined {\n const ext = path.includes('.') ? path.split('.').pop()?.toLowerCase() : undefined\n if (!ext) return undefined\n const map: Record<string, string> = {\n ts: 'ts',\n tsx: 'tsx',\n js: 'js',\n jsx: 'jsx',\n mjs: 'js',\n cjs: 'js',\n py: 'python',\n rs: 'rust',\n go: 'go',\n sol: 'solidity',\n java: 'java',\n rb: 'ruby',\n php: 'php',\n c: 'c',\n cpp: 'cpp',\n cs: 'csharp',\n css: 'css',\n scss: 'scss',\n html: 'html',\n json: 'json',\n yaml: 'yaml',\n yml: 'yaml',\n toml: 'toml',\n md: 'markdown',\n sh: 'bash',\n sql: 'sql',\n }\n return map[ext] ?? ext\n}\n\nfunction pick(obj: unknown, keys: string[]): string | undefined {\n if (!obj || typeof obj !== 'object') return undefined\n const rec = obj as Record<string, unknown>\n for (const k of Object.keys(rec)) {\n if (keys.includes(k.toLowerCase())) {\n const v = rec[k]\n if (typeof v === 'string') return v\n }\n }\n return undefined\n}\n\nfunction countDiff(diff?: string): { additions: number; deletions: number } {\n if (!diff) return { additions: 0, deletions: 0 }\n let additions = 0\n let deletions = 0\n for (const line of diff.split('\\n')) {\n if (line.startsWith('+') && !line.startsWith('+++')) additions++\n else if (line.startsWith('-') && !line.startsWith('---')) deletions++\n }\n return { additions, deletions }\n}\n\n/** Extract a CodeEdit from a single span, or undefined if it is not an edit. */\nfunction codeEditFromSpan(span: Span): CodeEdit | undefined {\n if (span.kind !== 'tool') return undefined\n const tool = span as Extract<Span, { kind: 'tool' }>\n if (!EDIT_TOOLS.test(tool.toolName)) return undefined\n const path = pick(tool.args, ['path', 'file_path', 'filepath', 'filename', 'file'])\n if (!path) return undefined\n const diff = pick(tool.args, ['diff', 'patch'])\n const after = pick(tool.args, ['content', 'new_str', 'new_string', 'newtext', 'text', 'body'])\n const before = pick(tool.args, ['old_str', 'old_string', 'oldtext', 'original'])\n const counts = countDiff(diff)\n return {\n spanId: span.spanId,\n path,\n language: languageOf(path),\n diff,\n before,\n after,\n additions: diff ? counts.additions : after ? after.split('\\n').length : 0,\n deletions: diff ? counts.deletions : 0,\n startedAt: span.startedAt,\n }\n}\n\n/** All code edits in a run, in chronological order. */\nexport function extractCodeEdits(spans: readonly Span[]): CodeEdit[] {\n return spans\n .map(codeEditFromSpan)\n .filter((e): e is CodeEdit => e != null)\n .sort((a, b) => a.startedAt - b.startedAt)\n}\n\n\n\n/** The text the animation types for an edit: prefer the full new file body,\n * then the added lines of a diff, then a minimal placeholder so the scene is\n * never blank. */\nexport function editAnimationText(edit: CodeEdit): string {\n if (edit.after?.trim()) return edit.after\n if (edit.diff) {\n const added = edit.diff\n .split('\\n')\n .filter((l) => l.startsWith('+') && !l.startsWith('+++'))\n .map((l) => l.slice(1))\n .join('\\n')\n if (added.trim()) return added\n }\n return `// ${edit.path}\\n// (${edit.additions} line${edit.additions === 1 ? '' : 's'} written)`\n}\n\nfunction esc(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\nexport interface CodeAnimationOptions {\n /** Page title. Default \"Agent writing code\". */\n title?: string\n /** Characters typed per animation tick. Higher = faster. Default 4. */\n charsPerTick?: number\n /** Pause between files, ms. Default 900. */\n pauseBetweenMs?: number\n}\n\n/**\n * Render a self-contained HTML page that animates the agent writing each file,\n * character by character, with a filename tab, line numbers, and a blinking\n * cursor — the shareable \"watch it build\" clip. No build step, no assets, no\n * deps. The same `CodeEdit[]` feeds a Remotion MP4 renderer in a consumer\n * package; this is the dependency-free baseline.\n */\nexport function renderCodeAnimationHtml(\n source: readonly Span[] | readonly CodeEdit[],\n opts: CodeAnimationOptions = {},\n): string {\n const edits: CodeEdit[] =\n source.length > 0 && 'path' in (source[0] as object)\n ? (source as CodeEdit[])\n : extractCodeEdits(source as readonly Span[])\n\n const files = edits.map((e) => ({\n path: e.path,\n language: e.language ?? '',\n additions: e.additions,\n deletions: e.deletions,\n code: editAnimationText(e),\n }))\n const title = opts.title ?? 'Agent writing code'\n const charsPerTick = opts.charsPerTick ?? 4\n const pauseBetweenMs = opts.pauseBetweenMs ?? 900\n const filesJson = JSON.stringify(files)\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>${esc(title)}</title>\n<style>\n :root { color-scheme: dark; }\n * { box-sizing: border-box; }\n body { margin: 0; background: #0b0f17; color: #e6edf3;\n font: 14px/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n display: flex; flex-direction: column; min-height: 100vh; align-items: center; justify-content: center; gap: 14px; }\n h1 { font-family: ui-sans-serif, system-ui, sans-serif; font-size: 1rem; font-weight: 600; color: #9aa7b5; margin: 0; }\n .editor { width: min(900px, 94vw); background: #0d1320; border: 1px solid #1e2a3a; border-radius: 12px;\n overflow: hidden; box-shadow: 0 16px 50px rgba(0,0,0,.5); }\n .tabbar { display: flex; align-items: center; gap: 8px; background: #111a29; padding: 9px 14px; border-bottom: 1px solid #1e2a3a; }\n .dot { width: 11px; height: 11px; border-radius: 50%; }\n .dot.r { background: #ff5f56; } .dot.y { background: #ffbd2e; } .dot.g { background: #27c93f; }\n .tab { margin-left: 10px; background: #0d1320; padding: 5px 12px; border-radius: 7px 7px 0 0;\n color: #cdd9e5; font-family: ui-sans-serif, system-ui, sans-serif; font-size: .85rem; }\n .lang { color: #5b6b7d; font-size: .75rem; margin-left: 6px; }\n .adds { margin-left: auto; color: #3fb950; font-size: .78rem; font-family: ui-sans-serif, system-ui, sans-serif; }\n .dels { color: #f85149; margin-left: 8px; }\n .codewrap { display: flex; max-height: 60vh; overflow: auto; }\n .gutter { padding: 14px 10px 14px 14px; text-align: right; color: #3a4757; user-select: none; white-space: pre; }\n pre { margin: 0; padding: 14px 18px 14px 6px; white-space: pre; tab-size: 2; flex: 1; }\n .cursor { display: inline-block; width: 8px; margin-left: 1px; background: #58a6ff; animation: blink .9s steps(1) infinite; }\n @keyframes blink { 50% { opacity: 0; } }\n .controls { display: flex; gap: 10px; align-items: center; font-family: ui-sans-serif, system-ui, sans-serif; font-size: .85rem; color: #8b98a6; }\n button { background: #1b2636; color: #e6edf3; border: 1px solid #2a3a4f; border-radius: 8px; padding: 6px 12px; cursor: pointer; font: inherit; }\n button:hover { background: #243349; }\n .empty { padding: 40px; color: #5b6b7d; }\n</style>\n</head>\n<body>\n <h1>✏️ ${esc(title)}</h1>\n <div class=\"editor\">\n <div class=\"tabbar\">\n <span class=\"dot r\"></span><span class=\"dot y\"></span><span class=\"dot g\"></span>\n <span class=\"tab\" id=\"tab\">—</span><span class=\"lang\" id=\"lang\"></span>\n <span class=\"adds\" id=\"adds\"></span>\n </div>\n <div class=\"codewrap\"><div class=\"gutter\" id=\"gutter\">1</div><pre id=\"code\"></pre></div>\n </div>\n <div class=\"controls\">\n <button id=\"pp\">⏸ Pause</button><button id=\"restart\">↻ Restart</button>\n <span id=\"counter\"></span>\n </div>\n<script>\n const FILES = ${filesJson};\n const CPT = ${charsPerTick}, PAUSE = ${pauseBetweenMs};\n const codeEl = document.getElementById('code'), gutterEl = document.getElementById('gutter');\n const tabEl = document.getElementById('tab'), langEl = document.getElementById('lang');\n const addsEl = document.getElementById('adds'), counterEl = document.getElementById('counter');\n let fi = 0, ci = 0, playing = true, raf = 0, paused = false;\n if (!FILES.length) { codeEl.innerHTML = '<span class=\"empty\">No code edits in this run.</span>'; }\n function esc(s){return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}\n function setHeader(){ const f = FILES[fi]; tabEl.textContent = f.path; langEl.textContent = f.language || '';\n addsEl.innerHTML = '+' + f.additions + (f.deletions ? ' <span class=\"dels\">-' + f.deletions + '</span>' : '');\n counterEl.textContent = (fi+1) + ' / ' + FILES.length + ' files'; }\n function paint(){ const f = FILES[fi]; const shown = f.code.slice(0, ci);\n const lines = (shown.match(/\\\\n/g) || []).length + 1;\n gutterEl.textContent = Array.from({length: lines}, (_, k) => k+1).join('\\\\n');\n codeEl.innerHTML = esc(shown) + '<span class=\"cursor\">&nbsp;</span>';\n const wrap = codeEl.parentElement; wrap.scrollTop = wrap.scrollHeight; }\n function tick(){ if (paused || !FILES.length) return;\n const f = FILES[fi];\n if (ci < f.code.length){ ci = Math.min(f.code.length, ci + CPT); paint(); raf = requestAnimationFrame(tick); }\n else if (fi < FILES.length - 1){ setTimeout(() => { fi++; ci = 0; setHeader(); paint(); raf = requestAnimationFrame(tick); }, PAUSE); }\n else { playing = false; document.getElementById('pp').textContent = '▶ Play'; } }\n document.getElementById('pp').onclick = () => { if (!playing){ playing = true; paused = false; tick(); } else { paused = !paused; if (!paused) tick(); } document.getElementById('pp').textContent = paused ? '▶ Play' : '⏸ Pause'; };\n document.getElementById('restart').onclick = () => { fi = 0; ci = 0; playing = true; paused = false; document.getElementById('pp').textContent = '⏸ Pause'; setHeader(); paint(); cancelAnimationFrame(raf); tick(); };\n if (FILES.length){ setHeader(); paint(); tick(); }\n</script>\n</body>\n</html>\n`\n}\n","/**\n * Storyboard — compile a raw agent trace into a small set of meaningful scenes,\n * then render them as a shareable, watchable replay.\n *\n * Span[] → SemanticEvent[] → Storyboard{scenes} → { markdown | html }\n *\n * The trace is the source of truth; the storyboard is the IR; markdown/html\n * (and, in a consumer package, Remotion/MP4) are compiled targets. Everything\n * here is PURE — same spans in, same bytes out (no clock/random) — so a run's\n * replay is deterministic and diffable.\n *\n * Crucially, every scene carries a modality-typed VISUAL extracted from the\n * span — a browser/computer screenshot, a code diff, a terminal command +\n * output, file content, an API request/response, or reasoning prose — so no\n * matter what the agent did, the replay SHOWS it, not just narrates it. The\n * reducer is rules-based; an LLM pass can refine titles/summaries later, but\n * the structure + visuals do not depend on one. Renderers that need a browser\n * (Remotion, React) live in consumers; this module only emits strings.\n */\n\nimport { escapeHtml } from '../reporting-html'\nimport type { Span } from '../trace/schema'\n\n/** What the agent meaningfully did — the compressed vocabulary. */\nexport type SemanticKind =\n | 'understood_task'\n | 'user_message'\n | 'agent_reply'\n | 'reasoned'\n | 'ran_command'\n | 'read_file'\n | 'edited_code'\n | 'searched'\n | 'used_browser'\n | 'used_computer'\n | 'called_api'\n | 'called_tool'\n | 'evaluated'\n | 'observed_failure'\n | 'completed'\n\n/** The modality-typed payload a scene shows. This is what makes any agent\n * action — screen, browser, shell, code, API — actually viewable. */\nexport type SceneVisual =\n | { type: 'screenshot'; src: string; caption?: string }\n | { type: 'browser'; url?: string; action?: string; screenshot?: string }\n | { type: 'diff'; path: string; patch: string }\n | { type: 'code'; path: string; content: string }\n | { type: 'terminal'; command: string; output?: string }\n | {\n type: 'api'\n method?: string\n url: string\n status?: number\n request?: string\n response?: string\n }\n | { type: 'prose'; text: string }\n | { type: 'none' }\n\nexport interface SemanticEvent {\n kind: SemanticKind\n /** One-line headline (the ticket/scene title). */\n title: string\n /** Short human summary. */\n summary: string\n /** The modality payload to show for this moment. */\n visual: SceneVisual\n /** Span ids backing this moment — the evidence trail. */\n evidenceSpanIds: string[]\n /** 1 (noise) … 5 (pivotal: failures, edits). Drives selection + duration. */\n importance: 1 | 2 | 3 | 4 | 5\n startTs: number\n endTs: number\n}\n\nexport interface ReduceOptions {\n /** Collapse adjacent same-kind moments into one. Default true. */\n collapseAdjacent?: boolean\n}\n\n// ── Modality extraction ─────────────────────────────────────────────────────\n\nfunction str(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined\n}\n\nfunction num(v: unknown): number | undefined {\n return typeof v === 'number' ? v : undefined\n}\n\nfunction attr(span: Span, ...keys: string[]): unknown {\n const a = span.attributes as Record<string, unknown> | undefined\n if (!a) return undefined\n for (const k of keys) if (a[k] != null) return a[k]\n return undefined\n}\n\nfunction asObj(v: unknown): Record<string, unknown> | undefined {\n return v && typeof v === 'object' && !Array.isArray(v)\n ? (v as Record<string, unknown>)\n : undefined\n}\n\nfunction safeJson(v: unknown): string | undefined {\n if (v == null) return undefined\n if (typeof v === 'string') return v\n try {\n return JSON.stringify(v, null, 2)\n } catch {\n return String(v)\n }\n}\n\n/** Is this string an embeddable image (data URI or http URL)? */\nfunction isImageSrc(s: string | undefined): s is string {\n return !!s && (s.startsWith('data:image') || /^https?:\\/\\//.test(s))\n}\n\n/** Pull the modality-appropriate visual out of whatever the span carries.\n * Conventions (checked in priority order): an image rides on\n * `attributes.screenshot|image|frame|videoFrame` or `result.screenshot`; a\n * diff on `attributes.diff|patch` or `args.diff`; a command on `args` /\n * `args.command`; an API call on a `url`/`method` in args; file content on\n * `result`. Unknown tools degrade to an args/result inspector. */\nfunction extractVisual(span: Span): SceneVisual {\n const shot =\n str(attr(span, 'screenshot', 'screenshotUrl', 'image', 'frame', 'videoFrame')) ??\n (span.kind === 'tool'\n ? (str(asObj(span.result)?.screenshot) ?? str(asObj(span.result)?.image))\n : undefined)\n\n if (span.kind === 'tool') {\n const tn = span.toolName.toLowerCase()\n const a = asObj(span.args)\n // computer use (GUI / desktop control)\n if (/computer|cua|desktop|\\bgui\\b|xdotool|mouse|keyboard|screen_|pyautogui/.test(tn)) {\n return {\n type: 'browser',\n action: str(a?.action) ?? span.toolName,\n url: str(a?.target),\n screenshot: shot,\n }\n }\n // browser use\n if (\n /browser|playwright|puppeteer|\\bpage\\b|navigate|goto|\\bclick\\b|\\btype\\b|screenshot|dom/.test(\n tn,\n )\n ) {\n return {\n type: 'browser',\n url: str(a?.url) ?? str(attr(span, 'url')),\n action: str(a?.action) ?? str(a?.selector) ?? span.toolName,\n screenshot: shot,\n }\n }\n // code edit → diff\n const diff = str(attr(span, 'diff', 'patch')) ?? str(a?.diff) ?? str(a?.patch)\n if (diff && /edit|write|patch|apply|str_replace|create|save|file/.test(tn)) {\n return {\n type: 'diff',\n path: str(a?.path) ?? str(a?.file) ?? str(attr(span, 'path')) ?? '',\n patch: truncate(diff, 2000),\n }\n }\n if (/edit|write|patch|apply|str_replace/.test(tn)) {\n const newText = str(a?.new_str) ?? str(a?.content) ?? str(a?.text)\n return {\n type: 'diff',\n path: str(a?.path) ?? str(a?.file) ?? '',\n patch: newText ? `+ ${truncate(newText, 1600)}` : '(no diff captured)',\n }\n }\n // file read → code\n if (/read|\\bcat\\b|open|view|get_file|load|fetch_file/.test(tn)) {\n const content =\n str(asObj(span.result)?.content) ??\n (typeof span.result === 'string' ? span.result : undefined) ??\n str(attr(span, 'content'))\n return {\n type: 'code',\n path: str(a?.path) ?? str(a?.file) ?? '',\n content: truncate(content ?? '', 1400),\n }\n }\n // search\n if (/search|grep|find|glob|query/.test(tn)) {\n return {\n type: 'terminal',\n command: `search ${str(a?.query) ?? str(a?.pattern) ?? ''}`.trim(),\n output: truncate(safeJson(span.result) ?? '', 1000),\n }\n }\n // api / http / network\n const url = str(a?.url) ?? str(attr(span, 'url'))\n if (url || /http|\\bapi\\b|fetch|request|webhook|rest|graphql|endpoint/.test(tn)) {\n return {\n type: 'api',\n method: str(a?.method) ?? str(attr(span, 'method')),\n url: url ?? span.toolName,\n status: num(attr(span, 'status', 'statusCode')) ?? num(asObj(span.result)?.status),\n request: truncate(str(a?.body) ?? safeJson(span.args) ?? '', 900),\n response: truncate(str(attr(span, 'response')) ?? safeJson(span.result) ?? '', 900),\n }\n }\n // shell / sandbox exec\n if (/shell|exec|bash|\\brun\\b|terminal|command|sandbox|process/.test(tn)) {\n const command =\n typeof span.args === 'string'\n ? span.args\n : (str(a?.command) ?? str(a?.cmd) ?? span.toolName)\n const output =\n str(attr(span, 'output', 'stdout')) ??\n (typeof span.result === 'string' ? span.result : safeJson(span.result))\n return {\n type: 'terminal',\n command: truncate(command, 240),\n output: truncate(output ?? '', 1400),\n }\n }\n // generic tool — show the call\n return {\n type: 'api',\n url: span.toolName,\n request: truncate(safeJson(span.args) ?? '', 900),\n response: truncate(safeJson(span.result) ?? '', 900),\n }\n }\n\n if (isImageSrc(shot)) return { type: 'screenshot', src: shot }\n if (span.kind === 'llm') {\n const text = str(span.output) ?? str(span.messages?.[span.messages.length - 1]?.content)\n return text ? { type: 'prose', text: truncate(text, 900) } : { type: 'none' }\n }\n if (span.kind === 'sandbox')\n return { type: 'terminal', command: span.name, output: str(attr(span, 'output')) }\n return { type: 'none' }\n}\n\n// ── Classification ──────────────────────────────────────────────────────────\n\ninterface Classified {\n kind: SemanticKind\n importance: 1 | 2 | 3 | 4 | 5\n label: string\n}\n\nfunction toolLabel(span: Span): string {\n if (span.kind === 'tool') {\n const a = asObj(span.args)\n const arg =\n typeof span.args === 'string'\n ? span.args\n : a\n ? (str(a.path) ??\n str(a.url) ??\n str(a.command) ??\n str(a.query) ??\n Object.values(a).find((v) => typeof v === 'string'))\n : undefined\n return typeof arg === 'string' && arg.length > 0\n ? `${span.toolName}: ${truncate(arg, 60)}`\n : span.toolName\n }\n return span.name\n}\n\nfunction classify(span: Span): Classified {\n if (span.status === 'error' || span.error) {\n return { kind: 'observed_failure', importance: 5, label: span.error ?? span.name }\n }\n if (span.kind === 'llm' || span.kind === 'agent')\n return { kind: 'reasoned', importance: 2, label: span.name }\n if (span.kind === 'judge') return { kind: 'evaluated', importance: 2, label: span.name }\n if (span.kind === 'retrieval') return { kind: 'searched', importance: 2, label: span.name }\n if (span.kind === 'sandbox') return { kind: 'ran_command', importance: 3, label: span.name }\n if (span.kind === 'tool') {\n const tn = span.toolName.toLowerCase()\n const label = toolLabel(span)\n if (/computer|cua|desktop|\\bgui\\b|xdotool|pyautogui/.test(tn))\n return { kind: 'used_computer', importance: 3, label }\n if (/browser|playwright|puppeteer|\\bpage\\b|navigate|goto|\\bclick\\b|screenshot|dom/.test(tn))\n return { kind: 'used_browser', importance: 3, label }\n if (/edit|write|patch|apply|str_replace|create.*file|save/.test(tn))\n return { kind: 'edited_code', importance: 4, label }\n if (/read|\\bcat\\b|open|view|get.*file|load/.test(tn))\n return { kind: 'read_file', importance: 2, label }\n if (/search|grep|find|glob|query/.test(tn)) return { kind: 'searched', importance: 2, label }\n if (\n /http|\\bapi\\b|fetch|request|webhook|rest|graphql|endpoint/.test(tn) ||\n str(asObj(span.args)?.url)\n ) {\n return { kind: 'called_api', importance: 3, label }\n }\n if (/shell|exec|bash|\\brun\\b|terminal|command|process/.test(tn))\n return { kind: 'ran_command', importance: 3, label }\n return { kind: 'called_tool', importance: 3, label }\n }\n return { kind: 'called_tool', importance: 2, label: span.name }\n}\n\nconst KIND_VERB: Record<SemanticKind, string> = {\n understood_task: 'Understood the task',\n user_message: 'User said',\n agent_reply: 'Agent replied',\n reasoned: 'Reasoned',\n ran_command: 'Ran a command',\n read_file: 'Read files',\n edited_code: 'Edited code',\n searched: 'Searched',\n used_browser: 'Used the browser',\n used_computer: 'Controlled the computer',\n called_api: 'Called an API',\n called_tool: 'Used a tool',\n evaluated: 'Evaluated the result',\n observed_failure: 'Hit a failure',\n completed: 'Finished',\n}\n\n/** Kinds that must never collapse into a neighbour — each is its own beat:\n * a failure, and every conversation turn (so the dialogue reads in full). */\nconst STANDALONE_KINDS = new Set<SemanticKind>([\n 'observed_failure',\n 'understood_task',\n 'user_message',\n 'agent_reply',\n])\n\n/** Lift the conversation turns out of an LLM span. The user/assistant text\n * lives in `LlmSpan.messages` (role:'user'|'assistant') and the new reply in\n * `output`; the full history repeats across spans, so `seen` dedupes turns to\n * the first time each is said. The first user turn becomes `understood_task`\n * (the premise), later user turns `user_message`, assistant text `agent_reply`. */\nfunction conversationEvents(\n span: Span,\n seen: Set<string>,\n state: { sawUser: boolean },\n): SemanticEvent[] {\n if (span.kind !== 'llm') return []\n const out: SemanticEvent[] = []\n const emit = (kind: SemanticKind, text: string, importance: 1 | 2 | 3 | 4 | 5) => {\n const t = text.trim()\n if (!t) return\n const who = kind === 'agent_reply' ? 'a' : 'u'\n const key = `${who}\\n${t}`\n if (seen.has(key)) return\n seen.add(key)\n const speaker = kind === 'understood_task' ? 'Task' : kind === 'user_message' ? 'User' : 'Agent'\n out.push({\n kind,\n title: `${speaker}: ${truncate(t, 64)}`,\n summary: truncate(t, 280),\n visual: { type: 'prose', text: truncate(t, 1200) },\n evidenceSpanIds: [span.spanId],\n importance,\n startTs: span.startedAt,\n endTs: span.endedAt ?? span.startedAt,\n })\n }\n for (const m of span.messages ?? []) {\n const content = str(m.content)\n if (!content) continue\n if (m.role === 'user') {\n emit(state.sawUser ? 'user_message' : 'understood_task', content, state.sawUser ? 4 : 5)\n state.sawUser = true\n } else if (m.role === 'assistant') {\n emit('agent_reply', content, 3)\n }\n }\n const reply = str(span.output)\n if (reply) emit('agent_reply', reply, 3)\n return out\n}\n\n/**\n * Reduce a span tree into the meaningful moments a viewer cares about. The\n * conversation (user asks, agent replies) is lifted from LLM spans first so the\n * dialogue is first-class; the remaining work spans are classified + have their\n * modality visual extracted. Adjacent same-kind work moments collapse (the\n * compression step), carrying the latest visual; failures and conversation\n * turns never collapse.\n */\nexport function reduceToSemanticEvents(\n spans: readonly Span[],\n opts: ReduceOptions = {},\n): SemanticEvent[] {\n const collapse = opts.collapseAdjacent ?? true\n const ordered = [...spans].sort((a, b) => a.startedAt - b.startedAt)\n const seen = new Set<string>()\n const convState = { sawUser: false }\n const raw: SemanticEvent[] = []\n for (const s of ordered) {\n const conv = conversationEvents(s, seen, convState)\n if (conv.length > 0) {\n // this LLM span IS dialogue — surface the turns, not a generic \"reasoned\"\n raw.push(...conv)\n continue\n }\n const c = classify(s)\n raw.push({\n kind: c.kind,\n title: c.label,\n summary: `${KIND_VERB[c.kind]} — ${c.label}`,\n visual: extractVisual(s),\n evidenceSpanIds: [s.spanId],\n importance: c.importance,\n startTs: s.startedAt,\n endTs: s.endedAt ?? s.startedAt,\n })\n }\n if (!collapse) return raw\n\n const merged: SemanticEvent[] = []\n for (const ev of raw) {\n const prev = merged[merged.length - 1]\n if (prev && prev.kind === ev.kind && !STANDALONE_KINDS.has(ev.kind)) {\n prev.evidenceSpanIds.push(...ev.evidenceSpanIds)\n prev.endTs = Math.max(prev.endTs, ev.endTs)\n if (ev.visual.type !== 'none') prev.visual = ev.visual // keep the latest state\n const n = prev.evidenceSpanIds.length\n prev.title = `${KIND_VERB[ev.kind]} (${n}×)`\n prev.summary = `${KIND_VERB[ev.kind]} ${n} time${n === 1 ? '' : 's'} — latest: ${ev.title}`\n } else {\n merged.push({ ...ev, evidenceSpanIds: [...ev.evidenceSpanIds] })\n }\n }\n return merged\n}\n\n// ── Storyboard ────────────────────────────────────────────────────────────\n\nexport type SceneType =\n | 'title_card'\n | 'prompt'\n | 'reply'\n | 'reasoning'\n | 'terminal'\n | 'file'\n | 'diff'\n | 'search'\n | 'browser'\n | 'computer'\n | 'api'\n | 'tool'\n | 'eval'\n | 'error'\n | 'summary'\n\nexport interface Scene {\n sceneType: SceneType\n title: string\n narration: string\n /** The modality payload the renderer shows. */\n visual: SceneVisual\n durationMs: number\n evidenceSpanIds: string[]\n}\n\nexport interface Storyboard {\n title: string\n totalMs: number\n scenes: Scene[]\n}\n\nexport interface CompileOptions {\n /** Headline for the title card. Default \"Agent run\". */\n title?: string\n /** Max action scenes between the title + summary cards. Default 16. */\n maxScenes?: number\n}\n\nconst KIND_TO_SCENE: Record<SemanticKind, SceneType> = {\n understood_task: 'title_card',\n user_message: 'prompt',\n agent_reply: 'reply',\n reasoned: 'reasoning',\n ran_command: 'terminal',\n read_file: 'file',\n edited_code: 'diff',\n searched: 'search',\n used_browser: 'browser',\n used_computer: 'computer',\n called_api: 'api',\n called_tool: 'tool',\n evaluated: 'eval',\n observed_failure: 'error',\n completed: 'summary',\n}\n\nconst DURATION_BY_IMPORTANCE: Record<1 | 2 | 3 | 4 | 5, number> = {\n 1: 2500,\n 2: 3000,\n 3: 4000,\n 4: 5000,\n 5: 6000,\n}\n\n/**\n * Select the moments worth showing and lay them out as scenes. Every failure\n * (importance 5) and edit (4) is always kept; the rest fill the budget by\n * importance, then re-sort chronological. A title card opens, a summary closes.\n */\nexport function compileStoryboard(\n events: readonly SemanticEvent[],\n opts: CompileOptions = {},\n): Storyboard {\n const title = opts.title ?? 'Agent run'\n const maxScenes = opts.maxScenes ?? 16\n\n // The first user turn is the premise — it frames the title card rather than\n // being shown twice, so it's excluded from the action selection below.\n const taskEvent = events.find((e) => e.kind === 'understood_task')\n\n const indexed = events.filter((ev) => ev.kind !== 'understood_task').map((ev, i) => ({ ev, i }))\n const mustKeep = indexed.filter(({ ev }) => ev.importance >= 4)\n const rest = indexed\n .filter(({ ev }) => ev.importance < 4)\n .sort((a, b) => b.ev.importance - a.ev.importance || a.i - b.i)\n const budget = Math.max(0, maxScenes - mustKeep.length)\n const selected = [...mustKeep, ...rest.slice(0, budget)].sort((a, b) => a.i - b.i)\n\n const actionScenes: Scene[] = selected.map(({ ev }) => ({\n sceneType: KIND_TO_SCENE[ev.kind],\n title: ev.title,\n narration: ev.summary,\n visual: ev.visual,\n durationMs: DURATION_BY_IMPORTANCE[ev.importance],\n evidenceSpanIds: ev.evidenceSpanIds,\n }))\n\n const failures = events.filter((e) => e.kind === 'observed_failure').length\n const edits = events.filter((e) => e.kind === 'edited_code').length\n const commands = events.filter((e) => e.kind === 'ran_command').length\n const summaryNarration =\n `${events.length} moments · ${commands} command${commands === 1 ? '' : 's'} · ` +\n `${edits} edit${edits === 1 ? '' : 's'} · ${failures} failure${failures === 1 ? '' : 's'}`\n\n const scenes: Scene[] = [\n {\n sceneType: 'title_card',\n title,\n narration: taskEvent ? taskEvent.summary : 'The agent receives its task.',\n visual: taskEvent ? taskEvent.visual : { type: 'none' },\n durationMs: 3000,\n evidenceSpanIds: taskEvent ? taskEvent.evidenceSpanIds : [],\n },\n ...actionScenes,\n {\n sceneType: 'summary',\n title: failures > 0 ? 'Finished — with failures' : 'Finished',\n narration: summaryNarration,\n visual: { type: 'none' },\n durationMs: 4000,\n evidenceSpanIds: [],\n },\n ]\n return { title, totalMs: scenes.reduce((s, sc) => s + sc.durationMs, 0), scenes }\n}\n\n// ── Renderers (pure string out) ─────────────────────────────────────────────\n\nconst SCENE_ICON: Record<SceneType, string> = {\n title_card: '🎬',\n prompt: '💬',\n reply: '🤖',\n reasoning: '🧠',\n terminal: '⌨️',\n file: '📄',\n diff: '✏️',\n search: '🔎',\n browser: '🌐',\n computer: '🖥️',\n api: '🔌',\n tool: '🔧',\n eval: '⚖️',\n error: '❌',\n summary: '🏁',\n}\n\nfunction mmss(ms: number): string {\n const s = Math.round(ms / 1000)\n return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, Math.max(0, max - 1))}…`\n}\n\n/** A short modality tag for the markdown shot list. */\nfunction visualMarkdown(v: SceneVisual): string {\n switch (v.type) {\n case 'screenshot':\n return `🖼 screenshot (${truncate(v.src, 60)})`\n case 'browser':\n return `🌐 ${v.action ?? 'browser'}${v.url ? ` → ${v.url}` : ''}${v.screenshot ? ' [screenshot]' : ''}`\n case 'diff':\n return `\\n\\n\\`\\`\\`diff\\n${truncate(v.patch, 600)}\\n\\`\\`\\`${v.path ? `\\n_${v.path}_` : ''}`\n case 'code':\n return `\\n\\n\\`\\`\\`\\n${truncate(v.content, 500)}\\n\\`\\`\\`${v.path ? `\\n_${v.path}_` : ''}`\n case 'terminal':\n return `\\n\\n\\`\\`\\`sh\\n$ ${v.command}${v.output ? `\\n${truncate(v.output, 500)}` : ''}\\n\\`\\`\\``\n case 'api':\n return `🔌 ${v.method ?? 'CALL'} ${v.url}${v.status != null ? ` → ${v.status}` : ''}`\n case 'prose':\n return `\\n\\n> ${truncate(v.text, 400).replace(/\\n/g, '\\n> ')}`\n default:\n return ''\n }\n}\n\n/** Build the (escaped, structured) HTML for a scene's visual. We never inject\n * raw agent markup — every text part is escaped; only image `src` (data/http)\n * is passed through as an attribute. */\nfunction visualHtml(v: SceneVisual): string {\n switch (v.type) {\n case 'screenshot':\n return `<img class=\"shot\" src=\"${escapeHtml(v.src)}\" alt=\"screenshot\" loading=\"lazy\"/>`\n case 'browser': {\n const bar = `<div class=\"urlbar\">${escapeHtml(v.url ?? v.action ?? 'browser')}</div>`\n const body = isImageSrc(v.screenshot)\n ? `<img class=\"shot\" src=\"${escapeHtml(v.screenshot)}\" alt=\"page\" loading=\"lazy\"/>`\n : `<div class=\"browser-action\">${escapeHtml(v.action ?? 'navigated')}</div>`\n return `<div class=\"browser\">${bar}${body}</div>`\n }\n case 'diff': {\n const lines = v.patch.split('\\n').map((l) => {\n const cls = l.startsWith('+') ? 'add' : l.startsWith('-') ? 'del' : ''\n return `<span class=\"${cls}\">${escapeHtml(l)}</span>`\n })\n return `${v.path ? `<div class=\"pathhdr\">${escapeHtml(v.path)}</div>` : ''}<pre class=\"diff\">${lines.join('\\n')}</pre>`\n }\n case 'code':\n return `${v.path ? `<div class=\"pathhdr\">${escapeHtml(v.path)}</div>` : ''}<pre class=\"code\">${escapeHtml(v.content)}</pre>`\n case 'terminal':\n return `<pre class=\"term\"><span class=\"cmd\">$ ${escapeHtml(v.command)}</span>${v.output ? `\\n${escapeHtml(v.output)}` : ''}</pre>`\n case 'api': {\n const badge = `<span class=\"method\">${escapeHtml(v.method ?? 'CALL')}</span> <span class=\"url\">${escapeHtml(v.url)}</span>${v.status != null ? ` <span class=\"status s${Math.floor(v.status / 100)}\">${v.status}</span>` : ''}`\n const req = v.request\n ? `<div class=\"kv\"><b>req</b><pre>${escapeHtml(v.request)}</pre></div>`\n : ''\n const res = v.response\n ? `<div class=\"kv\"><b>res</b><pre>${escapeHtml(v.response)}</pre></div>`\n : ''\n return `<div class=\"api\"><div class=\"apihdr\">${badge}</div>${req}${res}</div>`\n }\n case 'prose':\n return `<div class=\"prose\">${escapeHtml(v.text)}</div>`\n default:\n return ''\n }\n}\n\n/** Render the storyboard as a Markdown timeline — the human-readable shot list. */\nexport function renderStoryboardMarkdown(storyboard: Storyboard): string {\n const out: string[] = [\n `# 🎬 ${storyboard.title}`,\n '',\n `_${storyboard.scenes.length} scenes · ${mmss(storyboard.totalMs)} replay_`,\n '',\n ]\n let elapsed = 0\n for (const sc of storyboard.scenes) {\n out.push(`### [${mmss(elapsed)}] ${SCENE_ICON[sc.sceneType]} ${sc.title}`)\n out.push('')\n out.push(sc.narration)\n const vm = visualMarkdown(sc.visual)\n if (vm) out.push(vm)\n if (sc.evidenceSpanIds.length > 0) {\n out.push('')\n out.push(`_evidence: ${sc.evidenceSpanIds.length} span(s)_`)\n }\n out.push('')\n elapsed += sc.durationMs\n }\n return out.join('\\n')\n}\n\nexport interface HtmlRenderOptions {\n /** Document title + on-page heading. Defaults to the storyboard title. */\n title?: string\n}\n\n/**\n * Render the storyboard as a self-contained, auto-playing HTML replay — one\n * shareable file, no build step, no external assets. Each scene animates in\n * for its duration and SHOWS its modality (screenshot / diff / terminal / API\n * / browser / prose); controls let a viewer scrub. This is the \"free clip\" a\n * run produces; an MP4 is the same storyboard fed to Remotion in a consumer.\n */\nexport function renderStoryboardHtml(storyboard: Storyboard, opts: HtmlRenderOptions = {}): string {\n const docTitle = opts.title ?? storyboard.title\n // Pre-render each scene's visual to safe HTML here (testable, escaped); the\n // player just sets innerHTML. `<` is escaped in the JSON so a payload can't\n // break out of the <script> tag.\n const scenesJson = JSON.stringify(\n storyboard.scenes.map((s) => ({\n icon: SCENE_ICON[s.sceneType],\n type: s.sceneType,\n title: s.title,\n narration: s.narration,\n durationMs: s.durationMs,\n evidence: s.evidenceSpanIds.length,\n visual: visualHtml(s.visual),\n })),\n ).replace(/</g, '\\\\u003c')\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>${escapeHtml(docTitle)}</title>\n<style>\n :root { color-scheme: dark; }\n * { box-sizing: border-box; }\n body { margin: 0; font: 16px/1.5 ui-sans-serif, system-ui, -apple-system, sans-serif;\n background: #0b0f17; color: #e6edf3; display: flex; min-height: 100vh; align-items: center; justify-content: center; }\n .stage { width: min(900px, 95vw); }\n h1 { font-size: 1.1rem; font-weight: 600; color: #9aa7b5; margin: 0 0 14px; letter-spacing: .02em; }\n .card { background: #111824; border: 1px solid #1e2a3a; border-radius: 14px; padding: 24px 28px;\n min-height: 300px; box-shadow: 0 12px 40px rgba(0,0,0,.45); position: relative; overflow: hidden; }\n .card::before { content: \"\"; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--accent, #3b82f6); }\n .head { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }\n .icon { font-size: 2rem; line-height: 1; }\n .title { font-size: 1.3rem; font-weight: 650; }\n .narration { color: #9fb0c0; font-size: .95rem; margin-bottom: 14px; }\n .visual { margin-top: 6px; }\n .visual img.shot { max-width: 100%; max-height: 360px; border-radius: 8px; border: 1px solid #1e2a3a; display: block; }\n .visual pre { background: #0a0e15; border: 1px solid #1e2a3a; border-radius: 8px; padding: 12px 14px;\n overflow: auto; max-height: 340px; font: 13px/1.5 ui-monospace, \"SF Mono\", Menlo, monospace; white-space: pre-wrap; word-break: break-word; }\n .pathhdr { font: 12px ui-monospace, monospace; color: #7d8da0; margin-bottom: 4px; }\n .diff .add { color: #56d364; } .diff .del { color: #f85149; }\n .term .cmd { color: #eab308; }\n .browser { border: 1px solid #1e2a3a; border-radius: 8px; overflow: hidden; }\n .urlbar { background: #0a0e15; padding: 7px 12px; font: 12px ui-monospace, monospace; color: #8b98a6; border-bottom: 1px solid #1e2a3a; }\n .browser-action { padding: 28px; color: #9fb0c0; text-align: center; }\n .api .apihdr { font: 13px ui-monospace, monospace; margin-bottom: 8px; }\n .method { background: #1b2636; padding: 2px 8px; border-radius: 5px; color: #79c0ff; }\n .status.s2 { color: #56d364; } .status.s4, .status.s5 { color: #f85149; }\n .kv { margin-top: 6px; } .kv b { color: #7d8da0; font-weight: 600; font-size: 12px; }\n .prose { color: #c9d4e0; font-size: 1rem; white-space: pre-wrap; max-height: 340px; overflow: auto; }\n .type-error { --accent: #ef4444; } .type-diff { --accent: #22c55e; } .type-terminal { --accent: #eab308; }\n .type-browser { --accent: #06b6d4; } .type-computer { --accent: #14b8a6; } .type-api { --accent: #79c0ff; }\n .type-summary { --accent: #a855f7; } .type-title_card { --accent: #3b82f6; }\n .type-prompt { --accent: #f59e0b; } .type-reply { --accent: #10b981; }\n .scene-enter { animation: pop .45s cubic-bezier(.2,.7,.3,1.2); }\n @keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }\n .bar { height: 4px; background: #1e2a3a; border-radius: 4px; margin-top: 14px; overflow: hidden; }\n .bar > i { display: block; height: 100%; width: 0; background: var(--accent, #3b82f6); transition: width .1s linear; }\n .controls { display: flex; gap: 10px; align-items: center; margin-top: 14px; color: #8b98a6; font-size: .85rem; }\n button { background: #1b2636; color: #e6edf3; border: 1px solid #2a3a4f; border-radius: 8px; padding: 6px 12px; cursor: pointer; font: inherit; }\n button:hover { background: #243349; }\n .dots { display: flex; gap: 5px; margin-left: auto; flex-wrap: wrap; }\n .dot { width: 7px; height: 7px; border-radius: 50%; background: #2a3a4f; cursor: pointer; }\n .dot.on { background: var(--accent, #3b82f6); }\n</style>\n</head>\n<body>\n<div class=\"stage\">\n <h1>🎬 ${escapeHtml(docTitle)}</h1>\n <div class=\"card\" id=\"card\">\n <div class=\"head\"><span class=\"icon\" id=\"icon\"></span><span class=\"title\" id=\"title\"></span></div>\n <div class=\"narration\" id=\"narration\"></div>\n <div class=\"visual\" id=\"visual\"></div>\n <div class=\"bar\"><i id=\"fill\"></i></div>\n </div>\n <div class=\"controls\">\n <button id=\"playPause\">⏸ Pause</button>\n <button id=\"prev\">◀ Prev</button>\n <button id=\"next\">Next ▶</button>\n <span id=\"counter\"></span>\n <span class=\"dots\" id=\"dots\"></span>\n </div>\n</div>\n<script>\n const SCENES = ${scenesJson};\n let i = 0, playing = true, raf = 0, start = 0;\n const card = document.getElementById('card'), counter = document.getElementById('counter'), dotsEl = document.getElementById('dots');\n SCENES.forEach((_, k) => { const d = document.createElement('span'); d.className = 'dot'; d.onclick = () => go(k); dotsEl.appendChild(d); });\n function paint() {\n const s = SCENES[i];\n card.className = 'card scene-enter type-' + s.type;\n document.getElementById('icon').textContent = s.icon;\n document.getElementById('title').textContent = s.title;\n document.getElementById('narration').textContent = s.narration;\n document.getElementById('visual').innerHTML = s.visual || '';\n counter.textContent = (i + 1) + ' / ' + SCENES.length;\n [...dotsEl.children].forEach((d, k) => d.className = 'dot' + (k === i ? ' on' : ''));\n void card.offsetWidth;\n }\n function tick(t) {\n if (!start) start = t;\n const s = SCENES[i], p = Math.min(1, (t - start) / s.durationMs);\n document.getElementById('fill').style.width = (p * 100) + '%';\n if (p >= 1) { if (i < SCENES.length - 1) { go(i + 1); } else { playing = false; updateBtn(); return; } }\n if (playing) raf = requestAnimationFrame(tick);\n }\n function go(n) { i = Math.max(0, Math.min(SCENES.length - 1, n)); start = 0; cancelAnimationFrame(raf); paint(); if (playing) raf = requestAnimationFrame(tick); }\n function updateBtn() { document.getElementById('playPause').textContent = playing ? '⏸ Pause' : '▶ Play'; }\n document.getElementById('playPause').onclick = () => { playing = !playing; updateBtn(); start = 0; if (playing) raf = requestAnimationFrame(tick); else cancelAnimationFrame(raf); };\n document.getElementById('next').onclick = () => go(i + 1);\n document.getElementById('prev').onclick = () => go(i - 1);\n paint(); raf = requestAnimationFrame(tick);\n</script>\n</body>\n</html>\n`\n}\n\n// The \"watch the agent write code\" keystroke animation + the CodeEdit IR a\n// Remotion consumer reads. Composes with this pipeline: a 'diff' scene shows an\n// inline card here; renderCodeAnimationHtml types the whole file out there.\nexport { editAnimationText, extractCodeEdits, renderCodeAnimationHtml } from './code-edit'\nexport type { CodeAnimationOptions, CodeEdit } from './code-edit'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/storyboard/code-edit.ts","../../src/storyboard/index.ts"],"sourcesContent":["/**\n * Code-edit extraction + the \"watch the agent write code\" animation.\n *\n * The base storyboard (./index) compresses a run into scenes but keeps scenes\n * payload-free (title + narration + evidence span ids). To actually SHOW the\n * code an agent wrote, this module pulls the concrete edit (path, diff,\n * before/after, language) out of the raw edit-tool spans and renders a\n * self-contained HTML replay that types each file out, character by character,\n * like an editor recording.\n *\n * Additive on purpose: it reuses the canonical `Span` (trace/schema) and the\n * `Storyboard` IR (./index) without modifying the reducer/compiler — so it\n * composes with the existing pipeline and a Remotion consumer can read the same\n * `CodeEdit[]` to render an MP4.\n */\n\nimport type { Span } from '../trace/schema'\n\n\nconst EDIT_TOOLS =\n /(edit|write|patch|apply|str_replace|create.*file|save|insert|update.*file|multi_edit)/i\n\n/** A concrete code change lifted from a tool span. */\nexport interface CodeEdit {\n /** Span the edit came from — back-reference into the trace. */\n spanId: string\n path: string\n language?: string\n /** Unified diff, when the tool carried one. */\n diff?: string\n /** Full file body before / after, when present — enables true keystroke\n * animation rather than only flashing a diff. */\n before?: string\n after?: string\n additions: number\n deletions: number\n startedAt: number\n}\n\nfunction languageOf(path: string): string | undefined {\n const ext = path.includes('.') ? path.split('.').pop()?.toLowerCase() : undefined\n if (!ext) return undefined\n const map: Record<string, string> = {\n ts: 'ts',\n tsx: 'tsx',\n js: 'js',\n jsx: 'jsx',\n mjs: 'js',\n cjs: 'js',\n py: 'python',\n rs: 'rust',\n go: 'go',\n sol: 'solidity',\n java: 'java',\n rb: 'ruby',\n php: 'php',\n c: 'c',\n cpp: 'cpp',\n cs: 'csharp',\n css: 'css',\n scss: 'scss',\n html: 'html',\n json: 'json',\n yaml: 'yaml',\n yml: 'yaml',\n toml: 'toml',\n md: 'markdown',\n sh: 'bash',\n sql: 'sql',\n }\n return map[ext] ?? ext\n}\n\nfunction pick(obj: unknown, keys: string[]): string | undefined {\n if (!obj || typeof obj !== 'object') return undefined\n const rec = obj as Record<string, unknown>\n for (const k of Object.keys(rec)) {\n if (keys.includes(k.toLowerCase())) {\n const v = rec[k]\n if (typeof v === 'string') return v\n }\n }\n return undefined\n}\n\nfunction countDiff(diff?: string): { additions: number; deletions: number } {\n if (!diff) return { additions: 0, deletions: 0 }\n let additions = 0\n let deletions = 0\n for (const line of diff.split('\\n')) {\n if (line.startsWith('+') && !line.startsWith('+++')) additions++\n else if (line.startsWith('-') && !line.startsWith('---')) deletions++\n }\n return { additions, deletions }\n}\n\n/** Extract a CodeEdit from a single span, or undefined if it is not an edit. */\nfunction codeEditFromSpan(span: Span): CodeEdit | undefined {\n if (span.kind !== 'tool') return undefined\n const tool = span as Extract<Span, { kind: 'tool' }>\n if (!EDIT_TOOLS.test(tool.toolName)) return undefined\n const path = pick(tool.args, ['path', 'file_path', 'filepath', 'filename', 'file'])\n if (!path) return undefined\n const diff = pick(tool.args, ['diff', 'patch'])\n const after = pick(tool.args, ['content', 'new_str', 'new_string', 'newtext', 'text', 'body'])\n const before = pick(tool.args, ['old_str', 'old_string', 'oldtext', 'original'])\n const counts = countDiff(diff)\n return {\n spanId: span.spanId,\n path,\n language: languageOf(path),\n diff,\n before,\n after,\n additions: diff ? counts.additions : after ? after.split('\\n').length : 0,\n deletions: diff ? counts.deletions : 0,\n startedAt: span.startedAt,\n }\n}\n\n/** All code edits in a run, in chronological order. */\nexport function extractCodeEdits(spans: readonly Span[]): CodeEdit[] {\n return spans\n .map(codeEditFromSpan)\n .filter((e): e is CodeEdit => e != null)\n .sort((a, b) => a.startedAt - b.startedAt)\n}\n\n\n\n/** The text the animation types for an edit: prefer the full new file body,\n * then the added lines of a diff, then a minimal placeholder so the scene is\n * never blank. */\nexport function editAnimationText(edit: CodeEdit): string {\n if (edit.after?.trim()) return edit.after\n if (edit.diff) {\n const added = edit.diff\n .split('\\n')\n .filter((l) => l.startsWith('+') && !l.startsWith('+++'))\n .map((l) => l.slice(1))\n .join('\\n')\n if (added.trim()) return added\n }\n return `// ${edit.path}\\n// (${edit.additions} line${edit.additions === 1 ? '' : 's'} written)`\n}\n\nfunction esc(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\nexport interface CodeAnimationOptions {\n /** Page title. Default \"Agent writing code\". */\n title?: string\n /** Characters typed per animation tick. Higher = faster. Default 4. */\n charsPerTick?: number\n /** Pause between files, ms. Default 900. */\n pauseBetweenMs?: number\n}\n\n/**\n * Render a self-contained HTML page that animates the agent writing each file,\n * character by character, with a filename tab, line numbers, and a blinking\n * cursor — the shareable \"watch it build\" clip. No build step, no assets, no\n * deps. The same `CodeEdit[]` feeds a Remotion MP4 renderer in a consumer\n * package; this is the dependency-free baseline.\n */\nexport function renderCodeAnimationHtml(\n source: readonly Span[] | readonly CodeEdit[],\n opts: CodeAnimationOptions = {},\n): string {\n const edits: CodeEdit[] =\n source.length > 0 && 'path' in (source[0] as object)\n ? (source as CodeEdit[])\n : extractCodeEdits(source as readonly Span[])\n\n const files = edits.map((e) => ({\n path: e.path,\n language: e.language ?? '',\n additions: e.additions,\n deletions: e.deletions,\n code: editAnimationText(e),\n }))\n const title = opts.title ?? 'Agent writing code'\n const charsPerTick = opts.charsPerTick ?? 4\n const pauseBetweenMs = opts.pauseBetweenMs ?? 900\n const filesJson = JSON.stringify(files)\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>${esc(title)}</title>\n<style>\n :root { color-scheme: dark; }\n * { box-sizing: border-box; }\n body { margin: 0; background: #0b0f17; color: #e6edf3;\n font: 14px/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n display: flex; flex-direction: column; min-height: 100vh; align-items: center; justify-content: center; gap: 14px; }\n h1 { font-family: ui-sans-serif, system-ui, sans-serif; font-size: 1rem; font-weight: 600; color: #9aa7b5; margin: 0; }\n .editor { width: min(900px, 94vw); background: #0d1320; border: 1px solid #1e2a3a; border-radius: 12px;\n overflow: hidden; box-shadow: 0 16px 50px rgba(0,0,0,.5); }\n .tabbar { display: flex; align-items: center; gap: 8px; background: #111a29; padding: 9px 14px; border-bottom: 1px solid #1e2a3a; }\n .dot { width: 11px; height: 11px; border-radius: 50%; }\n .dot.r { background: #ff5f56; } .dot.y { background: #ffbd2e; } .dot.g { background: #27c93f; }\n .tab { margin-left: 10px; background: #0d1320; padding: 5px 12px; border-radius: 7px 7px 0 0;\n color: #cdd9e5; font-family: ui-sans-serif, system-ui, sans-serif; font-size: .85rem; }\n .lang { color: #5b6b7d; font-size: .75rem; margin-left: 6px; }\n .adds { margin-left: auto; color: #3fb950; font-size: .78rem; font-family: ui-sans-serif, system-ui, sans-serif; }\n .dels { color: #f85149; margin-left: 8px; }\n .codewrap { display: flex; max-height: 60vh; overflow: auto; }\n .gutter { padding: 14px 10px 14px 14px; text-align: right; color: #3a4757; user-select: none; white-space: pre; }\n pre { margin: 0; padding: 14px 18px 14px 6px; white-space: pre; tab-size: 2; flex: 1; }\n .cursor { display: inline-block; width: 8px; margin-left: 1px; background: #58a6ff; animation: blink .9s steps(1) infinite; }\n @keyframes blink { 50% { opacity: 0; } }\n .controls { display: flex; gap: 10px; align-items: center; font-family: ui-sans-serif, system-ui, sans-serif; font-size: .85rem; color: #8b98a6; }\n button { background: #1b2636; color: #e6edf3; border: 1px solid #2a3a4f; border-radius: 8px; padding: 6px 12px; cursor: pointer; font: inherit; }\n button:hover { background: #243349; }\n .empty { padding: 40px; color: #5b6b7d; }\n</style>\n</head>\n<body>\n <h1>✏️ ${esc(title)}</h1>\n <div class=\"editor\">\n <div class=\"tabbar\">\n <span class=\"dot r\"></span><span class=\"dot y\"></span><span class=\"dot g\"></span>\n <span class=\"tab\" id=\"tab\">—</span><span class=\"lang\" id=\"lang\"></span>\n <span class=\"adds\" id=\"adds\"></span>\n </div>\n <div class=\"codewrap\"><div class=\"gutter\" id=\"gutter\">1</div><pre id=\"code\"></pre></div>\n </div>\n <div class=\"controls\">\n <button id=\"pp\">⏸ Pause</button><button id=\"restart\">↻ Restart</button>\n <span id=\"counter\"></span>\n </div>\n<script>\n const FILES = ${filesJson};\n const CPT = ${charsPerTick}, PAUSE = ${pauseBetweenMs};\n const codeEl = document.getElementById('code'), gutterEl = document.getElementById('gutter');\n const tabEl = document.getElementById('tab'), langEl = document.getElementById('lang');\n const addsEl = document.getElementById('adds'), counterEl = document.getElementById('counter');\n let fi = 0, ci = 0, playing = true, raf = 0, paused = false;\n if (!FILES.length) { codeEl.innerHTML = '<span class=\"empty\">No code edits in this run.</span>'; }\n function esc(s){return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}\n function setHeader(){ const f = FILES[fi]; tabEl.textContent = f.path; langEl.textContent = f.language || '';\n addsEl.innerHTML = '+' + f.additions + (f.deletions ? ' <span class=\"dels\">-' + f.deletions + '</span>' : '');\n counterEl.textContent = (fi+1) + ' / ' + FILES.length + ' files'; }\n function paint(){ const f = FILES[fi]; const shown = f.code.slice(0, ci);\n const lines = (shown.match(/\\\\n/g) || []).length + 1;\n gutterEl.textContent = Array.from({length: lines}, (_, k) => k+1).join('\\\\n');\n codeEl.innerHTML = esc(shown) + '<span class=\"cursor\">&nbsp;</span>';\n const wrap = codeEl.parentElement; wrap.scrollTop = wrap.scrollHeight; }\n function tick(){ if (paused || !FILES.length) return;\n const f = FILES[fi];\n if (ci < f.code.length){ ci = Math.min(f.code.length, ci + CPT); paint(); raf = requestAnimationFrame(tick); }\n else if (fi < FILES.length - 1){ setTimeout(() => { fi++; ci = 0; setHeader(); paint(); raf = requestAnimationFrame(tick); }, PAUSE); }\n else { playing = false; document.getElementById('pp').textContent = '▶ Play'; } }\n document.getElementById('pp').onclick = () => { if (!playing){ playing = true; paused = false; tick(); } else { paused = !paused; if (!paused) tick(); } document.getElementById('pp').textContent = paused ? '▶ Play' : '⏸ Pause'; };\n document.getElementById('restart').onclick = () => { fi = 0; ci = 0; playing = true; paused = false; document.getElementById('pp').textContent = '⏸ Pause'; setHeader(); paint(); cancelAnimationFrame(raf); tick(); };\n if (FILES.length){ setHeader(); paint(); tick(); }\n</script>\n</body>\n</html>\n`\n}\n","/**\n * Storyboard — compile a raw agent trace into a small set of meaningful scenes,\n * then render them as a shareable, watchable replay.\n *\n * Span[] → SemanticEvent[] → Storyboard{scenes} → { markdown | html }\n *\n * The trace is the source of truth; the storyboard is the IR; markdown/html\n * (and, in a consumer package, Remotion/MP4) are compiled targets. Everything\n * here is PURE — same spans in, same bytes out (no clock/random) — so a run's\n * replay is deterministic and diffable.\n *\n * Crucially, every scene carries a modality-typed VISUAL extracted from the\n * span — a browser/computer screenshot, a code diff, a terminal command +\n * output, file content, an API request/response, or reasoning prose — so no\n * matter what the agent did, the replay SHOWS it, not just narrates it. The\n * reducer is rules-based; an LLM pass can refine titles/summaries later, but\n * the structure + visuals do not depend on one. Renderers that need a browser\n * (Remotion, React) live in consumers; this module only emits strings.\n */\n\nimport { escapeHtml } from '../reporting-html'\nimport type { Span } from '../trace/schema'\n\n/** What the agent meaningfully did — the compressed vocabulary. */\nexport type SemanticKind =\n | 'understood_task'\n | 'user_message'\n | 'agent_reply'\n | 'reasoned'\n | 'ran_command'\n | 'read_file'\n | 'edited_code'\n | 'searched'\n | 'used_browser'\n | 'used_computer'\n | 'called_api'\n | 'called_tool'\n | 'evaluated'\n | 'observed_failure'\n | 'completed'\n\n/** The modality-typed payload a scene shows. This is what makes any agent\n * action — screen, browser, shell, code, API — actually viewable. */\nexport type SceneVisual =\n | { type: 'screenshot'; src: string; caption?: string }\n | { type: 'browser'; url?: string; action?: string; screenshot?: string }\n | { type: 'diff'; path: string; patch: string }\n | { type: 'code'; path: string; content: string }\n | { type: 'terminal'; command: string; output?: string }\n | {\n type: 'api'\n method?: string\n url: string\n status?: number\n request?: string\n response?: string\n }\n | { type: 'prose'; text: string }\n | { type: 'none' }\n\nexport interface SemanticEvent {\n kind: SemanticKind\n /** One-line headline (the ticket/scene title). */\n title: string\n /** Short human summary. */\n summary: string\n /** The modality payload to show for this moment. */\n visual: SceneVisual\n /** Span ids backing this moment — the evidence trail. */\n evidenceSpanIds: string[]\n /** 1 (noise) … 5 (pivotal: failures, edits). Drives selection + duration. */\n importance: 1 | 2 | 3 | 4 | 5\n startTs: number\n endTs: number\n}\n\nexport interface ReduceOptions {\n /** Collapse adjacent same-kind moments into one. Default true. */\n collapseAdjacent?: boolean\n}\n\n// ── Modality extraction ─────────────────────────────────────────────────────\n\nfunction str(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined\n}\n\nfunction num(v: unknown): number | undefined {\n return typeof v === 'number' ? v : undefined\n}\n\nfunction attr(span: Span, ...keys: string[]): unknown {\n const a = span.attributes as Record<string, unknown> | undefined\n if (!a) return undefined\n for (const k of keys) if (a[k] != null) return a[k]\n return undefined\n}\n\nfunction asObj(v: unknown): Record<string, unknown> | undefined {\n return v && typeof v === 'object' && !Array.isArray(v)\n ? (v as Record<string, unknown>)\n : undefined\n}\n\nfunction safeJson(v: unknown): string | undefined {\n if (v == null) return undefined\n if (typeof v === 'string') return v\n try {\n return JSON.stringify(v, null, 2)\n } catch {\n return String(v)\n }\n}\n\n/** Is this string an embeddable image (data URI or http URL)? */\nfunction isImageSrc(s: string | undefined): s is string {\n return !!s && (s.startsWith('data:image') || /^https?:\\/\\//.test(s))\n}\n\n/** Pull the modality-appropriate visual out of whatever the span carries.\n * Conventions (checked in priority order): an image rides on\n * `attributes.screenshot|image|frame|videoFrame` or `result.screenshot`; a\n * diff on `attributes.diff|patch` or `args.diff`; a command on `args` /\n * `args.command`; an API call on a `url`/`method` in args; file content on\n * `result`. Unknown tools degrade to an args/result inspector. */\nfunction extractVisual(span: Span): SceneVisual {\n const shot =\n str(attr(span, 'screenshot', 'screenshotUrl', 'image', 'frame', 'videoFrame')) ??\n (span.kind === 'tool'\n ? (str(asObj(span.result)?.screenshot) ?? str(asObj(span.result)?.image))\n : undefined)\n\n if (span.kind === 'tool') {\n const tn = span.toolName.toLowerCase()\n const a = asObj(span.args)\n // computer use (GUI / desktop control)\n if (/computer|cua|desktop|\\bgui\\b|xdotool|mouse|keyboard|screen_|pyautogui/.test(tn)) {\n return {\n type: 'browser',\n action: str(a?.action) ?? span.toolName,\n url: str(a?.target),\n screenshot: shot,\n }\n }\n // browser use\n if (\n /browser|playwright|puppeteer|\\bpage\\b|navigate|goto|\\bclick\\b|\\btype\\b|screenshot|dom/.test(\n tn,\n )\n ) {\n return {\n type: 'browser',\n url: str(a?.url) ?? str(attr(span, 'url')),\n action: str(a?.action) ?? str(a?.selector) ?? span.toolName,\n screenshot: shot,\n }\n }\n // code edit → diff\n const diff = str(attr(span, 'diff', 'patch')) ?? str(a?.diff) ?? str(a?.patch)\n if (diff && /edit|write|patch|apply|str_replace|create|save|file/.test(tn)) {\n return {\n type: 'diff',\n path: str(a?.path) ?? str(a?.file) ?? str(attr(span, 'path')) ?? '',\n patch: truncate(diff, 2000),\n }\n }\n if (/edit|write|patch|apply|str_replace/.test(tn)) {\n const newText = str(a?.new_str) ?? str(a?.content) ?? str(a?.text)\n return {\n type: 'diff',\n path: str(a?.path) ?? str(a?.file) ?? '',\n patch: newText ? `+ ${truncate(newText, 1600)}` : '(no diff captured)',\n }\n }\n // file read → code\n if (/read|\\bcat\\b|open|view|get_file|load|fetch_file/.test(tn)) {\n const content =\n str(asObj(span.result)?.content) ??\n (typeof span.result === 'string' ? span.result : undefined) ??\n str(attr(span, 'content'))\n return {\n type: 'code',\n path: str(a?.path) ?? str(a?.file) ?? '',\n content: truncate(content ?? '', 1400),\n }\n }\n // search\n if (/search|grep|find|glob|query/.test(tn)) {\n return {\n type: 'terminal',\n command: `search ${str(a?.query) ?? str(a?.pattern) ?? ''}`.trim(),\n output: truncate(safeJson(span.result) ?? '', 1000),\n }\n }\n // api / http / network\n const url = str(a?.url) ?? str(attr(span, 'url'))\n if (url || /http|\\bapi\\b|fetch|request|webhook|rest|graphql|endpoint/.test(tn)) {\n return {\n type: 'api',\n method: str(a?.method) ?? str(attr(span, 'method')),\n url: url ?? span.toolName,\n status: num(attr(span, 'status', 'statusCode')) ?? num(asObj(span.result)?.status),\n request: truncate(str(a?.body) ?? safeJson(span.args) ?? '', 900),\n response: truncate(str(attr(span, 'response')) ?? safeJson(span.result) ?? '', 900),\n }\n }\n // shell / sandbox exec\n if (/shell|exec|bash|\\brun\\b|terminal|command|sandbox|process/.test(tn)) {\n const command =\n typeof span.args === 'string'\n ? span.args\n : (str(a?.command) ?? str(a?.cmd) ?? span.toolName)\n const output =\n str(attr(span, 'output', 'stdout')) ??\n (typeof span.result === 'string' ? span.result : safeJson(span.result))\n return {\n type: 'terminal',\n command: truncate(command, 240),\n output: truncate(output ?? '', 1400),\n }\n }\n // generic tool — show the call\n return {\n type: 'api',\n url: span.toolName,\n request: truncate(safeJson(span.args) ?? '', 900),\n response: truncate(safeJson(span.result) ?? '', 900),\n }\n }\n\n if (isImageSrc(shot)) return { type: 'screenshot', src: shot }\n if (span.kind === 'llm') {\n const text = str(span.output) ?? str(span.messages?.[span.messages.length - 1]?.content)\n return text ? { type: 'prose', text: truncate(text, 900) } : { type: 'none' }\n }\n if (span.kind === 'sandbox')\n return { type: 'terminal', command: span.name, output: str(attr(span, 'output')) }\n return { type: 'none' }\n}\n\n// ── Classification ──────────────────────────────────────────────────────────\n\ninterface Classified {\n kind: SemanticKind\n importance: 1 | 2 | 3 | 4 | 5\n label: string\n}\n\nfunction toolLabel(span: Span): string {\n if (span.kind === 'tool') {\n const a = asObj(span.args)\n const arg =\n typeof span.args === 'string'\n ? span.args\n : a\n ? (str(a.path) ??\n str(a.url) ??\n str(a.command) ??\n str(a.query) ??\n Object.values(a).find((v) => typeof v === 'string'))\n : undefined\n return typeof arg === 'string' && arg.length > 0\n ? `${span.toolName}: ${truncate(arg, 60)}`\n : span.toolName\n }\n return span.name\n}\n\nfunction classify(span: Span): Classified {\n if (span.status === 'error' || span.error) {\n return { kind: 'observed_failure', importance: 5, label: span.error ?? span.name }\n }\n if (span.kind === 'llm' || span.kind === 'agent')\n return { kind: 'reasoned', importance: 2, label: span.name }\n if (span.kind === 'judge') return { kind: 'evaluated', importance: 2, label: span.name }\n if (span.kind === 'retrieval') return { kind: 'searched', importance: 2, label: span.name }\n if (span.kind === 'sandbox') return { kind: 'ran_command', importance: 3, label: span.name }\n if (span.kind === 'tool') {\n const tn = span.toolName.toLowerCase()\n const label = toolLabel(span)\n if (/computer|cua|desktop|\\bgui\\b|xdotool|pyautogui/.test(tn))\n return { kind: 'used_computer', importance: 3, label }\n if (/browser|playwright|puppeteer|\\bpage\\b|navigate|goto|\\bclick\\b|screenshot|dom/.test(tn))\n return { kind: 'used_browser', importance: 3, label }\n if (/edit|write|patch|apply|str_replace|create.*file|save/.test(tn))\n return { kind: 'edited_code', importance: 4, label }\n if (/read|\\bcat\\b|open|view|get.*file|load/.test(tn))\n return { kind: 'read_file', importance: 2, label }\n if (/search|grep|find|glob|query/.test(tn)) return { kind: 'searched', importance: 2, label }\n if (\n /http|\\bapi\\b|fetch|request|webhook|rest|graphql|endpoint/.test(tn) ||\n str(asObj(span.args)?.url)\n ) {\n return { kind: 'called_api', importance: 3, label }\n }\n if (/shell|exec|bash|\\brun\\b|terminal|command|process/.test(tn))\n return { kind: 'ran_command', importance: 3, label }\n return { kind: 'called_tool', importance: 3, label }\n }\n return { kind: 'called_tool', importance: 2, label: span.name }\n}\n\nconst KIND_VERB: Record<SemanticKind, string> = {\n understood_task: 'Understood the task',\n user_message: 'User said',\n agent_reply: 'Agent replied',\n reasoned: 'Reasoned',\n ran_command: 'Ran a command',\n read_file: 'Read files',\n edited_code: 'Edited code',\n searched: 'Searched',\n used_browser: 'Used the browser',\n used_computer: 'Controlled the computer',\n called_api: 'Called an API',\n called_tool: 'Used a tool',\n evaluated: 'Evaluated the result',\n observed_failure: 'Hit a failure',\n completed: 'Finished',\n}\n\n/** Kinds that must never collapse into a neighbour — each is its own beat:\n * a failure, and every conversation turn (so the dialogue reads in full). */\nconst STANDALONE_KINDS = new Set<SemanticKind>([\n 'observed_failure',\n 'understood_task',\n 'user_message',\n 'agent_reply',\n])\n\n/** Lift the conversation turns out of an LLM span. The user/assistant text\n * lives in `LlmSpan.messages` (role:'user'|'assistant') and the new reply in\n * `output`; the full history repeats across spans, so `seen` dedupes turns to\n * the first time each is said. The first user turn becomes `understood_task`\n * (the premise), later user turns `user_message`, assistant text `agent_reply`. */\nfunction conversationEvents(\n span: Span,\n seen: Set<string>,\n state: { sawUser: boolean },\n): SemanticEvent[] {\n if (span.kind !== 'llm') return []\n const out: SemanticEvent[] = []\n const emit = (kind: SemanticKind, text: string, importance: 1 | 2 | 3 | 4 | 5) => {\n const t = text.trim()\n if (!t) return\n const who = kind === 'agent_reply' ? 'a' : 'u'\n const key = `${who}\\n${t}`\n if (seen.has(key)) return\n seen.add(key)\n const speaker = kind === 'understood_task' ? 'Task' : kind === 'user_message' ? 'User' : 'Agent'\n out.push({\n kind,\n title: `${speaker}: ${truncate(t, 64)}`,\n summary: truncate(t, 280),\n visual: { type: 'prose', text: truncate(t, 1200) },\n evidenceSpanIds: [span.spanId],\n importance,\n startTs: span.startedAt,\n endTs: span.endedAt ?? span.startedAt,\n })\n }\n for (const m of span.messages ?? []) {\n const content = str(m.content)\n if (!content) continue\n if (m.role === 'user') {\n emit(state.sawUser ? 'user_message' : 'understood_task', content, state.sawUser ? 4 : 5)\n state.sawUser = true\n } else if (m.role === 'assistant') {\n emit('agent_reply', content, 3)\n }\n }\n const reply = str(span.output)\n if (reply) emit('agent_reply', reply, 3)\n return out\n}\n\n/**\n * Reduce a span tree into the meaningful moments a viewer cares about. The\n * conversation (user asks, agent replies) is lifted from LLM spans first so the\n * dialogue is first-class; the remaining work spans are classified + have their\n * modality visual extracted. Adjacent same-kind work moments collapse (the\n * compression step), carrying the latest visual; failures and conversation\n * turns never collapse.\n */\nexport function reduceToSemanticEvents(\n spans: readonly Span[],\n opts: ReduceOptions = {},\n): SemanticEvent[] {\n const collapse = opts.collapseAdjacent ?? true\n const ordered = [...spans].sort((a, b) => a.startedAt - b.startedAt)\n const seen = new Set<string>()\n const convState = { sawUser: false }\n const raw: SemanticEvent[] = []\n for (const s of ordered) {\n const conv = conversationEvents(s, seen, convState)\n if (conv.length > 0) {\n // this LLM span IS dialogue — surface the turns, not a generic \"reasoned\"\n raw.push(...conv)\n continue\n }\n const c = classify(s)\n raw.push({\n kind: c.kind,\n title: c.label,\n summary: `${KIND_VERB[c.kind]} — ${c.label}`,\n visual: extractVisual(s),\n evidenceSpanIds: [s.spanId],\n importance: c.importance,\n startTs: s.startedAt,\n endTs: s.endedAt ?? s.startedAt,\n })\n }\n if (!collapse) return raw\n\n const merged: SemanticEvent[] = []\n for (const ev of raw) {\n const prev = merged[merged.length - 1]\n if (prev && prev.kind === ev.kind && !STANDALONE_KINDS.has(ev.kind)) {\n prev.evidenceSpanIds.push(...ev.evidenceSpanIds)\n prev.endTs = Math.max(prev.endTs, ev.endTs)\n if (ev.visual.type !== 'none') prev.visual = ev.visual // keep the latest state\n const n = prev.evidenceSpanIds.length\n prev.title = `${KIND_VERB[ev.kind]} (${n}×)`\n prev.summary = `${KIND_VERB[ev.kind]} ${n} time${n === 1 ? '' : 's'} — latest: ${ev.title}`\n } else {\n merged.push({ ...ev, evidenceSpanIds: [...ev.evidenceSpanIds] })\n }\n }\n return merged\n}\n\n// ── Storyboard ────────────────────────────────────────────────────────────\n\nexport type SceneType =\n | 'title_card'\n | 'prompt'\n | 'reply'\n | 'reasoning'\n | 'terminal'\n | 'file'\n | 'diff'\n | 'search'\n | 'browser'\n | 'computer'\n | 'api'\n | 'tool'\n | 'eval'\n | 'error'\n | 'summary'\n\nexport interface Scene {\n sceneType: SceneType\n title: string\n narration: string\n /** The modality payload the renderer shows. */\n visual: SceneVisual\n durationMs: number\n evidenceSpanIds: string[]\n}\n\nexport interface Storyboard {\n title: string\n totalMs: number\n scenes: Scene[]\n}\n\nexport interface CompileOptions {\n /** Headline for the title card. Default \"Agent run\". */\n title?: string\n /** Max action scenes between the title + summary cards. Default 16. */\n maxScenes?: number\n}\n\nconst KIND_TO_SCENE: Record<SemanticKind, SceneType> = {\n understood_task: 'title_card',\n user_message: 'prompt',\n agent_reply: 'reply',\n reasoned: 'reasoning',\n ran_command: 'terminal',\n read_file: 'file',\n edited_code: 'diff',\n searched: 'search',\n used_browser: 'browser',\n used_computer: 'computer',\n called_api: 'api',\n called_tool: 'tool',\n evaluated: 'eval',\n observed_failure: 'error',\n completed: 'summary',\n}\n\nconst DURATION_BY_IMPORTANCE: Record<1 | 2 | 3 | 4 | 5, number> = {\n 1: 2500,\n 2: 3000,\n 3: 4000,\n 4: 5000,\n 5: 6000,\n}\n\n/**\n * Select the moments worth showing and lay them out as scenes. Every failure\n * (importance 5) and edit (4) is always kept; the rest fill the budget by\n * importance, then re-sort chronological. A title card opens, a summary closes.\n */\nexport function compileStoryboard(\n events: readonly SemanticEvent[],\n opts: CompileOptions = {},\n): Storyboard {\n const title = opts.title ?? 'Agent run'\n const maxScenes = opts.maxScenes ?? 16\n\n // The first user turn is the premise — it frames the title card rather than\n // being shown twice, so it's excluded from the action selection below.\n const taskEvent = events.find((e) => e.kind === 'understood_task')\n\n const indexed = events.filter((ev) => ev.kind !== 'understood_task').map((ev, i) => ({ ev, i }))\n const mustKeep = indexed.filter(({ ev }) => ev.importance >= 4)\n const rest = indexed\n .filter(({ ev }) => ev.importance < 4)\n .sort((a, b) => b.ev.importance - a.ev.importance || a.i - b.i)\n const budget = Math.max(0, maxScenes - mustKeep.length)\n const selected = [...mustKeep, ...rest.slice(0, budget)].sort((a, b) => a.i - b.i)\n\n const actionScenes: Scene[] = selected.map(({ ev }) => ({\n sceneType: KIND_TO_SCENE[ev.kind],\n title: ev.title,\n narration: ev.summary,\n visual: ev.visual,\n durationMs: DURATION_BY_IMPORTANCE[ev.importance],\n evidenceSpanIds: ev.evidenceSpanIds,\n }))\n\n const failures = events.filter((e) => e.kind === 'observed_failure').length\n const edits = events.filter((e) => e.kind === 'edited_code').length\n const commands = events.filter((e) => e.kind === 'ran_command').length\n const summaryNarration =\n `${events.length} moments · ${commands} command${commands === 1 ? '' : 's'} · ` +\n `${edits} edit${edits === 1 ? '' : 's'} · ${failures} failure${failures === 1 ? '' : 's'}`\n\n const scenes: Scene[] = [\n {\n sceneType: 'title_card',\n title,\n narration: taskEvent ? taskEvent.summary : 'The agent receives its task.',\n visual: taskEvent ? taskEvent.visual : { type: 'none' },\n durationMs: 3000,\n evidenceSpanIds: taskEvent ? taskEvent.evidenceSpanIds : [],\n },\n ...actionScenes,\n {\n sceneType: 'summary',\n title: failures > 0 ? 'Finished — with failures' : 'Finished',\n narration: summaryNarration,\n visual: { type: 'none' },\n durationMs: 4000,\n evidenceSpanIds: [],\n },\n ]\n return { title, totalMs: scenes.reduce((s, sc) => s + sc.durationMs, 0), scenes }\n}\n\n// ── Renderers (pure string out) ─────────────────────────────────────────────\n\nconst SCENE_ICON: Record<SceneType, string> = {\n title_card: '🎬',\n prompt: '💬',\n reply: '🤖',\n reasoning: '🧠',\n terminal: '⌨️',\n file: '📄',\n diff: '✏️',\n search: '🔎',\n browser: '🌐',\n computer: '🖥️',\n api: '🔌',\n tool: '🔧',\n eval: '⚖️',\n error: '❌',\n summary: '🏁',\n}\n\nfunction mmss(ms: number): string {\n const s = Math.round(ms / 1000)\n return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, Math.max(0, max - 1))}…`\n}\n\n/** A short modality tag for the markdown shot list. */\nfunction visualMarkdown(v: SceneVisual): string {\n switch (v.type) {\n case 'screenshot':\n return `🖼 screenshot (${truncate(v.src, 60)})`\n case 'browser':\n return `🌐 ${v.action ?? 'browser'}${v.url ? ` → ${v.url}` : ''}${v.screenshot ? ' [screenshot]' : ''}`\n case 'diff':\n return `\\n\\n\\`\\`\\`diff\\n${truncate(v.patch, 600)}\\n\\`\\`\\`${v.path ? `\\n_${v.path}_` : ''}`\n case 'code':\n return `\\n\\n\\`\\`\\`\\n${truncate(v.content, 500)}\\n\\`\\`\\`${v.path ? `\\n_${v.path}_` : ''}`\n case 'terminal':\n return `\\n\\n\\`\\`\\`sh\\n$ ${v.command}${v.output ? `\\n${truncate(v.output, 500)}` : ''}\\n\\`\\`\\``\n case 'api':\n return `🔌 ${v.method ?? 'CALL'} ${v.url}${v.status != null ? ` → ${v.status}` : ''}`\n case 'prose':\n return `\\n\\n> ${truncate(v.text, 400).replace(/\\n/g, '\\n> ')}`\n default:\n return ''\n }\n}\n\n/** Build the (escaped, structured) HTML for a scene's visual. We never inject\n * raw agent markup — every text part is escaped; only image `src` (data/http)\n * is passed through as an attribute. */\nfunction visualHtml(v: SceneVisual): string {\n switch (v.type) {\n case 'screenshot':\n return `<img class=\"shot\" src=\"${escapeHtml(v.src)}\" alt=\"screenshot\" loading=\"lazy\"/>`\n case 'browser': {\n const bar = `<div class=\"urlbar\">${escapeHtml(v.url ?? v.action ?? 'browser')}</div>`\n const body = isImageSrc(v.screenshot)\n ? `<img class=\"shot\" src=\"${escapeHtml(v.screenshot)}\" alt=\"page\" loading=\"lazy\"/>`\n : `<div class=\"browser-action\">${escapeHtml(v.action ?? 'navigated')}</div>`\n return `<div class=\"browser\">${bar}${body}</div>`\n }\n case 'diff': {\n const lines = v.patch.split('\\n').map((l) => {\n const cls = l.startsWith('+') ? 'add' : l.startsWith('-') ? 'del' : ''\n return `<span class=\"${cls}\">${escapeHtml(l)}</span>`\n })\n return `${v.path ? `<div class=\"pathhdr\">${escapeHtml(v.path)}</div>` : ''}<pre class=\"diff\">${lines.join('\\n')}</pre>`\n }\n case 'code':\n return `${v.path ? `<div class=\"pathhdr\">${escapeHtml(v.path)}</div>` : ''}<pre class=\"code\">${escapeHtml(v.content)}</pre>`\n case 'terminal':\n return `<pre class=\"term\"><span class=\"cmd\">$ ${escapeHtml(v.command)}</span>${v.output ? `\\n${escapeHtml(v.output)}` : ''}</pre>`\n case 'api': {\n const badge = `<span class=\"method\">${escapeHtml(v.method ?? 'CALL')}</span> <span class=\"url\">${escapeHtml(v.url)}</span>${v.status != null ? ` <span class=\"status s${Math.floor(v.status / 100)}\">${v.status}</span>` : ''}`\n const req = v.request\n ? `<div class=\"kv\"><b>req</b><pre>${escapeHtml(v.request)}</pre></div>`\n : ''\n const res = v.response\n ? `<div class=\"kv\"><b>res</b><pre>${escapeHtml(v.response)}</pre></div>`\n : ''\n return `<div class=\"api\"><div class=\"apihdr\">${badge}</div>${req}${res}</div>`\n }\n case 'prose':\n return `<div class=\"prose\">${escapeHtml(v.text)}</div>`\n default:\n return ''\n }\n}\n\n/** Render the storyboard as a Markdown timeline — the human-readable shot list. */\nexport function renderStoryboardMarkdown(storyboard: Storyboard): string {\n const out: string[] = [\n `# 🎬 ${storyboard.title}`,\n '',\n `_${storyboard.scenes.length} scenes · ${mmss(storyboard.totalMs)} replay_`,\n '',\n ]\n let elapsed = 0\n for (const sc of storyboard.scenes) {\n out.push(`### [${mmss(elapsed)}] ${SCENE_ICON[sc.sceneType]} ${sc.title}`)\n out.push('')\n out.push(sc.narration)\n const vm = visualMarkdown(sc.visual)\n if (vm) out.push(vm)\n if (sc.evidenceSpanIds.length > 0) {\n out.push('')\n out.push(`_evidence: ${sc.evidenceSpanIds.length} span(s)_`)\n }\n out.push('')\n elapsed += sc.durationMs\n }\n return out.join('\\n')\n}\n\nexport interface HtmlRenderOptions {\n /** Document title + on-page heading. Defaults to the storyboard title. */\n title?: string\n}\n\n/**\n * Render the storyboard as a self-contained, auto-playing HTML replay — one\n * shareable file, no build step, no external assets. Each scene animates in\n * for its duration and SHOWS its modality (screenshot / diff / terminal / API\n * / browser / prose); controls let a viewer scrub. This is the \"free clip\" a\n * run produces; an MP4 is the same storyboard fed to Remotion in a consumer.\n */\nexport function renderStoryboardHtml(storyboard: Storyboard, opts: HtmlRenderOptions = {}): string {\n const docTitle = opts.title ?? storyboard.title\n // Pre-render each scene's visual to safe HTML here (testable, escaped); the\n // player just sets innerHTML. `<` is escaped in the JSON so a payload can't\n // break out of the <script> tag.\n const scenesJson = JSON.stringify(\n storyboard.scenes.map((s) => ({\n icon: SCENE_ICON[s.sceneType],\n type: s.sceneType,\n title: s.title,\n narration: s.narration,\n durationMs: s.durationMs,\n evidence: s.evidenceSpanIds.length,\n visual: visualHtml(s.visual),\n })),\n ).replace(/</g, '\\\\u003c')\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>${escapeHtml(docTitle)}</title>\n<style>\n :root { color-scheme: dark; }\n * { box-sizing: border-box; }\n body { margin: 0; font: 16px/1.5 ui-sans-serif, system-ui, -apple-system, sans-serif;\n background: #0b0f17; color: #e6edf3; display: flex; min-height: 100vh; align-items: center; justify-content: center; }\n .stage { width: min(900px, 95vw); }\n h1 { font-size: 1.1rem; font-weight: 600; color: #9aa7b5; margin: 0 0 14px; letter-spacing: .02em; }\n .card { background: #111824; border: 1px solid #1e2a3a; border-radius: 14px; padding: 24px 28px;\n min-height: 300px; box-shadow: 0 12px 40px rgba(0,0,0,.45); position: relative; overflow: hidden; }\n .card::before { content: \"\"; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--accent, #3b82f6); }\n .head { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }\n .icon { font-size: 2rem; line-height: 1; }\n .title { font-size: 1.3rem; font-weight: 650; }\n .narration { color: #9fb0c0; font-size: .95rem; margin-bottom: 14px; }\n .visual { margin-top: 6px; }\n .visual img.shot { max-width: 100%; max-height: 360px; border-radius: 8px; border: 1px solid #1e2a3a; display: block; }\n .visual pre { background: #0a0e15; border: 1px solid #1e2a3a; border-radius: 8px; padding: 12px 14px;\n overflow: auto; max-height: 340px; font: 13px/1.5 ui-monospace, \"SF Mono\", Menlo, monospace; white-space: pre-wrap; word-break: break-word; }\n .pathhdr { font: 12px ui-monospace, monospace; color: #7d8da0; margin-bottom: 4px; }\n .diff .add { color: #56d364; } .diff .del { color: #f85149; }\n .term .cmd { color: #eab308; }\n .browser { border: 1px solid #1e2a3a; border-radius: 8px; overflow: hidden; }\n .urlbar { background: #0a0e15; padding: 7px 12px; font: 12px ui-monospace, monospace; color: #8b98a6; border-bottom: 1px solid #1e2a3a; }\n .browser-action { padding: 28px; color: #9fb0c0; text-align: center; }\n .api .apihdr { font: 13px ui-monospace, monospace; margin-bottom: 8px; }\n .method { background: #1b2636; padding: 2px 8px; border-radius: 5px; color: #79c0ff; }\n .status.s2 { color: #56d364; } .status.s4, .status.s5 { color: #f85149; }\n .kv { margin-top: 6px; } .kv b { color: #7d8da0; font-weight: 600; font-size: 12px; }\n .prose { color: #c9d4e0; font-size: 1rem; white-space: pre-wrap; max-height: 340px; overflow: auto; }\n .type-error { --accent: #ef4444; } .type-diff { --accent: #22c55e; } .type-terminal { --accent: #eab308; }\n .type-browser { --accent: #06b6d4; } .type-computer { --accent: #14b8a6; } .type-api { --accent: #79c0ff; }\n .type-summary { --accent: #a855f7; } .type-title_card { --accent: #3b82f6; }\n .type-prompt { --accent: #f59e0b; } .type-reply { --accent: #10b981; }\n .scene-enter { animation: pop .45s cubic-bezier(.2,.7,.3,1.2); }\n @keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }\n .bar { height: 4px; background: #1e2a3a; border-radius: 4px; margin-top: 14px; overflow: hidden; }\n .bar > i { display: block; height: 100%; width: 0; background: var(--accent, #3b82f6); transition: width .1s linear; }\n .controls { display: flex; gap: 10px; align-items: center; margin-top: 14px; color: #8b98a6; font-size: .85rem; }\n button { background: #1b2636; color: #e6edf3; border: 1px solid #2a3a4f; border-radius: 8px; padding: 6px 12px; cursor: pointer; font: inherit; }\n button:hover { background: #243349; }\n .dots { display: flex; gap: 5px; margin-left: auto; flex-wrap: wrap; }\n .dot { width: 7px; height: 7px; border-radius: 50%; background: #2a3a4f; cursor: pointer; }\n .dot.on { background: var(--accent, #3b82f6); }\n</style>\n</head>\n<body>\n<div class=\"stage\">\n <h1>🎬 ${escapeHtml(docTitle)}</h1>\n <div class=\"card\" id=\"card\">\n <div class=\"head\"><span class=\"icon\" id=\"icon\"></span><span class=\"title\" id=\"title\"></span></div>\n <div class=\"narration\" id=\"narration\"></div>\n <div class=\"visual\" id=\"visual\"></div>\n <div class=\"bar\"><i id=\"fill\"></i></div>\n </div>\n <div class=\"controls\">\n <button id=\"playPause\">⏸ Pause</button>\n <button id=\"prev\">◀ Prev</button>\n <button id=\"next\">Next ▶</button>\n <span id=\"counter\"></span>\n <span class=\"dots\" id=\"dots\"></span>\n </div>\n</div>\n<script>\n const SCENES = ${scenesJson};\n let i = 0, playing = true, raf = 0, start = 0;\n const card = document.getElementById('card'), counter = document.getElementById('counter'), dotsEl = document.getElementById('dots');\n SCENES.forEach((_, k) => { const d = document.createElement('span'); d.className = 'dot'; d.onclick = () => go(k); dotsEl.appendChild(d); });\n function paint() {\n const s = SCENES[i];\n card.className = 'card scene-enter type-' + s.type;\n document.getElementById('icon').textContent = s.icon;\n document.getElementById('title').textContent = s.title;\n document.getElementById('narration').textContent = s.narration;\n document.getElementById('visual').innerHTML = s.visual || '';\n counter.textContent = (i + 1) + ' / ' + SCENES.length;\n [...dotsEl.children].forEach((d, k) => d.className = 'dot' + (k === i ? ' on' : ''));\n void card.offsetWidth;\n }\n function tick(t) {\n if (!start) start = t;\n const s = SCENES[i], p = Math.min(1, (t - start) / s.durationMs);\n document.getElementById('fill').style.width = (p * 100) + '%';\n if (p >= 1) { if (i < SCENES.length - 1) { go(i + 1); } else { playing = false; updateBtn(); return; } }\n if (playing) raf = requestAnimationFrame(tick);\n }\n function go(n) { i = Math.max(0, Math.min(SCENES.length - 1, n)); start = 0; cancelAnimationFrame(raf); paint(); if (playing) raf = requestAnimationFrame(tick); }\n function updateBtn() { document.getElementById('playPause').textContent = playing ? '⏸ Pause' : '▶ Play'; }\n document.getElementById('playPause').onclick = () => { playing = !playing; updateBtn(); start = 0; if (playing) raf = requestAnimationFrame(tick); else cancelAnimationFrame(raf); };\n document.getElementById('next').onclick = () => go(i + 1);\n document.getElementById('prev').onclick = () => go(i - 1);\n paint(); raf = requestAnimationFrame(tick);\n</script>\n</body>\n</html>\n`\n}\n\n// The \"watch the agent write code\" keystroke animation + the CodeEdit IR a\n// Remotion consumer reads. Composes with this pipeline: a 'diff' scene shows an\n// inline card here; renderCodeAnimationHtml types the whole file out there.\nexport { editAnimationText, extractCodeEdits, renderCodeAnimationHtml } from './code-edit'\nexport type { CodeAnimationOptions, CodeEdit } from './code-edit'\n"],"mappings":"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"}
@@ -1,8 +1,7 @@
1
- import { a as RunRecord } from "./run-record-C3awiXPf.js";
2
- import { r as PairedDecisionStatistic } from "./paired-promotion-decision-CQMJ5xGN.js";
3
- import "./reward-BeUgVVC_.js";
4
- import { n as FailureClusterReport } from "./failure-cluster-DN0t63Z0.js";
5
- //#region src/held-out-gate.d.ts
1
+ import { a as RunRecord } from "./run-record-D2BFMPGl.js";
2
+ import { r as PairedDecisionStatistic } from "./paired-promotion-decision-BDnqepZ1.js";
3
+ import "./reward-ST4PXNXF.js";
4
+ import { n as FailureClusterReport } from "./failure-cluster-DOoa7CBg.js";
6
5
  type HeldOutGateRejectionCode = 'few_runs' | 'incomplete_coverage' | 'missing_split_scores' | 'missing_cost' | 'negative_delta' | 'indeterminate_delta' | 'overfit_gap' | 'cost_ceiling';
7
6
  /**
8
7
  * How much of one split's DEALT work the comparison actually measured.
@@ -250,8 +249,6 @@ declare class HeldOutGate {
250
249
  */
251
250
  private chooseShape;
252
251
  }
253
- //#endregion
254
- //#region src/summary-report-figures.d.ts
255
252
  interface SummaryTableOptions {
256
253
  /** Comparator candidate id. Wilcoxon + paired Cohen's dz are computed
257
254
  * versus this candidate. Required for paired stats columns. */
@@ -361,16 +358,12 @@ interface GainDistributionOptions {
361
358
  * delta — same primitive the promotion gate uses.
362
359
  */
363
360
  declare function gainHistogram(runs: RunRecord[], candidateId: string, comparator: string, opts?: GainDistributionOptions): GainDistributionFigureSpec;
364
- //#endregion
365
- //#region src/research-report-analysis.d.ts
366
361
  /**
367
362
  * Hard floor below which a paired comparison is treated as uninformative
368
363
  * regardless of `minPairs`. Mirrors the lower limit on Wilcoxon signed-rank
369
364
  * exact tables; below this the test has no power to separate effect sizes.
370
365
  */
371
366
  declare const RESEARCH_REPORT_HARD_PAIR_FLOOR = 6;
372
- //#endregion
373
- //#region src/research-report.d.ts
374
367
  type ResearchReportDecision = 'promote' | 'hold' | 'reject' | 'equivalent' | 'needs_more_data';
375
368
  interface ResearchReportOptions {
376
369
  /** Human-readable report title. */
@@ -536,6 +529,5 @@ interface ResearchReport {
536
529
  * for any fixed `runs`, `seed`, and ROPE.
537
530
  */
538
531
  declare function researchReport(runs: RunRecord[], opts?: ResearchReportOptions): Promise<ResearchReport>;
539
- //#endregion
540
532
  export { HeldOutGateRejectionCode as C, HeldOutGateDecision as S, gainHistogram as _, ResearchReportOptions as a, HeldOutGate as b, RESEARCH_REPORT_HARD_PAIR_FLOOR as c, GainDistributionOptions as d, ParetoFigureSpec as f, SummaryTableRow as g, SummaryTableOptions as h, ResearchReportMethodology as i, GainDistributionBin as l, SummaryTable as m, ResearchReportCandidate as n, ResearchReportRecommendation as o, ParetoPoint as p, ResearchReportDecision as r, researchReport as s, ResearchReport as t, GainDistributionFigureSpec as u, summaryTable as v, SplitCoverage as w, HeldOutGateConfig as x, GateEvidence as y };
541
- //# sourceMappingURL=summary-report-C8V49Jt3.d.ts.map
533
+ //# sourceMappingURL=summary-report-0La5vejY.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-report-0La5vejY.d.ts","names":[],"sources":["../src/held-out-gate.ts","../src/summary-report-figures.ts","../src/research-report-analysis.ts","../src/research-report.ts"],"mappings":";;;;KAuIY;;;;;;;;UAiBK;;EAEf;;;EAGA;;;;EAIA;;EAEA;;EAEA;;;EAGA;;UAGe;;;;EAIf;;;;;EAKA;;;;;;;;;;;EAWA;;;;EAIA;;;EAGA;;EAEA;;EAEA;;;;EAIA;;;;;;;;;;;;;;;;;EAiBA;;;;;;;;;;;;;;EAcA;;;;KAKG,iBAAiB;UAEL;;EAEf;;EAEA;;EAEA;;;;;;;;EAQA,iBAAiB;;;;;EAKjB,gBAAgB;;;;;EAKhB;;;;;;;;;EASA,gBAAgB;;;EAGhB;;;EAGA;IAAY;IAAa;;;;EAGzB;;;;;;;EAOA;IAAW;IAAW;IAAW;IAAqB;;;;;;EAKtD;;;;;EAKA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;EAKA;;;EAGA;;;;;;;EAOA;;UAGe;;EAEf;;EAEA;;EAEA;;EAEA,UAAU;;EAEV;;EAEA,eAAe;;;;;;;cAQJ;mBACM;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;EAEL,YAAA,QAAQ;;;;EAoCpB,SAAS,WAAW,aAAa,UAAU,cAAc;;;UAiCjD;;;;;;UAoEA;;;UAiCA;;;UAkEA;;;;;;;UAqDA;;UCvnBO;;;EAGf;;EAEA;;EAEA;;EAEA;;UAGe;EACf;EACA;EACA;EACA;EACA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;UAGe;EACf,MAAM;EACN;EACA;;EAEA;;;;;;;iBAQc,aAAa,MAAM,aAAa,OAAM,sBAA2B;UAkHhE;EACf;;EAEA;;EAEA;;EAEA;;;EAGA;;;EAGA;;UAGe;EACf;EACA;EACA,QAAQ;EACR;IAAQ;IAAc;;;UAoEP;;EAEf;;EAEA;;EAEA;;UAGe;EACf;EACA;EACA;EACA;;EAEA;;EAEA;;EAEA;EACA,MAAM;EACN;EACA;IAAM;IAAa;;;UAGJ;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;iBAQc,cACd,MAAM,aACN,qBACA,oBACA,OAAM,0BACL;;;;;;cCrSU;KCWD;UAOK;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;EASA;;;;;;;EAOA;IAAS;IAAa;;;;;;EAKtB;;;;;EAKA;;EAEA,gBAAgB,eAAe;;EAE/B,kBAAkB;;EAElB;;EAEA;;EAEA;;;;;;EAMA;;UAGe;EACf,UAAU;EACV;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IAAU;IAAa;;;;;;;EAMvB;EACA;;;;;;;EAOA;EACA;EACA,OAAO;EACP,UAAU;EACV;;UAGe;;;;;EAKf;;EAEA;;EAEA;;EAEA;;EAEA;;UAGe;EACf;EACA;EACA;EACA;EACA;;;;;;EAMA;EACA;EACA;IAAQ;IAAa;;EACrB;EACA,gBAAgB;EAChB,YAAY;EACZ,SAAS;EACT;IACE,QAAQ;IACR,OAAO;;EAET,aAAa;EACb,kBAAkB;EAClB;EACA;;;;;;;;;;;;;;;;;;;;;iBAsBoB,eACpB,MAAM,aACN,OAAM,wBACL,QAAQ"}
@@ -1,14 +1,15 @@
1
- import { s as ValidationError } from "./errors-BcOs5MKW.js";
2
- import { l as hashJson } from "./agent-profile-cell-B1V1gUZs.js";
3
- import { r as observedSplitScore } from "./reward-nw2xZGZG.js";
4
- import { n as renderResearchHtml } from "./reporting-html-Kvlc8oMt.js";
5
- import { a as wilcoxonSignedRank, r as pairRunRecords } from "./paired-arms-B2ttLc0_.js";
6
- import { i as makeRng } from "./internal-BTK91Bqt.js";
7
- import { t as confidenceInterval } from "./descriptive-CVNy48rR.js";
8
- import { t as benjaminiHochberg } from "./multiplicity-Sg0U7h8j.js";
9
- import { i as pairedBootstrap, t as mean } from "./mean-BbA_JCzW.js";
10
- import { r as pairedMde } from "./power-and-mde-CQX-0weG.js";
11
- //#region src/research-report-render.ts
1
+ import { s as ValidationError } from "./errors-DeEEV9Vx.js";
2
+ import { l as hashJson } from "./agent-profile-cell-CT5JYueM.js";
3
+ import { r as observedSplitScore } from "./reward-P0VD_Aft.js";
4
+ import { n as renderResearchHtml } from "./reporting-html-DMXIjATy.js";
5
+ import { t as interpolatedQuantile } from "./quantile-CncXP-Ss.js";
6
+ import { a as wilcoxonSignedRank, r as pairRunRecords } from "./paired-arms-D-54hO-k.js";
7
+ import { i as makeRng } from "./internal-v6XfOeJW.js";
8
+ import { t as confidenceInterval } from "./descriptive-cPwITVfy.js";
9
+ import { t as benjaminiHochberg } from "./multiplicity-DAd4xaDC.js";
10
+ import { i as pairedBootstrap, t as mean } from "./mean-CdDYG-us.js";
11
+ import { r as pairedMde } from "./power-and-mde-ClI6RWw4.js";
12
+ // src/research-report-render.ts
12
13
  function renderResearchMarkdown(report) {
13
14
  const lines = [];
14
15
  lines.push(`# ${report.title}`);
@@ -114,8 +115,7 @@ function fmt(x) {
114
115
  if (!Number.isFinite(x)) return String(x);
115
116
  return x.toFixed(4);
116
117
  }
117
- //#endregion
118
- //#region src/research-report-analysis.ts
118
+ // src/research-report-analysis.ts
119
119
  /**
120
120
  * Hard floor below which a paired comparison is treated as uninformative
121
121
  * regardless of `minPairs`. Mirrors the lower limit on Wilcoxon signed-rank
@@ -287,8 +287,7 @@ function decisionWeight(decision) {
287
287
  if (decision === "needs_more_data") return 2;
288
288
  return 1;
289
289
  }
290
- //#endregion
291
- //#region src/statistics/effect-sizes.ts
290
+ // src/statistics/effect-sizes.ts
292
291
  /**
293
292
  * Standardized effect sizes: Cohen's d family and Cliff's delta, with the
294
293
  * shared degenerate-input contract (null where the effect is undefined).
@@ -365,8 +364,7 @@ function interpretCliffs(delta) {
365
364
  if (d < .474) return "medium";
366
365
  return "large";
367
366
  }
368
- //#endregion
369
- //#region src/summary-report-evidence.ts
367
+ // src/summary-report-evidence.ts
370
368
  /** Matched split scores and paired statistical evidence for report consumers. */
371
369
  function pairScoresByKey(candidate, baseline, split) {
372
370
  const scoreOf = (run) => {
@@ -401,7 +399,8 @@ function pairedPosterior(runs, candidateId, comparator, opts) {
401
399
  if (n === 0) return null;
402
400
  const deltas = before.map((b, i) => after[i] - b);
403
401
  const meanDelta = deltas.reduce((s, x) => s + x, 0) / n;
404
- const medianDelta = medianOfSorted([...deltas].sort((a, b) => a - b));
402
+ const sortedDeltas = [...deltas].sort((a, b) => a - b);
403
+ const medianDelta = interpolatedQuantile(sortedDeltas, .5);
405
404
  const sdDelta = stdev(deltas, meanDelta);
406
405
  const ci = pairedBootstrap(before, after, {
407
406
  confidence: opts.confidence,
@@ -456,13 +455,7 @@ function stdev(xs, mean) {
456
455
  for (const x of xs) sse += (x - mean) ** 2;
457
456
  return Math.sqrt(sse / (xs.length - 1));
458
457
  }
459
- function medianOfSorted(sorted) {
460
- if (sorted.length === 0) return 0;
461
- const mid = Math.floor(sorted.length / 2);
462
- return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
463
- }
464
- //#endregion
465
- //#region src/summary-report-figures.ts
458
+ // src/summary-report-figures.ts
466
459
  /**
467
460
  * Table 1 helper. Buckets runs by `candidateId`, computes mean +
468
461
  * bootstrap CI on the chosen split, and (when a comparator is given)
@@ -631,7 +624,7 @@ function gainHistogram(runs, candidateId, comparator, opts = {}) {
631
624
  };
632
625
  const deltas = before.map((b, i) => after[i] - b);
633
626
  const sortedDeltas = [...deltas].sort((a, b) => a - b);
634
- const median = medianOfSorted(sortedDeltas);
627
+ const median = interpolatedQuantile(sortedDeltas, .5);
635
628
  const min = sortedDeltas[0];
636
629
  const max = sortedDeltas[sortedDeltas.length - 1];
637
630
  const bound = Math.max(Math.abs(min), Math.abs(max), 1e-6);
@@ -671,8 +664,7 @@ function gainHistogram(runs, candidateId, comparator, opts = {}) {
671
664
  }
672
665
  };
673
666
  }
674
- //#endregion
675
- //#region src/research-report.ts
667
+ // src/research-report.ts
676
668
  /**
677
669
  * Executive research report for CPO / AI-lead / launch-review consumption.
678
670
  *
@@ -846,7 +838,6 @@ async function researchReport(runs, opts = {}) {
846
838
  html
847
839
  };
848
840
  }
849
- //#endregion
850
841
  export { cliffsDelta as a, pairedCohensDz as c, summaryTable as i, RESEARCH_REPORT_HARD_PAIR_FLOOR as l, gainHistogram as n, cohensD as o, paretoChart as r, interpretCliffs as s, researchReport as t };
851
842
 
852
- //# sourceMappingURL=summary-report-DHDWxe6p.js.map
843
+ //# sourceMappingURL=summary-report-CPfsrLac.js.map