@hona/openeval 0.5.3 → 0.5.5

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 (181) hide show
  1. package/JUDGING.md +7 -5
  2. package/VERIFICATION.md +18 -2
  3. package/package.json +1 -1
  4. package/src/app/input-fingerprints.ts +9 -1
  5. package/src/app/load-benchmark.ts +32 -8
  6. package/src/app/run-eval.ts +4 -3
  7. package/src/index.ts +2 -1
  8. package/src/infra/judging/code-source.ts +45 -37
  9. package/src/infra/verification/image.ts +12 -1
  10. package/src/infra/verification/limits.ts +14 -0
  11. package/src/infra/verification/session.ts +4 -4
  12. package/src/judge-context.ts +8 -0
  13. package/src/types.ts +10 -3
  14. package/src/view.ts +29 -6
  15. package/viewer/assets/{abnfDiagram-VCTEODGH-DheibVLk.js → abnfDiagram-VCTEODGH-ug3iRKuR.js} +1 -1
  16. package/viewer/assets/{angular-html-4AdCdqA_.js → angular-html-BrDmDg4M.js} +1 -1
  17. package/viewer/assets/{angular-ts-D-G3eLWz.js → angular-ts-Cog8g0dp.js} +1 -1
  18. package/viewer/assets/{apl-Ckl95Nnu.js → apl-u0m73XJK.js} +1 -1
  19. package/viewer/assets/{arc-DBaUWWiS.js → arc-DwFAF4oI.js} +1 -1
  20. package/viewer/assets/architecture-7GRP2DOG-BE4yjtoN.js +1 -0
  21. package/viewer/assets/{architectureDiagram-5GKGNRK7-BSEYyvUG.js → architectureDiagram-5GKGNRK7-DQCcEnAE.js} +1 -1
  22. package/viewer/assets/{astro-BpiishHg.js → astro-Bh_DypAJ.js} +1 -1
  23. package/viewer/assets/{blade-DvRbLCOy.js → blade-BKpbbd0G.js} +1 -1
  24. package/viewer/assets/{blockDiagram-I7D4REHJ-DLxyKv07.js → blockDiagram-I7D4REHJ-CMWWJZCD.js} +1 -1
  25. package/viewer/assets/{c-BZYE5LIm.js → c-3D1Q4Rnv.js} +1 -1
  26. package/viewer/assets/{c4Diagram-7LVT6UL2--I50ySVl.js → c4Diagram-7LVT6UL2-T2XwgnDq.js} +1 -1
  27. package/viewer/assets/channel-LYhuLo7L.js +1 -0
  28. package/viewer/assets/{chapel-T-o4rT-z.js → chapel-C8bO2CrC.js} +1 -1
  29. package/viewer/assets/{chunk-4HAMMTFA-B9xd7TwX.js → chunk-4HAMMTFA-DP15Gd37.js} +1 -1
  30. package/viewer/assets/{chunk-75Z2AOVW-B4XIg4PJ.js → chunk-75Z2AOVW-BH0f-Wnb.js} +1 -1
  31. package/viewer/assets/{chunk-DU6HZSFF-Cty-qidK.js → chunk-DU6HZSFF-BI4SVpji.js} +1 -1
  32. package/viewer/assets/{chunk-F27PBJKO-8WDDKCG7.js → chunk-F27PBJKO-BSNNTPfe.js} +1 -1
  33. package/viewer/assets/{chunk-GMAD6QVW-G948aN1X.js → chunk-GMAD6QVW-WnVsWLvz.js} +1 -1
  34. package/viewer/assets/{chunk-GVQU2GXP-CVFpDQVF.js → chunk-GVQU2GXP-CdFmNEz4.js} +1 -1
  35. package/viewer/assets/{chunk-IMKFNOWR-BUQviXHJ.js → chunk-IMKFNOWR-Dvd33dQw.js} +1 -1
  36. package/viewer/assets/{chunk-L3NEJ4N5-BXvzxNPv.js → chunk-L3NEJ4N5-CL6o4wty.js} +1 -1
  37. package/viewer/assets/{chunk-OSK3NFVY-wLdUx9yD.js → chunk-OSK3NFVY-ITNjoAvY.js} +1 -1
  38. package/viewer/assets/{chunk-P2QGCYS3-hDwRspSg.js → chunk-P2QGCYS3-BSCEl9ld.js} +1 -1
  39. package/viewer/assets/{chunk-POPQ4Y6H-LbeiA8tL.js → chunk-POPQ4Y6H-cdNgvxKY.js} +1 -1
  40. package/viewer/assets/{chunk-PWAF6VOD-BcGZUKY4.js → chunk-PWAF6VOD-BMdmv8wx.js} +1 -1
  41. package/viewer/assets/{chunk-SHT3W25Y-BqKh1v-r.js → chunk-SHT3W25Y-CjnAASPR.js} +1 -1
  42. package/viewer/assets/{chunk-SVP7TREG-BEMJeRHW.js → chunk-SVP7TREG-CGuEYo-A.js} +1 -1
  43. package/viewer/assets/{chunk-TICWLB2K-BiHATE6U.js → chunk-TICWLB2K-Ctd8ESX_.js} +1 -1
  44. package/viewer/assets/{chunk-XXDRQBXY-B0X2aTwI.js → chunk-XXDRQBXY-CeNgfrFR.js} +1 -1
  45. package/viewer/assets/classDiagram-ZZMXUADV-BgxrVQRR.js +1 -0
  46. package/viewer/assets/classDiagram-v2-VYDZK3BY-BgxrVQRR.js +1 -0
  47. package/viewer/assets/{cobol-DS-OUv7W.js → cobol-osZcAF7j.js} +1 -1
  48. package/viewer/assets/{coffee-UJZBXrQS.js → coffee-3IUVSrSB.js} +1 -1
  49. package/viewer/assets/{cose-bilkent-JH36ORCC-h7Gx4dzS.js → cose-bilkent-JH36ORCC-CyD9he_v.js} +1 -1
  50. package/viewer/assets/{cpp-BuO_io74.js → cpp-CN2PLd-1.js} +1 -1
  51. package/viewer/assets/{crystal-D_Q6HPhm.js → crystal-DkrkhqdA.js} +1 -1
  52. package/viewer/assets/{css-B9bdOUvs.js → css-Y7OW5uKN.js} +1 -1
  53. package/viewer/assets/{cynefin-OW5HDTMX-BONm5P8S.js → cynefin-OW5HDTMX-H8lBmHMH.js} +1 -1
  54. package/viewer/assets/{cynefinDiagram-5FMLGOSQ-CWsyzZBO.js → cynefinDiagram-5FMLGOSQ-CJIYAkvT.js} +1 -1
  55. package/viewer/assets/{dagre-GXQ25YYZ-CJG_-oax.js → dagre-GXQ25YYZ-pxdbKP2Y.js} +1 -1
  56. package/viewer/assets/{diagram-S7CK7UJ4-uOGlO2Fe.js → diagram-S7CK7UJ4-VtFOpSmi.js} +1 -1
  57. package/viewer/assets/{diagram-UQ7AKVKN-B2mgymOu.js → diagram-UQ7AKVKN-D_P4AgV5.js} +1 -1
  58. package/viewer/assets/{diagram-VSXAHHWV-UkXvypTd.js → diagram-VSXAHHWV-DAGjorXD.js} +1 -1
  59. package/viewer/assets/{diagram-VX7I27RA-Bzge-YWf.js → diagram-VX7I27RA-2zCtxu12.js} +1 -1
  60. package/viewer/assets/{diagram-Z3DM3KII-BAqqEKF_.js → diagram-Z3DM3KII-EYZlAOgk.js} +1 -1
  61. package/viewer/assets/{dist-CACpyRbj.js → dist-GOYxPZ4F.js} +1 -1
  62. package/viewer/assets/{ebnfDiagram-PWID7BFC-dsRp8_0H.js → ebnfDiagram-PWID7BFC-DjPdLCtD.js} +1 -1
  63. package/viewer/assets/{edge-DUnvwjmM.js → edge-BXhOSzIo.js} +1 -1
  64. package/viewer/assets/{elixir-QfE-NI0D.js → elixir-7AwElWAC.js} +1 -1
  65. package/viewer/assets/{elm-D4J4FYyf.js → elm-Rl2m4djM.js} +1 -1
  66. package/viewer/assets/{erDiagram-RLTQ6QDP-Dmfq32IQ.js → erDiagram-RLTQ6QDP-SmyuIGbH.js} +1 -1
  67. package/viewer/assets/{erb-DfUVZzqX.js → erb-CaYBWLa-.js} +1 -1
  68. package/viewer/assets/eventmodeling-NTZA5JFV-mpkZTTpn.js +1 -0
  69. package/viewer/assets/flowDiagram-HODETNUW-BCQvK0Ku.js +1 -0
  70. package/viewer/assets/{ganttDiagram-EL5Y4UJY-DVTv_n_T.js → ganttDiagram-EL5Y4UJY-DfSG_mot.js} +1 -1
  71. package/viewer/assets/{git-rebase-B22-kUR2.js → git-rebase-Y999REzC.js} +1 -1
  72. package/viewer/assets/{gitGraph-4MIJSDKK-C3ZU1Sml.js → gitGraph-4MIJSDKK-BXiKSzAB.js} +1 -1
  73. package/viewer/assets/{gitGraphDiagram-WWUBYQGX-BJqeOFYd.js → gitGraphDiagram-WWUBYQGX-BouZhMNn.js} +1 -1
  74. package/viewer/assets/{glimmer-js-Cm5f8kCy.js → glimmer-js-DTFvFoOE.js} +1 -1
  75. package/viewer/assets/{glimmer-ts-CQ-nNZCl.js → glimmer-ts-RbXN3mhk.js} +1 -1
  76. package/viewer/assets/{glsl-XxfyrGb3.js → glsl-BhmvaPUj.js} +1 -1
  77. package/viewer/assets/{graphql-DBlG1DNQ.js → graphql-CohJYf5Y.js} +1 -1
  78. package/viewer/assets/{hack-Dkc1g494.js → hack-xLFm4gc4.js} +1 -1
  79. package/viewer/assets/{haml-D9E0-Hw0.js → haml-B433XQTv.js} +1 -1
  80. package/viewer/assets/{handlebars-Cb17q7C4.js → handlebars-BDpXFZR1.js} +1 -1
  81. package/viewer/assets/{html-5E3Hc3ha.js → html-BvwGTXL2.js} +1 -1
  82. package/viewer/assets/{html-derivative-DOZTqg-2.js → html-derivative-DSCM_5Uj.js} +1 -1
  83. package/viewer/assets/{http-DJH-LMLV.js → http-ZyduKjGN.js} +1 -1
  84. package/viewer/assets/{hurl-CEYg3T6-.js → hurl-Dtl73Mol.js} +1 -1
  85. package/viewer/assets/{index-CkY7ZfKs.css → index-BmSDOoQ0.css} +1 -1
  86. package/viewer/assets/{index-Dfdu9MKA.js → index-DOIiHLHw.js} +76 -76
  87. package/viewer/assets/{info-A6RAGUB7-B-4F1obM.js → info-A6RAGUB7-DuWuidi4.js} +1 -1
  88. package/viewer/assets/{infoDiagram-27XIBGKW-B8RIO086.js → infoDiagram-27XIBGKW-DczGtN5R.js} +1 -1
  89. package/viewer/assets/{ishikawaDiagram-5VMMS53U-DIGOldDh.js → ishikawaDiagram-5VMMS53U-DidQ3_7N.js} +1 -1
  90. package/viewer/assets/{java-e3vi9Uzs.js → java-mouNBEOT.js} +1 -1
  91. package/viewer/assets/{javascript-DXnYMYO7.js → javascript-U-JBzSDk.js} +1 -1
  92. package/viewer/assets/{jinja-C-Qo2832.js → jinja-DBlWVTqh.js} +1 -1
  93. package/viewer/assets/{jison-CfzTRAm0.js → jison-ELt1NYXo.js} +1 -1
  94. package/viewer/assets/{journeyDiagram-3NMN7TZE-DbQ5PKPQ.js → journeyDiagram-3NMN7TZE-0fr5OEH9.js} +1 -1
  95. package/viewer/assets/{json-BaqYW62L.js → json-B_LODAI7.js} +1 -1
  96. package/viewer/assets/{jsx-DTafsOf-.js → jsx-BohFPbbA.js} +1 -1
  97. package/viewer/assets/{julia-Djdi6Tch.js → julia-Dco09L8E.js} +1 -1
  98. package/viewer/assets/{just-gZxWcw47.js → just-Dpx2bwga.js} +1 -1
  99. package/viewer/assets/{kanban-definition-UXKFOSKX-CwEeXphJ.js → kanban-definition-UXKFOSKX-3FngVt7d.js} +1 -1
  100. package/viewer/assets/{latex-CIO1OdmU.js → latex-Dccz5tQA.js} +1 -1
  101. package/viewer/assets/{line-Basn7TUv.js → line-Dhwi7DC5.js} +1 -1
  102. package/viewer/assets/{linear-Bu88wzXh.js → linear-gHMHD-Wa.js} +1 -1
  103. package/viewer/assets/{liquid-mYuCSXLi.js → liquid-D8w3l38v.js} +1 -1
  104. package/viewer/assets/{lua-lXhbu8ma.js → lua-tuIjH_94.js} +1 -1
  105. package/viewer/assets/{marko-BH-anPb4.js → marko-W3rkETdp.js} +1 -1
  106. package/viewer/assets/{mdc-DOuUtwPr.js → mdc-OJ1zd1BA.js} +1 -1
  107. package/viewer/assets/{mermaid-parser.core-CiGT3tRM.js → mermaid-parser.core-VTfqiyyK.js} +3 -3
  108. package/viewer/assets/{mermaid.core-BfFqBx2V.js → mermaid.core-eoOgKmWC.js} +4 -4
  109. package/viewer/assets/{mindmap-definition-YA3MSWOX-d_TnVAJG.js → mindmap-definition-YA3MSWOX-DeA-tJsi.js} +1 -1
  110. package/viewer/assets/{nginx-BB1dPcHJ.js → nginx-lXyaNnvL.js} +1 -1
  111. package/viewer/assets/{nim-BSJ4UdAS.js → nim-SOay_4P1.js} +1 -1
  112. package/viewer/assets/{org-JRn8h-K_.js → org-CRmJq-uC.js} +1 -1
  113. package/viewer/assets/{packet-AYTQ26CC-BA7VIQ3l.js → packet-AYTQ26CC-QgHmAlwp.js} +1 -1
  114. package/viewer/assets/{pegDiagram-XKGWAZYB-pfsoYtx9.js → pegDiagram-XKGWAZYB-BP0VAXd_.js} +1 -1
  115. package/viewer/assets/{perl-GzZ7epP9.js → perl-CHndoS_5.js} +1 -1
  116. package/viewer/assets/{php-Crolu7lU.js → php-DZCOF2Hm.js} +1 -1
  117. package/viewer/assets/{pie-WAS4IAKB-B9gCbpVP.js → pie-WAS4IAKB-Lghc8UPt.js} +1 -1
  118. package/viewer/assets/{pieDiagram-E7YTZNPT-D578iJLj.js → pieDiagram-E7YTZNPT-_ZEa88u4.js} +1 -1
  119. package/viewer/assets/{pug-BRaBHOlA.js → pug-Bj-uu214.js} +1 -1
  120. package/viewer/assets/{qml-BBlfnxMr.js → qml-DLfThugB.js} +1 -1
  121. package/viewer/assets/{quadrantDiagram-AXDQQJYC-DoKeLBeZ.js → quadrantDiagram-AXDQQJYC-BLeHQnim.js} +1 -1
  122. package/viewer/assets/{r-DG1YsJtP.js → r-Cnkx2_Um.js} +1 -1
  123. package/viewer/assets/{radar-RG4KPBEZ-Dr6Zcwqy.js → radar-RG4KPBEZ-CLW3C4xB.js} +1 -1
  124. package/viewer/assets/{railroad-74A4TZTK-CEncWApU.js → railroad-74A4TZTK-DLtGvURT.js} +1 -1
  125. package/viewer/assets/railroad-abnf-HS5TGJTU-CMoBRU-d.js +1 -0
  126. package/viewer/assets/railroad-ebnf-LZEXJU2U-Cs-h2401.js +1 -0
  127. package/viewer/assets/railroad-peg-WCYAUIDC-Q-VU3IQG.js +1 -0
  128. package/viewer/assets/{railroadDiagram-O6MQD6OU-7j0Th0r6.js → railroadDiagram-O6MQD6OU-DocKmoio.js} +1 -1
  129. package/viewer/assets/{razor-CY_sYdwH.js → razor-OW6qQyun.js} +1 -1
  130. package/viewer/assets/{regexp-DZiZuF5z.js → regexp-6RZ3RRCf.js} +1 -1
  131. package/viewer/assets/{requirementDiagram-BXWQKSXE-Dk1vCdh-.js → requirementDiagram-BXWQKSXE-cEjmGoYY.js} +1 -1
  132. package/viewer/assets/{rst-Dn_AtwYd.js → rst-CpEVnW9I.js} +1 -1
  133. package/viewer/assets/{ruby-BIB6MqpW.js → ruby-B2fIwwQt.js} +1 -1
  134. package/viewer/assets/{sankeyDiagram-P5KCCOFB-DaB06Zgj.js → sankeyDiagram-P5KCCOFB-BUdtY7Wt.js} +1 -1
  135. package/viewer/assets/{sas-Ccxd8Air.js → sas-DCHEi6wl.js} +1 -1
  136. package/viewer/assets/{scss-Cr7j0d4P.js → scss-D2bGvizF.js} +1 -1
  137. package/viewer/assets/{sequenceDiagram-WJ2MYXX4-BGEb3NdT.js → sequenceDiagram-WJ2MYXX4-DmsKCV1w.js} +1 -1
  138. package/viewer/assets/{shellscript-CHN-dwU6.js → shellscript-dnMGBhYw.js} +1 -1
  139. package/viewer/assets/{shellsession-uVGeQNm3.js → shellsession-EXXCHS9B.js} +1 -1
  140. package/viewer/assets/{soy-D7NWwJ5L.js → soy-BhJTFcrF.js} +1 -1
  141. package/viewer/assets/{sql-DRImQ2Oi.js → sql-Bg9JbbKb.js} +1 -1
  142. package/viewer/assets/{src-BnSwVg9U.js → src-C171e0nu.js} +1 -1
  143. package/viewer/assets/{stata-BIe0AUpg.js → stata-CAxSMxW7.js} +1 -1
  144. package/viewer/assets/{stateDiagram-D77RDMKH-DsRu-B2h.js → stateDiagram-D77RDMKH-OFqeW2Tm.js} +1 -1
  145. package/viewer/assets/stateDiagram-v2-MP3YSRHH-BeZW_eXx.js +1 -0
  146. package/viewer/assets/{surrealql-LEEn9cBl.js → surrealql-ChhGZa01.js} +1 -1
  147. package/viewer/assets/{svelte-CAMB-f9H.js → svelte-nQiI4XLd.js} +1 -1
  148. package/viewer/assets/{swimlanes-42K2YHIH-DqXHORT2.js → swimlanes-42K2YHIH-DHYfKuk0.js} +1 -1
  149. package/viewer/assets/swimlanesDiagram-VR7AAH4N-BYZ-vs6I.js +8 -0
  150. package/viewer/assets/{templ-zrRSW6Nf.js → templ-QcYlpMb-.js} +1 -1
  151. package/viewer/assets/{tex-D4XEXDuZ.js → tex-DkJXeRDT.js} +1 -1
  152. package/viewer/assets/{timeline-definition-24CTP7MA-DSpHKRpt.js → timeline-definition-24CTP7MA-CyRzlxCL.js} +1 -1
  153. package/viewer/assets/{treeView-Q6P3EWNA-pE7RJ0LU.js → treeView-Q6P3EWNA-dNcA3Vfo.js} +1 -1
  154. package/viewer/assets/{treemap-WGGIJYW6-CBfU2tIc.js → treemap-WGGIJYW6-BZWPBgpp.js} +1 -1
  155. package/viewer/assets/{ts-tags-DqFdF1-k.js → ts-tags-Fro3huiC.js} +1 -1
  156. package/viewer/assets/{tsx-Dz5osFq9.js → tsx-Dpl8Dyu3.js} +1 -1
  157. package/viewer/assets/{twig-CQ3wxbq3.js → twig-V8RRy40u.js} +1 -1
  158. package/viewer/assets/{typescript-Cu1dPDHw.js → typescript-DkL9-LA1.js} +1 -1
  159. package/viewer/assets/{typst-DHrnWrov.js → typst-DlTx93FO.js} +1 -1
  160. package/viewer/assets/{vennDiagram-4TSXK5OY-BPPSR6nr.js → vennDiagram-4TSXK5OY-CzTHbS5I.js} +1 -1
  161. package/viewer/assets/{vue-BaoJW0em.js → vue-B3Y_KP0j.js} +1 -1
  162. package/viewer/assets/{vue-html-DB9LdXl9.js → vue-html-CU1oynDW.js} +1 -1
  163. package/viewer/assets/{vue-vine-CqtlBPYW.js → vue-vine-zaYTs9kI.js} +1 -1
  164. package/viewer/assets/{wardley-WFR3VGLG-DfCbsSvk.js → wardley-WFR3VGLG-BHfRoe2C.js} +1 -1
  165. package/viewer/assets/{wardleyDiagram-VM6X3IG4-DeiKcJbE.js → wardleyDiagram-VM6X3IG4-YhghL-ul.js} +1 -1
  166. package/viewer/assets/{xml-CQ5T6aNZ.js → xml-CnVdnzon.js} +1 -1
  167. package/viewer/assets/{xsl-DVQ2v5YX.js → xsl-B9rDiHW0.js} +1 -1
  168. package/viewer/assets/{xychartDiagram-S5SC5T6Z-BsvlKd7r.js → xychartDiagram-S5SC5T6Z-BwmCelEN.js} +1 -1
  169. package/viewer/assets/{yaml-DXrThoWS.js → yaml-CbhKf1fN.js} +1 -1
  170. package/viewer/index.html +2 -2
  171. package/viewer/assets/architecture-7GRP2DOG-DtdqvSTn.js +0 -1
  172. package/viewer/assets/channel-BksTOWku.js +0 -1
  173. package/viewer/assets/classDiagram-ZZMXUADV-Cbfu0NLs.js +0 -1
  174. package/viewer/assets/classDiagram-v2-VYDZK3BY-Cbfu0NLs.js +0 -1
  175. package/viewer/assets/eventmodeling-NTZA5JFV-BsZg3yrD.js +0 -1
  176. package/viewer/assets/flowDiagram-HODETNUW-55jB5pet.js +0 -1
  177. package/viewer/assets/railroad-abnf-HS5TGJTU-BUgwRsng.js +0 -1
  178. package/viewer/assets/railroad-ebnf-LZEXJU2U-C22SR2MX.js +0 -1
  179. package/viewer/assets/railroad-peg-WCYAUIDC-DjI1jJwc.js +0 -1
  180. package/viewer/assets/stateDiagram-v2-MP3YSRHH-DtGwflXN.js +0 -1
  181. package/viewer/assets/swimlanesDiagram-VR7AAH4N-DCpSoqRu.js +0 -8
package/JUDGING.md CHANGED
@@ -47,11 +47,13 @@ cannot silently disappear from the benchmark denominator. Use consistent score
47
47
  IDs across models and repetitions; a missing required score stays unresolved.
48
48
  There are no built-in task-specific scorers, registration steps, or builder APIs.
49
49
 
50
- The host bundles local imports before execution, captures source maps and
51
- dependency manifests/lockfiles, and records their fingerprint. Code, imported
52
- references, or dependency changes schedule rejudging rather than candidate
53
- execution. Use static imports for reference data; make runtime network and file
54
- inputs reproducible when an author-owned judge uses them.
50
+ The host bundles local imports before execution, captures source maps, and
51
+ fingerprints the bundled code with the name and version of each imported
52
+ package. Code, imported references, or package version changes schedule
53
+ rejudging rather than candidate execution. The checkout location, working
54
+ directory, install layout, lockfiles, and SDK version do not. Use static imports
55
+ for reference data; make runtime network and file inputs reproducible when an
56
+ author-owned judge uses them.
55
57
 
56
58
  The viewer shows normalized criterion scores, original returned JSON, frozen
57
59
  source, process logs, and recorded candidate metrics. A synchronous loop can be
package/VERIFICATION.md CHANGED
@@ -8,7 +8,7 @@ run it in a disposable OCI container rather than on the runner host.
8
8
  import { VERIFICATION_IMAGE, type Benchmark } from "@hona/openeval";
9
9
  export default {
10
10
  models: ["example/model"],
11
- judge: { verification: { image: VERIFICATION_IMAGE, cpus: 2, memoryMiB: 4096 } },
11
+ judge: { verification: { image: VERIFICATION_IMAGE, cpus: 2, memoryMiB: 4096, workspaceMiB: 2048, inputMiB: 256 } },
12
12
  } satisfies Benchmark;
13
13
  ```
14
14
 
@@ -56,11 +56,27 @@ prefix does not necessarily establish final-task failure.
56
56
  - Commands, exit statuses, image/resource identity, logs, and requested regular
57
57
  output files are retained with the JudgeRun. Viewer previews never execute HTML
58
58
  or SVG from the delivered artifact.
59
- - Workspace transfer is limited to 128 MiB; each output archive is limited to
59
+ - Workspace transfer defaults to 128 MiB; each output archive is limited to
60
60
  32 MiB; logs are limited to 1 MiB per stream and are marked when truncated.
61
61
  - Containers self-expire. The parent also removes containers bearing only its
62
62
  unique execution label after worker interruption. No shared/broad cleanup.
63
63
 
64
+ The workspace tmpfs defaults to 512 MiB. Set `judge.verification.workspaceMiB`
65
+ for a larger restored project or prepared dependency tree. The value must be a
66
+ positive integer no larger than `memoryMiB` (which defaults to 4096). It is
67
+ retained in verification receipts and code-judge identity. Omitting it preserves
68
+ existing identities and limits. Network, credentials, privileges, transfer caps,
69
+ and the read-only image filesystem are unchanged.
70
+
71
+ For larger source snapshots, set `judge.verification.inputMiB` to a positive
72
+ integer archive limit. This is separate from `workspaceMiB`: increasing storage
73
+ alone does not increase the transfer limit. The configured byte count must be a
74
+ safe integer. Non-default limits are retained in receipts and code-judge identity;
75
+ omitting the field or setting it to 128 preserves existing identities. Output and
76
+ log caps, filesystem permissions, network access, and container isolation stay
77
+ unchanged. Provision enough workspace storage for the actual restored files and
78
+ any verification-generated data.
79
+
64
80
  The standard image includes Bun 1.4.2, Python, Git, Node, and Playwright 1.63.0
65
81
  with Chromium. Import Playwright from
66
82
  `/opt/verify/node_modules/playwright/index.mjs`. Dependencies needed by a task
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hona/openeval",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "Code and LLM evaluations with isolated agents, recorded OpenCode data, and a results viewer",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -43,6 +43,14 @@ export function candidateProviders(
43
43
  : undefined;
44
44
  }
45
45
 
46
+ /** The candidate session limit for one eval: its eval.ts override, else the benchmark value. */
47
+ export const candidateTimeout = (
48
+ definition: BenchmarkDefinition,
49
+ evalId: string,
50
+ ) =>
51
+ definition.evals.find((item) => item.id === evalId)?.settings.candidate
52
+ ?.timeoutMs ?? definition.candidate.timeoutMs;
53
+
46
54
  /** Declared, candidate-visible inputs. Harness implementation hashes are provenance.
47
55
  * Early stopping is a judge-side policy; the planner re-collects sessions it cut short. */
48
56
  export function candidateFingerprint(
@@ -59,7 +67,7 @@ export function candidateFingerprint(
59
67
  model,
60
68
  image: runtime.imageId,
61
69
  candidate: {
62
- timeoutMs: definition.candidate.timeoutMs,
70
+ timeoutMs: candidateTimeout(definition, evalId),
63
71
  websearch: definition.candidate.websearch,
64
72
  provider: scope && { ...scope.settings, model: scope.override },
65
73
  },
@@ -8,7 +8,7 @@ import type {
8
8
  EvalDefinition,
9
9
  ModelRef,
10
10
  } from "../types";
11
- import { CANDIDATE_TIMEOUT_MS } from "../types";
11
+ import { CANDIDATE_TIMEOUT_MS, MAX_CANDIDATE_TIMEOUT_MS } from "../types";
12
12
  import { rubricCriteria } from "../judgment";
13
13
  import {
14
14
  categoryKey,
@@ -18,6 +18,7 @@ import {
18
18
  import { compileCodeJudge } from "../infra/judging/code-source";
19
19
  import { readCodeCriteria } from "../infra/judging/code-criteria";
20
20
  import { RUNTIME_IMAGE } from "../infra/opencode/version";
21
+ import { DEFAULT_INPUT_MIB, verificationInputMiB } from "../infra/verification/limits";
21
22
  import { monitorPolicy } from "./monitor-policy";
22
23
  import {
23
24
  fingerprint,
@@ -32,6 +33,12 @@ const positive = (value: unknown, fallback: number, label: string) => {
32
33
  throw new Error(`${label} must be a positive integer`);
33
34
  return result;
34
35
  };
36
+ const timeLimit = (value: unknown, label: string) => {
37
+ const timeoutMs = positive(value, CANDIDATE_TIMEOUT_MS, label);
38
+ if (timeoutMs > MAX_CANDIDATE_TIMEOUT_MS)
39
+ throw new Error(`${label} cannot exceed 12 hours`);
40
+ return timeoutMs;
41
+ };
35
42
  export const modelRef = (value: unknown): ModelRef => {
36
43
  if (
37
44
  typeof value !== "string" ||
@@ -66,10 +73,23 @@ async function loadEval(directory: string): Promise<EvalDefinition> {
66
73
  throw new Error(`${id}/eval.ts must export a declaration`);
67
74
  if (
68
75
  Object.keys(settings).some(
69
- (key) => !["workspace", "prepare", "earlyStop"].includes(key),
76
+ (key) =>
77
+ !["workspace", "prepare", "earlyStop", "candidate"].includes(key),
70
78
  )
71
79
  )
72
80
  throw new Error(`${id}/eval.ts has unsupported settings`);
81
+ if (settings.candidate !== undefined) {
82
+ const candidate: unknown = settings.candidate;
83
+ if (
84
+ !candidate ||
85
+ typeof candidate !== "object" ||
86
+ Array.isArray(candidate) ||
87
+ Object.keys(candidate).some((key) => key !== "timeoutMs")
88
+ )
89
+ throw new Error(`${id}: candidate contains unsupported settings`);
90
+ if (settings.candidate.timeoutMs !== undefined)
91
+ timeLimit(settings.candidate.timeoutMs, `${id}: candidate timeout`);
92
+ }
73
93
  monitorPolicy(settings.earlyStop);
74
94
  if (hasCode && settings.earlyStop)
75
95
  throw new Error(
@@ -308,13 +328,10 @@ export async function loadBenchmark(
308
328
  );
309
329
  if (new Set(models).size !== models.length)
310
330
  throw new Error("Benchmark contains duplicate models");
311
- const timeoutMs = positive(
331
+ const timeoutMs = timeLimit(
312
332
  definition.candidate?.timeoutMs,
313
- CANDIDATE_TIMEOUT_MS,
314
333
  "Candidate timeout",
315
334
  );
316
- if (timeoutMs > CANDIDATE_TIMEOUT_MS)
317
- throw new Error("Candidate timeout cannot exceed 45 minutes");
318
335
  const evalRoot = resolve(directory, "evals");
319
336
  const directories = (await readdir(evalRoot, { withFileTypes: true }))
320
337
  .filter((entry) => entry.isDirectory() && !entry.name.startsWith("."))
@@ -348,10 +365,15 @@ export async function loadBenchmark(
348
365
  const verification = definition.judge?.verification;
349
366
  if (verification && (
350
367
  typeof verification !== "object" || Array.isArray(verification) ||
351
- Object.keys(verification).some(key => !["image", "engine", "cpus", "memoryMiB"].includes(key)) ||
368
+ Object.keys(verification).some(key => !["image", "engine", "cpus", "memoryMiB", "workspaceMiB", "inputMiB"].includes(key)) ||
352
369
  typeof verification.image !== "string" || !verification.image.trim() || /\s/.test(verification.image) ||
353
370
  !["docker", "podman"].includes(verification.engine ?? engine)
354
371
  )) throw new Error("judge.verification requires an image and valid container limits");
372
+ const verificationMemory = positive(verification?.memoryMiB, 4096, "Verification memory");
373
+ if (verification?.workspaceMiB !== undefined &&
374
+ (!Number.isSafeInteger(verification.workspaceMiB) || verification.workspaceMiB < 1 || verification.workspaceMiB > verificationMemory))
375
+ throw new Error("Verification workspaceMiB must be a positive integer within memoryMiB");
376
+ const inputMiB = verificationInputMiB(verification?.inputMiB);
355
377
  for (const search of [
356
378
  definition.candidate?.websearch,
357
379
  definition.judge?.websearch,
@@ -387,7 +409,9 @@ export async function loadBenchmark(
387
409
  image: verification.image,
388
410
  engine: verification.engine ?? engine,
389
411
  cpus: positive(verification.cpus, 2, "Verification CPU count"),
390
- memoryMiB: positive(verification.memoryMiB, 4096, "Verification memory"),
412
+ memoryMiB: verificationMemory,
413
+ ...(verification.workspaceMiB === undefined ? {} : { workspaceMiB: verification.workspaceMiB }),
414
+ ...(inputMiB === DEFAULT_INPUT_MIB ? {} : { inputMiB }),
391
415
  } } : {}),
392
416
  },
393
417
  container: {
@@ -5,7 +5,7 @@ import { executeCandidate } from "../infra/containers/candidate";
5
5
  import type { EvidenceFeed } from "../evidence";
6
6
  import { CandidateEvidence } from "../infra/evidence";
7
7
  import { measureRecording } from "../infra/recording/metrics";
8
- import { candidateProviders } from "./input-fingerprints";
8
+ import { candidateProviders, candidateTimeout } from "./input-fingerprints";
9
9
 
10
10
  /** The normal candidate use case: record its inputs, execute, finalize its evidence. */
11
11
  export async function runEval(
@@ -20,6 +20,7 @@ export async function runEval(
20
20
  const definition = context.definition.evals.find(
21
21
  (item) => item.id === slot.evalId,
22
22
  )!;
23
+ const timeoutMs = candidateTimeout(context.definition, slot.evalId);
23
24
  const run = context.results.startEval(slot, {
24
25
  evalId: slot.evalId,
25
26
  model: slot.model,
@@ -28,7 +29,7 @@ export async function runEval(
28
29
  candidateHash: slot.candidateHash,
29
30
  sourceHash: definition.sourceHash,
30
31
  imageId: context.runtime.imageId,
31
- timeoutMs: context.definition.candidate.timeoutMs,
32
+ timeoutMs,
32
33
  earlyStop: !!controls.onEvidence,
33
34
  runtime: context.runtime,
34
35
  });
@@ -39,7 +40,7 @@ export async function runEval(
39
40
  prompt: definition.prompt,
40
41
  workspace,
41
42
  prepare: definition.settings.prepare ?? [],
42
- timeoutMs: context.definition.candidate.timeoutMs,
43
+ timeoutMs,
43
44
  websearch: context.definition.candidate.websearch,
44
45
  container: context.definition.container,
45
46
  imageId: context.runtime.imageId,
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export type {
2
2
  Benchmark,
3
+ CandidateLimits,
3
4
  Eval,
4
5
  ModelRef,
5
6
  ProviderDefinitions,
@@ -30,7 +31,7 @@ export type {
30
31
  EvidenceQuery,
31
32
  JudgeSession,
32
33
  } from "./evidence";
33
- export { CANDIDATE_TIMEOUT_MS } from "./types";
34
+ export { CANDIDATE_TIMEOUT_MS, MAX_CANDIDATE_TIMEOUT_MS } from "./types";
34
35
  export { rubricCriteria, criterionMean, isScored } from "./judgment";
35
36
  export {
36
37
  categoryKey,
@@ -1,18 +1,34 @@
1
- import { dirname, isAbsolute, resolve } from "node:path";
2
- import { fileURLToPath } from "node:url";
1
+ import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
3
2
  import type { CodeJudgeDefinition } from "../../judge-context";
4
3
  import { fingerprint } from "../files";
5
4
 
5
+ /** Raise when a release changes what judge.ts receives or how it runs; every code judge then runs again. */
6
+ const CODE_JUDGE_PROTOCOL = 1;
7
+ const printer = new Bun.Transpiler({
8
+ loader: "js",
9
+ target: "bun",
10
+ deadCodeElimination: false,
11
+ });
12
+
13
+ /** The package that provides an external import, as `name@version/path`. */
14
+ async function packageSpecifier(path: string, from: string) {
15
+ for (let directory = dirname(path); ; directory = dirname(directory)) {
16
+ const manifest = Bun.file(resolve(directory, "package.json"));
17
+ const { name, version } = (await manifest.exists())
18
+ ? await manifest.json().catch(() => ({}))
19
+ : {};
20
+ if (typeof name === "string" && name)
21
+ return `${name}@${version ?? ""}/${relative(directory, path).split(sep).join("/")}`;
22
+ if (dirname(directory) === directory)
23
+ return relative(from, path).split(sep).join("/");
24
+ }
25
+ }
26
+
6
27
  /** Bundle local imports without executing author code during planning. */
7
28
  export async function compileCodeJudge(
8
29
  file: string,
9
30
  ): Promise<CodeJudgeDefinition> {
10
31
  file = resolve(file);
11
- const dependencies: Record<string, string> = {};
12
- const sdkManifest = fileURLToPath(
13
- new URL("../../../package.json", import.meta.url),
14
- );
15
- dependencies[sdkManifest] = await Bun.file(sdkManifest).text();
16
32
  const external = new Set<string>();
17
33
  const built = await Bun.build({
18
34
  // Import only the judge function: unused reporting metadata is tree-shaken.
@@ -65,40 +81,32 @@ export async function compileCodeJudge(
65
81
  (await built.outputs
66
82
  .find((output) => output.kind === "sourcemap")
67
83
  ?.text()) ?? "";
68
- const collect = async (directory: string, stopAtPackage: boolean) => {
69
- for (;;) {
70
- let found = false;
71
- for (const name of [
72
- "package.json",
73
- "bun.lock",
74
- "bun.lockb",
75
- "package-lock.json",
76
- "pnpm-lock.yaml",
77
- "yarn.lock",
78
- ]) {
79
- const path = resolve(directory, name);
80
- if (await Bun.file(path).exists()) {
81
- dependencies[path] =
82
- name === "bun.lockb"
83
- ? Buffer.from(await Bun.file(path).bytes()).toString("base64")
84
- : await Bun.file(path).text();
85
- found ||= name === "package.json";
86
- }
87
- }
88
- if (found && stopAtPackage) return;
89
- const parent = dirname(directory);
90
- if (parent === directory) return;
91
- directory = parent;
92
- }
93
- };
94
- await collect(dirname(file), false);
95
- for (const path of external) await collect(dirname(path), true);
84
+ // The executable keeps absolute import paths; identity uses the package name and version.
85
+ const dependencies: Record<string, string> = {};
86
+ let portable = source;
87
+ for (const path of external) {
88
+ const specifier = await packageSpecifier(path, dirname(file));
89
+ dependencies[specifier] = path;
90
+ portable = portable.replaceAll(
91
+ JSON.stringify(path),
92
+ JSON.stringify(specifier),
93
+ );
94
+ }
95
+ // Bun writes __dirname and __filename as absolute paths. Like other runtime file inputs, they are not identity.
96
+ portable = portable.replace(
97
+ /^\s*var __(?:dirname|filename) = .*$/gm,
98
+ (line) => line.replace(/"(?:[^"\\]|\\.)*"/g, '""'),
99
+ );
96
100
  return {
97
101
  file,
98
102
  source,
99
103
  sourceMap,
100
104
  dependencies,
101
- // Debug mappings and original-source metadata are retained, but not executable inputs.
102
- hash: fingerprint({ source, dependencies }),
105
+ // Reprinting drops comments: module comments name files relative to the working
106
+ // directory, and the debug ID depends on them. Source maps are retained, not hashed.
107
+ hash: fingerprint({
108
+ protocol: CODE_JUDGE_PROTOCOL,
109
+ source: printer.transformSync(portable),
110
+ }),
103
111
  };
104
112
  }
@@ -2,6 +2,7 @@ import { fileURLToPath } from "node:url";
2
2
  import type { VerificationEnvironment, VerificationRuntime } from "../../judge-context";
3
3
  import { engineCommand } from "../containers/docker";
4
4
  import { treeHash } from "../files";
5
+ import { DEFAULT_INPUT_MIB, verificationInputMiB } from "./limits";
5
6
 
6
7
  export const VERIFICATION_IMAGE = "openeval-verification:0.5.0";
7
8
  const directory = fileURLToPath(new URL("./runtime/", import.meta.url));
@@ -21,6 +22,11 @@ export async function verificationRuntime(environment?: VerificationEnvironment)
21
22
  if (!["docker", "podman"].includes(engine) || !environment.image || /\s/.test(environment.image) ||
22
23
  [environment.cpus ?? 2, environment.memoryMiB ?? 4096].some(value => !Number.isSafeInteger(value) || value < 1))
23
24
  throw new Error("Verification requires a valid image, engine, and positive integer resource limits");
25
+ if (environment.workspaceMiB !== undefined &&
26
+ (!Number.isSafeInteger(environment.workspaceMiB) || environment.workspaceMiB < 1 ||
27
+ environment.workspaceMiB > (environment.memoryMiB ?? 4096)))
28
+ throw new Error("Verification workspaceMiB must be a positive integer within memoryMiB");
29
+ const inputMiB = verificationInputMiB(environment.inputMiB);
24
30
  const output = await engineCommand(engine, [
25
31
  "image", "inspect", environment.image, "--format",
26
32
  '{{.Id}}|{{index .Config.Labels "openeval.verification"}}',
@@ -29,5 +35,10 @@ export async function verificationRuntime(environment?: VerificationEnvironment)
29
35
  if (!/^sha256:[a-f0-9]{64}$/.test(imageId)) throw new Error("Verification image has no immutable image ID");
30
36
  if (environment.image === VERIFICATION_IMAGE && label !== await treeHash(directory))
31
37
  throw new Error("Verification runtime changed. Run image --verification first.");
32
- return { engine, image: environment.image, imageId, cpus: environment.cpus ?? 2, memoryMiB: environment.memoryMiB ?? 4096 };
38
+ return {
39
+ engine, image: environment.image, imageId,
40
+ cpus: environment.cpus ?? 2, memoryMiB: environment.memoryMiB ?? 4096,
41
+ ...(environment.workspaceMiB === undefined ? {} : { workspaceMiB: environment.workspaceMiB }),
42
+ ...(inputMiB === DEFAULT_INPUT_MIB ? {} : { inputMiB }),
43
+ };
33
44
  }
@@ -0,0 +1,14 @@
1
+ export const DEFAULT_INPUT_MIB = 128;
2
+ const MIB = 1024 * 1024;
3
+
4
+ /** Restored workspace archives stay bounded, including opt-in larger inputs. */
5
+ export function verificationInputMiB(value?: number): number {
6
+ const limit = value === undefined ? DEFAULT_INPUT_MIB : value;
7
+ if (!Number.isSafeInteger(limit) || limit < 1 || !Number.isSafeInteger(limit * MIB))
8
+ throw new Error("Verification inputMiB must be a positive integer with a safe byte count");
9
+ return limit;
10
+ }
11
+
12
+ export function verificationInputBytes(value?: number): number {
13
+ return verificationInputMiB(value) * MIB;
14
+ }
@@ -6,10 +6,10 @@ import type { Engine } from "../../types";
6
6
  import { engineCommand } from "../containers/docker";
7
7
  import { extractWorkspaceArchive } from "../containers/transfer";
8
8
  import { contained, hash, relativePath, writeJson } from "../files";
9
+ import { verificationInputBytes, verificationInputMiB } from "./limits";
9
10
 
10
11
  const LOG_BYTES = 1024 * 1024;
11
12
  const OUTPUT_BYTES = 32 * 1024 * 1024;
12
- const INPUT_BYTES = 128 * 1024 * 1024;
13
13
 
14
14
  export function verificationPath(value: string): string {
15
15
  relativePath(value, "Verification path");
@@ -26,7 +26,7 @@ export function verificationArgs(runtime: VerificationRuntime, owner: string, na
26
26
  "--network=none", "--cap-drop=ALL", "--security-opt=no-new-privileges", "--read-only",
27
27
  "--pids-limit", "128", "--cpus", String(runtime.cpus), "--memory", `${runtime.memoryMiB}m`,
28
28
  "--memory-swap", `${runtime.memoryMiB}m`, "--user", "10001:10001",
29
- "--tmpfs", "/workspace:rw,exec,nosuid,nodev,mode=1777,size=512m",
29
+ "--tmpfs", `/workspace:rw,exec,nosuid,nodev,mode=1777,size=${runtime.workspaceMiB ?? 512}m`,
30
30
  "--tmpfs", "/verification:rw,exec,nosuid,nodev,mode=0755,size=64m",
31
31
  "--tmpfs", "/tmp:rw,exec,nosuid,nodev,mode=1777,size=256m",
32
32
  "--env", "HOME=/tmp/home", "--env", "CI=1",
@@ -116,8 +116,8 @@ export function verificationSession(options: {
116
116
  const archive = resolve(staging, "workspace.tar");
117
117
  const pack = Bun.spawn(["tar", "-cf", archive, "-C", workspace, "."], { stdout: "ignore", stderr: "pipe" });
118
118
  const [packed, packError] = await Promise.all([pack.exited, new Response(pack.stderr).text()]);
119
- if (packed || (await lstat(archive)).size > INPUT_BYTES)
120
- throw new Error(packed ? `Verification transfer failed: ${packError}` : "Restored verification workspace exceeds 128 MiB");
119
+ if (packed || (await lstat(archive)).size > verificationInputBytes(runtime.inputMiB))
120
+ throw new Error(packed ? `Verification transfer failed: ${packError}` : `Restored verification workspace exceeds ${verificationInputMiB(runtime.inputMiB)} MiB`);
121
121
  const name = `openeval-verify-${randomUUID()}`;
122
122
  const startedAt = new Date().toISOString();
123
123
  const deadlineAt = Date.now() + timeoutMs;
@@ -39,6 +39,10 @@ export type VerificationEnvironment = {
39
39
  image: string;
40
40
  cpus?: number;
41
41
  memoryMiB?: number;
42
+ /** Workspace tmpfs capacity in MiB; default 512. A custom value must fit within memoryMiB. */
43
+ workspaceMiB?: number;
44
+ /** Maximum restored workspace archive size in MiB; default 128. */
45
+ inputMiB?: number;
42
46
  };
43
47
  export type VerificationRuntime = {
44
48
  engine: Engine;
@@ -46,6 +50,8 @@ export type VerificationRuntime = {
46
50
  imageId: string;
47
51
  cpus: number;
48
52
  memoryMiB: number;
53
+ workspaceMiB?: number;
54
+ inputMiB?: number;
49
55
  };
50
56
  export type VerificationRequest = {
51
57
  revision?: Revision;
@@ -185,9 +191,11 @@ export interface JudgeContext {
185
191
  /** Frozen judging source and dependency identity, kept in host-side run records. */
186
192
  export type CodeJudgeDefinition = {
187
193
  file: string;
194
+ /** Executable identity: bundled code and imported package versions, without host paths or comments. */
188
195
  hash: string;
189
196
  source: string;
190
197
  sourceMap: string;
198
+ /** Packages imported at run time, as `name@version/path`, with the file each resolved to. */
191
199
  dependencies: Record<string, string>;
192
200
  };
193
201
  export type CodeJudgeExecution = {
package/src/types.ts CHANGED
@@ -15,6 +15,7 @@ import type {
15
15
  export type OpenCodeStreamEvent = OpenCodeEvent | SessionLogItem;
16
16
 
17
17
  export const CANDIDATE_TIMEOUT_MS = 45 * 60 * 1000;
18
+ export const MAX_CANDIDATE_TIMEOUT_MS = 12 * 60 * 60 * 1000;
18
19
  export type ModelRef = `${string}/${string}`;
19
20
  export type Engine = "docker" | "podman";
20
21
  export type ProviderDefinitions = NonNullable<
@@ -34,6 +35,11 @@ export type Judge = {
34
35
  websearch?: "exa" | false;
35
36
  verification?: VerificationEnvironment;
36
37
  };
38
+ /** Execution controls for one candidate attempt. Eval values override benchmark values. */
39
+ export type CandidateLimits = {
40
+ /** Agent session limit, after preparation; default 45 minutes, at most 12 hours. */
41
+ timeoutMs?: number;
42
+ };
37
43
  export type Benchmark = {
38
44
  name?: string;
39
45
  /** Display label for one benchmark.ts among several that share `name`, such as "Frontier". */
@@ -42,8 +48,7 @@ export type Benchmark = {
42
48
  judge?: Judge;
43
49
  repetitions?: number;
44
50
  concurrency?: number;
45
- candidate?: {
46
- timeoutMs?: number;
51
+ candidate?: CandidateLimits & {
47
52
  websearch?: "exa" | false;
48
53
  providers?: ProviderDefinitions;
49
54
  };
@@ -82,6 +87,8 @@ export type Eval = {
82
87
  overlay?: string;
83
88
  };
84
89
  prepare?: readonly PreparationStep[];
90
+ /** Overrides benchmark.candidate for this eval. */
91
+ candidate?: CandidateLimits;
85
92
  };
86
93
  export type EvalDefinition = {
87
94
  id: string;
@@ -106,7 +113,7 @@ export type BenchmarkDefinition = {
106
113
  suite?: string;
107
114
  directory: string;
108
115
  models: ModelRef[];
109
- judge: { model?: ModelRef; timeoutMs: number; websearch: "exa" | false; verification?: VerificationRuntime | Required<VerificationEnvironment> };
116
+ judge: { model?: ModelRef; timeoutMs: number; websearch: "exa" | false; verification?: VerificationRuntime | Omit<VerificationRuntime, "imageId"> };
110
117
  repetitions: number;
111
118
  concurrency: number;
112
119
  candidate: {
package/src/view.ts CHANGED
@@ -171,13 +171,33 @@ function componentBounds(
171
171
  coverage: coverage * scale,
172
172
  };
173
173
  }
174
- export const sumCosts = (costs: readonly (Cost | undefined)[]): Cost => {
174
+ /** A cost summed over executions. `unaccounted` counts executions without a final cost. */
175
+ export type CostTotal = Cost & { unaccounted: number };
176
+ /** Sum execution costs or totals; a single execution without a final cost counts once. */
177
+ export const sumCosts = (
178
+ costs: readonly (Cost | CostTotal | undefined)[],
179
+ ): CostTotal => {
175
180
  const reportedUSD = costs.reduce(
176
181
  (sum, cost) => sum + (cost?.reportedUSD ?? 0),
177
182
  0,
178
183
  );
179
184
  const complete = costs.every((cost) => cost?.complete === true);
180
- return { reportedUSD, complete, usd: complete ? reportedUSD : null };
185
+ const unaccounted = costs.reduce(
186
+ (sum, cost) =>
187
+ sum +
188
+ (cost && "unaccounted" in cost
189
+ ? cost.unaccounted
190
+ : cost?.complete
191
+ ? 0
192
+ : 1),
193
+ 0,
194
+ );
195
+ return {
196
+ reportedUSD,
197
+ complete,
198
+ usd: complete ? reportedUSD : null,
199
+ unaccounted,
200
+ };
181
201
  };
182
202
  export type ResultEntry = {
183
203
  id: string;
@@ -209,8 +229,8 @@ export type Overview = {
209
229
  evalNames: Record<string, string>;
210
230
  modelNames: ModelNames;
211
231
  categories: CategorySummary[];
212
- cost: Cost;
213
- evalCosts: Record<string, Cost>;
232
+ cost: CostTotal;
233
+ evalCosts: Record<string, CostTotal>;
214
234
  runtime: RuntimeInterval[];
215
235
  };
216
236
  export type ResultSummary = {
@@ -305,7 +325,10 @@ export type JudgeAudit = {
305
325
  Pick<JudgeRun, "id" | "state" | "startedAt"> & { mode: "monitor" | "final" }
306
326
  >;
307
327
  };
308
- export type EvalRunSummary = LiveEvalRun & { cost: Cost; elapsedMs: number };
328
+ export type EvalRunSummary = LiveEvalRun & {
329
+ cost: CostTotal;
330
+ elapsedMs: number;
331
+ };
309
332
  export type EvalRunIndex = {
310
333
  entry: ResultEntry;
311
334
  eval: string;
@@ -316,7 +339,7 @@ export type ActivityRun = {
316
339
  id: string;
317
340
  benchmarkId: string;
318
341
  resultId: string;
319
- cost: Cost;
342
+ cost: CostTotal;
320
343
  state: {
321
344
  id: string;
322
345
  eval: string;
@@ -1 +1 @@
1
- import{m as e,t}from"./mermaid-parser.core-CiGT3tRM.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-BnSwVg9U.js";import"./chunk-DU6HZSFF-Cty-qidK.js";import{n as i,r as a,t as o}from"./chunk-SVP7TREG-BEMJeRHW.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-BfFqBx2V.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
1
+ import{m as e,t}from"./mermaid-parser.core-VTfqiyyK.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-C171e0nu.js";import"./chunk-DU6HZSFF-BI4SVpji.js";import{n as i,r as a,t as o}from"./chunk-SVP7TREG-CGuEYo-A.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-eoOgKmWC.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};