reeval 0.6.3 → 0.8.0

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 (226) hide show
  1. package/README.md +265 -0
  2. package/THIRD_PARTY_NOTICES.md +5 -5
  3. package/assets/package.json +1 -1
  4. package/assets/pnpm-lock.yaml +30 -307
  5. package/dist/{agent-DKuFnZPM.js → agent-B72lZ6w5.js} +6 -6
  6. package/dist/{agent-DKuFnZPM.js.map → agent-B72lZ6w5.js.map} +1 -1
  7. package/dist/{agent-oirN_8IS.js → agent-Cfj1wD4D.js} +5 -5
  8. package/dist/{agent-oirN_8IS.js.map → agent-Cfj1wD4D.js.map} +1 -1
  9. package/dist/{analysis-BV3TCznv.js → analysis-BTNnKh1w.js} +4 -4
  10. package/dist/{analysis-BV3TCznv.js.map → analysis-BTNnKh1w.js.map} +1 -1
  11. package/dist/{assemble-DYCDgbTq.js → assemble-BbFVjHeS.js} +125 -14
  12. package/dist/assemble-BbFVjHeS.js.map +1 -0
  13. package/dist/assemble-CXiTVyHD.js +2 -0
  14. package/dist/bridge/index.mjs +66 -7
  15. package/dist/bridge/package.json +3 -3
  16. package/dist/bridge/pnpm-lock.yaml +84 -89
  17. package/dist/capture-BXhBfmsM.js +1206 -0
  18. package/dist/capture-BXhBfmsM.js.map +1 -0
  19. package/dist/capture-N7r3yeak.js +2 -0
  20. package/dist/{cli-BIhzl_v_.js → cli-BMjTKY-D.js} +151 -193
  21. package/dist/cli-BMjTKY-D.js.map +1 -0
  22. package/dist/{cli-spec-DUeyuSIQ.js → cli-spec-DSvKsOK4.js} +25 -11
  23. package/dist/cli-spec-DSvKsOK4.js.map +1 -0
  24. package/dist/cli.js +2 -2
  25. package/dist/client-CwzU9CiW.js +256 -0
  26. package/dist/client-CwzU9CiW.js.map +1 -0
  27. package/dist/{command-B8tcwUJk.js → command-BK4kOgkH.js} +15 -15
  28. package/dist/{command-B8tcwUJk.js.map → command-BK4kOgkH.js.map} +1 -1
  29. package/dist/{command-fJpZK205.js → command-BdstSEHu.js} +7 -7
  30. package/dist/{command-fJpZK205.js.map → command-BdstSEHu.js.map} +1 -1
  31. package/dist/{command-DuJBqcwu.js → command-BqJtFiPy.js} +153 -36
  32. package/dist/command-BqJtFiPy.js.map +1 -0
  33. package/dist/command-CTVGuH8y.js +2 -0
  34. package/dist/{command-KoOJ0ntD.js → command-JPGNzFsA.js} +9 -9
  35. package/dist/{command-KoOJ0ntD.js.map → command-JPGNzFsA.js.map} +1 -1
  36. package/dist/{commands-CHdTfPB6.js → commands-B618jg3C.js} +6 -6
  37. package/dist/{commands-CHdTfPB6.js.map → commands-B618jg3C.js.map} +1 -1
  38. package/dist/{commands-DE604ldB.js → commands-Duo2ur3r.js} +1 -1
  39. package/dist/{config-7-gXOgQf.js → config-B-E0xRkf.js} +4 -4
  40. package/dist/{config-7-gXOgQf.js.map → config-B-E0xRkf.js.map} +1 -1
  41. package/dist/db-CnoUy-FZ.js +3 -0
  42. package/dist/{db-DvkzBhM6.js → db-DFbtGIYy.js} +84 -37
  43. package/dist/db-DFbtGIYy.js.map +1 -0
  44. package/dist/{dist-DsZNsoD3.js → dist-CTzThfu_.js} +3 -3
  45. package/dist/{dist-DsZNsoD3.js.map → dist-CTzThfu_.js.map} +1 -1
  46. package/dist/{docker-BBOMThRi.js → docker-2qns7hJ2.js} +4 -4
  47. package/dist/{docker-BBOMThRi.js.map → docker-2qns7hJ2.js.map} +1 -1
  48. package/dist/{docker-CiNVc7di.js → docker-D6t23fZl.js} +1 -1
  49. package/dist/{docker-CzFiN2AZ.js → docker-IFRW8K5f.js} +2 -2
  50. package/dist/{docker-CzFiN2AZ.js.map → docker-IFRW8K5f.js.map} +1 -1
  51. package/dist/{doctor-C06kYs2r.js → doctor-B6oYTPoR.js} +11 -11
  52. package/dist/{doctor-C06kYs2r.js.map → doctor-B6oYTPoR.js.map} +1 -1
  53. package/dist/{egress-De64jpeQ.js → egress-IUKdeayc.js} +17 -10
  54. package/dist/egress-IUKdeayc.js.map +1 -0
  55. package/dist/fake-instructions-CUI33I_F.js +32 -0
  56. package/dist/fake-instructions-CUI33I_F.js.map +1 -0
  57. package/dist/{files-BqIF7iu4.js → files-B6aVVGrk.js} +3 -3
  58. package/dist/{files-BqIF7iu4.js.map → files-B6aVVGrk.js.map} +1 -1
  59. package/dist/files-BpYgF2z0.js +2 -0
  60. package/dist/{files-Cq99wif-.js → files-CMSUXAEg.js} +16 -5
  61. package/dist/{files-Cq99wif-.js.map → files-CMSUXAEg.js.map} +1 -1
  62. package/dist/files-YCCVaTQC.js +2 -0
  63. package/dist/{git-Dnl-kXgD.js → git-EmdFJ4DY.js} +2 -2
  64. package/dist/{git-Dnl-kXgD.js.map → git-EmdFJ4DY.js.map} +1 -1
  65. package/dist/{harness-3QUEWx8G.js → harness-iqWeJQMM.js} +35 -12
  66. package/dist/harness-iqWeJQMM.js.map +1 -0
  67. package/dist/harness.d.ts +22 -11
  68. package/dist/harness.js +1 -1
  69. package/dist/{header-IE-uIvX0.js → header-_F0EWob3.js} +2 -2
  70. package/dist/{header-IE-uIvX0.js.map → header-_F0EWob3.js.map} +1 -1
  71. package/dist/{images-B8Mp_VXZ.js → images-CscddrJU.js} +6 -6
  72. package/dist/{images-B8Mp_VXZ.js.map → images-CscddrJU.js.map} +1 -1
  73. package/dist/index.d.ts +13 -8
  74. package/dist/index.js +99 -24
  75. package/dist/index.js.map +1 -1
  76. package/dist/init-DBHyi92L.js +2 -0
  77. package/dist/{init-B8mw86E6.js → init-NQfIvi-0.js} +4 -4
  78. package/dist/{init-B8mw86E6.js.map → init-NQfIvi-0.js.map} +1 -1
  79. package/dist/{invocations-DHC946b-.js → invocations-nPvrlZPj.js} +3 -3
  80. package/dist/{invocations-DHC946b-.js.map → invocations-nPvrlZPj.js.map} +1 -1
  81. package/dist/{judge-7WjNdU9z.js → judge-CeYPN8P_.js} +2 -2
  82. package/dist/{judge-7WjNdU9z.js.map → judge-CeYPN8P_.js.map} +1 -1
  83. package/dist/judge.d.ts +5 -4
  84. package/dist/judge.js +4 -3
  85. package/dist/judge.js.map +1 -1
  86. package/dist/{live-DZkCtmNP.js → live-S0qODb6o.js} +2 -2
  87. package/dist/{live-DZkCtmNP.js.map → live-S0qODb6o.js.map} +1 -1
  88. package/dist/model-BbLGRtOs.js +2 -0
  89. package/dist/{model-CtrJdFi6.js → model-BndnmcLm.js} +241 -26
  90. package/dist/model-BndnmcLm.js.map +1 -0
  91. package/dist/{model-Cp6NoAT3.js → model-Cl507trk.js} +8 -7
  92. package/dist/model-Cl507trk.js.map +1 -0
  93. package/dist/{model-Bv8uUZ07.js → model-DEQo3FkZ.js} +6 -6
  94. package/dist/model-DEQo3FkZ.js.map +1 -0
  95. package/dist/{model-BeoRxCcJ.js → model-DMOraCcm.js} +1 -1
  96. package/dist/{opencode-providers-DjlA5fuC.js → opencode-providers-ByD85Q0l.js} +21 -7
  97. package/dist/{opencode-providers-DjlA5fuC.js.map → opencode-providers-ByD85Q0l.js.map} +1 -1
  98. package/dist/{options-CWYB613o.js → options-DPUlm4FI.js} +152 -29
  99. package/dist/options-DPUlm4FI.js.map +1 -0
  100. package/dist/pairs-DDsjgm5F.js +149 -0
  101. package/dist/pairs-DDsjgm5F.js.map +1 -0
  102. package/dist/{plan-CsPE24pp.js → plan-PPc4-6xd.js} +35 -18
  103. package/dist/plan-PPc4-6xd.js.map +1 -0
  104. package/dist/{preflight-r0DgibQV.js → preflight-CddycK92.js} +3 -3
  105. package/dist/{preflight-r0DgibQV.js.map → preflight-CddycK92.js.map} +1 -1
  106. package/dist/{preflight-DKZjb7ZH.js → preflight-Zumy0adT.js} +1 -1
  107. package/dist/{prepare-DOkvAa9D.js → prepare-CKdMoC7e.js} +2 -2
  108. package/dist/{prepare-CTLg3nuk.js → prepare-CsP-057p.js} +4 -4
  109. package/dist/{prepare-CTLg3nuk.js.map → prepare-CsP-057p.js.map} +1 -1
  110. package/dist/{provenance--cVNo80L.js → provenance-CsX6PHDR.js} +2 -2
  111. package/dist/{provenance--cVNo80L.js.map → provenance-CsX6PHDR.js.map} +1 -1
  112. package/dist/{providers-DNLQzVnc.js → providers-DkwiLKDS.js} +3 -3
  113. package/dist/{providers-DNLQzVnc.js.map → providers-DkwiLKDS.js.map} +1 -1
  114. package/dist/{providers-B2cSfewm.js → providers-yXZZcPfx.js} +1 -1
  115. package/dist/{query-DTtIZaua.js → query-BUcwCYsI.js} +2 -2
  116. package/dist/{query-DTtIZaua.js.map → query-BUcwCYsI.js.map} +1 -1
  117. package/dist/query-noGbekGF.js +2 -0
  118. package/dist/{questions-ZdT3JDyQ.js → questions-BEPj98fZ.js} +27 -118
  119. package/dist/questions-BEPj98fZ.js.map +1 -0
  120. package/dist/{record-CbuQH4l1.js → record-BRP9vZrj.js} +21 -1
  121. package/dist/record-BRP9vZrj.js.map +1 -0
  122. package/dist/results-BcSHWbgB.js +52 -0
  123. package/dist/results-BcSHWbgB.js.map +1 -0
  124. package/dist/resume-DZ9AmfPv.js +406 -0
  125. package/dist/resume-DZ9AmfPv.js.map +1 -0
  126. package/dist/{matchers-Bp-OH1vj.js → runtime-Dfb2r-cS.js} +2 -179
  127. package/dist/runtime-Dfb2r-cS.js.map +1 -0
  128. package/dist/sandbox.d.ts +1 -1
  129. package/dist/{server-BFlKK2j6.js → server-Da60oe4b.js} +9 -9
  130. package/dist/{server-BFlKK2j6.js.map → server-Da60oe4b.js.map} +1 -1
  131. package/dist/server-DiGR4JxK.js +2 -0
  132. package/dist/{source-B2ASbTdc.js → source-BVOnL3sn.js} +2 -2
  133. package/dist/{source-B2ASbTdc.js.map → source-BVOnL3sn.js.map} +1 -1
  134. package/dist/source-Dqu0jKwx.js +2 -0
  135. package/dist/src-BHNiP-5A.js +4 -0
  136. package/dist/{src-CDiGyoDt.js → src-BT4dB5CO.js} +1 -1
  137. package/dist/src-BT5pwco0.js +3 -0
  138. package/dist/src-BrMbt1B2.js +3 -0
  139. package/dist/{src-s-VffoYK.js → src-C1E9HDWO.js} +5 -3
  140. package/dist/{src-s-VffoYK.js.map → src-C1E9HDWO.js.map} +1 -1
  141. package/dist/{src-CqsERnCZ.js → src-CxTC5kNI.js} +10 -6
  142. package/dist/{src-CqsERnCZ.js.map → src-CxTC5kNI.js.map} +1 -1
  143. package/dist/src-D13vpMh0.js +3 -0
  144. package/dist/{src-DxFJrMUA.js → src-D95O-Smv.js} +12 -7
  145. package/dist/{src-DxFJrMUA.js.map → src-D95O-Smv.js.map} +1 -1
  146. package/dist/{src-CVoCJjEe.js → src-DDNXsD9H.js} +29 -5
  147. package/dist/{src-CVoCJjEe.js.map → src-DDNXsD9H.js.map} +1 -1
  148. package/dist/{src-DSE0FWaU.js → src-DVy58-zZ.js} +2 -2
  149. package/dist/{src-DSE0FWaU.js.map → src-DVy58-zZ.js.map} +1 -1
  150. package/dist/{src-BHFNhTTQ.js → src-D_cXqmnI.js} +59 -49
  151. package/dist/{src-BHFNhTTQ.js.map → src-D_cXqmnI.js.map} +1 -1
  152. package/dist/src-DdRlaiRc.js +3 -0
  153. package/dist/{src-zOeHvrzR.js → src-TdJuDYqB.js} +13 -13
  154. package/dist/{src-zOeHvrzR.js.map → src-TdJuDYqB.js.map} +1 -1
  155. package/dist/src-xczuQbE6.js +3 -0
  156. package/dist/{state-DBKcUJ2u.js → state-B72h_jEw.js} +14 -14
  157. package/dist/{state-DBKcUJ2u.js.map → state-B72h_jEw.js.map} +1 -1
  158. package/dist/state-Bf_Vq_pV.js +2 -0
  159. package/dist/studio-app/assets/{index-WQPq5K3E.js → index-Bgr-efZm.js} +9 -9
  160. package/dist/studio-app/index.html +1 -1
  161. package/dist/{summary-BBABbon9.js → summary-CJdxaRdM.js} +7 -7
  162. package/dist/{summary-BBABbon9.js.map → summary-CJdxaRdM.js.map} +1 -1
  163. package/dist/{summary-CahgSiVt.js → summary-k3mhWWXv.js} +8 -4
  164. package/dist/summary-k3mhWWXv.js.map +1 -0
  165. package/dist/testing.d.ts +14 -0
  166. package/dist/testing.js +2 -0
  167. package/dist/tool-target-BU1JnSE9.js +34 -0
  168. package/dist/tool-target-BU1JnSE9.js.map +1 -0
  169. package/dist/{tools-53YHomyk.js → tools-D0gF2QoV.js} +3 -3
  170. package/dist/{tools-53YHomyk.js.map → tools-D0gF2QoV.js.map} +1 -1
  171. package/dist/{types-CoAfC-_k.d.ts → types-_LOFdPUf.d.ts} +266 -36
  172. package/dist/{usage-DsYUqIUM.js → usage-DDF_6tkV.js} +4 -2
  173. package/dist/{usage-DsYUqIUM.js.map → usage-DDF_6tkV.js.map} +1 -1
  174. package/dist/view/index.d.ts +19 -6
  175. package/dist/view/index.js +6 -6
  176. package/dist/{views-Drl2OXuj.js → views-DZ1YDqey.js} +4 -4
  177. package/dist/{views-Drl2OXuj.js.map → views-DZ1YDqey.js.map} +1 -1
  178. package/dist/views-Ds0GXWtX.js +3 -0
  179. package/dist/{worker-entry-mCctDzig.js → worker-entry-DXeyWY-m.js} +73 -2
  180. package/dist/worker-entry-DXeyWY-m.js.map +1 -0
  181. package/dist/{workspace-BT4jd04k.js → workspace-DpXdrslo.js} +3 -3
  182. package/dist/{workspace-BT4jd04k.js.map → workspace-DpXdrslo.js.map} +1 -1
  183. package/dist/{workspace-U6M1gKzo.js → workspace-DzNL-3iO.js} +1 -1
  184. package/package.json +14 -8
  185. package/dist/assemble-DYCDgbTq.js.map +0 -1
  186. package/dist/assemble-DykFydSU.js +0 -2
  187. package/dist/capture-CisAmy-G.js +0 -587
  188. package/dist/capture-CisAmy-G.js.map +0 -1
  189. package/dist/capture-DquyqAHC.js +0 -2
  190. package/dist/cli-BIhzl_v_.js.map +0 -1
  191. package/dist/cli-spec-DUeyuSIQ.js.map +0 -1
  192. package/dist/command-CwuwuKJD.js +0 -2
  193. package/dist/command-DuJBqcwu.js.map +0 -1
  194. package/dist/db-BVE1kZ2w.js +0 -2
  195. package/dist/db-DvkzBhM6.js.map +0 -1
  196. package/dist/egress-De64jpeQ.js.map +0 -1
  197. package/dist/files-Cs8tbYQY.js +0 -2
  198. package/dist/files-wUtoO5aA.js +0 -2
  199. package/dist/harness-3QUEWx8G.js.map +0 -1
  200. package/dist/init-DDEpamaf.js +0 -2
  201. package/dist/matchers-Bp-OH1vj.js.map +0 -1
  202. package/dist/model-Bv8uUZ07.js.map +0 -1
  203. package/dist/model-C_B5JrhL.js +0 -2
  204. package/dist/model-Cp6NoAT3.js.map +0 -1
  205. package/dist/model-CtrJdFi6.js.map +0 -1
  206. package/dist/options-CWYB613o.js.map +0 -1
  207. package/dist/plan-CsPE24pp.js.map +0 -1
  208. package/dist/query-BWc_5Lhe.js +0 -2
  209. package/dist/questions-ZdT3JDyQ.js.map +0 -1
  210. package/dist/record-CbuQH4l1.js.map +0 -1
  211. package/dist/results-CrFs7_In.js +0 -37
  212. package/dist/results-CrFs7_In.js.map +0 -1
  213. package/dist/server-HRUHVcHc.js +0 -2
  214. package/dist/source-Co7h89WK.js +0 -2
  215. package/dist/src-BE19tji4.js +0 -3
  216. package/dist/src-Bo8GFUXg.js +0 -3
  217. package/dist/src-BoziVhKa.js +0 -3
  218. package/dist/src-CFxHPwQA.js +0 -3
  219. package/dist/src-CPkDaNxp.js +0 -3
  220. package/dist/src-D-go5-qz.js +0 -4
  221. package/dist/state-BaHjYXr1.js +0 -2
  222. package/dist/stats-BNAHlNMD.js +0 -114
  223. package/dist/stats-BNAHlNMD.js.map +0 -1
  224. package/dist/summary-CahgSiVt.js.map +0 -1
  225. package/dist/views-BhGinAz_.js +0 -3
  226. package/dist/worker-entry-mCctDzig.js.map +0 -1
@@ -1,10 +1,14 @@
1
1
  //#region src/view/effort.d.ts
2
2
  /** Below this two-sided p, an effort difference is an effect. */
3
3
  declare const EFFORT_ALPHA = 0.05;
4
+ /** Some counted attempts reported no usage. Not a verdict; never printed as one. */
5
+ declare const TOKENS_UNREPORTED = "some cells did not report usage";
4
6
  type EffortSample = {
5
7
  tools: number;
6
8
  agentMs: number;
7
9
  fileEdits: number;
10
+ /** Total tokens when this attempt reported usage; omitted when the harness dropped it. */
11
+ tokens?: number;
8
12
  };
9
13
  type Spread = {
10
14
  median: number;
@@ -17,10 +21,13 @@ type CellEffort = {
17
21
  tools: Spread;
18
22
  agentMs: Spread;
19
23
  fileEdits: number;
24
+ /** Over the counted attempts that reported usage; omitted when none did. */
25
+ tokens?: Spread;
20
26
  };
21
27
  /**
22
28
  * `fewer` / `more`: the exact rank test's p is below `EFFORT_ALPHA`. `noise`: it isn't.
23
- * `insufficient`: too few attempts for the test to ever reach it (2 against 2 can't).
29
+ * `insufficient`: too few attempts for the test to ever reach it (2 against 2 can't). Never
30
+ * means a harness dropped usage.
24
31
  */
25
32
  type EffortVerdict = 'fewer' | 'more' | 'noise' | 'insufficient';
26
33
  type EffortContrast = {
@@ -37,8 +44,23 @@ type EffortContrast = {
37
44
  /** On tool calls, the steadier measure; `timeVerdict` on agent time. */
38
45
  verdict: EffortVerdict;
39
46
  timeVerdict: EffortVerdict;
47
+ /**
48
+ * Token medians' ratio when both sides have at least one usage sample; null when the
49
+ * control's is 0 or the token test was omitted.
50
+ */
51
+ tokensRatio: number | null;
52
+ tokensP: number | null;
53
+ /**
54
+ * Rank-test verdict on the attempts that reported usage. Null when either side has no
55
+ * token sample — omitted, not `insufficient`.
56
+ */
57
+ tokensVerdict: EffortVerdict | null;
58
+ /** Set when some counted attempts on either side reported no usage. Not a verdict. */
59
+ tokensNote?: typeof TOKENS_UNREPORTED;
40
60
  };
41
- declare const effortSample: (a: Pick<AttemptRecord, 'activity' | 'timings'>) => EffortSample;
61
+ declare const effortSample: (a: Pick<AttemptRecord, 'activity' | 'timings' | 'usage'>) => EffortSample;
62
+ /** Token totals from the attempts that reported usage; empty when none did. */
63
+ declare const tokenValues: (samples: EffortSample[]) => number[];
42
64
  declare function effortOf(samples: EffortSample[]): CellEffort | null;
43
65
  /** The verdict of an exact rank test of `xs` (variant) against `ys` (control). */
44
66
  declare function effortVerdict(xs: number[], ys: number[]): {
@@ -59,13 +81,14 @@ declare function formatSeconds(ms: number): string;
59
81
  declare const VERDICT_TEXT: Record<EffortVerdict, (what: string) => string>;
60
82
  /**
61
83
  * `tools 5 vs 43 (×0.11), agent 21s vs 46s (×0.47): too few attempts to test` for a variant
62
- * against its control; with enough attempts, `fewer tool calls (p = 0.029)`.
84
+ * against its control; with enough attempts, `fewer tool calls (p = 0.029)`. Tokens fold in
85
+ * when both sides have usage samples; they are omitted (not `insufficient`) when either does not.
63
86
  */
64
87
  declare function effortLabel(c: EffortContrast): string;
65
- /** One cell's effort on its own: `tools 43 · agent 46s`. */
66
- declare const effortSummary: (e: Pick<CellEffort, 'tools' | 'agentMs'>) => string;
88
+ /** One cell's effort on its own: `tools 43 · agent 46s`, plus tokens when any attempt reported them. */
89
+ declare const effortSummary: (e: Pick<CellEffort, 'tools' | 'agentMs' | 'tokens'>) => string;
67
90
  /** The same cell between two runs: `tools 44 → 10 (×0.23) · agent 45s → 21s (×0.47)`. */
68
- declare function effortChangeLabel(base: Pick<CellEffort, 'tools' | 'agentMs'>, head: Pick<CellEffort, 'tools' | 'agentMs'>): string;
91
+ declare function effortChangeLabel(base: Pick<CellEffort, 'tools' | 'agentMs' | 'tokens'>, head: Pick<CellEffort, 'tools' | 'agentMs' | 'tokens'>): string;
69
92
  //#endregion
70
93
  //#region src/history/types.d.ts
71
94
  /** Stays 1 while reeval is pre-release: the record changes in place. */
@@ -86,10 +109,19 @@ type ArtifactRef = FileRef & {
86
109
  capture?: {
87
110
  port: number;
88
111
  path: string;
112
+ /** The live window, never the string `'full-page'`. */
89
113
  viewport?: {
90
114
  width: number;
91
115
  height: number;
92
116
  };
117
+ /** Saved PNG used `captureBeyondViewport`. */
118
+ fullPage?: boolean;
119
+ /** Goal strings only; wait beats omitted. */
120
+ instructions?: string[];
121
+ use?: {
122
+ model: string;
123
+ moves: number;
124
+ };
93
125
  };
94
126
  };
95
127
  type GitInfo = {
@@ -149,6 +181,8 @@ type JudgementRecord = {
149
181
  key: string;
150
182
  /** Transient provider errors retried before this verdict, with the backoff before each retry. */
151
183
  retries?: JudgeRetry[];
184
+ /** Captures this call sent the judge as file parts, when any. */
185
+ artifacts?: JudgeArtifactRef[];
152
186
  };
153
187
  type AttemptFiles = {
154
188
  /** Each environment setup step's command, exit code, duration and output. */
@@ -197,6 +231,17 @@ type AttemptRecord = {
197
231
  * recorded them.
198
232
  */
199
233
  servedModels: string[] | null;
234
+ /**
235
+ * The reasoning effort the harness factory asked for (`claudeCode({ effort: 'high' })`);
236
+ * null when the factory left it unset. Fast is not this.
237
+ */
238
+ effort: string | null;
239
+ /**
240
+ * The reasoning effort the harness's API said it ran at, from `servedModels` /
241
+ * each turn's `model` (`medium` from `gpt-5.6-luna[effort=medium]`); null when those
242
+ * labels name none. Fast (`[fast=true]`) is not this.
243
+ */
244
+ servedEffort: string | null;
200
245
  outcome: Outcome;
201
246
  error: AttemptError | null;
202
247
  durationMs: number;
@@ -218,6 +263,15 @@ type AttemptRecord = {
218
263
  }>;
219
264
  /** Tokens across the attempt's turns; null when the harness reported none. */
220
265
  usage: TokenUsage | null;
266
+ /**
267
+ * Tokens the capture vision loop used. Infrastructure only: never folded
268
+ * into `usage`, effort, compare or lift.
269
+ */
270
+ captureUse?: {
271
+ model: string;
272
+ moves: number;
273
+ usage: TokenUsage | null;
274
+ };
221
275
  timings: PhaseTimings;
222
276
  /** Counts from the transcript, so a run's shape is visible without reading it. */
223
277
  activity: {
@@ -277,7 +331,9 @@ type EvalEntry = {
277
331
  attempts: AttemptRecord[];
278
332
  /**
279
333
  * The compare's questions, answered after its attempts by pairwise votes, one per question;
280
- * unset without any. They annotate: `outcome` and `passRate` never depend on them.
334
+ * unset without any. They annotate: `outcome` and `passRate` never depend on them. Each vote
335
+ * may include a short `reason` (capped). `reeval analyze` includes each answer in the digest
336
+ * (rates by cut, votes, ties, a failed call, a sample of reasons).
281
337
  */
282
338
  answers?: CompareAnswer[];
283
339
  };
@@ -332,6 +388,11 @@ type CellRecord = Cell & {
332
388
  harnessKind: string;
333
389
  /** The configured harness model, when it has one. */
334
390
  model: string | null;
391
+ /**
392
+ * The reasoning effort the harness factory asked for; null when it left it unset.
393
+ * Fast is not this.
394
+ */
395
+ effort: string | null;
335
396
  /** How the attempts decide the cell's outcome; `'none'` when it doesn't fail the eval. */
336
397
  gate: CellGate;
337
398
  /** Environment keys the variant replaced on the control's (or a child on its parent's). */
@@ -478,21 +539,31 @@ type Stack = {
478
539
  /** Exact versions of the packages that run and grade the agent. */
479
540
  packages: Record<string, string>;
480
541
  /**
481
- * Each harness: its configured `model`, and `resolvedModels`, what it reported serving across
482
- * the run's turns with the variant it resolved (`composer-2.5[fast=true]` for `composer-2.5`
483
- * without `params`); empty when it reports none.
542
+ * Each harness: its configured `model` and requested `effort`, `resolvedModels` (what it
543
+ * reported serving, with the variant it resolved), and `resolvedEffort` (reasoning-effort
544
+ * suffixes those labels named). Fast (`[fast=true]`) is not `resolvedEffort`.
484
545
  */
485
546
  harnesses: Array<{
486
547
  id: string;
487
548
  kind: string;
488
549
  /** The configured model, when the harness has one. */
489
550
  model: string | null;
551
+ /**
552
+ * The reasoning effort the harness factory asked for; null when it left it unset.
553
+ * Fast is not this.
554
+ */
555
+ effort: string | null;
490
556
  /**
491
557
  * The models the harness reported serving, across every turn in the run, with the variant it
492
558
  * resolved (`composer-2.5[fast=true]` for `composer-2.5` with no `params`); empty when it
493
559
  * reports none.
494
560
  */
495
561
  resolvedModels: string[];
562
+ /**
563
+ * Reasoning-effort suffixes those served models named (`medium` from
564
+ * `gpt-5.6-luna[effort=medium]`); empty when they name none. Fast is not this.
565
+ */
566
+ resolvedEffort: string[];
496
567
  }>;
497
568
  /**
498
569
  * The run's judge: the config's, with what the profile's `judge` and `defaults.judge` set over it.
@@ -535,7 +606,7 @@ type HistoryCell = Pick<CellRecord, 'key' | 'role' | 'variant' | 'harness' | 'mo
535
606
  hi: number;
536
607
  withinNoise: boolean;
537
608
  };
538
- /** Median tool calls and agent time over the counted attempts; null when none counted. */
609
+ /** Median tool calls, agent time and tokens over the counted attempts; null when none counted. */
539
610
  effort: CellEffort | null;
540
611
  };
541
612
  /**
@@ -640,14 +711,67 @@ type ExecResult = {
640
711
  stdout: string;
641
712
  stderr: string;
642
713
  };
643
- /** CSS pixels for `c.capture()`. Default 1280×720 when the call and cascade omit it. */
644
- type Viewport = {
714
+ /** Live tab size for `c.capture()`. Default 1280×720 when the call and cascade omit `viewport`. */
715
+ type CaptureWindow = {
645
716
  width: number;
646
717
  height: number;
647
718
  };
719
+ /**
720
+ * Author camera. `{ width, height }` is the live window and the saved PNG.
721
+ * `'full-page'` keeps the default window and saves with `captureBeyondViewport`.
722
+ */
723
+ type Viewport = CaptureWindow | 'full-page';
724
+ /**
725
+ * Chromium look-ready events. `'load'` is `window` load (`Page.loadEventFired`).
726
+ * `'idle'` is `Page.lifecycleEvent` `networkAlmostIdle`.
727
+ */
728
+ type CaptureWait = 'load' | 'idle';
729
+ /** Same shape at top-level `wait` and `{ wait }` between instructions. */
730
+ type Wait = CaptureWait | {
731
+ ms: number;
732
+ };
733
+ type CaptureInstruction = string | {
734
+ wait: Wait;
735
+ };
736
+ type CaptureUseAction = {
737
+ type: 'click';
738
+ x: number;
739
+ y: number;
740
+ } | {
741
+ type: 'type';
742
+ text: string;
743
+ } | {
744
+ type: 'key';
745
+ key: 'Tab' | 'Enter';
746
+ } | {
747
+ type: 'scroll';
748
+ x: number;
749
+ y: number;
750
+ dy: number;
751
+ } | {
752
+ type: 'drag';
753
+ x: number;
754
+ y: number;
755
+ toX: number;
756
+ toY: number;
757
+ } | {
758
+ type: 'hover';
759
+ x: number;
760
+ y: number;
761
+ } | {
762
+ type: 'done';
763
+ };
764
+ /** One list per instruction string. Tests; never downloads a model. */
765
+ type CaptureUseScript = CaptureUseAction[][];
766
+ /** Resolved vision driver after cascade, call override and analysis fallback. */
767
+ type CaptureUse = {
768
+ model: string;
769
+ } | {
770
+ fake: CaptureUseScript;
771
+ };
648
772
  /**
649
773
  * Camera defaults for `c.capture()`. Cascades config → profile defaults → group → eval,
650
- * shallow-merged. `viewport` on a level replaces the whole object. `port` is not an option:
774
+ * shallow-merged. `viewport` on a level replaces the whole value. `port` is not an option:
651
775
  * pass it as the first argument to `c.capture`.
652
776
  */
653
777
  type CaptureOptions = {
@@ -656,6 +780,11 @@ type CaptureOptions = {
656
780
  timeout?: Duration;
657
781
  /** `false` refuses the host `chrome-headless-shell` binary. `c.capture()` then throws. */
658
782
  browser?: boolean;
783
+ /**
784
+ * Vision model for `instructions`. Cascades like `question`. Default is the analysis
785
+ * model when that model accepts images; never Jev.
786
+ */
787
+ model?: string;
659
788
  };
660
789
  /** A background process started by `c.exec(..., { background: true })` or `c.serve`. */
661
790
  type BackgroundHandle = {
@@ -672,6 +801,7 @@ type Capture = {
672
801
  port: number;
673
802
  /** Path on the app, as passed in. */
674
803
  path: string;
804
+ /** What the author asked, including `'full-page'`. */
675
805
  viewport: Viewport;
676
806
  /** `artifacts/<name>.png` under the attempt directory. */
677
807
  file: {
@@ -683,13 +813,19 @@ type Capture = {
683
813
  /**
684
814
  * Optional camera and path for `c.capture(port | ServeHandle, options?)`.
685
815
  * `port` is the first argument, not a field here. Default `path` is `/`;
686
- * default `name` is derived from the path.
816
+ * default `name` is derived from the path. `wait` and `instructions` are call-only.
687
817
  */
688
818
  type CaptureCall = {
689
819
  name?: string;
690
820
  path?: string;
691
821
  viewport?: Viewport;
692
822
  timeout?: Duration;
823
+ /** Look-ready once, before the first model shot or the saved PNG. Default `'load'`. */
824
+ wait?: Wait;
825
+ /** Journey: goal strings and `{ wait }` beats. Tests may pass `fakeInstructions(...)`. */
826
+ instructions?: CaptureInstruction[];
827
+ /** Overrides cascaded `capture.model` for this call. */
828
+ model?: string;
693
829
  };
694
830
  type FileChange = {
695
831
  path: string;
@@ -730,9 +866,10 @@ type TurnData = {
730
866
  model: string | null;
731
867
  /**
732
868
  * Event types the harness couldn't report for this turn: the agent may have searched or
733
- * fetched with no event in `transcript`. `toHaveSearched()` and `toHaveFetched()` refuse such a
734
- * turn. Usually `[]`; a Cursor turn whose web calls the adapter couldn't recover (its SDK drops
735
- * them from the stream) is `['web-search', 'web-fetch']`.
869
+ * fetched with no event in `transcript`. `toHaveSearched()` and `toHaveFetched()` refuse
870
+ * such a turn. Usually `[]`; a Cursor turn
871
+ * whose web calls the adapter couldn't recover (its SDK drops them from the stream) is
872
+ * `['web-search', 'web-fetch']`.
736
873
  */
737
874
  unreported: WebEventType[];
738
875
  /** Workspace changes since the eval started, as of the end of this turn. */
@@ -746,19 +883,44 @@ type Turn = TurnData & {
746
883
  type JSONValue = null | boolean | number | string | JSONValue[] | {
747
884
  [key: string]: JSONValue;
748
885
  };
886
+ /** JSON fields the judge sees for the turn: task, output, files, diff, optional contents. */
887
+ type JudgeJsonState = {
888
+ [key: string]: JSONValue;
889
+ };
890
+ /** A capture sent to `experimental_decide` as a file part. */
891
+ type JudgeFilePart = {
892
+ type: 'file';
893
+ mediaType: string;
894
+ data: Uint8Array;
895
+ };
896
+ /**
897
+ * What `experimental_decide` (and a fake judge) receive: a JSON object when the call has no
898
+ * captures, or an ordered list of one JSON part plus each capture's file part.
899
+ */
900
+ type JudgeState = JudgeJsonState | Array<{
901
+ type: 'json';
902
+ value: JudgeJsonState;
903
+ } | JudgeFilePart>;
904
+ /** A capture this judge call sent as a file part. Bytes live in `artifacts/<name>.png`. */
905
+ type JudgeArtifactRef = {
906
+ name: string;
907
+ /** `artifacts/<name>.png` under the attempt directory. */
908
+ path: string;
909
+ sha256: string;
910
+ bytes: number;
911
+ mediaType: 'image/png';
912
+ };
749
913
  /**
750
914
  * A canned judge for tests and dry runs; see `fakeJudge()` in `reeval/judge`. `score` as a
751
915
  * function of the state the judge would see works per group, eval or call, not in the config.
752
916
  */
753
917
  type FakeJudgeModel = {
754
918
  kind: 'fake-judge';
755
- score: number | ((state: {
756
- [key: string]: JSONValue;
757
- }) => number);
919
+ score: number | ((state: JudgeState) => number);
758
920
  };
759
921
  /**
760
922
  * `'provider/model'` (e.g. `'typesafe-ai/jev-1.13.0'`, `'google/gemini-3.8-flash'`), an AI SDK
761
- * evaluation model object (per group, eval or call only), or a fake judge.
923
+ * decision model object (per group, eval or call only), or a fake judge.
762
924
  */
763
925
  type JudgeModel = string | FakeJudgeModel | {
764
926
  readonly specificationVersion: string;
@@ -782,6 +944,11 @@ type JudgeOptions = {
782
944
  type JudgeCallOptions = JudgeOptions & {
783
945
  /** What to grade instead of the latest turn: another turn, or a value used as the output. */
784
946
  on?: Turn | JSONValue;
947
+ /**
948
+ * Captures this call sends the judge as file parts. A `c.capture()` handle or its name.
949
+ * Call-only: the bytes are on this attempt. The provider that cannot take files fails the call.
950
+ */
951
+ artifacts?: Array<Capture | string>;
785
952
  };
786
953
  type Verdict = {
787
954
  verdict: 'pass' | 'fail';
@@ -792,6 +959,8 @@ type Verdict = {
792
959
  model: string;
793
960
  /** The model id the provider says served the call, when it reports one. */
794
961
  resolvedModel?: string;
962
+ /** Captures this call sent the judge as file parts, when any. */
963
+ artifacts?: JudgeArtifactRef[];
795
964
  };
796
965
  /**
797
966
  * What `c.judge()` returns when the call failed (the provider's error, after any retries): the attempt fails as a judge error once the eval's body has finished,
@@ -805,7 +974,10 @@ type JudgeFailure = Omit<Verdict, 'verdict' | 'score' | 'resolvedModel'> & {
805
974
  type AttemptContext = {
806
975
  /** Sends the next turn of this eval's agent session, starting the sandbox on first use. */
807
976
  send(prompt: string): Promise<Turn>;
808
- /** Asks the judge a yes/no question about the latest turn (or `options.on`). */
977
+ /**
978
+ * Asks the judge a yes/no question about the latest turn (or `options.on`).
979
+ * `options.artifacts` is a list of `c.capture()` handles or names.
980
+ */
809
981
  judge(question: string, options?: JudgeCallOptions): Promise<Verdict | JudgeFailure>;
810
982
  exec(command: string): Promise<ExecResult>;
811
983
  exec(command: string, options: {
@@ -822,6 +994,7 @@ type AttemptContext = {
822
994
  /**
823
995
  * Screenshots a path on a tunneled sandbox port and writes `artifacts/<name>.png`.
824
996
  * First argument is the container port or a `ServeHandle` from `c.serve`.
997
+ * `instructions` runs a vision journey on that same tab first.
825
998
  * Needs a sandbox, same as `c.exec`.
826
999
  */
827
1000
  capture(target: number | ServeHandle, options?: CaptureCall): Promise<Capture>;
@@ -866,6 +1039,11 @@ type FakeHarnessDescriptor = {
866
1039
  * and variant (`composer-2.5[fast=true]`); unset, it reports none.
867
1040
  */
868
1041
  servedModel?: string;
1042
+ /**
1043
+ * Requested reasoning effort, recorded as `effort` on the cell. Use `servedModel` for what the
1044
+ * turn reports (`fake-1[effort=medium]`). Fast is not this.
1045
+ */
1046
+ effort?: string;
869
1047
  /** Tool calls the fake agent reports on every turn, before writing files. */
870
1048
  tools?: Array<{
871
1049
  tool: string;
@@ -932,7 +1110,12 @@ type CursorHarnessDescriptor = {
932
1110
  * model catalog (`fast=true` for `composer-2.5`), sent explicitly; pass the ones that change cost.
933
1111
  */
934
1112
  params?: Record<string, string>;
935
- /** Cell id; defaults to `cursor:<model>`. */
1113
+ /**
1114
+ * Reasoning effort, mapped onto the catalog param `Cursor.models.list()` names for this model
1115
+ * (`reasoning_effort`, `effort`, …). Not Fast: that stays `params.fast`.
1116
+ */
1117
+ effort?: string;
1118
+ /** Cell id; defaults to `cursor:<model>`, or `cursor:<model>[effort=<value>]` when `effort` is set. */
936
1119
  id?: string;
937
1120
  /** The most Cursor attempts at once, across the run, e.g. for the account's rate limits. */
938
1121
  maxConcurrent?: number;
@@ -947,7 +1130,12 @@ type ClaudeCodeHarnessDescriptor = {
947
1130
  kind: 'claude-code';
948
1131
  /** A model id or alias the `claude` CLI accepts, e.g. `claude-sonnet-5` or `sonnet`. */
949
1132
  model: string;
950
- /** Cell id; defaults to `claude-code:<model>`. */
1133
+ /**
1134
+ * Reasoning effort the Agent SDK `/effort` control takes, e.g. `low`, `medium`, `high`,
1135
+ * `xhigh` (Extra in the UI) or `max`.
1136
+ */
1137
+ effort?: string;
1138
+ /** Cell id; defaults to `claude-code:<model>`, or `claude-code:<model>[effort=<value>]` when `effort` is set. */
951
1139
  id?: string;
952
1140
  /** The most Claude Code attempts at once, across the run, e.g. for the account's rate limits. */
953
1141
  maxConcurrent?: number;
@@ -962,7 +1150,12 @@ type AntigravityHarnessDescriptor = {
962
1150
  kind: 'antigravity';
963
1151
  /** A model slug `agy models` lists for a Gemini API key, e.g. `gemini-3.8-flash-medium`. */
964
1152
  model: string;
965
- /** Cell id; defaults to `antigravity:<model>`. */
1153
+ /**
1154
+ * Reasoning effort passed as `agy --effort`, e.g. `low`, `medium`, `high` or `max`. The
1155
+ * slug's `-low`/`-medium`/`-high` suffix is the same knob baked into `model`.
1156
+ */
1157
+ effort?: string;
1158
+ /** Cell id; defaults to `antigravity:<model>`, or `antigravity:<model>[effort=<value>]` when `effort` is set. */
966
1159
  id?: string;
967
1160
  /** The most Antigravity attempts at once, across the run, e.g. for the key's rate limits. */
968
1161
  maxConcurrent?: number;
@@ -984,7 +1177,12 @@ type OpenCodeHarnessDescriptor = {
984
1177
  * `anthropic/claude-haiku-4-5`; the provider picks the key.
985
1178
  */
986
1179
  model: string;
987
- /** Cell id; defaults to `opencode:<model>`. */
1180
+ /**
1181
+ * Reasoning effort for that provider: `options.reasoningEffort` (OpenAI) or `options.thinking`
1182
+ * (Anthropic). Values are whatever that provider takes.
1183
+ */
1184
+ effort?: string;
1185
+ /** Cell id; defaults to `opencode:<model>`, or `opencode:<model>[effort=<value>]` when `effort` is set. */
988
1186
  id?: string;
989
1187
  /** The most OpenCode attempts at once, across the run, e.g. for the key's rate limits. */
990
1188
  maxConcurrent?: number;
@@ -1002,7 +1200,11 @@ type GooseHarnessDescriptor = {
1002
1200
  kind: 'goose';
1003
1201
  /** A Gemini model id, run on Goose's `google` provider, e.g. `gemini-3.8-flash`. */
1004
1202
  model: string;
1005
- /** Cell id; defaults to `goose:<model>`. */
1203
+ /**
1204
+ * Reasoning effort as `GOOSE_THINKING_EFFORT`, e.g. `off`, `low`, `medium`, `high` or `max`.
1205
+ */
1206
+ effort?: string;
1207
+ /** Cell id; defaults to `goose:<model>`, or `goose:<model>[effort=<value>]` when `effort` is set. */
1006
1208
  id?: string;
1007
1209
  /** The most Goose attempts at once, across the run, e.g. for the key's rate limits. */
1008
1210
  maxConcurrent?: number;
@@ -1021,7 +1223,12 @@ type PiHarnessDescriptor = {
1021
1223
  kind: 'pi';
1022
1224
  /** A Gemini model id, run on pi's `google` provider, e.g. `gemini-3.8-flash`. */
1023
1225
  model: string;
1024
- /** Cell id; defaults to `pi:<model>`. */
1226
+ /**
1227
+ * Reasoning effort, passed as pi's `--thinking` (the CLI's name). Values are whatever that
1228
+ * flag takes, e.g. `off`, `minimal`, `low`, `medium`, `high`, `xhigh` or `max`.
1229
+ */
1230
+ effort?: string;
1231
+ /** Cell id; defaults to `pi:<model>`, or `pi:<model>[effort=<value>]` when `effort` is set. */
1025
1232
  id?: string;
1026
1233
  /** The most pi attempts at once, across the run, e.g. for the key's rate limits. */
1027
1234
  maxConcurrent?: number;
@@ -1039,7 +1246,12 @@ type CodexHarnessDescriptor = {
1039
1246
  kind: 'codex';
1040
1247
  /** An OpenAI model id Codex runs on the Responses API, e.g. `gpt-5.6-luna`. */
1041
1248
  model: string;
1042
- /** Cell id; defaults to `codex:<model>`. */
1249
+ /**
1250
+ * Reasoning effort as Codex's `model_reasoning_effort`, e.g. `low`, `medium`, `high`,
1251
+ * `xhigh`, `max` or `ultra`.
1252
+ */
1253
+ effort?: string;
1254
+ /** Cell id; defaults to `codex:<model>`, or `codex:<model>[effort=<value>]` when `effort` is set. */
1043
1255
  id?: string;
1044
1256
  /** The most Codex attempts at once, across the run, e.g. for the key's rate limits. */
1045
1257
  maxConcurrent?: number;
@@ -1396,16 +1608,27 @@ type CompareOptions<E = Environment> = {
1396
1608
  * win rates and never change pass, fail or the exit code.
1397
1609
  */
1398
1610
  questions?: CompareQuestion[];
1611
+ /**
1612
+ * The factor every question varies when pairing, when a question does not name its own
1613
+ * `across`. `'environment'` holds the harness; `'harness'` holds the environment. A list of
1614
+ * both, or omitted, asks both pair kinds.
1615
+ */
1616
+ across?: PairFactor | PairFactor[];
1399
1617
  };
1400
1618
  /**
1401
1619
  * A question for pairwise judgement: its text, or the text and the `'provider/model'` that
1402
1620
  * answers it. Without a model, `analysis.model` answers, else the judge's when it's a language model.
1621
+ * `across` is the factor it varies when pairing; without it (and without a one-factor
1622
+ * `compare.across`) both pair kinds run.
1403
1623
  */
1404
1624
  type CompareQuestion = string | {
1405
1625
  question: string;
1406
1626
  model?: string;
1627
+ across?: PairFactor;
1407
1628
  };
1408
- /** Which pairs a vote is over: two arms on one harness, or two harnesses on one arm. */
1629
+ /** A matrix factor a compare question varies when pairing; the others are held. */
1630
+ type PairFactor = 'environment' | 'harness';
1631
+ /** Which pairs a vote is over: two environments on one harness, or two harnesses on one environment. */
1409
1632
  type CompareCut = 'within' | 'across';
1410
1633
  /** One judgement of one pair of attempts, in one order. */
1411
1634
  type PairVote = {
@@ -1424,6 +1647,8 @@ type PairVote = {
1424
1647
  winner: string | 'tie';
1425
1648
  /** True for the repeat that showed `b` first. */
1426
1649
  swapped: boolean;
1650
+ /** The model's short reason for this pick; omitted when it gave none. Capped. */
1651
+ reason?: string;
1427
1652
  };
1428
1653
  /** A compare question's answer: every vote, and each side's wins over decided votes per cut. */
1429
1654
  type CompareAnswer = {
@@ -1476,7 +1701,7 @@ type EvalOptionFields = {
1476
1701
  */
1477
1702
  egress?: EgressPolicy;
1478
1703
  judge?: JudgeOptions;
1479
- /** Screenshot defaults for `c.capture()`. Shallow-merged; `viewport` replaces the whole object. */
1704
+ /** Screenshot defaults for `c.capture()`. Shallow-merged; `viewport` and `model` replace the value. */
1480
1705
  capture?: CaptureOptions;
1481
1706
  /** Per attempt. */
1482
1707
  timeout?: Duration;
@@ -1585,14 +1810,19 @@ type FakeAnalysisModel = {
1585
1810
  };
1586
1811
  /**
1587
1812
  * How it answers compare questions: a fixed pick, a function of the blinded pair, or
1588
- * `{ error }` to fail every call. Default `'tie'`.
1813
+ * `{ error }` to fail every call. A pick may be `{ winner, reason? }`. Default `'tie'`.
1589
1814
  */
1590
- vote?: FakeVote | ((pair: BlindPair) => FakeVote) | {
1815
+ vote?: FakePick | ((pair: BlindPair) => FakePick) | {
1591
1816
  error: string;
1592
1817
  };
1593
1818
  };
1594
1819
  /** A blinded label's pick: the attempt shown first (`A`), second (`B`), or neither. */
1595
1820
  type FakeVote = 'A' | 'B' | 'tie';
1821
+ /** A fake compare-question pick, optionally with a reason. */
1822
+ type FakePick = FakeVote | {
1823
+ winner: FakeVote;
1824
+ reason?: string;
1825
+ };
1596
1826
  /** What a compare question's model is shown: the prompt, and the two diffs in slot order. */
1597
1827
  type BlindPair = {
1598
1828
  question: string;
@@ -1857,5 +2087,5 @@ type SandboxWarning = {
1857
2087
  message: string;
1858
2088
  };
1859
2089
  //#endregion
1860
- export { JudgeFailure as $, effortVerdict as $t, EnvironmentHelpers as A, FileRef as At, FakeNoteInput as B, EffortSample as Bt, DirectoryOptions as C, Verdict as Ct, EgressRecord as D, AttemptRecord as Dt, EgressPolicy as E, ArtifactRef as Et, EvalOptions as F, RunRecord as Ft, GroupOptions as G, cellEffort as Gt, FakeScriptStep as H, Spread as Ht, ExecResult as I, StackSummary as It, HarnessEdit as J, effortChangeLabel as Jt, HarnessData as K, cellSamples as Kt, FakeAnalysisModel as L, CellEffort as Lt, EnvironmentSpec as M, HistoryEntry as Mt, EsConfig as N, JudgementRecord as Nt, EnvVars as O, CellRecord as Ot, EvalFn as P, Lift as Pt, JudgeCallOptions as Q, effortSummary as Qt, FakeHarnessDescriptor as R, EFFORT_ALPHA as Rt, Diff as S, TurnStatus as St, Duration as T, WebEventType as Tt, FakeVote as U, VERDICT_TEXT as Ut, FakeSandboxDescriptor as V, EffortVerdict as Vt, GooseHarnessDescriptor as W, cellContrast as Wt, HistoryConfig as X, effortOf as Xt, HarnessOption as Y, effortLabel as Yt, HostFile as Z, effortSample as Zt, CompareOptions as _, SkillSource as _t, BackgroundHandle as a, PairVote as at, ConfigJudgeOptions as b, Turn as bt, Capture as c, Profile as ct, Cell as d, SandboxDescriptor as dt, formatCount as en, JudgeModel as et, CellRole as f, SandboxWarning as ft, CompareCut as g, SetupStep as gt, CompareAnswer as h, ServeHandle as ht, AttemptContext as i, Outcome as it, EnvironmentInput as j, HistoryCell as jt, Environment as k, EvalEntry as kt, CaptureCall as l, ProfileDefaults as lt, CodexHarnessDescriptor as m, SecretTemplate as mt, AnalysisConfig as n, formatSeconds as nn, McpServer as nt, BlindPair as o, PiHarnessDescriptor as ot, ClaudeCodeHarnessDescriptor as p, Secret as pt, HarnessDescriptor as q, contrastEffort as qt, AntigravityHarnessDescriptor as r, OpenCodeHarnessDescriptor as rt, Budget as s, PinnableKey as st, AgentHarnessDescriptor as t, formatRatio as tn, JudgeOptions as tt, CaptureOptions as u, ProfileLimit as ut, CompareQuestion as v, TokenUsage as vt, DockerSandboxDescriptor as w, Viewport as wt, CursorHarnessDescriptor as x, TurnData as xt, ConfigHelpers as y, TranscriptEvent as yt, FakeJudgeModel as z, EffortContrast as zt };
1861
- //# sourceMappingURL=types-CoAfC-_k.d.ts.map
2090
+ export { HarnessDescriptor as $, TOKENS_UNREPORTED as $t, DockerSandboxDescriptor as A, TurnData as At, EvalFn as B, FileRef as Bt, CompareOptions as C, SecretTemplate as Ct, CursorHarnessDescriptor as D, TokenUsage as Dt, ConfigJudgeOptions as E, SkillSource as Et, Environment as F, WebEventType as Ft, FakeJudgeModel as G, RunRecord as Gt, ExecResult as H, HistoryEntry as Ht, EnvironmentHelpers as I, ArtifactRef as It, FakeScriptStep as J, EFFORT_ALPHA as Jt, FakeNoteInput as K, StackSummary as Kt, EnvironmentInput as L, AttemptRecord as Lt, EgressPolicy as M, Verdict as Mt, EgressRecord as N, Viewport as Nt, Diff as O, TranscriptEvent as Ot, EnvVars as P, Wait as Pt, HarnessData as Q, Spread as Qt, EnvironmentSpec as R, CellRecord as Rt, CompareCut as S, Secret as St, ConfigHelpers as T, SetupStep as Tt, FakeAnalysisModel as U, JudgementRecord as Ut, EvalOptions as V, HistoryCell as Vt, FakeHarnessDescriptor as W, Lift as Wt, GooseHarnessDescriptor as X, EffortSample as Xt, FakeVote as Y, EffortContrast as Yt, GroupOptions as Z, EffortVerdict as Zt, Cell as _, Profile as _t, BackgroundHandle as a, effortChangeLabel as an, JudgeCallOptions as at, CodexHarnessDescriptor as b, SandboxDescriptor as bt, Capture as c, effortSample as cn, JudgeOptions as ct, CaptureOptions as d, formatCount as dn, OpenCodeHarnessDescriptor as dt, VERDICT_TEXT as en, HarnessEdit as et, CaptureUse as f, formatRatio as fn, Outcome as ft, CaptureWindow as g, PinnableKey as gt, CaptureWait as h, PiHarnessDescriptor as ht, AttemptContext as i, contrastEffort as in, JudgeArtifactRef as it, Duration as j, TurnStatus as jt, DirectoryOptions as k, Turn as kt, CaptureCall as l, effortSummary as ln, JudgeState as lt, CaptureUseScript as m, tokenValues as mn, PairVote as mt, AnalysisConfig as n, cellEffort as nn, HistoryConfig as nt, BlindPair as o, effortLabel as on, JudgeFailure as ot, CaptureUseAction as p, formatSeconds as pn, PairFactor as pt, FakeSandboxDescriptor as q, CellEffort as qt, AntigravityHarnessDescriptor as r, cellSamples as rn, HostFile as rt, Budget as s, effortOf as sn, JudgeModel as st, AgentHarnessDescriptor as t, cellContrast as tn, HarnessOption as tt, CaptureInstruction as u, effortVerdict as un, McpServer as ut, CellRole as v, ProfileDefaults as vt, CompareQuestion as w, ServeHandle as wt, CompareAnswer as x, SandboxWarning as xt, ClaudeCodeHarnessDescriptor as y, ProfileLimit as yt, EsConfig as z, EvalEntry as zt };
2091
+ //# sourceMappingURL=types-_LOFdPUf.d.ts.map
@@ -18,7 +18,9 @@ const sumUsage = (usages) => {
18
18
  };
19
19
  /** Every token the prompt side used: uncached input plus cache reads and writes. */
20
20
  const promptTokens = (u) => u.input + u.cacheRead + u.cacheWrite;
21
+ /** Prompt side, output, and reasoning when the harness reported it. No USD. */
22
+ const totalTokens = (u) => promptTokens(u) + u.output + (u.reasoning ?? 0);
21
23
  //#endregion
22
- export { promptTokens as n, sumUsage as r, addUsage as t };
24
+ export { totalTokens as i, promptTokens as n, sumUsage as r, addUsage as t };
23
25
 
24
- //# sourceMappingURL=usage-DsYUqIUM.js.map
26
+ //# sourceMappingURL=usage-DDF_6tkV.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"usage-DsYUqIUM.js","names":[],"sources":["../src/usage.ts"],"mappings":";;AAGA,SAAgB,SAAS,GAAsB,GAAyC;CACtF,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,KAAK;CAC1B,OAAO;EACL,OAAO,EAAE,QAAQ,EAAE;EACnB,QAAQ,EAAE,SAAS,EAAE;EACrB,WAAW,EAAE,YAAY,EAAE;EAC3B,YAAY,EAAE,aAAa,EAAE;EAC7B,WACE,EAAE,cAAc,QAAQ,EAAE,cAAc,OAAO,QAAQ,EAAE,aAAa,MAAM,EAAE,aAAa;CAC/F;AACF;;AAGA,MAAa,YAAY,WAAuE;CAC9F,IAAI,QAA2B;CAC/B,KAAK,MAAM,KAAK,QAAQ,QAAQ,SAAS,OAAO,KAAK,IAAI;CACzD,OAAO;AACT;;AAGA,MAAa,gBAAgB,MAAkB,EAAE,QAAQ,EAAE,YAAY,EAAE"}
1
+ {"version":3,"file":"usage-DDF_6tkV.js","names":[],"sources":["../src/usage.ts"],"mappings":";;AAGA,SAAgB,SAAS,GAAsB,GAAyC;CACtF,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,KAAK;CAC1B,OAAO;EACL,OAAO,EAAE,QAAQ,EAAE;EACnB,QAAQ,EAAE,SAAS,EAAE;EACrB,WAAW,EAAE,YAAY,EAAE;EAC3B,YAAY,EAAE,aAAa,EAAE;EAC7B,WACE,EAAE,cAAc,QAAQ,EAAE,cAAc,OAAO,QAAQ,EAAE,aAAa,MAAM,EAAE,aAAa;CAC/F;AACF;;AAGA,MAAa,YAAY,WAAuE;CAC9F,IAAI,QAA2B;CAC/B,KAAK,MAAM,KAAK,QAAQ,QAAQ,SAAS,OAAO,KAAK,IAAI;CACzD,OAAO;AACT;;AAGA,MAAa,gBAAgB,MAAkB,EAAE,QAAQ,EAAE,YAAY,EAAE;;AAGzE,MAAa,eAAe,MAAkB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,aAAa"}