niceeval 0.13.1 → 0.13.2

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 (548) hide show
  1. package/INDEX.md +25 -2
  2. package/README.md +9 -10
  3. package/README.zh.md +9 -10
  4. package/dist/agents/ai-sdk.cjs.map +1 -1
  5. package/dist/agents/ai-sdk.d.cts +1 -1
  6. package/dist/agents/ai-sdk.d.mts +1 -1
  7. package/dist/agents/ai-sdk.d.ts +1 -1
  8. package/dist/agents/bub-install-spec.cjs +19 -5
  9. package/dist/agents/bub-install-spec.cjs.map +1 -1
  10. package/dist/agents/bub-install-spec.d.cts +9 -2
  11. package/dist/agents/bub-install-spec.d.mts +9 -2
  12. package/dist/agents/bub-install-spec.d.ts +9 -2
  13. package/dist/agents/bub-install-spec.js +14 -12
  14. package/dist/agents/bub.cjs +10 -6
  15. package/dist/agents/bub.cjs.map +1 -1
  16. package/dist/agents/bub.d.cts +2 -2
  17. package/dist/agents/bub.d.mts +2 -2
  18. package/dist/agents/bub.d.ts +2 -2
  19. package/dist/agents/claude-code.cjs.map +1 -1
  20. package/dist/agents/claude-code.d.cts +2 -2
  21. package/dist/agents/claude-code.d.mts +2 -2
  22. package/dist/agents/claude-code.d.ts +2 -2
  23. package/dist/agents/codex.cjs +4 -4
  24. package/dist/agents/codex.cjs.map +1 -1
  25. package/dist/agents/codex.d.cts +3 -3
  26. package/dist/agents/codex.d.mts +3 -3
  27. package/dist/agents/codex.d.ts +3 -3
  28. package/dist/agents/coding-cli-versions.cjs +10 -1
  29. package/dist/agents/coding-cli-versions.cjs.map +1 -1
  30. package/dist/agents/coding-cli-versions.d.cts +8 -3
  31. package/dist/agents/coding-cli-versions.d.mts +8 -3
  32. package/dist/agents/coding-cli-versions.d.ts +8 -3
  33. package/dist/agents/coding-cli-versions.js +18 -12
  34. package/dist/agents/deepseek-harness.cjs +151 -0
  35. package/dist/agents/deepseek-harness.cjs.map +1 -0
  36. package/dist/agents/deepseek-harness.d.cts +14 -0
  37. package/dist/agents/deepseek-harness.d.mts +14 -0
  38. package/dist/agents/deepseek-harness.d.ts +14 -0
  39. package/dist/agents/deepseek-harness.js +7 -0
  40. package/dist/agents/deepseek-harness.js.map +1 -0
  41. package/dist/agents/exact-npm-plugins.cjs +28 -0
  42. package/dist/agents/exact-npm-plugins.cjs.map +1 -0
  43. package/dist/agents/exact-npm-plugins.d.cts +10 -0
  44. package/dist/agents/exact-npm-plugins.d.mts +10 -0
  45. package/dist/agents/exact-npm-plugins.d.ts +10 -0
  46. package/dist/agents/exact-npm-plugins.js +8 -0
  47. package/dist/agents/exact-npm-plugins.js.map +1 -0
  48. package/dist/agents/index.cjs +5 -1
  49. package/dist/agents/index.cjs.map +1 -1
  50. package/dist/agents/index.d.cts +4 -0
  51. package/dist/agents/index.d.mts +4 -0
  52. package/dist/agents/index.d.ts +4 -0
  53. package/dist/agents/index.js +54 -50
  54. package/dist/agents/index.mjs +54 -50
  55. package/dist/agents/omp.cjs +170 -0
  56. package/dist/agents/omp.cjs.map +1 -0
  57. package/dist/agents/omp.d.cts +14 -0
  58. package/dist/agents/omp.d.mts +14 -0
  59. package/dist/agents/omp.d.ts +14 -0
  60. package/dist/agents/omp.js +7 -0
  61. package/dist/agents/omp.js.map +1 -0
  62. package/dist/agents/openclaw.cjs +51 -2
  63. package/dist/agents/openclaw.cjs.map +1 -1
  64. package/dist/agents/openclaw.d.cts +2 -0
  65. package/dist/agents/openclaw.d.mts +2 -0
  66. package/dist/agents/openclaw.d.ts +2 -0
  67. package/dist/agents/types.cjs.map +1 -1
  68. package/dist/agents/types.d.cts +4 -4
  69. package/dist/agents/types.d.mts +4 -4
  70. package/dist/agents/types.d.ts +4 -4
  71. package/dist/agents/ui-message-stream.cjs +24 -7
  72. package/dist/agents/ui-message-stream.cjs.map +1 -1
  73. package/dist/analysis/api.cjs +28 -2
  74. package/dist/analysis/api.cjs.map +1 -1
  75. package/dist/analysis/api.d.cts +22 -1
  76. package/dist/analysis/api.d.mts +22 -1
  77. package/dist/analysis/api.d.ts +22 -1
  78. package/dist/analysis/api.js +8 -6
  79. package/dist/analysis/bindings.cjs +11 -18
  80. package/dist/analysis/bindings.cjs.map +1 -1
  81. package/dist/analysis/bindings.d.cts +177 -49
  82. package/dist/analysis/bindings.d.mts +177 -49
  83. package/dist/analysis/bindings.d.ts +177 -49
  84. package/dist/analysis/contracts.cjs +1 -0
  85. package/dist/analysis/contracts.cjs.map +1 -1
  86. package/dist/analysis/contracts.d.cts +43 -3
  87. package/dist/analysis/contracts.d.mts +43 -3
  88. package/dist/analysis/contracts.d.ts +43 -3
  89. package/dist/analysis/cost-projection.cjs +2 -1
  90. package/dist/analysis/cost-projection.cjs.map +1 -1
  91. package/dist/analysis/cost-projection.d.cts +1 -1
  92. package/dist/analysis/cost-projection.d.mts +1 -1
  93. package/dist/analysis/cost-projection.d.ts +1 -1
  94. package/dist/analysis/cost.cjs +13 -3
  95. package/dist/analysis/cost.cjs.map +1 -1
  96. package/dist/analysis/cost.d.cts +10 -3
  97. package/dist/analysis/cost.d.mts +10 -3
  98. package/dist/analysis/cost.d.ts +10 -3
  99. package/dist/analysis/experiment-groups.cjs +96 -0
  100. package/dist/analysis/experiment-groups.cjs.map +1 -0
  101. package/dist/analysis/experiment-groups.d.cts +9 -0
  102. package/dist/analysis/experiment-groups.d.mts +9 -0
  103. package/dist/analysis/experiment-groups.d.ts +9 -0
  104. package/dist/analysis/experiment-groups.js +10 -0
  105. package/dist/analysis/experiment-groups.js.map +1 -0
  106. package/dist/analysis/index.cjs +4 -1
  107. package/dist/analysis/index.cjs.map +1 -1
  108. package/dist/analysis/index.d.cts +4 -2
  109. package/dist/analysis/index.d.mts +4 -2
  110. package/dist/analysis/index.d.ts +4 -2
  111. package/dist/analysis/index.js +40 -36
  112. package/dist/analysis/index.mjs +40 -36
  113. package/dist/assertions/limits.cjs +4 -0
  114. package/dist/assertions/limits.cjs.map +1 -1
  115. package/dist/assertions/limits.d.cts +4 -0
  116. package/dist/assertions/limits.d.mts +4 -0
  117. package/dist/assertions/limits.d.ts +4 -0
  118. package/dist/assertions/match.cjs +63 -25
  119. package/dist/assertions/match.cjs.map +1 -1
  120. package/dist/assertions/match.d.cts +7 -0
  121. package/dist/assertions/match.d.mts +7 -0
  122. package/dist/assertions/match.d.ts +7 -0
  123. package/dist/assertions/record/attachment.cjs +32 -4
  124. package/dist/assertions/record/attachment.cjs.map +1 -1
  125. package/dist/assertions/record/diff.cjs +10 -4
  126. package/dist/assertions/record/diff.cjs.map +1 -1
  127. package/dist/assertions/record/producer.cjs +101 -4
  128. package/dist/assertions/record/producer.cjs.map +1 -1
  129. package/dist/assertions/record/producer.d.cts +4 -1
  130. package/dist/assertions/record/producer.d.mts +4 -1
  131. package/dist/assertions/record/producer.d.ts +4 -1
  132. package/dist/assertions/runtime.cjs +45 -5
  133. package/dist/assertions/runtime.cjs.map +1 -1
  134. package/dist/cli/record.cjs +113 -8
  135. package/dist/cli/record.cjs.map +1 -1
  136. package/dist/cli/record.d.cts +20 -1
  137. package/dist/cli/record.d.mts +20 -1
  138. package/dist/cli/record.d.ts +20 -1
  139. package/dist/cli/record.js +4 -2
  140. package/dist/cli.cjs +386 -31
  141. package/dist/cli.cjs.map +1 -1
  142. package/dist/cli.d.cts +10 -2
  143. package/dist/cli.d.mts +10 -2
  144. package/dist/cli.d.ts +10 -2
  145. package/dist/context/send-retry.cjs +4 -4
  146. package/dist/context/send-retry.cjs.map +1 -1
  147. package/dist/coordination/host/runtime.cjs +8 -30
  148. package/dist/coordination/host/runtime.cjs.map +1 -1
  149. package/dist/coordination/host/runtime.d.cts +3 -3
  150. package/dist/coordination/host/runtime.d.mts +3 -3
  151. package/dist/coordination/host/runtime.d.ts +3 -3
  152. package/dist/coordination/host/types.cjs.map +1 -1
  153. package/dist/coordination/host/types.d.cts +0 -5
  154. package/dist/coordination/host/types.d.mts +0 -5
  155. package/dist/coordination/host/types.d.ts +0 -5
  156. package/dist/coordination/platform/node.cjs +90 -9
  157. package/dist/coordination/platform/node.cjs.map +1 -1
  158. package/dist/define.cjs +25 -1
  159. package/dist/define.cjs.map +1 -1
  160. package/dist/experiment/host/index.cjs +1 -0
  161. package/dist/experiment/host/index.cjs.map +1 -1
  162. package/dist/i18n/en.cjs +26 -8
  163. package/dist/i18n/en.cjs.map +1 -1
  164. package/dist/i18n/en.d.cts +19 -6
  165. package/dist/i18n/en.d.mts +19 -6
  166. package/dist/i18n/en.d.ts +19 -6
  167. package/dist/index.cjs.map +1 -1
  168. package/dist/index.d.cts +1 -1
  169. package/dist/index.d.mts +1 -1
  170. package/dist/index.d.ts +1 -1
  171. package/dist/o11y/parsers/hermes.cjs +1 -1
  172. package/dist/o11y/parsers/hermes.cjs.map +1 -1
  173. package/dist/o11y/prices.json +1 -1
  174. package/dist/o11y/record/families.cjs +12 -3
  175. package/dist/o11y/record/families.cjs.map +1 -1
  176. package/dist/o11y/record/families.d.cts +8 -8
  177. package/dist/o11y/record/families.d.mts +8 -8
  178. package/dist/o11y/record/families.d.ts +8 -8
  179. package/dist/o11y/record/family-projectors.d.cts +66 -18
  180. package/dist/o11y/record/family-projectors.d.mts +66 -18
  181. package/dist/o11y/record/family-projectors.d.ts +66 -18
  182. package/dist/o11y/record/family-writers.d.cts +11 -3
  183. package/dist/o11y/record/family-writers.d.mts +11 -3
  184. package/dist/o11y/record/family-writers.d.ts +11 -3
  185. package/dist/o11y/record/runner-producer.cjs +14 -4
  186. package/dist/o11y/record/runner-producer.cjs.map +1 -1
  187. package/dist/record/codec/core.d.cts +2 -2
  188. package/dist/record/codec/core.d.mts +2 -2
  189. package/dist/record/codec/core.d.ts +2 -2
  190. package/dist/record/family/catalog.d.cts +44 -12
  191. package/dist/record/family/catalog.d.mts +44 -12
  192. package/dist/record/family/catalog.d.ts +44 -12
  193. package/dist/record/family/index.js +128 -124
  194. package/dist/record/family/observability-v1.cjs +35 -0
  195. package/dist/record/family/observability-v1.cjs.map +1 -0
  196. package/dist/record/family/observability-v1.d.cts +3 -0
  197. package/dist/record/family/observability-v1.d.mts +3 -0
  198. package/dist/record/family/observability-v1.d.ts +3 -0
  199. package/dist/record/family/observability-v1.js +6 -0
  200. package/dist/record/family/observability-v1.js.map +1 -0
  201. package/dist/record/family/observability.cjs +58 -9
  202. package/dist/record/family/observability.cjs.map +1 -1
  203. package/dist/record/family/observability.d.cts +1014 -15
  204. package/dist/record/family/observability.d.mts +1014 -15
  205. package/dist/record/family/observability.d.ts +1014 -15
  206. package/dist/record/family/observability.js +22 -18
  207. package/dist/record/host/runtime.cjs +600 -31
  208. package/dist/record/host/runtime.cjs.map +1 -1
  209. package/dist/record/host/types.cjs.map +1 -1
  210. package/dist/record/host/types.d.cts +33 -9
  211. package/dist/record/host/types.d.mts +33 -9
  212. package/dist/record/host/types.d.ts +33 -9
  213. package/dist/record/maintenance/runtime.cjs +1 -2
  214. package/dist/record/maintenance/runtime.cjs.map +1 -1
  215. package/dist/record/model/core.cjs.map +1 -1
  216. package/dist/record/model/core.d.cts +1 -1
  217. package/dist/record/model/core.d.mts +1 -1
  218. package/dist/record/model/core.d.ts +1 -1
  219. package/dist/record/model/definition.d.cts +6 -6
  220. package/dist/record/model/definition.d.mts +6 -6
  221. package/dist/record/model/definition.d.ts +6 -6
  222. package/dist/record/model/identifiers.cjs +1 -1
  223. package/dist/record/model/identifiers.cjs.map +1 -1
  224. package/dist/record/model/identifiers.d.cts +1 -1
  225. package/dist/record/model/identifiers.d.mts +1 -1
  226. package/dist/record/model/identifiers.d.ts +1 -1
  227. package/dist/record/platform/node.cjs +159 -23
  228. package/dist/record/platform/node.cjs.map +1 -1
  229. package/dist/record/platform/services.cjs.map +1 -1
  230. package/dist/record/platform/services.d.cts +15 -2
  231. package/dist/record/platform/services.d.mts +15 -2
  232. package/dist/record/platform/services.d.ts +15 -2
  233. package/dist/record/reader/errors.cjs +37 -1
  234. package/dist/record/reader/errors.cjs.map +1 -1
  235. package/dist/record/reader/errors.d.cts +49 -1
  236. package/dist/record/reader/errors.d.mts +49 -1
  237. package/dist/record/reader/errors.d.ts +49 -1
  238. package/dist/record/reader/errors.js +22 -12
  239. package/dist/record/reader/format.cjs +76 -17
  240. package/dist/record/reader/format.cjs.map +1 -1
  241. package/dist/record/reader/format.d.cts +11 -4
  242. package/dist/record/reader/format.d.mts +11 -4
  243. package/dist/record/reader/format.d.ts +11 -4
  244. package/dist/record/reader/format.js +2 -0
  245. package/dist/record/reader/index.js +32 -18
  246. package/dist/record/reader/runtime.cjs +64 -0
  247. package/dist/record/reader/runtime.cjs.map +1 -1
  248. package/dist/record/reader/runtime.d.cts +15 -0
  249. package/dist/record/reader/runtime.d.mts +15 -0
  250. package/dist/record/reader/runtime.d.ts +15 -0
  251. package/dist/record/reader/runtime.js +2 -0
  252. package/dist/report/assets/styles.css +53 -29
  253. package/dist/report/built-in/analysis-values.cjs +21 -13
  254. package/dist/report/built-in/analysis-values.cjs.map +1 -1
  255. package/dist/report/built-in/analysis-values.d.cts +11 -22
  256. package/dist/report/built-in/analysis-values.d.mts +11 -22
  257. package/dist/report/built-in/analysis-values.d.ts +11 -22
  258. package/dist/report/built-in/analysis-values.js +4 -6
  259. package/dist/report/built-in/index.cjs +1 -3
  260. package/dist/report/built-in/index.cjs.map +1 -1
  261. package/dist/report/built-in/index.d.cts +1 -1
  262. package/dist/report/built-in/index.d.mts +1 -1
  263. package/dist/report/built-in/index.d.ts +1 -1
  264. package/dist/report/built-in/index.js +4 -8
  265. package/dist/report/built-in/index.mjs +4 -8
  266. package/dist/report/built-in/machine.cjs +0 -2
  267. package/dist/report/built-in/machine.cjs.map +1 -1
  268. package/dist/report/built-in/machine.d.cts +0 -2
  269. package/dist/report/built-in/machine.d.mts +0 -2
  270. package/dist/report/built-in/machine.d.ts +0 -2
  271. package/dist/report/built-in/result-components.cjs +49 -51
  272. package/dist/report/built-in/result-components.cjs.map +1 -1
  273. package/dist/report/built-in/result-components.d.cts +16 -17
  274. package/dist/report/built-in/result-components.d.mts +16 -17
  275. package/dist/report/built-in/result-components.d.ts +16 -17
  276. package/dist/report/built-in/result-components.js +0 -4
  277. package/dist/report/built-in/run-membership-overview.cjs +126 -17
  278. package/dist/report/built-in/run-membership-overview.cjs.map +1 -1
  279. package/dist/report/built-in/run-membership-overview.d.cts +14 -0
  280. package/dist/report/built-in/run-membership-overview.d.mts +14 -0
  281. package/dist/report/built-in/run-membership-overview.d.ts +14 -0
  282. package/dist/report/built-in/run-membership-overview.js +4 -2
  283. package/dist/report/built-in/standard.cjs +80 -45
  284. package/dist/report/built-in/standard.cjs.map +1 -1
  285. package/dist/report/built-in/standard.d.cts +19 -41
  286. package/dist/report/built-in/standard.d.mts +19 -41
  287. package/dist/report/built-in/standard.d.ts +19 -41
  288. package/dist/report/built-in/standard.js +6 -6
  289. package/dist/report/components/attempt-detail/compute.cjs +78 -2
  290. package/dist/report/components/attempt-detail/compute.cjs.map +1 -1
  291. package/dist/report/components/attempt-detail/compute.d.cts +1 -1
  292. package/dist/report/components/attempt-detail/compute.d.mts +1 -1
  293. package/dist/report/components/attempt-detail/compute.d.ts +1 -1
  294. package/dist/report/components/attempt-detail/content.cjs +1 -1
  295. package/dist/report/components/attempt-detail/content.cjs.map +1 -1
  296. package/dist/report/components/entity-lists/compute.cjs +42 -5
  297. package/dist/report/components/entity-lists/compute.cjs.map +1 -1
  298. package/dist/report/components/entity-lists/compute.d.cts +10 -8
  299. package/dist/report/components/entity-lists/compute.d.mts +10 -8
  300. package/dist/report/components/entity-lists/compute.d.ts +10 -8
  301. package/dist/report/components/entity-lists/content.cjs +31 -6
  302. package/dist/report/components/entity-lists/content.cjs.map +1 -1
  303. package/dist/report/components/entity-lists/index.cjs +9 -4
  304. package/dist/report/components/entity-lists/index.cjs.map +1 -1
  305. package/dist/report/components/entity-lists/index.d.cts +4 -7
  306. package/dist/report/components/entity-lists/index.d.mts +4 -7
  307. package/dist/report/components/entity-lists/index.d.ts +4 -7
  308. package/dist/report/components/summaries/compute.cjs +8 -1
  309. package/dist/report/components/summaries/compute.cjs.map +1 -1
  310. package/dist/report/components/summaries/compute.d.cts +9 -1
  311. package/dist/report/components/summaries/compute.d.mts +9 -1
  312. package/dist/report/components/summaries/compute.d.ts +9 -1
  313. package/dist/report/components/summaries/index.cjs +48 -4
  314. package/dist/report/components/summaries/index.cjs.map +1 -1
  315. package/dist/report/components/summaries/index.d.cts +7 -4
  316. package/dist/report/components/summaries/index.d.mts +7 -4
  317. package/dist/report/components/summaries/index.d.ts +7 -4
  318. package/dist/report/definition/cell.cjs +3 -0
  319. package/dist/report/definition/cell.cjs.map +1 -1
  320. package/dist/report/definition/cell.d.cts +2 -0
  321. package/dist/report/definition/cell.d.mts +2 -0
  322. package/dist/report/definition/cell.d.ts +2 -0
  323. package/dist/report/definition/primitives/chart.cjs +8 -5
  324. package/dist/report/definition/primitives/chart.cjs.map +1 -1
  325. package/dist/report/definition/primitives/points-dataset.cjs +1 -0
  326. package/dist/report/definition/primitives/points-dataset.cjs.map +1 -1
  327. package/dist/report/definition/primitives.cjs +15 -2
  328. package/dist/report/definition/primitives.cjs.map +1 -1
  329. package/dist/report/definition/report.cjs +27 -3
  330. package/dist/report/definition/report.cjs.map +1 -1
  331. package/dist/report/definition/report.d.cts +8 -0
  332. package/dist/report/definition/report.d.mts +8 -0
  333. package/dist/report/definition/report.d.ts +8 -0
  334. package/dist/report/execution/machine.cjs +30 -14
  335. package/dist/report/execution/machine.cjs.map +1 -1
  336. package/dist/report/execution/machine.d.cts +20 -10
  337. package/dist/report/execution/machine.d.mts +20 -10
  338. package/dist/report/execution/machine.d.ts +20 -10
  339. package/dist/report/execution/machine.js +6 -6
  340. package/dist/report/host/execute.cjs +25 -16
  341. package/dist/report/host/execute.cjs.map +1 -1
  342. package/dist/report/host/execute.d.cts +4 -0
  343. package/dist/report/host/execute.d.mts +4 -0
  344. package/dist/report/host/execute.d.ts +4 -0
  345. package/dist/report/host/from-record.cjs +22 -5
  346. package/dist/report/host/from-record.cjs.map +1 -1
  347. package/dist/report/host/machine.cjs +53 -11
  348. package/dist/report/host/machine.cjs.map +1 -1
  349. package/dist/report/host/site-runtime.cjs +9 -8
  350. package/dist/report/host/site-runtime.cjs.map +1 -1
  351. package/dist/report/host/site-runtime.d.cts +1 -1
  352. package/dist/report/host/site-runtime.d.mts +1 -1
  353. package/dist/report/host/site-runtime.d.ts +1 -1
  354. package/dist/report/host/static.cjs +56 -9
  355. package/dist/report/host/static.cjs.map +1 -1
  356. package/dist/report/index.cjs.map +1 -1
  357. package/dist/report/index.d.cts +1 -1
  358. package/dist/report/index.d.mts +1 -1
  359. package/dist/report/index.d.ts +1 -1
  360. package/dist/report/model/dataset.cjs +7 -2
  361. package/dist/report/model/dataset.cjs.map +1 -1
  362. package/dist/report/model/locale.cjs +2 -0
  363. package/dist/report/model/locale.cjs.map +1 -1
  364. package/dist/report/model/locale.d.cts +1 -0
  365. package/dist/report/model/locale.d.mts +1 -0
  366. package/dist/report/model/locale.d.ts +1 -0
  367. package/dist/report/model/metrics.cjs +3 -1
  368. package/dist/report/model/metrics.cjs.map +1 -1
  369. package/dist/report/model/pricing.cjs +16 -11
  370. package/dist/report/model/pricing.cjs.map +1 -1
  371. package/dist/report/react/styles.css +53 -29
  372. package/dist/runner/adoption.cjs +1 -0
  373. package/dist/runner/adoption.cjs.map +1 -1
  374. package/dist/runner/attempt.cjs +44 -5
  375. package/dist/runner/attempt.cjs.map +1 -1
  376. package/dist/runner/attempt.d.cts +13 -1
  377. package/dist/runner/attempt.d.mts +13 -1
  378. package/dist/runner/attempt.d.ts +13 -1
  379. package/dist/runner/config-identity.cjs +10 -2
  380. package/dist/runner/config-identity.cjs.map +1 -1
  381. package/dist/runner/config-identity.d.cts +4 -2
  382. package/dist/runner/config-identity.d.mts +4 -2
  383. package/dist/runner/config-identity.d.ts +4 -2
  384. package/dist/runner/feedback/human.cjs +298 -59
  385. package/dist/runner/feedback/human.cjs.map +1 -1
  386. package/dist/runner/feedback/json.cjs +14 -6
  387. package/dist/runner/feedback/json.cjs.map +1 -1
  388. package/dist/runner/feedback/json.d.cts +3 -2
  389. package/dist/runner/feedback/json.d.mts +3 -2
  390. package/dist/runner/feedback/json.d.ts +3 -2
  391. package/dist/runner/feedback/reducer.cjs +2 -0
  392. package/dist/runner/feedback/reducer.cjs.map +1 -1
  393. package/dist/runner/judge-config.cjs +1 -1
  394. package/dist/runner/judge-config.cjs.map +1 -1
  395. package/dist/runner/ledger.cjs +124 -12
  396. package/dist/runner/ledger.cjs.map +1 -1
  397. package/dist/runner/project-current.cjs +13 -5
  398. package/dist/runner/project-current.cjs.map +1 -1
  399. package/dist/runner/run.cjs +564 -256
  400. package/dist/runner/run.cjs.map +1 -1
  401. package/dist/runner/sandbox-pool.cjs +161 -30
  402. package/dist/runner/sandbox-pool.cjs.map +1 -1
  403. package/dist/runner/sandbox-pool.d.cts +34 -2
  404. package/dist/runner/sandbox-pool.d.mts +34 -2
  405. package/dist/runner/sandbox-pool.d.ts +34 -2
  406. package/dist/runner/shared-state-lease.cjs +803 -0
  407. package/dist/runner/shared-state-lease.cjs.map +1 -0
  408. package/dist/runner/shared-state-lease.d.cts +121 -0
  409. package/dist/runner/shared-state-lease.d.mts +121 -0
  410. package/dist/runner/shared-state-lease.d.ts +121 -0
  411. package/dist/runner/shared-state-lease.js +24 -0
  412. package/dist/runner/shared-state-lease.js.map +1 -0
  413. package/dist/runner/teardown-registry.cjs +97 -34
  414. package/dist/runner/teardown-registry.cjs.map +1 -1
  415. package/dist/runner/teardown-registry.d.cts +27 -1
  416. package/dist/runner/teardown-registry.d.mts +27 -1
  417. package/dist/runner/teardown-registry.d.ts +27 -1
  418. package/dist/runner/teardown-registry.js +20 -16
  419. package/dist/runner/types.cjs.map +1 -1
  420. package/dist/runner/types.d.cts +31 -5
  421. package/dist/runner/types.d.mts +31 -5
  422. package/dist/runner/types.d.ts +31 -5
  423. package/dist/sample/analysis.cjs +249 -459
  424. package/dist/sample/analysis.cjs.map +1 -1
  425. package/dist/sample/capability.cjs +138 -7
  426. package/dist/sample/capability.cjs.map +1 -1
  427. package/dist/sample/capability.d.cts +3 -1
  428. package/dist/sample/capability.d.mts +3 -1
  429. package/dist/sample/capability.d.ts +3 -1
  430. package/dist/sample/capability.js +8 -6
  431. package/dist/sandbox/docker-agent-image.cjs +5 -1
  432. package/dist/sandbox/docker-agent-image.cjs.map +1 -1
  433. package/dist/sandbox/docker-agent-image.d.cts +2 -0
  434. package/dist/sandbox/docker-agent-image.d.mts +2 -0
  435. package/dist/sandbox/docker-agent-image.d.ts +2 -0
  436. package/dist/sandbox/docker-agent-image.js +14 -10
  437. package/dist/sandbox/docker-profile/schema.cjs +283 -534
  438. package/dist/sandbox/docker-profile/schema.cjs.map +1 -1
  439. package/dist/sandbox/docker-profile/schema.d.cts +10 -27
  440. package/dist/sandbox/docker-profile/schema.d.mts +10 -27
  441. package/dist/sandbox/docker-profile/schema.d.ts +10 -27
  442. package/dist/sandbox/e2b-agent-template.cjs +5 -2
  443. package/dist/sandbox/e2b-agent-template.cjs.map +1 -1
  444. package/dist/sandbox/index.cjs +4 -2
  445. package/dist/sandbox/index.cjs.map +1 -1
  446. package/dist/sandbox/index.d.cts +1 -1
  447. package/dist/sandbox/index.d.mts +1 -1
  448. package/dist/sandbox/index.d.ts +1 -1
  449. package/dist/sandbox/index.js +120 -116
  450. package/dist/sandbox/index.mjs +120 -116
  451. package/dist/sandbox/keep-registry.cjs +28 -66
  452. package/dist/sandbox/keep-registry.cjs.map +1 -1
  453. package/dist/sandbox/types.cjs.map +1 -1
  454. package/dist/sandbox/types.d.cts +1 -1
  455. package/dist/sandbox/types.d.mts +1 -1
  456. package/dist/sandbox/types.d.ts +1 -1
  457. package/dist/shared/aggregate.cjs +16 -6
  458. package/dist/shared/aggregate.cjs.map +1 -1
  459. package/dist/shared/aggregate.d.cts +12 -4
  460. package/dist/shared/aggregate.d.mts +12 -4
  461. package/dist/shared/aggregate.d.ts +12 -4
  462. package/dist/shared/turn-label.cjs +20 -2
  463. package/dist/shared/turn-label.cjs.map +1 -1
  464. package/dist/shared/turn-label.d.cts +2 -0
  465. package/dist/shared/turn-label.d.mts +2 -0
  466. package/dist/shared/turn-label.d.ts +2 -0
  467. package/dist/shared/turn-label.js +4 -2
  468. package/dist/vendor/remark/remark-gfm.cjs +7 -7
  469. package/dist/vendor/remark/remark-gfm.cjs.map +1 -1
  470. package/dist/vendor/remark/remark-parse.cjs +12 -12
  471. package/dist/vendor/remark/remark-parse.cjs.map +1 -1
  472. package/dist/vendor/remark/remark.cjs +13 -13
  473. package/dist/vendor/remark/remark.cjs.map +1 -1
  474. package/dist/view/server.cjs +6 -0
  475. package/dist/view/server.cjs.map +1 -1
  476. package/docs-site/images/hitl-handshake-zh.svg +3 -3
  477. package/docs-site/zh/examples/ai-agent-application.mdx +1 -1
  478. package/docs-site/zh/examples/coding-agent-extensions.mdx +1 -1
  479. package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +4 -3
  480. package/docs-site/zh/examples/integrations/claude-sdk.mdx +3 -3
  481. package/docs-site/zh/examples/integrations/codex-sdk.mdx +5 -5
  482. package/docs-site/zh/examples/integrations/langgraph.mdx +4 -4
  483. package/docs-site/zh/examples/integrations/pi-sdk.mdx +5 -5
  484. package/docs-site/zh/explanation/adapter.mdx +5 -5
  485. package/docs-site/zh/explanation/assert.mdx +7 -7
  486. package/docs-site/zh/explanation/drive.mdx +4 -2
  487. package/docs-site/zh/explanation/evals.mdx +10 -8
  488. package/docs-site/zh/explanation/experiment.mdx +2 -2
  489. package/docs-site/zh/explanation/hitl.mdx +9 -9
  490. package/docs-site/zh/explanation/judge.mdx +5 -5
  491. package/docs-site/zh/explanation/overview.mdx +3 -3
  492. package/docs-site/zh/explanation/runner.mdx +1 -1
  493. package/docs-site/zh/index.mdx +3 -3
  494. package/docs-site/zh/reference/builtin-agents.mdx +13 -13
  495. package/docs-site/zh/reference/capabilities.mdx +1 -1
  496. package/docs-site/zh/reference/cli.mdx +18 -12
  497. package/docs-site/zh/reference/define-agent.mdx +130 -5
  498. package/docs-site/zh/reference/define-config.mdx +2 -2
  499. package/docs-site/zh/reference/define-eval.mdx +4 -4
  500. package/docs-site/zh/reference/events.mdx +11 -11
  501. package/docs-site/zh/reference/official-adapters.mdx +6 -6
  502. package/docs-site/zh/reference/results-data.mdx +6 -0
  503. package/docs-site/zh/troubleshooting/debugging.mdx +1 -1
  504. package/docs-site/zh/troubleshooting/recover-after-kill.mdx +37 -5
  505. package/docs-site/zh/tutorials/accept-results.mdx +72 -0
  506. package/docs-site/zh/tutorials/agent-onboarding.mdx +6 -6
  507. package/docs-site/zh/tutorials/authoring.mdx +9 -13
  508. package/docs-site/zh/tutorials/ci-integration.mdx +6 -6
  509. package/docs-site/zh/tutorials/compare-runs.mdx +61 -0
  510. package/docs-site/zh/tutorials/concurrency.mdx +13 -12
  511. package/docs-site/zh/tutorials/configuration.mdx +4 -6
  512. package/docs-site/zh/tutorials/connect-your-agent.mdx +1 -1
  513. package/docs-site/zh/tutorials/control-run-cost.mdx +58 -0
  514. package/docs-site/zh/tutorials/criteria-files.mdx +2 -2
  515. package/docs-site/zh/tutorials/custom-reports.mdx +2 -2
  516. package/docs-site/zh/tutorials/debug-lifecycle-plan.mdx +46 -0
  517. package/docs-site/zh/tutorials/docker-in-docker.mdx +52 -43
  518. package/docs-site/zh/tutorials/eval-groups.mdx +6 -6
  519. package/docs-site/zh/tutorials/evaluation-kinds.mdx +3 -3
  520. package/docs-site/zh/tutorials/experiments.mdx +2 -3
  521. package/docs-site/zh/tutorials/handle-execution-failures.mdx +18 -10
  522. package/docs-site/zh/tutorials/install-custom-sandbox-agent.mdx +16 -8
  523. package/docs-site/zh/tutorials/nixos-managed-dind.mdx +160 -0
  524. package/docs-site/zh/tutorials/plugins.mdx +14 -0
  525. package/docs-site/zh/tutorials/rerun-and-cache.mdx +4 -2
  526. package/docs-site/zh/tutorials/sandbox-agent.mdx +17 -11
  527. package/docs-site/zh/tutorials/sandbox-providers.mdx +17 -13
  528. package/docs-site/zh/tutorials/sandbox-reuse.mdx +12 -19
  529. package/docs-site/zh/tutorials/select-and-preview.mdx +65 -0
  530. package/docs-site/zh/tutorials/verify-judge.mdx +78 -0
  531. package/docs-site/zh/tutorials/viewing-results.mdx +38 -1
  532. package/docs-site/zh/tutorials/write-experiment.mdx +7 -5
  533. package/docs-site/zh/tutorials/write-send.mdx +9 -8
  534. package/package.json +9 -5
  535. package/dist/report/built-in/overview.cjs +0 -44
  536. package/dist/report/built-in/overview.cjs.map +0 -1
  537. package/dist/report/built-in/overview.d.cts +0 -6
  538. package/dist/report/built-in/overview.d.mts +0 -6
  539. package/dist/report/built-in/overview.d.ts +0 -6
  540. package/dist/report/built-in/overview.js +0 -9
  541. package/dist/report/built-in/overview.js.map +0 -1
  542. package/dist/runner/gate-lease.cjs +0 -283
  543. package/dist/runner/gate-lease.cjs.map +0 -1
  544. package/dist/runner/gate-lease.d.cts +0 -62
  545. package/dist/runner/gate-lease.d.mts +0 -62
  546. package/dist/runner/gate-lease.d.ts +0 -62
  547. package/dist/runner/gate-lease.js +0 -22
  548. package/dist/runner/gate-lease.js.map +0 -1
@@ -73,16 +73,19 @@ function createJsonRenderer(options) {
73
73
  // "diagnostic" 变体的 identity 注释)。
74
74
  const experimentId = event.identity?.experimentId ?? stringField(event.data?.experimentId);
75
75
  const evalId = event.identity?.evalId ?? stringField(event.data?.evalId);
76
+ const planned = numberField(event.data?.planned);
77
+ const errored = numberField(event.data?.errored);
76
78
  const common = {
77
79
  code,
78
80
  message: event.message,
79
81
  ...(phase !== undefined ? { phase } : {}),
80
82
  ...(experimentId !== undefined ? { experimentId } : {}),
81
83
  ...(evalId !== undefined ? { evalId } : {}),
84
+ ...(planned !== undefined ? { planned } : {}),
85
+ ...(errored !== undefined ? { errored } : {}),
82
86
  };
83
87
  if (event.severity === "info") {
84
88
  const resource = coordinationResourceField(event.data?.resource);
85
- const slot = numberField(event.data?.slot);
86
89
  const previousPid = numberField(event.data?.previousPid);
87
90
  const previousHost = stringField(event.data?.previousHost);
88
91
  writeEvent(io, {
@@ -90,7 +93,6 @@ function createJsonRenderer(options) {
90
93
  level: "info",
91
94
  ...common,
92
95
  ...(resource !== undefined ? { resource } : {}),
93
- ...(slot !== undefined ? { slot } : {}),
94
96
  ...(previousPid !== undefined ? { previousPid } : {}),
95
97
  ...(previousHost !== undefined ? { previousHost } : {}),
96
98
  });
@@ -243,7 +245,7 @@ function numberField(value) {
243
245
  return typeof value === "number" ? value : undefined;
244
246
  }
245
247
  function coordinationResourceField(value) {
246
- return value === "concurrency-slot" || value === "case-lock" ? value : undefined;
248
+ return value === "case-lock" ? value : undefined;
247
249
  }
248
250
  /** 通知 data 是 JSON 边界;只有全局 LifecyclePhase 闭集成员才能进入 notice/warning phase。 */
249
251
  function lifecyclePhaseField(value) {
@@ -326,7 +328,10 @@ function requiredExperimentId(experimentId, evalId) {
326
328
  function evalConclusionEvent(row) {
327
329
  const experimentId = requiredExperimentId(row.experimentId, row.evalId);
328
330
  if (row.locator === undefined) {
329
- throw new Error(`JSON experiment event is missing locator for eval ${row.evalId}`);
331
+ // Pre-dispatch failures have no origin Attempt and therefore no locator.
332
+ // `eval` events are locator-addressable conclusions, so the run-level
333
+ // diagnostic and final result counts are their public projection.
334
+ return undefined;
330
335
  }
331
336
  const base = {
332
337
  event: "eval",
@@ -351,8 +356,11 @@ function writeEvalConclusions(io, pending, state) {
351
356
  if (!pending)
352
357
  return;
353
358
  const rows = (0, eval_conclusions_ts_1.evalConclusionRows)(pending.results, state.earlyExitByEval, state.diagnostics);
354
- for (const row of rows)
355
- writeEvent(io, evalConclusionEvent(row));
359
+ for (const row of rows) {
360
+ const event = evalConclusionEvent(row);
361
+ if (event !== undefined)
362
+ writeEvent(io, event);
363
+ }
356
364
  }
357
365
  // ───────────────────────── 退出码(CompletionStatus 驱动) ─────────────────────────
358
366
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"json.js","sourceRoot":"","sources":["json.ts"],"names":[],"mappings":"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","sourcesContent":["// JSON profile renderer(见 docs/feature/experiments/cli.md「机器怎么读:--json」与「事件与\n// 计划文档的 TypeScript 形状」)。合并了此前 agent.ts + ci.ts 两个 profile —— 逐项对照证实\n// agent 档/ci 档是同一消费者模型的两套参数(heartbeat 30/60s、失败展开上限 5/50、流路由、词法\n// 前缀……),没有模型差,见 memory/exp-output-two-forms-ruling.md。\n//\n// 目标读者是任何非交互解析者(coding agent、CI annotation adapter、脚本),不是人眼:\n// - 单一 stdout 上的 NDJSON 事件流,一行一个 JSON 对象,词法就是 JSON,没有自造 envelope\n// 语法。`stderr` 只留给 run 尚未建立前的 argv/config 错误(那些错误发生在 coordinator/renderer\n// 存在之前,根本不经过这个模块——所以这里没有任何写 `io.stderr` 的分支,不是遗漏)。\n// - 首行 `start` 携带 `format`/`schemaVersion` 标识整条流;其余事件不重复这两个字段。\n// - 失败/错误立即逐条追加,不做展开上限 suppression(机器逐事件消费,截断反而是信息损失,\n// 见 cli.md「'立即追加'也必须有上限」表:上限只约束人读文本)。\n// - 连续 30 秒没有永久事件才追加一条 `progress` 心跳;任意永久事件重置这个时钟。\n// - 事件形状按 `ExpEvent` 判别联合(判别字段 `event`)逐个实现,字段名复用 Record 词表\n// (locator/evalId/experimentId/phase/verdict),不为事件流发明第二套命名。\n//\n// 不实现 `clearDynamic`/`redrawDynamic`/`activity`/`onLifecycle`:JSON 流没有「动态区域」概念,\n// 不展示 active phase、不逐次输出 provisioning retry/backoff、不逐条打印 passed attempt —— 这些\n// 目标行为由「不实现对应可选钩子」天然满足(见 renderer.ts 的接口注释)。\n//\n// 为什么 diagnostic/budget-exhausted/interrupted/reporter-error 仍然去重(只在首次出现时追加)\n// 而 failure/error 不做 suppression:cli.md「什么动态更新,什么逐条追加」表把两者分成不同的行——\n// 「retry 耗尽、降级、budget 不可执行」是「去重后追加一次」的永久事件,「failed/errored + locator」\n// 是「立即追加,不设上限」的独立证据;`--json` 的「不做 suppression」只针对后者(每条失败一个\n// 有界事件),不是把去重规则也一起取消。\nimport type { FeedbackRenderer } from \"./renderer.ts\";\nimport type { FeedbackIO } from \"./io.ts\";\nimport type { DurableFeedbackEvent, InvocationCompletion, InvocationReceipt, InvocationSummary, LifecyclePhase, RunFeedbackState, } from \"../types.ts\";\nimport type { JsonValue, Verdict } from \"../../shared/types.ts\";\nimport { evalConclusionRows, type EvalConclusionRow } from \"./eval-conclusions.ts\";\n/** `ExpEvent`/`ExpPlanDocument` 的 `format`/`schemaVersion` —— 只在破坏性形状变更时递增\n * (见 cli.md「事件与计划文档的 TypeScript 形状」)。 */\nconst EXP_STREAM_FORMAT = \"niceeval.exp\";\nconst EXP_PLAN_FORMAT = \"niceeval.exp-plan\";\nconst SCHEMA_VERSION = 1;\nconst EXP_PLAN_SCHEMA_VERSION = 4;\n/** 连续无永久事件多久才追加一条 `progress` 心跳(cli.md「机器怎么读:--json」:「连续 30 秒\n * 没有这些永久事件,才追加一条 progress 心跳」——两者合并前分别是 30s/60s,统一取 30s)。 */\nconst JSON_HEARTBEAT_IDLE_MS = 30000;\nexport interface JsonRendererOptions {\n io: FeedbackIO;\n}\nexport interface StartEvent {\n format: typeof EXP_STREAM_FORMAT;\n schemaVersion: number;\n event: \"start\";\n total: number;\n configs: number;\n concurrency: number;\n experimentConcurrency?: Readonly<globalThis.Record<string, number>>;\n reused: number;\n}\nexport interface ProgressEvent {\n event: \"progress\";\n elapsedMs: number;\n total: number;\n reused: number;\n running: number;\n elsewhere: number;\n queued: number;\n passed: number;\n failed: number;\n errored: number;\n skipped: number;\n}\nexport interface FailureEvent {\n event: \"failure\";\n locator: string;\n evalId: string;\n experimentId: string;\n verdict: \"failed\" | \"errored\";\n fact: string;\n matcher?: string;\n expected?: JsonValue;\n received?: JsonValue;\n}\nexport interface ErrorEvent {\n event: \"error\";\n locator: string;\n evalId: string;\n experimentId: string;\n phase: LifecyclePhase;\n reason: string;\n}\ninterface EvalEventBase {\n event: \"eval\";\n locator: string;\n evalId: string;\n experimentId: string;\n verdict: Verdict;\n attempts: number;\n}\nexport type EvalEvent = EvalEventBase & ({\n passed: number;\n planned?: never;\n unstarted?: never;\n reason?: never;\n} | {\n passed?: never;\n planned: number;\n unstarted: number;\n reason: \"early_exit\";\n});\nexport interface KeptEvent {\n event: \"kept\";\n locator: string;\n evalId: string;\n attempt: number;\n verdict: Exclude<Verdict, \"skipped\">;\n provider: string;\n sandboxId: string;\n enter: string;\n}\nexport interface WarningEvent {\n event: \"warning\";\n code: string;\n level: \"warning\" | \"error\";\n message: string;\n phase?: LifecyclePhase;\n experimentId?: string;\n evalId?: string;\n}\nexport interface NoticeEvent {\n event: \"notice\";\n code: string;\n level: \"info\";\n message: string;\n phase?: LifecyclePhase;\n experimentId?: string;\n evalId?: string;\n resource?: \"concurrency-slot\" | \"case-lock\";\n slot?: number;\n previousPid?: number;\n previousHost?: string;\n}\nexport interface BudgetExhaustedEvent {\n event: \"budget_exhausted\";\n experimentId: string;\n spent: number;\n unstarted: number;\n}\nexport interface ReporterErrorEvent {\n event: \"reporter_error\";\n reporter: string;\n required: boolean;\n message: string;\n}\nexport interface InterruptedEvent {\n event: \"interrupted\";\n}\nexport interface JudgePrecheckEvent {\n event: \"judge_precheck\";\n status: \"started\" | \"done\" | \"failed\";\n durationMs?: number;\n}\nexport interface ExperimentSetupEvent {\n event: \"experiment_setup\";\n experimentId: string;\n status: \"started\" | \"done\" | \"failed\";\n durationMs?: number;\n}\nexport interface ExperimentTeardownEvent {\n event: \"experiment_teardown\";\n experimentId: string;\n status: \"started\" | \"done\" | \"failed\";\n durationMs?: number;\n}\nexport interface LockWaitEvent {\n event: \"lock_wait\";\n experimentId: string;\n evalId: string;\n status: \"started\" | \"resolved\";\n holderPid?: number;\n holderHost?: string;\n resolution?: \"carried\" | \"dispatched\";\n waitedMs?: number;\n}\n/** The final machine hand-off is the Record v1 receipt, without paths or snapshots. */\nexport interface ReceiptEvent {\n type: \"receipt\";\n receipt: InvocationReceipt;\n}\n/** `niceeval exp --json` 唯一公开事件词表;新增事件必须先进入已采纳文档与这个闭合联合。 */\nexport type ExpEvent = StartEvent | ProgressEvent | FailureEvent | ErrorEvent | EvalEvent | KeptEvent | NoticeEvent | WarningEvent | BudgetExhaustedEvent | ReporterErrorEvent | InterruptedEvent | JudgePrecheckEvent | ExperimentSetupEvent | ExperimentTeardownEvent | LockWaitEvent | ReceiptEvent;\nfunction writeEvent(io: FeedbackIO, event: ExpEvent): void {\n io.stdout.write(`${JSON.stringify(event)}\\n`);\n}\n/**\n * 创建 JSON profile 的 `FeedbackRenderer`。只用 `io.stdout` 写文本——`--json` 的全部正常事件\n * 走一个 stdout sink,不拆到 stderr(两个 OS stream 被 CI runner 或 agent 工具层分开缓冲时会\n * 打乱顺序,单流才能保证事件序就是发生序)。\n */\nexport function createJsonRenderer(options: JsonRendererOptions): FeedbackRenderer {\n const { io } = options;\n // 距上一次「有意义的输出」(任意一次永久事件)过了多久,用来判断要不要追加一条心跳;\n // 由 appendDurable 无条件更新——\"plan\" 本身就是第一次永久事件,天然把这个时钟从 0 开始计。\n let lastCheckpointAtMs = 0;\n // \"summary\" 与 \"receipt\" 是 coordinator.finish() 里连续 emit 的两个独立永久事件(中间不会插入\n // 其它事件)。先暂存 summary,receipt 到达时再写 eval 结论行与唯一的最终 receipt。\n let pendingSummary: InvocationSummary | undefined;\n function noteCheckpoint(atMs: number): void {\n lastCheckpointAtMs = atMs;\n }\n return {\n appendDurable(event, state) {\n switch (event.type) {\n case \"plan\": {\n noteCheckpoint(event.at);\n const { shape, reused, experimentConcurrency } = event.plan;\n writeEvent(io, {\n format: EXP_STREAM_FORMAT,\n schemaVersion: SCHEMA_VERSION,\n event: \"start\",\n total: shape.totalAttempts,\n configs: shape.configs,\n concurrency: shape.maxConcurrency,\n // 一个实验都没声明 maxConcurrency 时省略整个字段,不输出空对象(cli.md 的 StartEvent)。\n ...(experimentConcurrency && Object.keys(experimentConcurrency).length > 0\n ? { experimentConcurrency }\n : {}),\n reused,\n });\n return;\n }\n case \"failure\": {\n noteCheckpoint(event.at);\n writeFailureOrError(io, event);\n return;\n }\n case \"diagnostic\": {\n noteCheckpoint(event.at);\n if (!isFirstOccurrence(state, event.key))\n return; // 去重后只追加一次(cli.md)\n const phase = lifecyclePhaseField(event.data?.phase);\n // `code` 是 cli.md notice/warning 事件的稳定词法(`coordination-recovered` /\n // `dispatch-halted`),**不是**去重 key:去重 key 常把折叠身份编进去,原样\n // 透出会让消费方拿到一个每次运行都不同的 code、没法按值分支。折叠到哪一条实验/用例\n // 由下面的 experimentId/evalId 两个具名字段回答。\n const code = event.code ?? event.key;\n // 身份两字段:attempt 级诊断从 identity 取;运行级诊断(实验闸 / eval 闸这类不属于\n // 任何单条 attempt 的事实)不许伪造 identity,从 `data` 的同名字段取(见 ../types.ts\n // \"diagnostic\" 变体的 identity 注释)。\n const experimentId = event.identity?.experimentId ?? stringField(event.data?.experimentId);\n const evalId = event.identity?.evalId ?? stringField(event.data?.evalId);\n const common = {\n code,\n message: event.message,\n ...(phase !== undefined ? { phase } : {}),\n ...(experimentId !== undefined ? { experimentId } : {}),\n ...(evalId !== undefined ? { evalId } : {}),\n };\n if (event.severity === \"info\") {\n const resource = coordinationResourceField(event.data?.resource);\n const slot = numberField(event.data?.slot);\n const previousPid = numberField(event.data?.previousPid);\n const previousHost = stringField(event.data?.previousHost);\n writeEvent(io, {\n event: \"notice\",\n level: \"info\",\n ...common,\n ...(resource !== undefined ? { resource } : {}),\n ...(slot !== undefined ? { slot } : {}),\n ...(previousPid !== undefined ? { previousPid } : {}),\n ...(previousHost !== undefined ? { previousHost } : {}),\n });\n }\n else {\n writeEvent(io, { event: \"warning\", level: event.severity, ...common });\n }\n return;\n }\n case \"budget-exhausted\": {\n noteCheckpoint(event.at);\n if (!isFirstOccurrence(state, `budget-exhausted:${event.experimentId}`))\n return;\n writeEvent(io, {\n event: \"budget_exhausted\",\n experimentId: event.experimentId,\n spent: event.spent,\n unstarted: event.unstarted,\n });\n return;\n }\n case \"experiment-hook\": {\n noteCheckpoint(event.at);\n writeEvent(io, {\n event: event.hook === \"setup\" ? \"experiment_setup\" : \"experiment_teardown\",\n experimentId: event.experimentId,\n status: event.status,\n ...(event.durationMs !== undefined ? { durationMs: event.durationMs } : {}),\n });\n return;\n }\n case \"precheck\": {\n noteCheckpoint(event.at);\n writeEvent(io, {\n event: \"judge_precheck\",\n status: event.status,\n ...(event.durationMs !== undefined ? { durationMs: event.durationMs } : {}),\n });\n return;\n }\n case \"lock-wait\": {\n noteCheckpoint(event.at);\n writeEvent(io, {\n event: \"lock_wait\",\n experimentId: event.experimentId,\n evalId: event.evalId,\n status: event.status,\n ...(event.holderPid !== undefined ? { holderPid: event.holderPid } : {}),\n ...(event.holderHost !== undefined ? { holderHost: event.holderHost } : {}),\n // 折叠 carried/dispatched 两个内部计数为一个公开 resolution:仍有 attempt 需要真实\n // 派发(dispatched > 0)记 \"dispatched\",全部由携带满足才记 \"carried\"\n // (见 ../types.ts 里 DurableFeedbackEvent \"lock-wait\" 变体的字段注释)。\n ...(event.status === \"resolved\"\n ? { resolution: (event.dispatched ?? 0) > 0 ? \"dispatched\" : \"carried\" }\n : {}),\n ...(event.waitedMs !== undefined ? { waitedMs: event.waitedMs } : {}),\n });\n return;\n }\n case \"run-activity\": {\n // Run activity 只服务 human live 面;ExpEvent 的已采纳词表没有这一种事件。\n return;\n }\n case \"interrupted\": {\n noteCheckpoint(event.at);\n if (!isFirstOccurrence(state, \"interrupted\"))\n return;\n writeEvent(io, { event: \"interrupted\" });\n return;\n }\n case \"reporter-error\": {\n noteCheckpoint(event.at);\n if (!isFirstOccurrence(state, `reporter-error:${event.reporter}`))\n return;\n writeEvent(io, {\n event: \"reporter_error\",\n reporter: event.reporter,\n required: event.required,\n message: event.message,\n });\n return;\n }\n case \"summary\":\n pendingSummary = event.summary;\n return;\n case \"kept\": {\n if (event.verdict === \"skipped\") {\n throw new Error(\"A skipped attempt cannot own a retained sandbox\");\n }\n writeEvent(io, {\n event: \"kept\",\n locator: String(event.locator),\n evalId: event.identity.evalId,\n attempt: event.identity.attempt,\n verdict: event.verdict,\n provider: event.provider,\n sandboxId: event.sandboxId,\n enter: event.enter ?? `niceeval sandbox enter ${event.sandboxId.slice(0, 12)}`,\n });\n return;\n }\n case \"receipt\":\n writeEvalConclusions(io, pendingSummary, state);\n writeEvent(io, { type: \"receipt\", receipt: event.receipt });\n return;\n default: {\n // 穷尽性检查:新增 DurableFeedbackEvent 变体时这里编译期报错提醒补上对应分支。\n const exhaustive: never = event;\n return exhaustive;\n }\n }\n },\n onTick(event, state) {\n const idle = event.at - lastCheckpointAtMs;\n if (idle < JSON_HEARTBEAT_IDLE_MS)\n return;\n noteCheckpoint(event.at);\n writeEvent(io, {\n event: \"progress\",\n elapsedMs: event.elapsedMs,\n total: state.total,\n reused: state.reused,\n running: state.running,\n elsewhere: state.elsewhere,\n queued: state.queued,\n // 与 human 首行同一份状态、同一套划分:已了结的 attempt 按 verdict 分项,消费方不必\n // 自己从合计数里猜成败(契约见 docs/feature/experiments/cli.md 的 ProgressEvent)。\n passed: state.passed,\n failed: state.failed,\n errored: state.errored,\n skipped: state.skipped,\n });\n },\n // 没有 clearDynamic/redrawDynamic/activity/onLifecycle:见文件顶部注释——JSON 流不维护\n // 动态区域、不逐次输出 provisioning retry/backoff、不逐条展示 active phase 或 passed attempt。\n };\n}\n/** 某个去重 key 在 `state.diagnostics` 里是不是第一次出现(count === 1)。budget-exhausted /\n * interrupted / reporter-error 的去重 key 计算方式与 reducer.ts 完全一致(见该文件的\n * `budget-exhausted:${experimentId}` / `\"interrupted\"` / `reporter-error:${reporter}`)。 */\nfunction isFirstOccurrence(state: RunFeedbackState, key: string): boolean {\n return (state.diagnostics.find((d) => d.key === key)?.count ?? 0) <= 1;\n}\n/** `data` 里的一个字符串字段;非字符串(或缺失)一律当没有,不把数字/对象硬塞进只接受\n * 字符串的事件字段里。 */\nfunction stringField(value: JsonValue | undefined): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\nfunction numberField(value: JsonValue | undefined): number | undefined {\n return typeof value === \"number\" ? value : undefined;\n}\nfunction coordinationResourceField(value: JsonValue | undefined): NoticeEvent[\"resource\"] {\n return value === \"concurrency-slot\" || value === \"case-lock\" ? value : undefined;\n}\n/** 通知 data 是 JSON 边界;只有全局 LifecyclePhase 闭集成员才能进入 notice/warning phase。 */\nfunction lifecyclePhaseField(value: JsonValue | undefined): LifecyclePhase | undefined {\n switch (value) {\n case \"judge.precheck\":\n case \"experiment.setup\":\n case \"experiment.teardown\":\n case \"sandbox.queue\":\n case \"sandbox.create\":\n case \"sandbox.prepare\":\n case \"sandbox.prepare.eval\":\n case \"sandbox.prepare.group\":\n case \"sandbox.prepare.experiment\":\n case \"agent.ensure\":\n case \"workspace.baseline\":\n case \"agent.setup\":\n case \"telemetry.configure\":\n case \"eval.run\":\n case \"agent.run\":\n case \"workspace.diff\":\n case \"assertions.evaluate\":\n case \"telemetry.collect\":\n case \"agent.teardown\":\n case \"sandbox.cleanup\":\n case \"sandbox.suspend\":\n case \"sandbox.stop\":\n return value;\n default:\n return undefined;\n }\n}\n// ───────────────────────── failure / error 事件(不设上限) ─────────────────────────\nfunction writeFailureOrError(io: FeedbackIO, event: DurableFeedbackEvent & {\n type: \"failure\";\n}): void {\n const experimentId = requiredExperimentId(event.identity.experimentId, event.identity.evalId);\n const fact = event.fact;\n if (fact !== undefined) {\n writeEvent(io, {\n event: \"failure\",\n locator: String(event.locator),\n evalId: event.identity.evalId,\n experimentId,\n verdict: event.verdict,\n fact: fact.title,\n ...(fact.matcher !== undefined ? { matcher: fact.matcher } : {}),\n ...(fact.expected !== undefined ? { expected: fact.expected } : {}),\n ...(fact.received !== undefined ? { received: fact.received } : {}),\n });\n return;\n }\n if (event.verdict === \"errored\") {\n writeEvent(io, {\n event: \"error\",\n locator: String(event.locator),\n evalId: event.identity.evalId,\n experimentId,\n phase: event.phase ?? \"eval.run\",\n reason: event.reason,\n });\n return;\n }\n writeEvent(io, {\n event: \"failure\",\n locator: String(event.locator),\n evalId: event.identity.evalId,\n experimentId,\n verdict: event.verdict,\n fact: event.reason,\n });\n}\nfunction requiredExperimentId(experimentId: string | undefined, evalId: string): string {\n if (experimentId === undefined) {\n throw new Error(`JSON experiment event is missing experimentId for eval ${evalId}`);\n }\n return experimentId;\n}\n// ───────────────────────── 逐 eval 结论行(不设上限,写在 result 之前) ─────────────────────────\n/** 一条 `eval` 事件(cli.md「runs 与首过即停怎样展示」):字段随 earlyExit 是否触发在\n * planned/unstarted/reason 与 passed 两组间二选一,不同时出现两组字段。`rate` 是\n * `EvalConclusionRow` 派生出的额外读数,不在 `ExpEvent` 的 `EvalEvent` 形状里,这里不透出。 */\nfunction evalConclusionEvent(row: EvalConclusionRow): EvalEvent {\n const experimentId = requiredExperimentId(row.experimentId, row.evalId);\n if (row.locator === undefined) {\n throw new Error(`JSON experiment event is missing locator for eval ${row.evalId}`);\n }\n const base: EvalEventBase = {\n event: \"eval\",\n locator: row.locator,\n evalId: row.evalId,\n experimentId,\n verdict: row.verdict,\n attempts: row.attempts,\n };\n if (row.reason === \"early_exit\") {\n if (row.planned === undefined || row.unstarted === undefined) {\n throw new Error(`Early-exit eval event is missing planned counts for eval ${row.evalId}`);\n }\n return { ...base, planned: row.planned, unstarted: row.unstarted, reason: row.reason };\n }\n if (row.passed === undefined) {\n throw new Error(`Completed eval event is missing passed count for eval ${row.evalId}`);\n }\n return { ...base, passed: row.passed };\n}\nfunction writeEvalConclusions(io: FeedbackIO, pending: InvocationSummary | undefined, state: RunFeedbackState): void {\n if (!pending)\n return;\n const rows = evalConclusionRows(pending.results, state.earlyExitByEval, state.diagnostics);\n for (const row of rows)\n writeEvent(io, evalConclusionEvent(row));\n}\n// ───────────────────────── 退出码(CompletionStatus 驱动) ─────────────────────────\n/**\n * 把 `InvocationSummary` + `InvocationCompletion` 折成 CLI 退出码(cli.md「机器怎么读:--json」\n * 的退出码表)。纯函数,不看 CLI flag、不读 `process.env`;两种输出形态(human/json)共用同一套\n * 退出码,不是某一种 profile 专属——放在这个模块只是历史沿革(此前 `computeCiExitCode` 定义在\n * ci.ts,合并后更名为不带 profile 前缀的 `computeExitCode`)。\n *\n * 不在这里处理「2 = CLI/runner 未捕获崩溃」——那是进程级 uncaught exception/rejection 处理器\n * 的职责,不是「一次 run 正常收尾后该给什么退出码」的问题,不应该由 completion 驱动。\n */\nexport function computeExitCode(summary: InvocationSummary, completion: InvocationCompletion): number {\n if (completion.status === \"interrupted\")\n return 130;\n if (completion.status === \"incomplete\")\n return 1;\n if (completion.reporterErrors.some((e) => e.required))\n return 1;\n return summary.failed > 0 || summary.errored > 0 ? 1 : 0;\n}\n// ───────────────────────── `--dry --json`:单个 ExpPlanDocument,不是流 ─────────────────────────\n/** 一个 (experiment, eval) 组合在 `ExpPlanDocument.matrix` 里的一行(cli.md「`--dry --json`\n * 输出单个 `ExpPlanDocument`」)。 */\n/** 一条具名差异的机器面投影(`ExpPlanDelta`);selector 只解释本次指纹变化。 */\nexport interface JsonPlanDelta {\n /** 指纹差异词表:`config:<路径>` / `source:<路径>` / `data:<路径>` / `opaque:no-manifest`。 */\n selector: string;\n /** 差异方向。`unknown` 表示历史 manifest 缺失,无法列出具体值。 */\n kind: \"added\" | \"removed\" | \"changed\" | \"unknown\";\n /** 值或内容哈希的有界摘要;opaque 与新增/删除侧按缺省略。 */\n from?: string;\n to?: string;\n}\nexport interface JsonPlanFingerprintComparisonChanged {\n kind: \"changed\";\n deltas: [\n JsonPlanDelta,\n ...JsonPlanDelta[]\n ];\n}\nexport interface JsonPlanFingerprintComparisonUnexplained {\n kind: \"unexplained\";\n diagnostic: JsonPlanDiagnostic;\n}\nexport type JsonPlanDiagnosticFact = {\n label: string;\n value: JsonValue;\n} | {\n label: string;\n from: JsonValue;\n to: JsonValue;\n};\nexport interface JsonPlanDiagnostic {\n /** producer 命名空间内的开放 code;消费者不得按当前已知值穷举。 */\n code: string;\n /** 不依赖 code 才能读懂的单句摘要。 */\n summary: string;\n facts?: JsonPlanDiagnosticFact[];\n /** 省略=不可比较,[]=可比较字段未观察到差异,非空=观察到具名差异。 */\n observedDeltas?: JsonPlanDelta[];\n limitations?: string[];\n causes?: JsonPlanDiagnostic[];\n}\nexport type JsonPlanFingerprintComparison = JsonPlanFingerprintComparisonChanged | JsonPlanFingerprintComparisonUnexplained;\n/** 本行要派发的 attempt 按未携带原因分组(`ExpPlanDispatch`);gate 词表与六道门同名。 */\nexport interface JsonPlanDispatch {\n gate: \"fingerprint\" | \"terminal\" | \"eligibility\" | \"rerun\" | \"mode\" | \"missing\";\n /** 这组原因覆盖的 attempt 序号。 */\n attempts: number[];\n /** 指纹门的比较解释;其它 gate 省略。 */\n comparison?: JsonPlanFingerprintComparison;\n}\nexport interface JsonPlanRow {\n experimentId: string;\n evalId: string;\n evalGroupId?: string;\n /** 命中缓存指纹,本次不会派发新 attempt。 */\n reused: boolean;\n /** previous-result 历史结果。`acceptance: legacy-locator` 表示旧 locator 不符合当前命令语法,不能接受。 */\n prior?: readonly {\n locator: string;\n verdict: \"passed\" | \"failed\" | \"errored\" | \"skipped\";\n acceptance: \"available\" | \"legacy-locator\";\n evidenceState: \"local\" | \"borrowed\" | \"dangling\";\n }[];\n /** 本行要派发的 attempt 按未携带原因分组;全部携带时省略。 */\n dispatch?: JsonPlanDispatch[];\n /** 该用例正被另一条并行 Invocation 持锁运行,真实运行时将等待后携带或补跑(见\n * docs/feature/experiments/architecture.md「并发 Invocation:用例锁」)。`--dry` 只读锁\n * 目录,不取锁、不等待;省略等于 `false`(JSON.stringify 丢弃 `undefined` 属性,\n * 天然满足这条省略语义,不需要显式写 `locked: false`)。 */\n locked?: boolean;\n}\nexport interface JsonPlanInput {\n /** 与 `start` 事件同一口径的总 attempt 数。 */\n total: number;\n /** 去重后的 eval 数。 */\n evals: number;\n /** (agent, model, flags) 配置组合数。 */\n configs: number;\n /** 代表性的 `--attempts` 值(多个实验取值不同时,展示层不逐配置拆分——见 cli.md 未声明混合 attempts\n * 场景的展示规则,这里与 human/agent 既有的 dry 预览取同一个近似口径:最大值)。 */\n attempts: number;\n matrix: readonly JsonPlanRow[];\n}\n/**\n * `--dry --json`(cli.md:「一次完成的读取,不是事件流」)。dry run 不派发 attempt,没有\n * `RunFeedbackState` 可言,这是独立于 `FeedbackRenderer`/coordinator 的纯函数。\n */\nexport function renderJsonPlanDocument(input: JsonPlanInput): string {\n const reused = input.matrix.reduce((n, row) => n + (row.reused ? 1 : 0), 0);\n return `${JSON.stringify({\n format: EXP_PLAN_FORMAT,\n schemaVersion: EXP_PLAN_SCHEMA_VERSION,\n total: input.total,\n evals: input.evals,\n configs: input.configs,\n attempts: input.attempts,\n reused,\n matrix: input.matrix,\n })}\\n`;\n}\n"]}
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["json.ts"],"names":[],"mappings":"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","sourcesContent":["// JSON profile renderer(见 docs/feature/experiments/cli.md「机器怎么读:--json」与「事件与\n// 计划文档的 TypeScript 形状」)。合并了此前 agent.ts + ci.ts 两个 profile —— 逐项对照证实\n// agent 档/ci 档是同一消费者模型的两套参数(heartbeat 30/60s、失败展开上限 5/50、流路由、词法\n// 前缀……),没有模型差,见 memory/exp-output-two-forms-ruling.md。\n//\n// 目标读者是任何非交互解析者(coding agent、CI annotation adapter、脚本),不是人眼:\n// - 单一 stdout 上的 NDJSON 事件流,一行一个 JSON 对象,词法就是 JSON,没有自造 envelope\n// 语法。`stderr` 只留给 run 尚未建立前的 argv/config 错误(那些错误发生在 coordinator/renderer\n// 存在之前,根本不经过这个模块——所以这里没有任何写 `io.stderr` 的分支,不是遗漏)。\n// - 首行 `start` 携带 `format`/`schemaVersion` 标识整条流;其余事件不重复这两个字段。\n// - 失败/错误立即逐条追加,不做展开上限 suppression(机器逐事件消费,截断反而是信息损失,\n// 见 cli.md「'立即追加'也必须有上限」表:上限只约束人读文本)。\n// - 连续 30 秒没有永久事件才追加一条 `progress` 心跳;任意永久事件重置这个时钟。\n// - 事件形状按 `ExpEvent` 判别联合(判别字段 `event`)逐个实现,字段名复用 Record 词表\n// (locator/evalId/experimentId/phase/verdict),不为事件流发明第二套命名。\n//\n// 不实现 `clearDynamic`/`redrawDynamic`/`activity`/`onLifecycle`:JSON 流没有「动态区域」概念,\n// 不展示 active phase、不逐次输出 provisioning retry/backoff、不逐条打印 passed attempt —— 这些\n// 目标行为由「不实现对应可选钩子」天然满足(见 renderer.ts 的接口注释)。\n//\n// 为什么 diagnostic/budget-exhausted/interrupted/reporter-error 仍然去重(只在首次出现时追加)\n// 而 failure/error 不做 suppression:cli.md「什么动态更新,什么逐条追加」表把两者分成不同的行——\n// 「retry 耗尽、降级、budget 不可执行」是「去重后追加一次」的永久事件,「failed/errored + locator」\n// 是「立即追加,不设上限」的独立证据;`--json` 的「不做 suppression」只针对后者(每条失败一个\n// 有界事件),不是把去重规则也一起取消。\nimport type { FeedbackRenderer } from \"./renderer.ts\";\nimport type { FeedbackIO } from \"./io.ts\";\nimport type { DurableFeedbackEvent, InvocationCompletion, InvocationReceipt, InvocationSummary, LifecyclePhase, RunFeedbackState, } from \"../types.ts\";\nimport type { JsonValue, Verdict } from \"../../shared/types.ts\";\nimport { evalConclusionRows, type EvalConclusionRow } from \"./eval-conclusions.ts\";\n/** `ExpEvent`/`ExpPlanDocument` 的 `format`/`schemaVersion` —— 只在破坏性形状变更时递增\n * (见 cli.md「事件与计划文档的 TypeScript 形状」)。 */\nconst EXP_STREAM_FORMAT = \"niceeval.exp\";\nconst EXP_PLAN_FORMAT = \"niceeval.exp-plan\";\nconst SCHEMA_VERSION = 1;\nconst EXP_PLAN_SCHEMA_VERSION = 4;\n/** 连续无永久事件多久才追加一条 `progress` 心跳(cli.md「机器怎么读:--json」:「连续 30 秒\n * 没有这些永久事件,才追加一条 progress 心跳」——两者合并前分别是 30s/60s,统一取 30s)。 */\nconst JSON_HEARTBEAT_IDLE_MS = 30000;\nexport interface JsonRendererOptions {\n io: FeedbackIO;\n}\nexport interface StartEvent {\n format: typeof EXP_STREAM_FORMAT;\n schemaVersion: number;\n event: \"start\";\n total: number;\n configs: number;\n concurrency: number;\n experimentConcurrency?: Readonly<globalThis.Record<string, number>>;\n reused: number;\n}\nexport interface ProgressEvent {\n event: \"progress\";\n elapsedMs: number;\n total: number;\n reused: number;\n running: number;\n elsewhere: number;\n queued: number;\n passed: number;\n failed: number;\n errored: number;\n skipped: number;\n}\nexport interface FailureEvent {\n event: \"failure\";\n locator: string;\n evalId: string;\n experimentId: string;\n verdict: \"failed\" | \"errored\";\n fact: string;\n matcher?: string;\n expected?: JsonValue;\n received?: JsonValue;\n}\nexport interface ErrorEvent {\n event: \"error\";\n locator: string;\n evalId: string;\n experimentId: string;\n phase: LifecyclePhase;\n reason: string;\n}\ninterface EvalEventBase {\n event: \"eval\";\n locator: string;\n evalId: string;\n experimentId: string;\n verdict: Verdict;\n attempts: number;\n}\nexport type EvalEvent = EvalEventBase & ({\n passed: number;\n planned?: never;\n unstarted?: never;\n reason?: never;\n} | {\n passed?: never;\n planned: number;\n unstarted: number;\n reason: \"early_exit\";\n});\nexport interface KeptEvent {\n event: \"kept\";\n locator: string;\n evalId: string;\n attempt: number;\n verdict: Exclude<Verdict, \"skipped\">;\n provider: string;\n sandboxId: string;\n enter: string;\n}\nexport interface WarningEvent {\n event: \"warning\";\n code: string;\n level: \"warning\" | \"error\";\n message: string;\n phase?: LifecyclePhase;\n experimentId?: string;\n evalId?: string;\n planned?: number;\n errored?: number;\n}\nexport interface NoticeEvent {\n event: \"notice\";\n code: string;\n level: \"info\";\n message: string;\n phase?: LifecyclePhase;\n experimentId?: string;\n evalId?: string;\n resource?: \"case-lock\";\n previousPid?: number;\n previousHost?: string;\n}\nexport interface BudgetExhaustedEvent {\n event: \"budget_exhausted\";\n experimentId: string;\n spent: number;\n unstarted: number;\n}\nexport interface ReporterErrorEvent {\n event: \"reporter_error\";\n reporter: string;\n required: boolean;\n message: string;\n}\nexport interface InterruptedEvent {\n event: \"interrupted\";\n}\nexport interface JudgePrecheckEvent {\n event: \"judge_precheck\";\n status: \"started\" | \"done\" | \"failed\";\n durationMs?: number;\n}\nexport interface ExperimentSetupEvent {\n event: \"experiment_setup\";\n experimentId: string;\n status: \"started\" | \"done\" | \"failed\";\n durationMs?: number;\n}\nexport interface ExperimentTeardownEvent {\n event: \"experiment_teardown\";\n experimentId: string;\n status: \"started\" | \"done\" | \"failed\";\n durationMs?: number;\n}\nexport interface LockWaitEvent {\n event: \"lock_wait\";\n experimentId: string;\n evalId: string;\n status: \"started\" | \"resolved\";\n holderPid?: number;\n holderHost?: string;\n resolution?: \"carried\" | \"dispatched\";\n waitedMs?: number;\n}\n/** The final machine hand-off is the Record v1 receipt, without paths or snapshots. */\nexport interface ReceiptEvent {\n type: \"receipt\";\n receipt: InvocationReceipt;\n}\n/** `niceeval exp --json` 唯一公开事件词表;新增事件必须先进入已采纳文档与这个闭合联合。 */\nexport type ExpEvent = StartEvent | ProgressEvent | FailureEvent | ErrorEvent | EvalEvent | KeptEvent | NoticeEvent | WarningEvent | BudgetExhaustedEvent | ReporterErrorEvent | InterruptedEvent | JudgePrecheckEvent | ExperimentSetupEvent | ExperimentTeardownEvent | LockWaitEvent | ReceiptEvent;\nfunction writeEvent(io: FeedbackIO, event: ExpEvent): void {\n io.stdout.write(`${JSON.stringify(event)}\\n`);\n}\n/**\n * 创建 JSON profile 的 `FeedbackRenderer`。只用 `io.stdout` 写文本——`--json` 的全部正常事件\n * 走一个 stdout sink,不拆到 stderr(两个 OS stream 被 CI runner 或 agent 工具层分开缓冲时会\n * 打乱顺序,单流才能保证事件序就是发生序)。\n */\nexport function createJsonRenderer(options: JsonRendererOptions): FeedbackRenderer {\n const { io } = options;\n // 距上一次「有意义的输出」(任意一次永久事件)过了多久,用来判断要不要追加一条心跳;\n // 由 appendDurable 无条件更新——\"plan\" 本身就是第一次永久事件,天然把这个时钟从 0 开始计。\n let lastCheckpointAtMs = 0;\n // \"summary\" 与 \"receipt\" 是 coordinator.finish() 里连续 emit 的两个独立永久事件(中间不会插入\n // 其它事件)。先暂存 summary,receipt 到达时再写 eval 结论行与唯一的最终 receipt。\n let pendingSummary: InvocationSummary | undefined;\n function noteCheckpoint(atMs: number): void {\n lastCheckpointAtMs = atMs;\n }\n return {\n appendDurable(event, state) {\n switch (event.type) {\n case \"plan\": {\n noteCheckpoint(event.at);\n const { shape, reused, experimentConcurrency } = event.plan;\n writeEvent(io, {\n format: EXP_STREAM_FORMAT,\n schemaVersion: SCHEMA_VERSION,\n event: \"start\",\n total: shape.totalAttempts,\n configs: shape.configs,\n concurrency: shape.maxConcurrency,\n // 一个实验都没声明 maxConcurrency 时省略整个字段,不输出空对象(cli.md 的 StartEvent)。\n ...(experimentConcurrency && Object.keys(experimentConcurrency).length > 0\n ? { experimentConcurrency }\n : {}),\n reused,\n });\n return;\n }\n case \"failure\": {\n noteCheckpoint(event.at);\n writeFailureOrError(io, event);\n return;\n }\n case \"diagnostic\": {\n noteCheckpoint(event.at);\n if (!isFirstOccurrence(state, event.key))\n return; // 去重后只追加一次(cli.md)\n const phase = lifecyclePhaseField(event.data?.phase);\n // `code` 是 cli.md notice/warning 事件的稳定词法(`coordination-recovered` /\n // `dispatch-halted`),**不是**去重 key:去重 key 常把折叠身份编进去,原样\n // 透出会让消费方拿到一个每次运行都不同的 code、没法按值分支。折叠到哪一条实验/用例\n // 由下面的 experimentId/evalId 两个具名字段回答。\n const code = event.code ?? event.key;\n // 身份两字段:attempt 级诊断从 identity 取;运行级诊断(实验闸 / eval 闸这类不属于\n // 任何单条 attempt 的事实)不许伪造 identity,从 `data` 的同名字段取(见 ../types.ts\n // \"diagnostic\" 变体的 identity 注释)。\n const experimentId = event.identity?.experimentId ?? stringField(event.data?.experimentId);\n const evalId = event.identity?.evalId ?? stringField(event.data?.evalId);\n const planned = numberField(event.data?.planned);\n const errored = numberField(event.data?.errored);\n const common = {\n code,\n message: event.message,\n ...(phase !== undefined ? { phase } : {}),\n ...(experimentId !== undefined ? { experimentId } : {}),\n ...(evalId !== undefined ? { evalId } : {}),\n ...(planned !== undefined ? { planned } : {}),\n ...(errored !== undefined ? { errored } : {}),\n };\n if (event.severity === \"info\") {\n const resource = coordinationResourceField(event.data?.resource);\n const previousPid = numberField(event.data?.previousPid);\n const previousHost = stringField(event.data?.previousHost);\n writeEvent(io, {\n event: \"notice\",\n level: \"info\",\n ...common,\n ...(resource !== undefined ? { resource } : {}),\n ...(previousPid !== undefined ? { previousPid } : {}),\n ...(previousHost !== undefined ? { previousHost } : {}),\n });\n }\n else {\n writeEvent(io, { event: \"warning\", level: event.severity, ...common });\n }\n return;\n }\n case \"budget-exhausted\": {\n noteCheckpoint(event.at);\n if (!isFirstOccurrence(state, `budget-exhausted:${event.experimentId}`))\n return;\n writeEvent(io, {\n event: \"budget_exhausted\",\n experimentId: event.experimentId,\n spent: event.spent,\n unstarted: event.unstarted,\n });\n return;\n }\n case \"experiment-hook\": {\n noteCheckpoint(event.at);\n writeEvent(io, {\n event: event.hook === \"setup\" ? \"experiment_setup\" : \"experiment_teardown\",\n experimentId: event.experimentId,\n status: event.status,\n ...(event.durationMs !== undefined ? { durationMs: event.durationMs } : {}),\n });\n return;\n }\n case \"precheck\": {\n noteCheckpoint(event.at);\n writeEvent(io, {\n event: \"judge_precheck\",\n status: event.status,\n ...(event.durationMs !== undefined ? { durationMs: event.durationMs } : {}),\n });\n return;\n }\n case \"lock-wait\": {\n noteCheckpoint(event.at);\n writeEvent(io, {\n event: \"lock_wait\",\n experimentId: event.experimentId,\n evalId: event.evalId,\n status: event.status,\n ...(event.holderPid !== undefined ? { holderPid: event.holderPid } : {}),\n ...(event.holderHost !== undefined ? { holderHost: event.holderHost } : {}),\n // 折叠 carried/dispatched 两个内部计数为一个公开 resolution:仍有 attempt 需要真实\n // 派发(dispatched > 0)记 \"dispatched\",全部由携带满足才记 \"carried\"\n // (见 ../types.ts 里 DurableFeedbackEvent \"lock-wait\" 变体的字段注释)。\n ...(event.status === \"resolved\"\n ? { resolution: (event.dispatched ?? 0) > 0 ? \"dispatched\" : \"carried\" }\n : {}),\n ...(event.waitedMs !== undefined ? { waitedMs: event.waitedMs } : {}),\n });\n return;\n }\n case \"run-activity\": {\n // Run activity 只服务 human live 面;ExpEvent 的已采纳词表没有这一种事件。\n return;\n }\n case \"interrupted\": {\n noteCheckpoint(event.at);\n if (!isFirstOccurrence(state, \"interrupted\"))\n return;\n writeEvent(io, { event: \"interrupted\" });\n return;\n }\n case \"reporter-error\": {\n noteCheckpoint(event.at);\n if (!isFirstOccurrence(state, `reporter-error:${event.reporter}`))\n return;\n writeEvent(io, {\n event: \"reporter_error\",\n reporter: event.reporter,\n required: event.required,\n message: event.message,\n });\n return;\n }\n case \"summary\":\n pendingSummary = event.summary;\n return;\n case \"kept\": {\n if (event.verdict === \"skipped\") {\n throw new Error(\"A skipped attempt cannot own a retained sandbox\");\n }\n writeEvent(io, {\n event: \"kept\",\n locator: String(event.locator),\n evalId: event.identity.evalId,\n attempt: event.identity.attempt,\n verdict: event.verdict,\n provider: event.provider,\n sandboxId: event.sandboxId,\n enter: event.enter ?? `niceeval sandbox enter ${event.sandboxId.slice(0, 12)}`,\n });\n return;\n }\n case \"receipt\":\n writeEvalConclusions(io, pendingSummary, state);\n writeEvent(io, { type: \"receipt\", receipt: event.receipt });\n return;\n default: {\n // 穷尽性检查:新增 DurableFeedbackEvent 变体时这里编译期报错提醒补上对应分支。\n const exhaustive: never = event;\n return exhaustive;\n }\n }\n },\n onTick(event, state) {\n const idle = event.at - lastCheckpointAtMs;\n if (idle < JSON_HEARTBEAT_IDLE_MS)\n return;\n noteCheckpoint(event.at);\n writeEvent(io, {\n event: \"progress\",\n elapsedMs: event.elapsedMs,\n total: state.total,\n reused: state.reused,\n running: state.running,\n elsewhere: state.elsewhere,\n queued: state.queued,\n // 与 human 首行同一份状态、同一套划分:已了结的 attempt 按 verdict 分项,消费方不必\n // 自己从合计数里猜成败(契约见 docs/feature/experiments/cli.md 的 ProgressEvent)。\n passed: state.passed,\n failed: state.failed,\n errored: state.errored,\n skipped: state.skipped,\n });\n },\n // 没有 clearDynamic/redrawDynamic/activity/onLifecycle:见文件顶部注释——JSON 流不维护\n // 动态区域、不逐次输出 provisioning retry/backoff、不逐条展示 active phase 或 passed attempt。\n };\n}\n/** 某个去重 key 在 `state.diagnostics` 里是不是第一次出现(count === 1)。budget-exhausted /\n * interrupted / reporter-error 的去重 key 计算方式与 reducer.ts 完全一致(见该文件的\n * `budget-exhausted:${experimentId}` / `\"interrupted\"` / `reporter-error:${reporter}`)。 */\nfunction isFirstOccurrence(state: RunFeedbackState, key: string): boolean {\n return (state.diagnostics.find((d) => d.key === key)?.count ?? 0) <= 1;\n}\n/** `data` 里的一个字符串字段;非字符串(或缺失)一律当没有,不把数字/对象硬塞进只接受\n * 字符串的事件字段里。 */\nfunction stringField(value: JsonValue | undefined): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\nfunction numberField(value: JsonValue | undefined): number | undefined {\n return typeof value === \"number\" ? value : undefined;\n}\nfunction coordinationResourceField(value: JsonValue | undefined): NoticeEvent[\"resource\"] {\n return value === \"case-lock\" ? value : undefined;\n}\n/** 通知 data 是 JSON 边界;只有全局 LifecyclePhase 闭集成员才能进入 notice/warning phase。 */\nfunction lifecyclePhaseField(value: JsonValue | undefined): LifecyclePhase | undefined {\n switch (value) {\n case \"judge.precheck\":\n case \"experiment.setup\":\n case \"experiment.teardown\":\n case \"sandbox.queue\":\n case \"sandbox.create\":\n case \"sandbox.prepare\":\n case \"sandbox.prepare.eval\":\n case \"sandbox.prepare.group\":\n case \"sandbox.prepare.experiment\":\n case \"agent.ensure\":\n case \"workspace.baseline\":\n case \"agent.setup\":\n case \"telemetry.configure\":\n case \"eval.run\":\n case \"agent.run\":\n case \"workspace.diff\":\n case \"assertions.evaluate\":\n case \"telemetry.collect\":\n case \"agent.teardown\":\n case \"sandbox.cleanup\":\n case \"sandbox.suspend\":\n case \"sandbox.stop\":\n return value;\n default:\n return undefined;\n }\n}\n// ───────────────────────── failure / error 事件(不设上限) ─────────────────────────\nfunction writeFailureOrError(io: FeedbackIO, event: DurableFeedbackEvent & {\n type: \"failure\";\n}): void {\n const experimentId = requiredExperimentId(event.identity.experimentId, event.identity.evalId);\n const fact = event.fact;\n if (fact !== undefined) {\n writeEvent(io, {\n event: \"failure\",\n locator: String(event.locator),\n evalId: event.identity.evalId,\n experimentId,\n verdict: event.verdict,\n fact: fact.title,\n ...(fact.matcher !== undefined ? { matcher: fact.matcher } : {}),\n ...(fact.expected !== undefined ? { expected: fact.expected } : {}),\n ...(fact.received !== undefined ? { received: fact.received } : {}),\n });\n return;\n }\n if (event.verdict === \"errored\") {\n writeEvent(io, {\n event: \"error\",\n locator: String(event.locator),\n evalId: event.identity.evalId,\n experimentId,\n phase: event.phase ?? \"eval.run\",\n reason: event.reason,\n });\n return;\n }\n writeEvent(io, {\n event: \"failure\",\n locator: String(event.locator),\n evalId: event.identity.evalId,\n experimentId,\n verdict: event.verdict,\n fact: event.reason,\n });\n}\nfunction requiredExperimentId(experimentId: string | undefined, evalId: string): string {\n if (experimentId === undefined) {\n throw new Error(`JSON experiment event is missing experimentId for eval ${evalId}`);\n }\n return experimentId;\n}\n// ───────────────────────── 逐 eval 结论行(不设上限,写在 result 之前) ─────────────────────────\n/** 一条 `eval` 事件(cli.md「runs 与首过即停怎样展示」):字段随 earlyExit 是否触发在\n * planned/unstarted/reason 与 passed 两组间二选一,不同时出现两组字段。`rate` 是\n * `EvalConclusionRow` 派生出的额外读数,不在 `ExpEvent` 的 `EvalEvent` 形状里,这里不透出。 */\nfunction evalConclusionEvent(row: EvalConclusionRow): EvalEvent | undefined {\n const experimentId = requiredExperimentId(row.experimentId, row.evalId);\n if (row.locator === undefined) {\n // Pre-dispatch failures have no origin Attempt and therefore no locator.\n // `eval` events are locator-addressable conclusions, so the run-level\n // diagnostic and final result counts are their public projection.\n return undefined;\n }\n const base: EvalEventBase = {\n event: \"eval\",\n locator: row.locator,\n evalId: row.evalId,\n experimentId,\n verdict: row.verdict,\n attempts: row.attempts,\n };\n if (row.reason === \"early_exit\") {\n if (row.planned === undefined || row.unstarted === undefined) {\n throw new Error(`Early-exit eval event is missing planned counts for eval ${row.evalId}`);\n }\n return { ...base, planned: row.planned, unstarted: row.unstarted, reason: row.reason };\n }\n if (row.passed === undefined) {\n throw new Error(`Completed eval event is missing passed count for eval ${row.evalId}`);\n }\n return { ...base, passed: row.passed };\n}\nfunction writeEvalConclusions(io: FeedbackIO, pending: InvocationSummary | undefined, state: RunFeedbackState): void {\n if (!pending)\n return;\n const rows = evalConclusionRows(pending.results, state.earlyExitByEval, state.diagnostics);\n for (const row of rows) {\n const event = evalConclusionEvent(row);\n if (event !== undefined)\n writeEvent(io, event);\n }\n}\n// ───────────────────────── 退出码(CompletionStatus 驱动) ─────────────────────────\n/**\n * 把 `InvocationSummary` + `InvocationCompletion` 折成 CLI 退出码(cli.md「机器怎么读:--json」\n * 的退出码表)。纯函数,不看 CLI flag、不读 `process.env`;两种输出形态(human/json)共用同一套\n * 退出码,不是某一种 profile 专属——放在这个模块只是历史沿革(此前 `computeCiExitCode` 定义在\n * ci.ts,合并后更名为不带 profile 前缀的 `computeExitCode`)。\n *\n * 不在这里处理「2 = CLI/runner 未捕获崩溃」——那是进程级 uncaught exception/rejection 处理器\n * 的职责,不是「一次 run 正常收尾后该给什么退出码」的问题,不应该由 completion 驱动。\n */\nexport function computeExitCode(summary: InvocationSummary, completion: InvocationCompletion): number {\n if (completion.status === \"interrupted\")\n return 130;\n if (completion.status === \"incomplete\")\n return 1;\n if (completion.reporterErrors.some((e) => e.required))\n return 1;\n return summary.failed > 0 || summary.errored > 0 ? 1 : 0;\n}\n// ───────────────────────── `--dry --json`:单个 ExpPlanDocument,不是流 ─────────────────────────\n/** 一个 (experiment, eval) 组合在 `ExpPlanDocument.matrix` 里的一行(cli.md「`--dry --json`\n * 输出单个 `ExpPlanDocument`」)。 */\n/** 一条具名差异的机器面投影(`ExpPlanDelta`);selector 只解释本次指纹变化。 */\nexport interface JsonPlanDelta {\n /** 指纹差异词表:`config:<路径>` / `source:<路径>` / `data:<路径>` / `opaque:no-manifest`。 */\n selector: string;\n /** 差异方向。`unknown` 表示历史 manifest 缺失,无法列出具体值。 */\n kind: \"added\" | \"removed\" | \"changed\" | \"unknown\";\n /** 值或内容哈希的有界摘要;opaque 与新增/删除侧按缺省略。 */\n from?: string;\n to?: string;\n}\nexport interface JsonPlanFingerprintComparisonChanged {\n kind: \"changed\";\n deltas: [\n JsonPlanDelta,\n ...JsonPlanDelta[]\n ];\n}\nexport interface JsonPlanFingerprintComparisonUnexplained {\n kind: \"unexplained\";\n diagnostic: JsonPlanDiagnostic;\n}\nexport type JsonPlanDiagnosticFact = {\n label: string;\n value: JsonValue;\n} | {\n label: string;\n from: JsonValue;\n to: JsonValue;\n};\nexport interface JsonPlanDiagnostic {\n /** producer 命名空间内的开放 code;消费者不得按当前已知值穷举。 */\n code: string;\n /** 不依赖 code 才能读懂的单句摘要。 */\n summary: string;\n facts?: JsonPlanDiagnosticFact[];\n /** 省略=不可比较,[]=可比较字段未观察到差异,非空=观察到具名差异。 */\n observedDeltas?: JsonPlanDelta[];\n limitations?: string[];\n causes?: JsonPlanDiagnostic[];\n}\nexport type JsonPlanFingerprintComparison = JsonPlanFingerprintComparisonChanged | JsonPlanFingerprintComparisonUnexplained;\n/** 本行要派发的 attempt 按未携带原因分组(`ExpPlanDispatch`);gate 词表与六道门同名。 */\nexport interface JsonPlanDispatch {\n gate: \"fingerprint\" | \"terminal\" | \"eligibility\" | \"rerun\" | \"mode\" | \"missing\";\n /** 这组原因覆盖的 attempt 序号。 */\n attempts: number[];\n /** 指纹门的比较解释;其它 gate 省略。 */\n comparison?: JsonPlanFingerprintComparison;\n}\nexport interface JsonPlanRow {\n experimentId: string;\n evalId: string;\n evalGroupId?: string;\n /** 命中缓存指纹,本次不会派发新 attempt。 */\n reused: boolean;\n /** previous-result 历史结果。`acceptance: legacy-locator` 表示旧 locator 不符合当前命令语法,不能接受。 */\n prior?: readonly {\n locator: string;\n verdict: \"passed\" | \"failed\" | \"errored\" | \"skipped\";\n acceptance: \"available\" | \"legacy-locator\";\n evidenceState: \"local\" | \"borrowed\" | \"dangling\";\n }[];\n /** 本行要派发的 attempt 按未携带原因分组;全部携带时省略。 */\n dispatch?: JsonPlanDispatch[];\n /** 该用例正被另一条并行 Invocation 持锁运行,真实运行时将等待后携带或补跑(见\n * docs/feature/experiments/architecture.md「并发 Invocation:用例锁」)。`--dry` 只读锁\n * 目录,不取锁、不等待;省略等于 `false`(JSON.stringify 丢弃 `undefined` 属性,\n * 天然满足这条省略语义,不需要显式写 `locked: false`)。 */\n locked?: boolean;\n}\nexport interface JsonPlanInput {\n /** 与 `start` 事件同一口径的总 attempt 数。 */\n total: number;\n /** 去重后的 eval 数。 */\n evals: number;\n /** (agent, model, flags) 配置组合数。 */\n configs: number;\n /** 代表性的 `--attempts` 值(多个实验取值不同时,展示层不逐配置拆分——见 cli.md 未声明混合 attempts\n * 场景的展示规则,这里与 human/agent 既有的 dry 预览取同一个近似口径:最大值)。 */\n attempts: number;\n matrix: readonly JsonPlanRow[];\n}\n/**\n * `--dry --json`(cli.md:「一次完成的读取,不是事件流」)。dry run 不派发 attempt,没有\n * `RunFeedbackState` 可言,这是独立于 `FeedbackRenderer`/coordinator 的纯函数。\n */\nexport function renderJsonPlanDocument(input: JsonPlanInput): string {\n const reused = input.matrix.reduce((n, row) => n + (row.reused ? 1 : 0), 0);\n return `${JSON.stringify({\n format: EXP_PLAN_FORMAT,\n schemaVersion: EXP_PLAN_SCHEMA_VERSION,\n total: input.total,\n evals: input.evals,\n configs: input.configs,\n attempts: input.attempts,\n reused,\n matrix: input.matrix,\n })}\\n`;\n}\n"]}
@@ -87,6 +87,8 @@ export interface WarningEvent {
87
87
  phase?: LifecyclePhase;
88
88
  experimentId?: string;
89
89
  evalId?: string;
90
+ planned?: number;
91
+ errored?: number;
90
92
  }
91
93
  export interface NoticeEvent {
92
94
  event: "notice";
@@ -96,8 +98,7 @@ export interface NoticeEvent {
96
98
  phase?: LifecyclePhase;
97
99
  experimentId?: string;
98
100
  evalId?: string;
99
- resource?: "concurrency-slot" | "case-lock";
100
- slot?: number;
101
+ resource?: "case-lock";
101
102
  previousPid?: number;
102
103
  previousHost?: string;
103
104
  }
@@ -87,6 +87,8 @@ export interface WarningEvent {
87
87
  phase?: LifecyclePhase;
88
88
  experimentId?: string;
89
89
  evalId?: string;
90
+ planned?: number;
91
+ errored?: number;
90
92
  }
91
93
  export interface NoticeEvent {
92
94
  event: "notice";
@@ -96,8 +98,7 @@ export interface NoticeEvent {
96
98
  phase?: LifecyclePhase;
97
99
  experimentId?: string;
98
100
  evalId?: string;
99
- resource?: "concurrency-slot" | "case-lock";
100
- slot?: number;
101
+ resource?: "case-lock";
101
102
  previousPid?: number;
102
103
  previousHost?: string;
103
104
  }
@@ -87,6 +87,8 @@ export interface WarningEvent {
87
87
  phase?: LifecyclePhase;
88
88
  experimentId?: string;
89
89
  evalId?: string;
90
+ planned?: number;
91
+ errored?: number;
90
92
  }
91
93
  export interface NoticeEvent {
92
94
  event: "notice";
@@ -96,8 +98,7 @@ export interface NoticeEvent {
96
98
  phase?: LifecyclePhase;
97
99
  experimentId?: string;
98
100
  evalId?: string;
99
- resource?: "concurrency-slot" | "case-lock";
100
- slot?: number;
101
+ resource?: "case-lock";
101
102
  previousPid?: number;
102
103
  previousHost?: string;
103
104
  }
@@ -7,6 +7,7 @@ const eval_conclusions_ts_1 = require("./eval-conclusions.cjs");
7
7
  /** reducer 的起始状态:一个尚未收到任何事件的 run。 */
8
8
  function createInitialRunFeedbackState() {
9
9
  return {
10
+ runIdsByExperiment: new Map(),
10
11
  total: 0,
11
12
  reused: 0,
12
13
  running: 0,
@@ -38,6 +39,7 @@ function reduceRunFeedback(state, event) {
38
39
  // 多次 run 也不会把上一次的残留状态带进新 run(正常用法下 plan 本来就应是第一个事件)。
39
40
  return {
40
41
  ...state,
42
+ runIdsByExperiment: new Map(event.plan.shape.runIds ?? []),
41
43
  total,
42
44
  reused,
43
45
  // 全部非携入 attempt 在此刻就已知会被派发,先计入 queued;后续 attempt:start
@@ -1 +1 @@
1
- {"version":3,"file":"reducer.js","sourceRoot":"","sources":["reducer.ts"],"names":[],"mappings":"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","sourcesContent":["// 纯 reducer:RunFeedbackEvent → RunFeedbackState。计数、active slot、cost 累计、\n// failure/diagnostic 去重全部只在这里计算 —— human/json 两种 renderer 只读\n// RunFeedbackState,不各自维护第二份推导,也不解析 message 里的人类文案(结构化字段都在\n// DiagnosticNotice.data / FailureNotice 的具名字段上,见 ../types.ts 的类型注释)。\n//\n// `total = reused + running + elsewhere + queued + passed + failed + errored + skipped`\n//(八项恒等式,契约见 docs/feature/experiments/cli.md「等待并发 run 的显示」)在处理每一个事件\n// 之后都成立 —— 见 reducer.test.ts 的表驱动用例,每一步都断言这个不变量,不只在流程末尾断言\n// 一次。八项是互斥状态划分:每一次迁移都是「从一项减 x、往另一项加 x」的原子操作(plan →\n// queued;attempt:start queued→running;attempt:complete running→事件携带的 verdict 那一项;\n// attempt:early-exit 与 budget-exhausted queued→skipped;lock-wait started queued→elsewhere;\n// lock-wait resolved elsewhere→reused / elsewhere→queued),没有一个事件会让某条 attempt 同时\n// 落在两项里或凭空消失。emitter 侧的对应义务是「报进 elsewhere 多少条,就要报出来多少条」\n//(见 run.ts 的 recheckCarry)。\n//\n// 了结的 attempt 按 verdict 落项,不折进一个笼统的完成数:运行中最该被回答的问题是「到现在\n// 为止挂了几个」,一个合计数回答不了,而失败流事件会被后续输出顶出可视区。携入结果的 verdict\n// 不摊进这四项(留在 reused),否则 reused 会同时既是状态又是来源、恒等式失去意义。\n//\n// reducer 本身不读 Date.now()、不碰 process.stdout/stderr、不知道 profile 是 human/json ——\n// 纯函数 (state, event) => state,方便脱离真实 runner/terminal 单测。\nimport type { DiagnosticNotice, FailureNotice, RunFeedbackEvent, RunFeedbackState } from \"../types.ts\";\nimport { encodeAttemptKey } from \"../types.ts\";\nimport { evalConclusionKey } from \"./eval-conclusions.ts\";\n/** reducer 的起始状态:一个尚未收到任何事件的 run。 */\nexport function createInitialRunFeedbackState(): RunFeedbackState {\n return {\n total: 0,\n reused: 0,\n running: 0,\n elsewhere: 0,\n queued: 0,\n passed: 0,\n failed: 0,\n errored: 0,\n skipped: 0,\n earlyExitSkipped: 0,\n earlyExitByEval: new Map(),\n elapsedMs: 0,\n active: new Map(),\n experimentHooks: new Map(),\n lockWaits: new Map(),\n runActivities: new Map(),\n failures: [],\n freshFailureCount: 0,\n diagnostics: [],\n kept: [],\n };\n}\nexport function reduceRunFeedback(state: RunFeedbackState, event: RunFeedbackEvent): RunFeedbackState {\n switch (event.type) {\n case \"plan\": {\n const total = event.plan.shape.totalAttempts;\n const reused = event.plan.reused;\n // plan 是一次 run 的起点:重置 active/failures/diagnostics,即便 reducer 被复用于\n // 多次 run 也不会把上一次的残留状态带进新 run(正常用法下 plan 本来就应是第一个事件)。\n return {\n ...state,\n total,\n reused,\n // 全部非携入 attempt 在此刻就已知会被派发,先计入 queued;后续 attempt:start\n // 逐个把它们移进 running,不必等每条 attempt:queued 事件才累加(见类型注释)。\n queued: Math.max(0, total - reused),\n running: 0,\n elsewhere: 0,\n // 携入结果的 verdict 不摊进四项结局(它们留在 reused):plan 带 reusedFailures 时\n // failures 已经预置好供结束面板使用,但首行的结局计数此刻仍全为零。\n passed: 0,\n failed: 0,\n errored: 0,\n skipped: 0,\n active: new Map(),\n activePrecheck: undefined,\n experimentHooks: new Map(),\n lockWaits: new Map(),\n runActivities: new Map(),\n failures: (event.plan.reusedFailures ?? []).map((failure) => ({ ...failure, at: event.at })),\n freshFailureCount: 0,\n diagnostics: [],\n };\n }\n case \"tick\":\n return { ...state, elapsedMs: event.elapsedMs };\n case \"attempt:queued\":\n // 计数已经在 \"plan\" 时一次性算好(见上);逐 attempt 的 queued 通知保留调度身份与事件序,\n // 但不重复迁移 RunFeedbackState。\n return state;\n case \"attempt:start\": {\n const key = encodeAttemptKey(event.identity);\n const active = new Map(state.active);\n active.set(key, {\n identity: event.identity,\n who: event.who,\n phase: event.phase,\n // active 行时间列的基准只在这里写一次:一条 attempt 的时间从派发起算,之后的阶段推进\n // 只换标签不重置时钟(见 ActiveAttempt.startedAt 与下面的 attempt:phase 分支)。\n startedAt: event.at,\n });\n return {\n ...state,\n queued: state.queued - 1,\n running: state.running + 1,\n active,\n };\n }\n case \"attempt:phase\": {\n const key = encodeAttemptKey(event.identity);\n const existing = state.active.get(key);\n if (!existing)\n return state; // 防御:识别不到的 attempt 静默忽略,不让 renderer 崩\n const active = new Map(state.active);\n // 进入新 phase 清空旧 detail —— 次要文本是绑定到具体 phase 的(如 running 阶段的\n // \"tool: shell\"),不该原样带进下一个 phase 显示。`startedAt` 原样带过去(spread 保留):\n // 阶段边界换的是「正在干什么」,不是「这条跑了多久」。\n active.set(key, { ...existing, phase: event.phase, detail: undefined });\n return { ...state, active };\n }\n case \"attempt:progress\": {\n const key = encodeAttemptKey(event.identity);\n const existing = state.active.get(key);\n if (!existing)\n return state;\n const active = new Map(state.active);\n active.set(key, { ...existing, detail: event.detail });\n return { ...state, active };\n }\n case \"attempt:complete\": {\n const key = encodeAttemptKey(event.identity);\n const active = new Map(state.active);\n active.delete(key);\n const estimatedCostUSD = event.estimatedCostUSD === undefined\n ? state.estimatedCostUSD\n : state.estimatedCostUSD === undefined\n ? event.estimatedCostUSD\n : state.estimatedCostUSD + event.estimatedCostUSD;\n const newTokenCount = event.tokenCount === undefined\n ? state.newTokenCount\n : (state.newTokenCount ?? 0) + event.tokenCount;\n // 落项完全由事件携带的 verdict 决定 —— reducer 不自己判断成败(那是断言求值的事),\n // 也不留一个「已完成但未归类」的兜底项:Verdict 是四值闭集,穷尽覆盖。\n return {\n ...state,\n running: state.running - 1,\n [event.verdict]: state[event.verdict] + 1,\n active,\n newTokenCount,\n estimatedCostUSD,\n };\n }\n case \"precheck\": {\n // judge 预检运行级行的增删(见 cli.md「判分预检的显示」):started 建行,done / failed 清行\n // ——预检失败后受影响 eval 的逐条 errored 由 failure 事件解释,这行没有留下来的理由。\n // 不动 running/queued 计数——预检发生在派发之前,attempt 全程保持 queued,计数不变量不受影响。\n if (event.status === \"started\") {\n return { ...state, activePrecheck: { startedAt: event.at } };\n }\n const { activePrecheck: _cleared, ...rest } = state;\n return rest;\n }\n case \"experiment-hook\": {\n // 运行级行的增删:started 添加,done/failed 移除(见 cli.md「实验级 Hook 的显示」)。\n // 不动 running/queued 计数——等待 setup 的 attempt 保持 queued,计数不变量不受钩子影响。\n const experimentHooks = new Map(state.experimentHooks);\n if (event.status === \"started\") {\n experimentHooks.set(event.experimentId, {\n experimentId: event.experimentId,\n hook: event.hook,\n startedAt: event.at,\n ...(event.recovery !== undefined ? { recovery: event.recovery } : {}),\n });\n }\n else {\n experimentHooks.delete(event.experimentId);\n }\n return { ...state, experimentHooks };\n }\n case \"experiment:progress\": {\n const existing = state.experimentHooks.get(event.experimentId);\n if (!existing)\n return state; // 防御:没有对应运行级行时静默忽略,不让 renderer 崩\n const experimentHooks = new Map(state.experimentHooks);\n experimentHooks.set(event.experimentId, { ...existing, detail: event.detail });\n return { ...state, experimentHooks };\n }\n case \"lock-wait\": {\n // 粒度是单个 (experimentId, evalId):\"started\" 把这次撞锁需要等待的 attempt 数从\n // queued 移入 elsewhere,\"resolved\" 按 carried/dispatched 分别迁入 reused/queued——\n // 两者之和不必等于 \"started\" 时的 attempts(同一批等待可能分批 resolve,虽然当前\n // emitter 恒一次性给出全部,reducer 不假设这一点,只按事件携带的数字增减)。\n const existing = state.lockWaits.get(event.experimentId);\n // 上一个「有等待用例」窗口已经完全关闭(waiting 为空)时,新窗口的累计计数从零开始——\n // 不把上一窗口 resolved 的历史计数带进这一窗口的非 TTY 聚合收尾行。\n const priorWindowClosed = !existing || existing.waiting.size === 0;\n const lockWaits = new Map(state.lockWaits);\n if (event.status === \"started\") {\n const attempts = event.attempts ?? 1;\n const waiting = new Map(priorWindowClosed ? [] : existing!.waiting);\n waiting.set(event.evalId, {\n startedAt: event.at,\n ...(event.holderPid !== undefined ? { holderPid: event.holderPid } : {}),\n ...(event.holderHost !== undefined ? { holderHost: event.holderHost } : {}),\n });\n lockWaits.set(event.experimentId, {\n experimentId: event.experimentId,\n waiting,\n resolvedCarried: priorWindowClosed ? 0 : existing!.resolvedCarried,\n resolvedDispatched: priorWindowClosed ? 0 : existing!.resolvedDispatched,\n });\n return { ...state, queued: state.queued - attempts, elsewhere: state.elsewhere + attempts, lockWaits };\n }\n // \"resolved\":没有对应的等待条目时静默忽略(防御,同 experiment:progress 对未知\n // experimentId 的处理),不让一次乱序/重复事件把计数推负。\n if (!existing || !existing.waiting.has(event.evalId))\n return state;\n const carried = event.carried ?? 0;\n const dispatched = event.dispatched ?? 0;\n const waiting = new Map(existing.waiting);\n waiting.delete(event.evalId);\n lockWaits.set(event.experimentId, {\n experimentId: event.experimentId,\n waiting,\n resolvedCarried: existing.resolvedCarried + carried,\n resolvedDispatched: existing.resolvedDispatched + dispatched,\n });\n return {\n ...state,\n elsewhere: state.elsewhere - (carried + dispatched),\n reused: state.reused + carried,\n queued: state.queued + dispatched,\n lockWaits,\n };\n }\n case \"run-activity\": {\n // Run 级开放 activity 的运行级行增删:started 建行,done / failed 清行。\n // 不动 running/queued/elsewhere——共享准备不占 attempt 并发位(见 architecture.md\n // 「Run 级共享准备」)。人读标签走 event.label,不查 LifecyclePhase 锚点表。\n const runActivities = new Map(state.runActivities);\n if (event.status === \"started\") {\n runActivities.set(event.id, {\n id: event.id,\n key: event.key,\n label: event.label,\n startedAt: event.at,\n });\n }\n else {\n runActivities.delete(event.id);\n }\n return { ...state, runActivities };\n }\n case \"attempt:early-exit\": {\n // 首过即停下已知 verdict 的省略次数:折进 skipped —— 这一轮没跑,没有自己的 verdict,\n // 不冒充 passed(题目结论已经确定,但这条 attempt 本身没产出结论),也\n // 不产生 failures/diagnostics —— 这不是一次失败或异常,只是省下的重复验证\n // (真正「未完整覆盖」的信号来自 budget-exhausted / fail-fast diagnostic,不是这里)。\n // 同一份事件也用于 fail-fast 未派发(run.ts 两处调用同一个 \"attempt:early-exit\" 类型)——\n // earlyExitByEval 在这里按 (experiment, eval) 记的是原始计数,不剔除 fail-fast 份额;\n // `feedback/eval-conclusions.ts` 的 `evalConclusionRows` 消费时才对照 `state.diagnostics`\n // 里的 `fail-fast:` 记录减去那部分,不在 reducer 这一步做(reducer 只管纯计数,不掺业务\n // 判断,也避免依赖 run.ts 里两个事件的发出顺序这类隐式契约)。\n const key = evalConclusionKey(event.identity);\n const earlyExitByEval = new Map(state.earlyExitByEval);\n earlyExitByEval.set(key, (earlyExitByEval.get(key) ?? 0) + 1);\n return {\n ...state,\n queued: state.queued - 1,\n skipped: state.skipped + 1,\n earlyExitSkipped: state.earlyExitSkipped + 1,\n earlyExitByEval,\n };\n }\n case \"failure\": {\n const isFresh = !state.failures.some((failure) => failure.locator === event.locator);\n return {\n ...state,\n failures: upsertFailure(state.failures, {\n at: event.at,\n locator: event.locator,\n identity: event.identity,\n who: event.who,\n verdict: event.verdict,\n reason: event.reason,\n ...(event.fact !== undefined ? { fact: event.fact } : {}),\n ...(event.phase !== undefined ? { phase: event.phase } : {}),\n ...(event.code !== undefined ? { code: event.code } : {}),\n ...(event.origin !== undefined ? { origin: event.origin } : {}),\n }),\n freshFailureCount: state.freshFailureCount + (isFresh ? 1 : 0),\n };\n }\n case \"diagnostic\":\n return {\n ...state,\n diagnostics: upsertDiagnostic(state.diagnostics, {\n at: event.at,\n key: event.key,\n ...(event.code !== undefined ? { code: event.code } : {}),\n severity: event.severity,\n message: event.message,\n identity: event.identity,\n data: event.data,\n }),\n };\n case \"budget-exhausted\":\n // 约定:emitter 对每一个因 budget 到顶而不派发的 attempt 各发一次这个事件(与\n // attempt:early-exit 同构),所以每次触发在这里折进 skipped 一次 —— 不去信任\n // event.unstarted 的绝对值来算「这次要挪多少」(那需要 reducer 额外记住上一次的值,\n // 破坏纯 (state, event) => state 的最小状态原则)。event.unstarted / event.spent 仍然\n // 整体写进 diagnostic 的 data,供 json 直接读取当次快照值;真正的去重计数由\n // upsertDiagnostic 的 count 字段给出,天然等于「目前为止因 budget 未派发的次数」。\n return {\n ...state,\n queued: state.queued - 1,\n skipped: state.skipped + 1,\n diagnostics: upsertDiagnostic(state.diagnostics, {\n at: event.at,\n key: `budget-exhausted:${event.experimentId}`,\n severity: \"warning\",\n message: `budget exhausted for ${event.experimentId}`,\n data: { experimentId: event.experimentId, spent: event.spent, unstarted: event.unstarted },\n }),\n };\n case \"kept\":\n // 留存授予的永久通知:run 摘要后各 profile 追加输出(见 docs/feature/sandbox/cli.md)。\n return {\n ...state,\n kept: [\n ...state.kept,\n {\n at: event.at,\n locator: event.locator,\n identity: event.identity,\n who: event.who,\n verdict: event.verdict,\n provider: event.provider,\n sandboxId: event.sandboxId,\n ...(event.enter !== undefined ? { enter: event.enter } : {}),\n },\n ],\n };\n case \"interrupted\":\n return {\n ...state,\n diagnostics: upsertDiagnostic(state.diagnostics, {\n at: event.at,\n key: \"interrupted\",\n severity: \"warning\",\n message: \"run interrupted\",\n }),\n };\n case \"reporter-error\":\n return {\n ...state,\n diagnostics: upsertDiagnostic(state.diagnostics, {\n at: event.at,\n key: `reporter-error:${event.reporter}`,\n severity: event.required ? \"error\" : \"warning\",\n message: `reporter \"${event.reporter}\" failed: ${event.message}`,\n data: { reporter: event.reporter, required: event.required },\n }),\n };\n case \"summary\":\n case \"receipt\":\n // 终局通知:发出时 counts/active 已经由前面的 attempt 事件更新到位,状态本身不再变化——\n // 这两个事件的 payload(summary/completion/receipt)由 coordinator 直接使用,不经 reducer\n // 折叠进 RunFeedbackState(RunFeedbackState 是「当前进行中」的 dashboard 状态,不是终局报告)。\n return state;\n default: {\n // 穷尽性检查:新增 RunFeedbackEvent 变体时,这里会在编译期报错提醒补上对应分支。\n const exhaustive: never = event;\n return exhaustive;\n }\n }\n}\nfunction upsertFailure(failures: readonly FailureNotice[], notice: FailureNotice): readonly FailureNotice[] {\n // 同一 locator 理论上不该出现两次;真出现时按最新一次覆盖(幂等),而不是重复追加同一条失败。\n const idx = failures.findIndex((f) => f.locator === notice.locator);\n if (idx === -1)\n return [...failures, notice];\n const next = failures.slice();\n next[idx] = notice;\n return next;\n}\nfunction upsertDiagnostic(diagnostics: readonly DiagnosticNotice[], input: Omit<DiagnosticNotice, \"count\">): readonly DiagnosticNotice[] {\n const idx = diagnostics.findIndex((d) => d.key === input.key);\n if (idx === -1)\n return [...diagnostics, { ...input, count: 1 }];\n const next = diagnostics.slice();\n next[idx] = { ...input, count: next[idx].count + 1 };\n return next;\n}\n"]}
1
+ {"version":3,"file":"reducer.js","sourceRoot":"","sources":["reducer.ts"],"names":[],"mappings":"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","sourcesContent":["// 纯 reducer:RunFeedbackEvent → RunFeedbackState。计数、active slot、cost 累计、\n// failure/diagnostic 去重全部只在这里计算 —— human/json 两种 renderer 只读\n// RunFeedbackState,不各自维护第二份推导,也不解析 message 里的人类文案(结构化字段都在\n// DiagnosticNotice.data / FailureNotice 的具名字段上,见 ../types.ts 的类型注释)。\n//\n// `total = reused + running + elsewhere + queued + passed + failed + errored + skipped`\n//(八项恒等式,契约见 docs/feature/experiments/cli.md「等待并发 run 的显示」)在处理每一个事件\n// 之后都成立 —— 见 reducer.test.ts 的表驱动用例,每一步都断言这个不变量,不只在流程末尾断言\n// 一次。八项是互斥状态划分:每一次迁移都是「从一项减 x、往另一项加 x」的原子操作(plan →\n// queued;attempt:start queued→running;attempt:complete running→事件携带的 verdict 那一项;\n// attempt:early-exit 与 budget-exhausted queued→skipped;lock-wait started queued→elsewhere;\n// lock-wait resolved elsewhere→reused / elsewhere→queued),没有一个事件会让某条 attempt 同时\n// 落在两项里或凭空消失。emitter 侧的对应义务是「报进 elsewhere 多少条,就要报出来多少条」\n//(见 run.ts 的 recheckCarry)。\n//\n// 了结的 attempt 按 verdict 落项,不折进一个笼统的完成数:运行中最该被回答的问题是「到现在\n// 为止挂了几个」,一个合计数回答不了,而失败流事件会被后续输出顶出可视区。携入结果的 verdict\n// 不摊进这四项(留在 reused),否则 reused 会同时既是状态又是来源、恒等式失去意义。\n//\n// reducer 本身不读 Date.now()、不碰 process.stdout/stderr、不知道 profile 是 human/json ——\n// 纯函数 (state, event) => state,方便脱离真实 runner/terminal 单测。\nimport type { DiagnosticNotice, FailureNotice, RunFeedbackEvent, RunFeedbackState } from \"../types.ts\";\nimport { encodeAttemptKey } from \"../types.ts\";\nimport { evalConclusionKey } from \"./eval-conclusions.ts\";\n/** reducer 的起始状态:一个尚未收到任何事件的 run。 */\nexport function createInitialRunFeedbackState(): RunFeedbackState {\n return {\n runIdsByExperiment: new Map(),\n total: 0,\n reused: 0,\n running: 0,\n elsewhere: 0,\n queued: 0,\n passed: 0,\n failed: 0,\n errored: 0,\n skipped: 0,\n earlyExitSkipped: 0,\n earlyExitByEval: new Map(),\n elapsedMs: 0,\n active: new Map(),\n experimentHooks: new Map(),\n lockWaits: new Map(),\n runActivities: new Map(),\n failures: [],\n freshFailureCount: 0,\n diagnostics: [],\n kept: [],\n };\n}\nexport function reduceRunFeedback(state: RunFeedbackState, event: RunFeedbackEvent): RunFeedbackState {\n switch (event.type) {\n case \"plan\": {\n const total = event.plan.shape.totalAttempts;\n const reused = event.plan.reused;\n // plan 是一次 run 的起点:重置 active/failures/diagnostics,即便 reducer 被复用于\n // 多次 run 也不会把上一次的残留状态带进新 run(正常用法下 plan 本来就应是第一个事件)。\n return {\n ...state,\n runIdsByExperiment: new Map(event.plan.shape.runIds ?? []),\n total,\n reused,\n // 全部非携入 attempt 在此刻就已知会被派发,先计入 queued;后续 attempt:start\n // 逐个把它们移进 running,不必等每条 attempt:queued 事件才累加(见类型注释)。\n queued: Math.max(0, total - reused),\n running: 0,\n elsewhere: 0,\n // 携入结果的 verdict 不摊进四项结局(它们留在 reused):plan 带 reusedFailures 时\n // failures 已经预置好供结束面板使用,但首行的结局计数此刻仍全为零。\n passed: 0,\n failed: 0,\n errored: 0,\n skipped: 0,\n active: new Map(),\n activePrecheck: undefined,\n experimentHooks: new Map(),\n lockWaits: new Map(),\n runActivities: new Map(),\n failures: (event.plan.reusedFailures ?? []).map((failure) => ({ ...failure, at: event.at })),\n freshFailureCount: 0,\n diagnostics: [],\n };\n }\n case \"tick\":\n return { ...state, elapsedMs: event.elapsedMs };\n case \"attempt:queued\":\n // 计数已经在 \"plan\" 时一次性算好(见上);逐 attempt 的 queued 通知保留调度身份与事件序,\n // 但不重复迁移 RunFeedbackState。\n return state;\n case \"attempt:start\": {\n const key = encodeAttemptKey(event.identity);\n const active = new Map(state.active);\n active.set(key, {\n identity: event.identity,\n who: event.who,\n phase: event.phase,\n // active 行时间列的基准只在这里写一次:一条 attempt 的时间从派发起算,之后的阶段推进\n // 只换标签不重置时钟(见 ActiveAttempt.startedAt 与下面的 attempt:phase 分支)。\n startedAt: event.at,\n });\n return {\n ...state,\n queued: state.queued - 1,\n running: state.running + 1,\n active,\n };\n }\n case \"attempt:phase\": {\n const key = encodeAttemptKey(event.identity);\n const existing = state.active.get(key);\n if (!existing)\n return state; // 防御:识别不到的 attempt 静默忽略,不让 renderer 崩\n const active = new Map(state.active);\n // 进入新 phase 清空旧 detail —— 次要文本是绑定到具体 phase 的(如 running 阶段的\n // \"tool: shell\"),不该原样带进下一个 phase 显示。`startedAt` 原样带过去(spread 保留):\n // 阶段边界换的是「正在干什么」,不是「这条跑了多久」。\n active.set(key, { ...existing, phase: event.phase, detail: undefined });\n return { ...state, active };\n }\n case \"attempt:progress\": {\n const key = encodeAttemptKey(event.identity);\n const existing = state.active.get(key);\n if (!existing)\n return state;\n const active = new Map(state.active);\n active.set(key, { ...existing, detail: event.detail });\n return { ...state, active };\n }\n case \"attempt:complete\": {\n const key = encodeAttemptKey(event.identity);\n const active = new Map(state.active);\n active.delete(key);\n const estimatedCostUSD = event.estimatedCostUSD === undefined\n ? state.estimatedCostUSD\n : state.estimatedCostUSD === undefined\n ? event.estimatedCostUSD\n : state.estimatedCostUSD + event.estimatedCostUSD;\n const newTokenCount = event.tokenCount === undefined\n ? state.newTokenCount\n : (state.newTokenCount ?? 0) + event.tokenCount;\n // 落项完全由事件携带的 verdict 决定 —— reducer 不自己判断成败(那是断言求值的事),\n // 也不留一个「已完成但未归类」的兜底项:Verdict 是四值闭集,穷尽覆盖。\n return {\n ...state,\n running: state.running - 1,\n [event.verdict]: state[event.verdict] + 1,\n active,\n newTokenCount,\n estimatedCostUSD,\n };\n }\n case \"precheck\": {\n // judge 预检运行级行的增删(见 cli.md「判分预检的显示」):started 建行,done / failed 清行\n // ——预检失败后受影响 eval 的逐条 errored 由 failure 事件解释,这行没有留下来的理由。\n // 不动 running/queued 计数——预检发生在派发之前,attempt 全程保持 queued,计数不变量不受影响。\n if (event.status === \"started\") {\n return { ...state, activePrecheck: { startedAt: event.at } };\n }\n const { activePrecheck: _cleared, ...rest } = state;\n return rest;\n }\n case \"experiment-hook\": {\n // 运行级行的增删:started 添加,done/failed 移除(见 cli.md「实验级 Hook 的显示」)。\n // 不动 running/queued 计数——等待 setup 的 attempt 保持 queued,计数不变量不受钩子影响。\n const experimentHooks = new Map(state.experimentHooks);\n if (event.status === \"started\") {\n experimentHooks.set(event.experimentId, {\n experimentId: event.experimentId,\n hook: event.hook,\n startedAt: event.at,\n ...(event.recovery !== undefined ? { recovery: event.recovery } : {}),\n });\n }\n else {\n experimentHooks.delete(event.experimentId);\n }\n return { ...state, experimentHooks };\n }\n case \"experiment:progress\": {\n const existing = state.experimentHooks.get(event.experimentId);\n if (!existing)\n return state; // 防御:没有对应运行级行时静默忽略,不让 renderer 崩\n const experimentHooks = new Map(state.experimentHooks);\n experimentHooks.set(event.experimentId, { ...existing, detail: event.detail });\n return { ...state, experimentHooks };\n }\n case \"lock-wait\": {\n // 粒度是单个 (experimentId, evalId):\"started\" 把这次撞锁需要等待的 attempt 数从\n // queued 移入 elsewhere,\"resolved\" 按 carried/dispatched 分别迁入 reused/queued——\n // 两者之和不必等于 \"started\" 时的 attempts(同一批等待可能分批 resolve,虽然当前\n // emitter 恒一次性给出全部,reducer 不假设这一点,只按事件携带的数字增减)。\n const existing = state.lockWaits.get(event.experimentId);\n // 上一个「有等待用例」窗口已经完全关闭(waiting 为空)时,新窗口的累计计数从零开始——\n // 不把上一窗口 resolved 的历史计数带进这一窗口的非 TTY 聚合收尾行。\n const priorWindowClosed = !existing || existing.waiting.size === 0;\n const lockWaits = new Map(state.lockWaits);\n if (event.status === \"started\") {\n const attempts = event.attempts ?? 1;\n const waiting = new Map(priorWindowClosed ? [] : existing!.waiting);\n waiting.set(event.evalId, {\n startedAt: event.at,\n ...(event.holderPid !== undefined ? { holderPid: event.holderPid } : {}),\n ...(event.holderHost !== undefined ? { holderHost: event.holderHost } : {}),\n });\n lockWaits.set(event.experimentId, {\n experimentId: event.experimentId,\n waiting,\n resolvedCarried: priorWindowClosed ? 0 : existing!.resolvedCarried,\n resolvedDispatched: priorWindowClosed ? 0 : existing!.resolvedDispatched,\n });\n return { ...state, queued: state.queued - attempts, elsewhere: state.elsewhere + attempts, lockWaits };\n }\n // \"resolved\":没有对应的等待条目时静默忽略(防御,同 experiment:progress 对未知\n // experimentId 的处理),不让一次乱序/重复事件把计数推负。\n if (!existing || !existing.waiting.has(event.evalId))\n return state;\n const carried = event.carried ?? 0;\n const dispatched = event.dispatched ?? 0;\n const waiting = new Map(existing.waiting);\n waiting.delete(event.evalId);\n lockWaits.set(event.experimentId, {\n experimentId: event.experimentId,\n waiting,\n resolvedCarried: existing.resolvedCarried + carried,\n resolvedDispatched: existing.resolvedDispatched + dispatched,\n });\n return {\n ...state,\n elsewhere: state.elsewhere - (carried + dispatched),\n reused: state.reused + carried,\n queued: state.queued + dispatched,\n lockWaits,\n };\n }\n case \"run-activity\": {\n // Run 级开放 activity 的运行级行增删:started 建行,done / failed 清行。\n // 不动 running/queued/elsewhere——共享准备不占 attempt 并发位(见 architecture.md\n // 「Run 级共享准备」)。人读标签走 event.label,不查 LifecyclePhase 锚点表。\n const runActivities = new Map(state.runActivities);\n if (event.status === \"started\") {\n runActivities.set(event.id, {\n id: event.id,\n key: event.key,\n label: event.label,\n startedAt: event.at,\n });\n }\n else {\n runActivities.delete(event.id);\n }\n return { ...state, runActivities };\n }\n case \"attempt:early-exit\": {\n // 首过即停下已知 verdict 的省略次数:折进 skipped —— 这一轮没跑,没有自己的 verdict,\n // 不冒充 passed(题目结论已经确定,但这条 attempt 本身没产出结论),也\n // 不产生 failures/diagnostics —— 这不是一次失败或异常,只是省下的重复验证\n // (真正「未完整覆盖」的信号来自 budget-exhausted / fail-fast diagnostic,不是这里)。\n // 同一份事件也用于 fail-fast 未派发(run.ts 两处调用同一个 \"attempt:early-exit\" 类型)——\n // earlyExitByEval 在这里按 (experiment, eval) 记的是原始计数,不剔除 fail-fast 份额;\n // `feedback/eval-conclusions.ts` 的 `evalConclusionRows` 消费时才对照 `state.diagnostics`\n // 里的 `fail-fast:` 记录减去那部分,不在 reducer 这一步做(reducer 只管纯计数,不掺业务\n // 判断,也避免依赖 run.ts 里两个事件的发出顺序这类隐式契约)。\n const key = evalConclusionKey(event.identity);\n const earlyExitByEval = new Map(state.earlyExitByEval);\n earlyExitByEval.set(key, (earlyExitByEval.get(key) ?? 0) + 1);\n return {\n ...state,\n queued: state.queued - 1,\n skipped: state.skipped + 1,\n earlyExitSkipped: state.earlyExitSkipped + 1,\n earlyExitByEval,\n };\n }\n case \"failure\": {\n const isFresh = !state.failures.some((failure) => failure.locator === event.locator);\n return {\n ...state,\n failures: upsertFailure(state.failures, {\n at: event.at,\n locator: event.locator,\n identity: event.identity,\n who: event.who,\n verdict: event.verdict,\n reason: event.reason,\n ...(event.fact !== undefined ? { fact: event.fact } : {}),\n ...(event.phase !== undefined ? { phase: event.phase } : {}),\n ...(event.code !== undefined ? { code: event.code } : {}),\n ...(event.origin !== undefined ? { origin: event.origin } : {}),\n }),\n freshFailureCount: state.freshFailureCount + (isFresh ? 1 : 0),\n };\n }\n case \"diagnostic\":\n return {\n ...state,\n diagnostics: upsertDiagnostic(state.diagnostics, {\n at: event.at,\n key: event.key,\n ...(event.code !== undefined ? { code: event.code } : {}),\n severity: event.severity,\n message: event.message,\n identity: event.identity,\n data: event.data,\n }),\n };\n case \"budget-exhausted\":\n // 约定:emitter 对每一个因 budget 到顶而不派发的 attempt 各发一次这个事件(与\n // attempt:early-exit 同构),所以每次触发在这里折进 skipped 一次 —— 不去信任\n // event.unstarted 的绝对值来算「这次要挪多少」(那需要 reducer 额外记住上一次的值,\n // 破坏纯 (state, event) => state 的最小状态原则)。event.unstarted / event.spent 仍然\n // 整体写进 diagnostic 的 data,供 json 直接读取当次快照值;真正的去重计数由\n // upsertDiagnostic 的 count 字段给出,天然等于「目前为止因 budget 未派发的次数」。\n return {\n ...state,\n queued: state.queued - 1,\n skipped: state.skipped + 1,\n diagnostics: upsertDiagnostic(state.diagnostics, {\n at: event.at,\n key: `budget-exhausted:${event.experimentId}`,\n severity: \"warning\",\n message: `budget exhausted for ${event.experimentId}`,\n data: { experimentId: event.experimentId, spent: event.spent, unstarted: event.unstarted },\n }),\n };\n case \"kept\":\n // 留存授予的永久通知:run 摘要后各 profile 追加输出(见 docs/feature/sandbox/cli.md)。\n return {\n ...state,\n kept: [\n ...state.kept,\n {\n at: event.at,\n locator: event.locator,\n identity: event.identity,\n who: event.who,\n verdict: event.verdict,\n provider: event.provider,\n sandboxId: event.sandboxId,\n ...(event.enter !== undefined ? { enter: event.enter } : {}),\n },\n ],\n };\n case \"interrupted\":\n return {\n ...state,\n diagnostics: upsertDiagnostic(state.diagnostics, {\n at: event.at,\n key: \"interrupted\",\n severity: \"warning\",\n message: \"run interrupted\",\n }),\n };\n case \"reporter-error\":\n return {\n ...state,\n diagnostics: upsertDiagnostic(state.diagnostics, {\n at: event.at,\n key: `reporter-error:${event.reporter}`,\n severity: event.required ? \"error\" : \"warning\",\n message: `reporter \"${event.reporter}\" failed: ${event.message}`,\n data: { reporter: event.reporter, required: event.required },\n }),\n };\n case \"summary\":\n case \"receipt\":\n // 终局通知:发出时 counts/active 已经由前面的 attempt 事件更新到位,状态本身不再变化——\n // 这两个事件的 payload(summary/completion/receipt)由 coordinator 直接使用,不经 reducer\n // 折叠进 RunFeedbackState(RunFeedbackState 是「当前进行中」的 dashboard 状态,不是终局报告)。\n return state;\n default: {\n // 穷尽性检查:新增 RunFeedbackEvent 变体时,这里会在编译期报错提醒补上对应分支。\n const exhaustive: never = event;\n return exhaustive;\n }\n }\n}\nfunction upsertFailure(failures: readonly FailureNotice[], notice: FailureNotice): readonly FailureNotice[] {\n // 同一 locator 理论上不该出现两次;真出现时按最新一次覆盖(幂等),而不是重复追加同一条失败。\n const idx = failures.findIndex((f) => f.locator === notice.locator);\n if (idx === -1)\n return [...failures, notice];\n const next = failures.slice();\n next[idx] = notice;\n return next;\n}\nfunction upsertDiagnostic(diagnostics: readonly DiagnosticNotice[], input: Omit<DiagnosticNotice, \"count\">): readonly DiagnosticNotice[] {\n const idx = diagnostics.findIndex((d) => d.key === input.key);\n if (idx === -1)\n return [...diagnostics, { ...input, count: 1 }];\n const next = diagnostics.slice();\n next[idx] = { ...input, count: next[idx].count + 1 };\n return next;\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveJudge = resolveJudge;
4
4
  const DEFAULT_BASE_URL = "https://api.openai.com/v1";
5
- const DEFAULT_API_KEY_ENV = "OPENAI_API_KEY";
5
+ const DEFAULT_API_KEY_ENV = "NICEEVAL_JUDGE_KEY";
6
6
  const DEFAULT_TIMEOUT_MS = 180000;
7
7
  /**
8
8
  * Resolve Judge once for a declared Eval capability. `true` inherits the
@@ -1 +1 @@
1
- {"version":3,"file":"judge-config.js","sourceRoot":"","sources":["judge-config.ts"],"names":[],"mappings":";;AAUA,oCAYC;AArBD,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AACrD,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAC7C,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,eAAwC,EAAE,WAAyC,EAAE,WAAoC;IAClJ,IAAI,WAAW,KAAK,SAAS;QACzB,OAAO,SAAS,CAAC;IACrB,MAAM,SAAS,GAAG,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;IACjE,OAAO,MAAM,CAAC,MAAM,CAAC;QACjB,GAAG,CAAC,SAAS,EAAE,KAAK,IAAI,eAAe,EAAE,KAAK,IAAI,WAAW,EAAE,KAAK,CAAC,KAAK,SAAS;YAC/E,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,eAAe,EAAE,KAAK,IAAI,WAAW,EAAE,KAAK,EAAE;QACjF,OAAO,EAAE,SAAS,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,IAAI,gBAAgB;QACnG,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,eAAe,EAAE,SAAS,IAAI,WAAW,EAAE,SAAS,IAAI,mBAAmB;QAC9G,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,eAAe,EAAE,SAAS,IAAI,WAAW,EAAE,SAAS,IAAI,kBAAkB;KAChH,CAAC,CAAC;AACP,CAAC","sourcesContent":["import type { JudgeDeclaration, JudgeConfig, ResolvedJudgeConfig } from \"../types.ts\";\nconst DEFAULT_BASE_URL = \"https://api.openai.com/v1\";\nconst DEFAULT_API_KEY_ENV = \"OPENAI_API_KEY\";\nconst DEFAULT_TIMEOUT_MS = 180000;\n/**\n * Resolve Judge once for a declared Eval capability. `true` inherits the\n * Experiment and project configuration; an Eval object both declares the\n * capability and overrides those layers. The frozen result is the sole input\n * to fingerprinting, precheck, and evaluator execution.\n */\nexport function resolveJudge(experimentJudge: JudgeConfig | undefined, declaration: JudgeDeclaration | undefined, configJudge: JudgeConfig | undefined): ResolvedJudgeConfig | undefined {\n if (declaration === undefined)\n return undefined;\n const evalJudge = declaration === true ? undefined : declaration;\n return Object.freeze({\n ...(evalJudge?.model ?? experimentJudge?.model ?? configJudge?.model) === undefined\n ? {}\n : { model: evalJudge?.model ?? experimentJudge?.model ?? configJudge?.model },\n baseUrl: evalJudge?.baseUrl ?? experimentJudge?.baseUrl ?? configJudge?.baseUrl ?? DEFAULT_BASE_URL,\n apiKeyEnv: evalJudge?.apiKeyEnv ?? experimentJudge?.apiKeyEnv ?? configJudge?.apiKeyEnv ?? DEFAULT_API_KEY_ENV,\n timeoutMs: evalJudge?.timeoutMs ?? experimentJudge?.timeoutMs ?? configJudge?.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n });\n}\n"]}
1
+ {"version":3,"file":"judge-config.js","sourceRoot":"","sources":["judge-config.ts"],"names":[],"mappings":";;AAUA,oCAYC;AArBD,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AACrD,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;AACjD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,eAAwC,EAAE,WAAyC,EAAE,WAAoC;IAClJ,IAAI,WAAW,KAAK,SAAS;QACzB,OAAO,SAAS,CAAC;IACrB,MAAM,SAAS,GAAG,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;IACjE,OAAO,MAAM,CAAC,MAAM,CAAC;QACjB,GAAG,CAAC,SAAS,EAAE,KAAK,IAAI,eAAe,EAAE,KAAK,IAAI,WAAW,EAAE,KAAK,CAAC,KAAK,SAAS;YAC/E,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,eAAe,EAAE,KAAK,IAAI,WAAW,EAAE,KAAK,EAAE;QACjF,OAAO,EAAE,SAAS,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,IAAI,gBAAgB;QACnG,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,eAAe,EAAE,SAAS,IAAI,WAAW,EAAE,SAAS,IAAI,mBAAmB;QAC9G,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,eAAe,EAAE,SAAS,IAAI,WAAW,EAAE,SAAS,IAAI,kBAAkB;KAChH,CAAC,CAAC;AACP,CAAC","sourcesContent":["import type { JudgeDeclaration, JudgeConfig, ResolvedJudgeConfig } from \"../types.ts\";\nconst DEFAULT_BASE_URL = \"https://api.openai.com/v1\";\nconst DEFAULT_API_KEY_ENV = \"NICEEVAL_JUDGE_KEY\";\nconst DEFAULT_TIMEOUT_MS = 180000;\n/**\n * Resolve Judge once for a declared Eval capability. `true` inherits the\n * Experiment and project configuration; an Eval object both declares the\n * capability and overrides those layers. The frozen result is the sole input\n * to fingerprinting, precheck, and evaluator execution.\n */\nexport function resolveJudge(experimentJudge: JudgeConfig | undefined, declaration: JudgeDeclaration | undefined, configJudge: JudgeConfig | undefined): ResolvedJudgeConfig | undefined {\n if (declaration === undefined)\n return undefined;\n const evalJudge = declaration === true ? undefined : declaration;\n return Object.freeze({\n ...(evalJudge?.model ?? experimentJudge?.model ?? configJudge?.model) === undefined\n ? {}\n : { model: evalJudge?.model ?? experimentJudge?.model ?? configJudge?.model },\n baseUrl: evalJudge?.baseUrl ?? experimentJudge?.baseUrl ?? configJudge?.baseUrl ?? DEFAULT_BASE_URL,\n apiKeyEnv: evalJudge?.apiKeyEnv ?? experimentJudge?.apiKeyEnv ?? configJudge?.apiKeyEnv ?? DEFAULT_API_KEY_ENV,\n timeoutMs: evalJudge?.timeoutMs ?? experimentJudge?.timeoutMs ?? configJudge?.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n });\n}\n"]}