niceeval 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/INDEX.md +31 -33
  2. package/dist/agents/types.d.ts +20 -17
  3. package/dist/context/types.d.ts +21 -21
  4. package/dist/i18n/en.d.ts +10 -2
  5. package/dist/i18n/zh-CN.d.ts +15 -7
  6. package/dist/o11y/execution-tree.d.ts +103 -0
  7. package/dist/o11y/otlp/select.d.ts +22 -0
  8. package/dist/report/{react → assets}/colors.d.ts +8 -0
  9. package/dist/report/{react → assets}/colors.js +23 -0
  10. package/dist/report/built-in/index.d.ts +2 -2
  11. package/dist/report/built-in/index.js +2 -2
  12. package/dist/report/built-in/standard.d.ts +8 -1
  13. package/dist/report/built-in/standard.js +17 -7
  14. package/dist/report/components/attempt-detail/AttemptAssertions.d.ts +6 -0
  15. package/dist/report/components/attempt-detail/AttemptAssertions.js +17 -0
  16. package/dist/report/components/attempt-detail/AttemptConversation.d.ts +6 -0
  17. package/dist/report/components/attempt-detail/AttemptConversation.js +34 -0
  18. package/dist/report/components/attempt-detail/AttemptDiagnostics.d.ts +6 -0
  19. package/dist/report/components/attempt-detail/AttemptDiagnostics.js +7 -0
  20. package/dist/report/components/attempt-detail/AttemptDiff.d.ts +6 -0
  21. package/dist/report/components/attempt-detail/AttemptDiff.js +11 -0
  22. package/dist/report/components/attempt-detail/AttemptError.d.ts +6 -0
  23. package/dist/report/components/attempt-detail/AttemptError.js +16 -0
  24. package/dist/report/components/attempt-detail/AttemptFixPrompt.d.ts +6 -0
  25. package/dist/report/components/attempt-detail/AttemptFixPrompt.js +7 -0
  26. package/dist/report/components/attempt-detail/AttemptSource.d.ts +6 -0
  27. package/dist/report/components/attempt-detail/AttemptSource.js +27 -0
  28. package/dist/report/components/attempt-detail/AttemptSummary.d.ts +8 -0
  29. package/dist/report/components/attempt-detail/AttemptSummary.js +20 -0
  30. package/dist/report/components/attempt-detail/AttemptTimeline.d.ts +6 -0
  31. package/dist/report/components/attempt-detail/AttemptTimeline.js +28 -0
  32. package/dist/report/components/attempt-detail/AttemptTrace.d.ts +6 -0
  33. package/dist/report/components/attempt-detail/AttemptTrace.js +29 -0
  34. package/dist/report/components/attempt-detail/AttemptUsage.d.ts +6 -0
  35. package/dist/report/components/attempt-detail/AttemptUsage.js +20 -0
  36. package/dist/report/components/attempt-detail/compute.d.ts +24 -0
  37. package/dist/report/components/attempt-detail/compute.js +254 -0
  38. package/dist/report/components/attempt-detail/faces.d.ts +14 -0
  39. package/dist/report/components/attempt-detail/faces.js +235 -0
  40. package/dist/report/components/attempt-detail/index.d.ts +38 -0
  41. package/dist/report/components/attempt-detail/index.js +527 -0
  42. package/dist/report/{react → components}/cell.d.ts +5 -3
  43. package/dist/report/{react → components}/cell.js +3 -3
  44. package/dist/report/{react → components/entity-lists}/AttemptList.d.ts +8 -4
  45. package/dist/report/{react → components/entity-lists}/AttemptList.js +16 -10
  46. package/dist/report/{react → components/entity-lists}/EvalList.d.ts +3 -3
  47. package/dist/report/{react → components/entity-lists}/EvalList.js +0 -0
  48. package/dist/report/{react → components/entity-lists}/ExperimentList.d.ts +3 -3
  49. package/dist/report/{react → components/entity-lists}/ExperimentList.js +10 -10
  50. package/dist/report/components/entity-lists/compute.d.ts +23 -0
  51. package/dist/report/components/entity-lists/compute.js +171 -0
  52. package/dist/report/components/entity-lists/faces.d.ts +5 -0
  53. package/dist/report/components/entity-lists/faces.js +174 -0
  54. package/dist/report/components/entity-lists/index.d.ts +51 -0
  55. package/dist/report/components/entity-lists/index.js +165 -0
  56. package/dist/report/{react → components}/fixtures.d.ts +2 -2
  57. package/dist/report/{react → components}/fixtures.js +1 -1
  58. package/dist/report/{react → components/metric-views}/DeltaTable.d.ts +2 -2
  59. package/dist/report/{react → components/metric-views}/DeltaTable.js +4 -4
  60. package/dist/report/{react → components/metric-views}/MetricBars.d.ts +3 -3
  61. package/dist/report/{react → components/metric-views}/MetricBars.js +3 -3
  62. package/dist/report/{react → components/metric-views}/MetricLine.d.ts +2 -2
  63. package/dist/report/{react → components/metric-views}/MetricLine.js +8 -5
  64. package/dist/report/{react → components/metric-views}/MetricMatrix.d.ts +3 -3
  65. package/dist/report/{react → components/metric-views}/MetricMatrix.js +4 -4
  66. package/dist/report/components/metric-views/MetricScatter.d.ts +11 -0
  67. package/dist/report/{react → components/metric-views}/MetricScatter.js +26 -23
  68. package/dist/report/{react → components/metric-views}/MetricTable.d.ts +3 -3
  69. package/dist/report/{react → components/metric-views}/MetricTable.js +4 -4
  70. package/dist/report/{react → components/metric-views}/Scoreboard.d.ts +2 -2
  71. package/dist/report/{react → components/metric-views}/Scoreboard.js +3 -3
  72. package/dist/report/components/metric-views/compute.d.ts +89 -0
  73. package/dist/report/{compute.js → components/metric-views/compute.js} +32 -415
  74. package/dist/report/components/metric-views/faces.d.ts +13 -0
  75. package/dist/report/components/metric-views/faces.js +381 -0
  76. package/dist/report/components/metric-views/index.d.ts +50 -0
  77. package/dist/report/components/metric-views/index.js +273 -0
  78. package/dist/report/{text → components/metric-views}/plot.js +1 -1
  79. package/dist/report/components/shared-compute.d.ts +22 -0
  80. package/dist/report/components/shared-compute.js +47 -0
  81. package/dist/report/components/shared-faces.d.ts +9 -0
  82. package/dist/report/components/shared-faces.js +26 -0
  83. package/dist/report/components/shared.d.ts +68 -0
  84. package/dist/report/components/shared.js +125 -0
  85. package/dist/report/{react → components/site-components}/CopyFixPrompt.d.ts +2 -2
  86. package/dist/report/{react → components/site-components}/CopyFixPrompt.js +2 -2
  87. package/dist/report/{react → components/site-components}/HeroCard.d.ts +2 -2
  88. package/dist/report/{react → components/site-components}/HeroCard.js +2 -2
  89. package/dist/report/{react → components/site-components}/ScopeWarnings.d.ts +2 -2
  90. package/dist/report/{react → components/site-components}/ScopeWarnings.js +3 -3
  91. package/dist/report/{react → components/site-components}/TraceWaterfall.d.ts +3 -3
  92. package/dist/report/{react → components/site-components}/TraceWaterfall.js +5 -5
  93. package/dist/report/components/site-components/compute.d.ts +28 -0
  94. package/dist/report/components/site-components/compute.js +132 -0
  95. package/dist/report/components/site-components/faces.d.ts +21 -0
  96. package/dist/report/components/site-components/faces.js +75 -0
  97. package/dist/report/components/site-components/index.d.ts +74 -0
  98. package/dist/report/components/site-components/index.js +220 -0
  99. package/dist/report/{scope-warnings.d.ts → components/site-components/scope-warnings.d.ts} +2 -2
  100. package/dist/report/{scope-warnings.js → components/site-components/scope-warnings.js} +2 -2
  101. package/dist/report/{react → components/summaries}/ScopeSummary.d.ts +2 -2
  102. package/dist/report/{react → components/summaries}/ScopeSummary.js +17 -8
  103. package/dist/report/components/summaries/compute.d.ts +7 -0
  104. package/dist/report/components/summaries/compute.js +51 -0
  105. package/dist/report/components/summaries/faces.d.ts +7 -0
  106. package/dist/report/components/summaries/faces.js +38 -0
  107. package/dist/report/components/summaries/index.d.ts +27 -0
  108. package/dist/report/components/summaries/index.js +78 -0
  109. package/dist/report/definition/grid-layout.d.ts +50 -0
  110. package/dist/report/definition/grid-layout.js +89 -0
  111. package/dist/report/{primitives.d.ts → definition/primitives.d.ts} +34 -4
  112. package/dist/report/{primitives.js → definition/primitives.js} +101 -10
  113. package/dist/report/{report.d.ts → definition/report.d.ts} +36 -65
  114. package/dist/report/{report.js → definition/report.js} +58 -90
  115. package/dist/report/{text/table.d.ts → definition/table-text.d.ts} +2 -2
  116. package/dist/report/{text/table.js → definition/table-text.js} +2 -2
  117. package/dist/report/{tree.d.ts → definition/tree.d.ts} +44 -12
  118. package/dist/report/{tree.js → definition/tree.js} +10 -12
  119. package/dist/report/index.d.ts +33 -18
  120. package/dist/report/index.js +23 -14
  121. package/dist/report/{aggregate.d.ts → model/aggregate.d.ts} +12 -4
  122. package/dist/report/{aggregate.js → model/aggregate.js} +28 -8
  123. package/dist/report/{flag.d.ts → model/flag.d.ts} +14 -1
  124. package/dist/report/{flag.js → model/flag.js} +35 -0
  125. package/dist/report/{format.d.ts → model/format.d.ts} +11 -5
  126. package/dist/report/{format.js → model/format.js} +48 -4
  127. package/dist/report/{locale.d.ts → model/locale.d.ts} +17 -17
  128. package/dist/report/{locale.js → model/locale.js} +31 -33
  129. package/dist/report/{metrics.d.ts → model/metrics.d.ts} +2 -2
  130. package/dist/report/{metrics.js → model/metrics.js} +2 -2
  131. package/dist/report/{types.d.ts → model/types.d.ts} +140 -20
  132. package/dist/report/react/index.d.ts +32 -21
  133. package/dist/report/react/index.js +33 -21
  134. package/dist/report/{load.d.ts → runtime/load.d.ts} +1 -1
  135. package/dist/report/{load.js → runtime/load.js} +1 -1
  136. package/dist/report/runtime/text.d.ts +67 -0
  137. package/dist/report/runtime/text.js +114 -0
  138. package/dist/report/runtime/web.d.ts +35 -0
  139. package/dist/report/runtime/web.js +70 -0
  140. package/dist/results/annotated-source.d.ts +87 -0
  141. package/dist/results/attempt-evidence.d.ts +74 -0
  142. package/dist/results/attempt-source.d.ts +15 -0
  143. package/dist/results/select.d.ts +12 -2
  144. package/dist/results/select.js +27 -5
  145. package/dist/runner/eval-selection.d.ts +26 -0
  146. package/dist/runner/feedback/sink.d.ts +26 -1
  147. package/dist/runner/types.d.ts +149 -23
  148. package/dist/sandbox/docker.d.ts +6 -0
  149. package/dist/sandbox/types.d.ts +23 -21
  150. package/dist/scoring/display.d.ts +7 -2
  151. package/dist/scoring/display.js +42 -4
  152. package/dist/scoring/types.d.ts +3 -3
  153. package/dist/shared/aggregate.d.ts +15 -1
  154. package/dist/shared/aggregate.js +32 -1
  155. package/dist/shared/types.d.ts +6 -1
  156. package/docs-site/images/logo-dark.svg +7 -0
  157. package/docs-site/images/logo.svg +6 -5
  158. package/docs-site/zh/README.md +8 -7
  159. package/docs-site/zh/examples/ai-agent-application.mdx +5 -5
  160. package/docs-site/zh/examples/coding-agent-extensions.mdx +4 -4
  161. package/docs-site/zh/examples/index.mdx +3 -3
  162. package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +1 -1
  163. package/docs-site/zh/examples/integrations/claude-sdk.mdx +3 -3
  164. package/docs-site/zh/examples/integrations/codex-sdk.mdx +3 -3
  165. package/docs-site/zh/examples/integrations/langgraph.mdx +3 -3
  166. package/docs-site/zh/examples/integrations/pi-sdk.mdx +2 -2
  167. package/docs-site/zh/explanation/adapter.mdx +19 -19
  168. package/docs-site/zh/explanation/assert.mdx +9 -9
  169. package/docs-site/zh/explanation/drive.mdx +4 -4
  170. package/docs-site/zh/explanation/evals.mdx +8 -8
  171. package/docs-site/zh/explanation/experiment.mdx +8 -8
  172. package/docs-site/zh/explanation/hitl.mdx +13 -13
  173. package/docs-site/zh/explanation/judge.mdx +3 -3
  174. package/docs-site/zh/explanation/overview.mdx +7 -7
  175. package/docs-site/zh/explanation/runner.mdx +11 -11
  176. package/docs-site/zh/explanation/tier.mdx +6 -6
  177. package/docs-site/zh/index.mdx +14 -14
  178. package/docs-site/zh/introduction.mdx +13 -16
  179. package/docs-site/zh/reference/builtin-agents.mdx +61 -28
  180. package/docs-site/zh/reference/capabilities.mdx +7 -27
  181. package/docs-site/zh/reference/cli.mdx +35 -32
  182. package/docs-site/zh/reference/define-agent.mdx +32 -31
  183. package/docs-site/zh/reference/define-config.mdx +6 -6
  184. package/docs-site/zh/reference/define-eval.mdx +33 -20
  185. package/docs-site/zh/reference/events.mdx +4 -4
  186. package/docs-site/zh/reference/expect.mdx +3 -3
  187. package/docs-site/zh/reference/official-adapters.mdx +17 -17
  188. package/docs-site/zh/reference/report-components.mdx +193 -121
  189. package/docs-site/zh/reference/results-data.mdx +13 -13
  190. package/docs-site/zh/troubleshooting/debug-sandbox.mdx +11 -11
  191. package/docs-site/zh/troubleshooting/debugging.mdx +43 -19
  192. package/docs-site/zh/{how-to → tutorials}/agent-feedback-loop.mdx +38 -38
  193. package/docs-site/zh/tutorials/agent-onboarding.mdx +100 -0
  194. package/docs-site/zh/tutorials/authoring.mdx +211 -0
  195. package/docs-site/zh/{how-to → tutorials}/ci-integration.mdx +8 -8
  196. package/docs-site/zh/{how-to → tutorials}/connect-otel.mdx +22 -22
  197. package/docs-site/zh/{how-to → tutorials}/connect-your-agent.mdx +58 -63
  198. package/docs-site/zh/tutorials/custom-reports.mdx +453 -0
  199. package/docs-site/zh/{how-to → tutorials}/dataset-fanout.mdx +4 -4
  200. package/docs-site/zh/tutorials/experiments.mdx +103 -0
  201. package/docs-site/zh/{how-to → tutorials}/fixtures.mdx +9 -9
  202. package/docs-site/zh/{how-to → tutorials}/publish-report.mdx +11 -5
  203. package/docs-site/zh/tutorials/quickstart.mdx +18 -18
  204. package/docs-site/zh/{how-to → tutorials}/reporters.mdx +6 -6
  205. package/docs-site/zh/{how-to → tutorials}/sandbox-agent.mdx +6 -6
  206. package/docs-site/zh/{how-to → tutorials}/sandbox-providers.mdx +41 -19
  207. package/docs-site/zh/{how-to → tutorials}/scoring-guide.mdx +4 -4
  208. package/docs-site/zh/{how-to → tutorials}/viewing-results.mdx +59 -50
  209. package/docs-site/zh/tutorials/write-experiment.mdx +355 -0
  210. package/docs-site/zh/{how-to → tutorials}/write-send.mdx +40 -40
  211. package/package.json +8 -4
  212. package/src/agents/bub.ts +21 -8
  213. package/src/agents/claude-code.ts +23 -10
  214. package/src/agents/codex.test.ts +22 -7
  215. package/src/agents/codex.ts +22 -9
  216. package/src/agents/index.ts +2 -2
  217. package/src/agents/openai-compat.ts +1 -1
  218. package/src/agents/post-setup.ts +45 -22
  219. package/src/agents/streaming.ts +1 -1
  220. package/src/agents/types.ts +20 -17
  221. package/src/agents/ui-message-stream.test.ts +10 -0
  222. package/src/agents/ui-message-stream.ts +12 -1
  223. package/src/cli.ts +77 -64
  224. package/src/context/types.ts +21 -21
  225. package/src/define.ts +13 -0
  226. package/src/i18n/en.ts +30 -15
  227. package/src/i18n/zh-CN.ts +30 -15
  228. package/src/index.ts +2 -0
  229. package/src/report/{react → assets}/colors.ts +22 -0
  230. package/src/report/{react → assets}/enhance.js +1 -33
  231. package/src/report/{react → assets}/styles.css +136 -112
  232. package/src/report/built-in/index.tsx +2 -2
  233. package/src/report/built-in/standard.tsx +18 -6
  234. package/src/report/components/attempt-detail/AttemptAssertions.tsx +67 -0
  235. package/src/report/components/attempt-detail/AttemptConversation.tsx +110 -0
  236. package/src/report/components/attempt-detail/AttemptDiagnostics.tsx +38 -0
  237. package/src/report/components/attempt-detail/AttemptDiff.tsx +35 -0
  238. package/src/report/components/attempt-detail/AttemptError.tsx +31 -0
  239. package/src/report/components/attempt-detail/AttemptFixPrompt.tsx +26 -0
  240. package/src/report/components/attempt-detail/AttemptSource.tsx +80 -0
  241. package/src/report/components/attempt-detail/AttemptSummary.tsx +74 -0
  242. package/src/report/components/attempt-detail/AttemptTimeline.tsx +108 -0
  243. package/src/report/components/attempt-detail/AttemptTrace.tsx +63 -0
  244. package/src/report/components/attempt-detail/AttemptUsage.tsx +29 -0
  245. package/src/report/components/attempt-detail/attempt-components.test.tsx +680 -0
  246. package/src/report/components/attempt-detail/compute.ts +287 -0
  247. package/src/report/components/attempt-detail/faces.ts +257 -0
  248. package/src/report/components/attempt-detail/index.tsx +583 -0
  249. package/src/report/components/attempt-detail/validate.test.ts +235 -0
  250. package/src/report/{react → components}/cell.tsx +6 -3
  251. package/src/report/{report.test.ts → components/compute.test.ts} +316 -46
  252. package/src/report/{react → components/entity-lists}/AttemptList.tsx +24 -16
  253. package/src/report/{react → components/entity-lists}/EvalList.tsx +0 -0
  254. package/src/report/{react → components/entity-lists}/ExperimentList.tsx +23 -20
  255. package/src/report/components/entity-lists/compute.ts +196 -0
  256. package/src/report/components/entity-lists/faces.ts +207 -0
  257. package/src/report/components/entity-lists/index.tsx +241 -0
  258. package/src/report/components/entity-lists/validate.test.ts +114 -0
  259. package/src/report/{react → components}/fixtures.ts +2 -2
  260. package/src/report/{react → components/metric-views}/DeltaTable.tsx +5 -5
  261. package/src/report/{react → components/metric-views}/MetricBars.tsx +5 -5
  262. package/src/report/{react → components/metric-views}/MetricLine.tsx +9 -6
  263. package/src/report/{react → components/metric-views}/MetricMatrix.tsx +6 -6
  264. package/src/report/{react → components/metric-views}/MetricScatter.tsx +41 -33
  265. package/src/report/{react → components/metric-views}/MetricTable.tsx +6 -6
  266. package/src/report/{react → components/metric-views}/Scoreboard.tsx +4 -4
  267. package/src/report/{compute.ts → components/metric-views/compute.ts} +51 -477
  268. package/src/report/components/metric-views/faces.ts +423 -0
  269. package/src/report/components/metric-views/index.tsx +352 -0
  270. package/src/report/{text → components/metric-views}/plot.ts +1 -1
  271. package/src/report/components/metric-views/validate.test.ts +211 -0
  272. package/src/report/{react → components}/render.test.tsx +47 -17
  273. package/src/report/components/shared-compute.ts +59 -0
  274. package/src/report/components/shared-faces.ts +30 -0
  275. package/src/report/components/shared.ts +192 -0
  276. package/src/report/{react → components/site-components}/CopyFixPrompt.tsx +3 -3
  277. package/src/report/{react → components/site-components}/HeroCard.tsx +3 -3
  278. package/src/report/{react → components/site-components}/ScopeWarnings.tsx +4 -4
  279. package/src/report/{react → components/site-components}/TraceWaterfall.tsx +13 -10
  280. package/src/report/components/site-components/compute.ts +144 -0
  281. package/src/report/components/site-components/faces.ts +80 -0
  282. package/src/report/components/site-components/index.tsx +265 -0
  283. package/src/report/{scope-warnings.ts → components/site-components/scope-warnings.ts} +3 -3
  284. package/src/report/{site-components.test.tsx → components/site-components/site-components.test.tsx} +23 -21
  285. package/src/report/components/site-components/validate.test.ts +89 -0
  286. package/src/report/{react → components/summaries}/ScopeSummary.tsx +26 -11
  287. package/src/report/components/summaries/compute.ts +56 -0
  288. package/src/report/components/summaries/faces.ts +48 -0
  289. package/src/report/components/summaries/index.tsx +127 -0
  290. package/src/report/components/summaries/validate.test.ts +49 -0
  291. package/src/report/definition/grid-layout.test.ts +124 -0
  292. package/src/report/definition/grid-layout.ts +146 -0
  293. package/src/report/{primitives.tsx → definition/primitives.tsx} +168 -18
  294. package/src/report/{report.ts → definition/report.ts} +98 -165
  295. package/src/report/{shell-head.test.ts → definition/shell-head.test.ts} +2 -2
  296. package/src/report/{text/table.ts → definition/table-text.ts} +4 -4
  297. package/src/report/{tree.ts → definition/tree.ts} +58 -22
  298. package/src/report/index.ts +126 -66
  299. package/src/report/{aggregate.ts → model/aggregate.ts} +31 -9
  300. package/src/report/{flag.ts → model/flag.ts} +39 -1
  301. package/src/report/{format.ts → model/format.ts} +59 -5
  302. package/src/report/{locale.ts → model/locale.ts} +34 -36
  303. package/src/report/{metrics.ts → model/metrics.ts} +3 -3
  304. package/src/report/{types.ts → model/types.ts} +143 -22
  305. package/src/report/react/index.tsx +52 -26
  306. package/src/report/{dual-render.test.tsx → runtime/dual-render.test.tsx} +564 -49
  307. package/src/report/runtime/host.test.ts +44 -0
  308. package/src/report/runtime/host.ts +138 -0
  309. package/src/report/{load.ts → runtime/load.ts} +1 -1
  310. package/src/report/runtime/text.ts +192 -0
  311. package/src/report/runtime/web.ts +106 -0
  312. package/src/results/attempt-evidence.ts +5 -1
  313. package/src/results/host-equivalence.test.ts +54 -3
  314. package/src/results/select.ts +30 -6
  315. package/src/runner/attempt.test.ts +48 -1
  316. package/src/runner/attempt.ts +62 -42
  317. package/src/runner/cleanup-timeout.test.ts +16 -0
  318. package/src/runner/cleanup-timeout.ts +23 -0
  319. package/src/runner/discover.ts +1 -2
  320. package/src/runner/eval-selection.test.ts +187 -0
  321. package/src/runner/eval-selection.ts +109 -0
  322. package/src/runner/experiment-cleanup-registry.test.ts +89 -0
  323. package/src/runner/experiment-cleanup-registry.ts +39 -0
  324. package/src/runner/experiment-labels.test.ts +71 -0
  325. package/src/runner/feedback/agent.test.ts +33 -1
  326. package/src/runner/feedback/agent.ts +12 -16
  327. package/src/runner/feedback/ci.test.ts +35 -1
  328. package/src/runner/feedback/ci.ts +16 -18
  329. package/src/runner/feedback/coordinator.ts +28 -0
  330. package/src/runner/feedback/human.test.ts +108 -1
  331. package/src/runner/feedback/human.ts +71 -21
  332. package/src/runner/feedback/reducer.test.ts +64 -0
  333. package/src/runner/feedback/reducer.ts +26 -0
  334. package/src/runner/feedback/sink.ts +40 -1
  335. package/src/runner/fingerprint.ts +2 -1
  336. package/src/runner/report.test.ts +14 -0
  337. package/src/runner/report.ts +3 -1
  338. package/src/runner/run.test.ts +390 -12
  339. package/src/runner/run.ts +259 -26
  340. package/src/runner/sandbox-selection.test.ts +13 -3
  341. package/src/runner/sandbox-selection.ts +4 -2
  342. package/src/runner/types.ts +158 -23
  343. package/src/sandbox/docker.ts +7 -0
  344. package/src/sandbox/e2b.ts +12 -13
  345. package/src/sandbox/types.ts +23 -21
  346. package/src/scoring/display.test.ts +28 -2
  347. package/src/scoring/display.ts +38 -5
  348. package/src/scoring/types.ts +3 -3
  349. package/src/shared/aggregate.test.ts +52 -0
  350. package/src/shared/aggregate.ts +30 -1
  351. package/src/shared/types.ts +6 -1
  352. package/src/show/command.test.ts +34 -0
  353. package/src/show/command.ts +16 -0
  354. package/src/show/compose.ts +1 -1
  355. package/src/show/index.ts +58 -22
  356. package/src/show/render.ts +16 -240
  357. package/src/show/show.test.ts +128 -35
  358. package/src/view/app/App.test.tsx +8 -7
  359. package/src/view/app/App.tsx +135 -51
  360. package/src/view/app/i18n.ts +7 -147
  361. package/src/view/app/lib/attempt-dialog.test.ts +65 -0
  362. package/src/view/app/lib/attempt-dialog.ts +69 -0
  363. package/src/view/app/main.tsx +0 -1
  364. package/src/view/app/types.ts +3 -86
  365. package/src/view/artifact-serving.test.ts +22 -38
  366. package/src/view/client-dist/app.css +1 -1
  367. package/src/view/client-dist/app.js +15 -22
  368. package/src/view/data.test.ts +48 -36
  369. package/src/view/data.ts +122 -89
  370. package/src/view/index.ts +3 -13
  371. package/src/view/server.ts +36 -6
  372. package/src/view/shared/types.ts +6 -31
  373. package/src/view/site-parity.test.ts +24 -1
  374. package/src/view/site.ts +144 -17
  375. package/src/view/styles.css +18 -806
  376. package/src/view/view-report.test.ts +182 -34
  377. package/dist/report/components.d.ts +0 -179
  378. package/dist/report/components.js +0 -544
  379. package/dist/report/compute.d.ts +0 -139
  380. package/dist/report/react/ExperimentComparison.d.ts +0 -10
  381. package/dist/report/react/ExperimentComparison.js +0 -12
  382. package/dist/report/react/MetricScatter.d.ts +0 -9
  383. package/dist/report/react/format.d.ts +0 -3
  384. package/dist/report/react/format.js +0 -7
  385. package/dist/report/text/faces.d.ts +0 -45
  386. package/dist/report/text/faces.js +0 -671
  387. package/dist/report/web.d.ts +0 -32
  388. package/dist/report/web.js +0 -48
  389. package/docs-site/zh/how-to/authoring.mdx +0 -162
  390. package/docs-site/zh/how-to/custom-reports.mdx +0 -414
  391. package/docs-site/zh/how-to/experiments.mdx +0 -86
  392. package/docs-site/zh/how-to/write-experiment.mdx +0 -164
  393. package/src/report/components.tsx +0 -925
  394. package/src/report/react/ExperimentComparison.tsx +0 -73
  395. package/src/report/react/format.ts +0 -9
  396. package/src/report/text/faces.ts +0 -767
  397. package/src/report/web.ts +0 -77
  398. package/src/show/report-host.test.ts +0 -205
  399. package/src/show/report-host.ts +0 -389
  400. package/src/view/app/components/AttemptModal.tsx +0 -496
  401. package/src/view/app/components/CodeView.test.tsx +0 -142
  402. package/src/view/app/components/CodeView.tsx +0 -310
  403. package/src/view/app/components/CopyControls.tsx +0 -106
  404. package/src/view/app/components/Trace.tsx +0 -100
  405. package/src/view/app/components/Transcript.tsx +0 -157
  406. package/src/view/app/components/ui/badge.tsx +0 -21
  407. package/src/view/app/lib/artifact-url.ts +0 -17
  408. package/src/view/app/lib/attempt-route.test.ts +0 -80
  409. package/src/view/app/lib/attempt-route.ts +0 -52
  410. package/src/view/app/lib/format.ts +0 -70
  411. package/src/view/app/lib/guards.test.ts +0 -108
  412. package/src/view/app/lib/guards.ts +0 -71
  413. package/src/view/app/lib/rows.ts +0 -22
  414. package/src/view/app/lib/transcript-data.tsx +0 -151
  415. package/src/view/app/lib/verdict.ts +0 -23
  416. package/src/view/app/shared.ts +0 -8
  417. /package/dist/report/{react → components/metric-views}/chart-math.d.ts +0 -0
  418. /package/dist/report/{react → components/metric-views}/chart-math.js +0 -0
  419. /package/dist/report/{text → components/metric-views}/plot.d.ts +0 -0
  420. /package/dist/report/{react → components/site-components}/PoweredBy.d.ts +0 -0
  421. /package/dist/report/{react → components/site-components}/PoweredBy.js +0 -0
  422. /package/dist/report/{text/layout.d.ts → model/text-layout.d.ts} +0 -0
  423. /package/dist/report/{text/layout.js → model/text-layout.js} +0 -0
  424. /package/dist/report/{types.js → model/types.js} +0 -0
  425. /package/src/report/{react → components/metric-views}/chart-math.test.ts +0 -0
  426. /package/src/report/{react → components/metric-views}/chart-math.ts +0 -0
  427. /package/src/report/{react → components/site-components}/PoweredBy.tsx +0 -0
  428. /package/src/report/{text/layout.ts → model/text-layout.ts} +0 -0
@@ -4,11 +4,11 @@ sidebarTitle: "CI 发布报告"
4
4
  description: "把经过 copySnapshots 大小预检的结果目录提交进仓库,CI 用一行 view --results 导出报告站;超大文件在 commit 前就会得到可执行错误。"
5
5
  ---
6
6
 
7
- `niceeval view --out <目录>` 把查看器导出成一个纯静态目录:报告、结果快照列表、transcript、trace 瀑布,和本地 `niceeval view` 看到的完全一样(导出行为见[查看结果 · 导出与静态托管](/zh/how-to/viewing-results#导出与静态托管))。CI 发布只需要让结果数据到构建机手里,但不要直接提交本地事实根 `.niceeval/`:逐字符串截断能防一条失控输出膨胀,不能保证整个文件小于 Git host 的限制。先用 `copySnapshots` 生成经过 50 MiB 单文件预检的发布结果根,再提交这个目录。
7
+ `niceeval view --out <目录>` 把查看器导出成一个纯静态目录:报告、结果快照列表、transcript、trace 瀑布,和本地 `niceeval view` 看到的完全一样(导出行为见[查看结果 · 导出与静态托管](/zh/tutorials/viewing-results#导出与静态托管))。CI 发布只需要让结果数据到构建机手里,但不要直接提交本地事实根 `.niceeval/`:逐字符串截断能防一条失控输出膨胀,不能保证整个文件小于 Git host 的限制。先用 `copySnapshots` 生成经过 50 MiB 单文件预检的发布结果根,再提交这个目录。
8
8
 
9
9
  ## 生成可提交的结果目录
10
10
 
11
- 新建 `scripts/publish-results.ts`(项目里 eval 和配置本来就是 TypeScript,脚本也用 `.ts`,由 `tsx` 直接运行):
11
+ 新建 `scripts/publish-results.ts`(项目里评估用例和配置本来就是 TypeScript,脚本也用 `.ts`,由 `tsx` 直接运行):
12
12
 
13
13
  ```javascript
14
14
  import { rm } from "node:fs/promises";
@@ -31,11 +31,17 @@ await copySnapshots(results.latest(), output, {
31
31
  npx niceeval view --results report-data --out site
32
32
  ```
33
33
 
34
+ 只发布一部分实验时,把收窄直接交给导出命令,页面和证据都只含收窄后的范围(见[查看结果 · 导出与静态托管](/zh/tutorials/viewing-results#导出与静态托管)):
35
+
36
+ ```bash
37
+ npx niceeval view --results report-data --exp compare --out site
38
+ ```
39
+
34
40
  `view` 对零可读结果直接报错、非零退出,不会导出一张空报告——`report-data/` checkout 坏掉,或所有落盘与当前 niceeval 的 schemaVersion 不兼容被整批跳过时,构建失败,Vercel / GitHub Pages 保留上一次部署。错误逐条列出被跳过的快照目录与原因,schemaVersion 场景还给出能直接查看旧落盘的 `npx niceeval@<版本> view` 命令。
35
41
 
36
42
  ## 发布自定义报告
37
43
 
38
- 不传 `--report` 时,发布出来的站点就是默认报告的三个页面(报告、Attempts、追踪)。想换成自己的页面,把 [`defineReport` 报告文件](/zh/how-to/custom-reports)传给 `--report` 就行——attempt 详情(transcript、trace、代码视图)仍在同一个站里,报告里的每个数字点进去就是对应证据,和本地 `view --report` 看到的一模一样:
44
+ 不传 `--report` 时,发布出来的站点就是默认报告的三个页面(报告、Attempts、追踪)。想换成自己的页面,把 [`defineReport` 报告文件](/zh/tutorials/custom-reports)传给 `--report` 就行——attempt 详情(transcript、trace、代码视图)仍在同一个站里,报告里的每个数字点进去就是对应证据,和本地 `view --report` 看到的一模一样:
39
45
 
40
46
  ```bash
41
47
  npx niceeval view --results report-data --report reports/exam.tsx --out site
@@ -133,8 +139,8 @@ jobs:
133
139
  uses: actions/deploy-pages@v4
134
140
  ```
135
141
 
136
- 日常循环是:本地跑 eval,运行 `npx tsx scripts/publish-results.ts`,提交更新后的 `report-data/` 并 push。发布目录只保留每个实验的最新结果快照;要发布其它选择策略,在脚本里替换 `results.latest()`。本地 `.niceeval/` 可以保留完整历史和 diff,不需要为了 Git 限制削掉调试证据。
142
+ 日常循环是:本地跑评估用例,运行 `npx tsx scripts/publish-results.ts`,提交更新后的 `report-data/` 并 push。发布目录只保留每个实验的最新结果快照;要发布其它选择策略,在脚本里替换 `results.latest()`。本地 `.niceeval/` 可以保留完整历史和 diff,不需要为了 Git 限制削掉调试证据。
137
143
 
138
144
  ## 发布的是选中的证据
139
145
 
140
- 整站导出会带上发布结果根里选中的 transcript、源码快照和 trace。新写入的超大 events / trace 字符串可能带结构化截断标记。`copySnapshots` 只做选择和整文件大小预检,不改写任何内容。发布的站点谁都能翻到 prompt 和工具输出,发布到公网前确认结果内容适合公开——NiceEval 在记录时就不把环境变量值和命令输出写进结果文件,transcript 里是 Agent 自己的输入输出和你的 eval 任务本身。
146
+ 整站导出会带上发布结果根里选中的 transcript、源码快照和 trace。新写入的超大 events / trace 字符串可能带结构化截断标记。`copySnapshots` 只做选择和整文件大小预检,不改写任何内容。发布的站点谁都能翻到 prompt 和工具输出,发布到公网前确认结果内容适合公开——NiceEval 在记录时就不把环境变量值和命令输出写进结果文件,transcript 里是 Agent 自己的输入输出和你的评估用例任务本身。
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  title: "为你的 Agent 项目设置评估"
3
3
  sidebarTitle: "快速开始"
4
- description: "安装 NiceEval,写三个文件,10 分钟内对你自己的应用跑通第一条 eval。"
4
+ description: "安装 NiceEval,写三个文件,10 分钟内对你自己的应用跑通第一条评估用例。"
5
5
  ---
6
6
 
7
- 接入你自己的应用只需要三个文件:一个 **adapter**(怎么调你的应用)、一个 **experiment**(评谁、跑几次)、一条 **eval**(断言什么)。下面是完整的最短路径;写给 coding agent 的一键接入和场景示例在后面。
7
+ 接入应用需要三个文件:一个 **Adapter** 负责调用应用,一个 **Experiment** 固定被测对象和运行次数,一条**评估用例**定义断言。以下步骤提供完整的最短路径,并分别覆盖 Coding Agent 自动接入和人工接入。
8
8
 
9
- ## AI 帮你接入 (推荐)
9
+ ## 使用 Coding Agent 接入(推荐)
10
10
  <Steps>
11
11
  <Step title="安装">
12
12
  ```text
@@ -21,7 +21,7 @@ description: "安装 NiceEval,写三个文件,10 分钟内对你自己的应
21
21
  </Step>
22
22
  <Step title="查看结果">
23
23
  ```bash
24
- pnpm exec niceeval show # 终端摘要,适合直接交给 AI 阅读
24
+ pnpm exec niceeval show # 终端摘要,适合 Coding Agent 读取
25
25
  pnpm exec niceeval view # 网页查看器,适合人浏览证据
26
26
  ```
27
27
  </Step>
@@ -36,14 +36,14 @@ pnpm exec niceeval init
36
36
  ```
37
37
 
38
38
  ### Adapter
39
- Adapter 是连接 Agent 与 [NiceEval](https://niceeval.com/) 的中间层。有三种不同程序的接入方式,从无侵入式到部分修改你的 Agent 代码,来解锁更有用的评估功能。 [Tier](/zh/explanation/tier)。
39
+ Adapter 连接 Agent 与 [NiceEval](https://niceeval.com/)。三种接入等级从无侵入连接到修改 Agent 配置,分别提供不同的评估能力,见 [Tier](/zh/explanation/tier)。
40
40
 
41
41
  ```ts
42
- // agents/my-bot.ts
42
+ // agents/my-agent.ts
43
43
  import { defineAgent } from "niceeval/adapter";
44
44
 
45
45
  export default defineAgent({
46
- name: "my-bot",
46
+ name: "my-agent",
47
47
  async send(input, ctx) {
48
48
  // 示例地址:换成你自己 agent 的真实端点(HTTP、CLI、SDK 都行,只要 send 里能拿到回复文本)
49
49
  const r = await fetch("http://localhost:3000/chat", {
@@ -64,19 +64,19 @@ export default defineAgent({
64
64
  ### Experiment
65
65
 
66
66
  ```ts
67
- // experiments/my-bot.ts
67
+ // experiments/my-agent.ts
68
68
  import { defineExperiment } from "niceeval";
69
- import myBot from "../agents/my-bot.ts";
69
+ import myAgent from "../agents/my-agent.ts";
70
70
 
71
71
  export default defineExperiment({
72
- description: "my-bot 基线",
72
+ description: "my-agent 基线",
73
73
  model: "gpt-4o",
74
- agent: myBot,
74
+ agent: myAgent,
75
75
  runs: 1,
76
76
  });
77
77
  ```
78
78
 
79
- ### Eval
79
+ ### 评估用例
80
80
 
81
81
  ```ts
82
82
  // evals/refund-policy.eval.ts
@@ -94,18 +94,18 @@ export default defineEval({
94
94
  ```
95
95
 
96
96
  ```bash
97
- pnpm exec niceeval exp my-bot # 跑起来
97
+ pnpm exec niceeval exp my-agent # 跑起来
98
98
  pnpm exec niceeval show # 在终端读结果;失败项会给出继续下钻的命令
99
99
  pnpm exec niceeval view # 需要交互浏览时打开本地查看器
100
100
  ```
101
101
 
102
- 到这里第一条 eval 已经跑通。
102
+ 到这里第一条评估用例已经跑通。
103
103
 
104
- 这个最小 adapter 是**单轮**的——第二轮不会记得第一轮说了什么,因为还没告诉应用怎么接上历史。多轮会话和工具调用事件(解锁 `t.calledTool()`)、HITL、tracing 一样,都是之后给 adapter 加的可选增量:顺着[接入你的 Agent](/zh/how-to/connect-your-agent)逐层往下走即可,已写的 eval 不用改。
104
+ 这个最小 Adapter 只支持**单轮**调用,第二轮不会携带第一轮的历史。多轮会话、工具调用事件(供 `t.calledTool()` 使用)、HITL tracing 都是后续可选能力。按[接入你的 Agent](/zh/tutorials/connect-your-agent)继续扩展时,已有评估用例不需要修改。
105
105
 
106
106
  ## 对照完整项目
107
107
 
108
- 第一条 Eval 跑通后,再到 [Examples](/zh/examples) 按被测对象选择完整项目。那里提供可运行源码;通用操作步骤仍以 How-to Guides 为准。
108
+ 第一条评估用例跑通后,再到 [Examples](/zh/examples) 按被测对象选择完整项目。那里提供可运行源码;通用操作步骤在 Tutorials 的对应任务页中。
109
109
 
110
110
  ## 放进 CI
111
111
 
@@ -119,9 +119,9 @@ jobs:
119
119
  - uses: actions/checkout@v4
120
120
  - uses: actions/setup-node@v4
121
121
  - run: npm ci
122
- - run: npm exec niceeval exp my-bot
122
+ - run: npm exec niceeval exp my-agent
123
123
  ```
124
124
 
125
125
  <Tip>
126
- 接下来读 [编写 eval](/zh/how-to/authoring) 和 [评分指南](/zh/how-to/scoring-guide),把示例替换成你的真实场景。
126
+ 阅读 [编写评估用例](/zh/tutorials/authoring) 和 [评分指南](/zh/tutorials/scoring-guide),再把示例替换成真实场景。
127
127
  </Tip>
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  title: "把结果上报到 Braintrust 与其它目的地"
3
3
  sidebarTitle: "Reporter 上报"
4
- description: "用内置 reporters eval 结果送到 Braintrust 实验、JUnit XML 或自定义目的地。"
4
+ description: "用内置 reporters 把评估用例结果送到 Braintrust 实验、JUnit XML 或自定义目的地。"
5
5
  ---
6
6
 
7
7
  [NiceEval](https://niceeval.com/) 自己跑、自己判分;Reporter 负责把完成结果送到其它目的地。运行中的 Human/Agent/CI 反馈由 `niceeval exp --output ...` 选择,不是用户配置的 Reporter;`.niceeval/` results artifacts 始终开启。其余 Reporter 从 `niceeval/reporters` 导入,按需挂载。
8
8
 
9
9
  挂载位置有两个:
10
10
 
11
- - `niceeval.config.ts` 的 `reporters`:观测整次运行的每个 eval。共享目的地(比如一个 Braintrust 实验)通常写在这里。
12
- - 单个 eval 的 `reporters`:实例只观测引用它的 eval。多个 eval 引用同一个实例时合并观测,结果落进同一个目的地;已经写在 config 里的实例在 eval 上再列一遍也不会重复上报。
11
+ - `niceeval.config.ts` 的 `reporters`:观测整次运行的每个评估用例。共享目的地(比如一个 Braintrust 实验)通常写在这里。
12
+ - 单个评估用例的 `reporters`:实例只观测引用它的评估用例。多个评估用例引用同一个实例时合并观测,结果落进同一个目的地;已经写在 config 里的实例在评估用例上再列一遍也不会重复上报。
13
13
 
14
14
  ## Braintrust
15
15
 
@@ -24,7 +24,7 @@ export default defineConfig({
24
24
  });
25
25
  ```
26
26
 
27
- 只想上报部分 eval 时,挂在 eval 上:
27
+ 只想上报部分评估用例时,挂在评估用例上:
28
28
 
29
29
  ```ts evals/forecast.eval.ts
30
30
  import { defineEval } from "niceeval";
@@ -105,9 +105,9 @@ const notify: Reporter = {
105
105
  };
106
106
  ```
107
107
 
108
- - `onRunStart(evals, agent, shape)`:运行开始,收到本次实际要跑的 eval 列表和运行规模。
108
+ - `onRunStart(evals, agent, shape)`:运行开始,收到本次实际要跑的评估用例列表和运行规模。
109
109
  - `onEvalComplete(result)`:每个 attempt 完成即时触发,回调串行化,不会交错。
110
110
  - `onRunComplete(summary)`:运行结束,收到聚合汇总。
111
111
  - `onEvent(event)`:更细粒度的事件流(`eval:start`、`run:budgetExceeded` 等)。
112
112
 
113
- 用户在 config/eval 中挂载的 Reporter 默认是 best-effort:抛错会形成永久 diagnostic,但不会中断在飞 Attempt。CLI 显式要求的 `--json` / `--junit` 与默认 results artifacts 是 required 输出,写失败会让最终运行判红。只有目的地没被内置覆盖时才需要自定义——`.niceeval/` 的 artifacts 已经记录了完整结果,事后分析直接读它(见[查看结果](./viewing-results))。
113
+ 用户在 config/评估用例中挂载的 Reporter 默认是 best-effort:抛错会形成永久 diagnostic,但不会中断在飞 Attempt。CLI 显式要求的 `--json` / `--junit` 与默认 results artifacts 是 required 输出,写失败会让最终运行判红。只有目的地没被内置覆盖时才需要自定义——`.niceeval/` 的 artifacts 已经记录了完整结果,事后分析直接读它(见[查看结果](./viewing-results))。
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: "沙箱 Agent:评估 Claude Code、Codex 和 bub"
3
- sidebarTitle: "沙箱 Agent"
2
+ title: "Sandbox Agent:评估 Claude Code、Codex 和 bub"
3
+ sidebarTitle: "Sandbox Agent"
4
4
  description: "使用 NiceEval 内置 agents 或自定义 adapter,在 Docker 或云端 sandbox 中运行 coding-agent CLI。"
5
5
  ---
6
6
 
@@ -63,7 +63,7 @@ export default defineExperiment({
63
63
  });
64
64
  ```
65
65
 
66
- Claude Code 使用 `correctroads-default-team/niceeval-claude-code:v0.6.1`,Bub 使用 `correctroads-default-team/niceeval-bub:v0.6.1`。版本 tag 适合 CI;省略 tag 会跟随当前稳定构建。如何继续增加系统包、二进制或模型缓存,见 [沙箱 provider · 从官方基线继续构建以提速](/zh/how-to/sandbox-providers#从官方基线继续构建以提速)。
66
+ Claude Code 使用 `correctroads-default-team/niceeval-claude-code:v0.6.1`,Bub 使用 `correctroads-default-team/niceeval-bub:v0.6.1`。版本 tag 适合 CI;省略 tag 会跟随当前稳定构建。添加系统包、二进制或模型缓存的步骤见 [Sandbox Provider · 从官方基线继续构建以提速](/zh/tutorials/sandbox-providers#从官方基线继续构建以提速)。
67
67
 
68
68
  内置 agent 从 `niceeval/adapter` 导出的是工厂函数。需要配置鉴权、代理、MCP 或 GitHub skill 时,把这些写进工厂参数;模型仍然写在 experiment 的 `model` 字段,sandbox provider 仍然写在 `sandbox` 字段:
69
69
 
@@ -104,7 +104,7 @@ export default defineExperiment({
104
104
  ```text
105
105
  createSandbox
106
106
  → sandbox spec 的 .setup() 钩子? # 环境准备(按实验装东西);没挂就跳过
107
- → eval 的 setup? # 这条 eval 的任务夹具(如果定义了)
107
+ → eval 的 setup? # 这条 eval 的 Fixture(如果定义了)
108
108
  → adapter.setup? # 装 CLI / 写 agent 配置
109
109
  → test(t): uploadDirectory(...) # 写入这条 eval 的起始文件
110
110
  → adapter.send(input, ctx) # agent 在这一步改动的文件才进 diff
@@ -120,7 +120,7 @@ createSandbox
120
120
 
121
121
  `t.sandbox.diff` 与 `t.sandbox.fileChanged()` 只包含 **agent 在 `t.send()` 期间改动的文件**:NiceEval 在每次 `t.send()` 前后记录一次工作区状态,把中间的变化记在 agent 名下。你上传的起始文件、`t.send()` 之后写入的验证材料都不会混进来,所以 `fileChanged("src/app.ts")` 只在 agent 真的动过这个文件时通过。
122
122
 
123
- 环境钩子(`.setup()` / `.teardown()`)挂在 experiment `sandbox` 字段的 spec 上,用来做"按实验变化的环境准备"——装某个实验专属的二进制、预热、跨 attempt 载入和回存状态。它写下的文件属于环境,不会被算进 agent 产出的 diff。写法和规则见 [沙箱 provider · 环境钩子](/zh/how-to/sandbox-providers#环境钩子)。
123
+ 生命周期(`.setup()` / `.teardown()`)挂在 experiment `sandbox` 字段的 spec 上,用来做"按实验变化的环境准备"——装某个实验专属的二进制、预热、跨 attempt 载入和回存状态。它写下的文件属于环境,不会被算进 agent 产出的 diff。写法和规则见 [Sandbox provider · 生命周期](/zh/tutorials/sandbox-providers#生命周期)。
124
124
 
125
125
  ## 自定义 sandbox agent
126
126
 
@@ -172,7 +172,7 @@ export default defineSandboxAgent({
172
172
 
173
173
  ## `ctx.model` 与 `ctx.flags`
174
174
 
175
- experiment 声明的 model 和 flags 会出现在 adapter context 中。adapter 可以决定如何把它们转成 CLI 参数或 HTTP payload。
175
+ Experiment 声明的 model 和 flags 会出现在 Adapter context 中。Adapter 可以把它们转换成 CLI 参数或 HTTP payload。
176
176
 
177
177
  ## 在 experiment 中使用自定义 agent
178
178
 
@@ -1,7 +1,7 @@
1
1
  ---
2
- title: "Sandbox provider:Docker、Vercel 与第三方"
3
- sidebarTitle: "沙箱 provider"
4
- description: "NiceEval Docker 或 Vercel sandbox 中运行 coding agents。了解如何选择 provider、配置权限,并通过 warm pools 改善性能。"
2
+ title: "Sandbox"
3
+ sidebarTitle: "Sandbox"
4
+ description: "官方 Sandbox Docker、VercelE2B Provider。通过预制快照加速评估"
5
5
  ---
6
6
 
7
7
  Sandbox Provider 是创建和管理隔离运行环境的基础设施。[NiceEval](https://niceeval.com/) 把它们包装成同一个 `Sandbox` 接口,所以 Adapter 不需要知道当前用的是本地 Docker、Vercel micro-VM、E2B 还是第三方云服务。
@@ -21,9 +21,9 @@ Adapter 常用操作包括:
21
21
  | `runCommand(..., { cwd })` | 单条命令临时切换工作目录;相对路径按 `workdir` 解析 |
22
22
  | `stop()` | 销毁环境 |
23
23
 
24
- ## 选择 provider
24
+ ## 选择 Sandbox
25
25
 
26
- 选择 provider 只能写在代码里——没有对应的 CLI flag,[NiceEval](https://niceeval.com/) 也不会自动探测 provider。在 experiment 里设置 `sandbox` 字段(或者在 `niceeval.config.ts` 里设置作为项目级兜底),三选一:
26
+ 在实验里设置 `sandbox` 字段
27
27
 
28
28
  ```ts
29
29
  // experiments/local.ts
@@ -49,7 +49,7 @@ export default defineExperiment({
49
49
 
50
50
  漏装时不会静默失败:NiceEval 在创建 sandbox 的那一刻报错并直接给出上面的安装命令,例如 `Docker sandbox requires 'dockerode'. Install it with: pnpm add dockerode @types/dockerode`。
51
51
 
52
- ## 环境钩子
52
+ ## 生命周期
53
53
 
54
54
  `dockerSandbox()` / `vercelSandbox()` / `e2bSandbox()` 返回的 spec 上有两个链式方法:`.setup(fn)` 和 `.teardown(fn)`。它们处理只有运行时才知道的环境内容,例如按实验写小配置、检查预制工具是否可用、安装 hook,或在多次 Attempt 之间载入和回存状态。
55
55
 
@@ -73,16 +73,38 @@ export default defineExperiment({
73
73
 
74
74
  规则一览:
75
75
 
76
- - **签名**:钩子函数是 `(sandbox, ctx)`;`setup` 可以返回一个清理函数。这里的 `ctx` 是窄的 Sandbox Hook Context,只有 experiment 身份、取消信号和反馈方法,不带 Agent 会话或 telemetry。
76
+ - **签名**:Hook 函数是 `(sandbox, ctx)`,不返回值。这里的 `ctx` 是窄的 Sandbox Hook Context,只有 experiment 身份、取消信号和反馈方法,不带 Agent 会话或 telemetry。
77
77
  - **不可变**:每次 `.setup()` / `.teardown()` 都返回一个新 spec,原对象不变,可以继续链。
78
- - **多个钩子**:多个 `.setup()` 按追加顺序执行;多个 `.teardown()` 按追加的逆序执行。
79
- - **执行时机**:`setup` 钩子在 sandbox 创建后、git 基线之前最先跑——它写下的文件会进基线,不会被算进 agent 产出的 diff;`teardown` 钩子在 Adapter 的 `teardown` 之后、sandbox 销毁之前最后跑——把状态回存到外部正好用这个时机。
80
- - **失败语义**:`setup` 钩子抛错,这次 Attempt 记为 `errored`(环境问题,不是 Agent 做错题);`teardown` 钩子可以报告 diagnostic,默认不改变已经得到的判定。某个收尾动作是结果成立的必要条件时应抛错,由 runner 明确记录为致命错误。
81
- - **不带 sandbox Agent**:`defineAgent` 构造的 Agent 没有 sandbox,`sandbox` 字段对它不生效,钩子自然不会跑。
78
+ - **多个 Hook**:多个 `.setup()` 按追加顺序执行;多个 `.teardown()` 按追加的逆序执行(LIFO);`.setup()` 链中途抛错时后续 `.setup()` 不再执行,`.teardown()` 链仍完整走完——半初始化的 Sandbox 同样要扫尾。
79
+ - **执行时机**:`setup` Hook sandbox 创建后、git 基线之前最先跑——它写下的文件会进基线,不会被算进 agent 产出的 diff;`teardown` Hook Adapter 的 `teardown` 之后、sandbox 销毁之前最后跑——把状态回存到外部正好用这个时机。
80
+ - **触发规则**:`teardown` 当且仅当同一 Sandbox `setup` 时点已经走到才执行——`setup` 抛错不豁免,收尾代码要对可能未赋值的句柄做防御;`setup` 没跑到(Sandbox 没创建成功)则 `teardown` 同样跳过。
81
+ - **失败语义**:`setup` Hook 抛错,这次 Attempt 记为 `errored`(环境问题,不是 Agent 做错题);`teardown` Hook 可以报告 diagnostic,默认不改变已经得到的判定。某个收尾动作是结果成立的必要条件时应抛错,由 runner 明确记录为致命错误。
82
+ - **不带 sandbox 的 Agent**:`defineAgent` 构造的 Agent 没有 sandbox,`sandbox` 字段对它不生效,Hook 自然不会跑。
82
83
 
83
- 钩子里可以用 `ctx.experimentId`(路径推导的实验 id)当状态隔离的键,比如不同实验各自维护一份跨 attempt 的缓存。跨 attempt 状态的载入和回存是你自己在钩子里写的普通代码——[NiceEval](https://niceeval.com/) 不提供状态存储;要保证同一实验的 attempt 不并发读写同一份状态,在 experiment 上声明 `maxConcurrency: 1`。
84
+ ### setup 的产物传给 teardown
84
85
 
85
- ### 从环境钩子报告进度和问题
86
+ `setup` 不返回值,`teardown` 要用 `setup` 建立的句柄(一个已打开的连接、一个临时文件路径)时不能存进普通模块变量——同一个 spec 被多个并发 Attempt 复用同一个模块,模块变量会被后来的 Attempt 互相覆写。以 `sandbox` 实例作键存取:每个 Attempt 有自己独立的 `sandbox`,是天然的 per-attempt 键:
87
+
88
+ ```ts
89
+ import type { Sandbox } from "niceeval/sandbox";
90
+
91
+ // 并发 Attempt 各有自己的 sandbox:句柄按 sandbox 键控,不用普通模块变量
92
+ const forwarders = new WeakMap<Sandbox, { stop(): Promise<void> }>();
93
+
94
+ const spec = e2bSandbox({ template: "niceeval-agents" })
95
+ .setup(async (sandbox, ctx) => {
96
+ forwarders.set(sandbox, await startLogForwarder(sandbox, { signal: ctx.signal }));
97
+ })
98
+ .teardown(async (sandbox) => {
99
+ await forwarders.get(sandbox)?.stop(); // setup 抛错也会进来:get 不到就跳过
100
+ });
101
+ ```
102
+
103
+ 「载入 / 回存」这类收尾不需要 setup → teardown 句柄:状态键是 `ctx.experimentId` 的外部 KV,普通代码即可,见下段。
104
+
105
+ Hook 里可以用 `ctx.experimentId`(路径推导的实验 id)当状态隔离的键,比如不同实验各自维护一份跨 attempt 的缓存。跨 attempt 状态的载入和回存是你自己在 Hook 里写的普通代码——[NiceEval](https://niceeval.com/) 不提供状态存储;要保证同一实验的 attempt 不并发读写同一份状态,在 experiment 上声明 `maxConcurrency: 1`。
106
+
107
+ ### 从 Hook 中输出进度和问题
86
108
 
87
109
  长时间安装、预热和状态恢复可以调用 `ctx.progress(...)`。它只更新当前 Attempt 的短期状态,不会把每一步都写进结果。需要运行结束后仍能看到的问题使用 `ctx.diagnostic(...)`:
88
110
 
@@ -109,7 +131,7 @@ const sandbox = e2bSandbox({ template: "niceeval-agents" })
109
131
 
110
132
  `progress` 和 `diagnostic` 都不能指定全局阶段、颜色或输出流。Runner 知道当前回调属于 `sandbox.setup`,会把 Human 终端中的阶段显示为 sandbox setup。`diagnostic` 会随 Attempt 写入 `result.json`,之后可用 `niceeval show @<locator>` 回顾;它本身不会改变判定。环境无法继续时直接抛出异常。
111
133
 
112
- 和另外两处 setup 的分工:Adapter 的 `setup` 管"怎么连被测 agent"(装 CLI、写鉴权配置);eval `test(t)` 开头的代码管"这道题需要哪些起始文件";sandbox 的 `.setup()` 管"这次实验的环境里要多装什么"。三层各写各的,互相不知道对方的内容。MCP server、Skill、model 这些被测 agent 的配置仍然只从 Adapter 工厂参数进——环境钩子不做 Adapter 的事。
134
+ 三种 setup 各有职责。Adapter 的 `setup` 负责连接被测 Agent,例如安装 CLI 和写入鉴权配置;评估用例中 `test(t)` 开头的代码负责准备任务起始文件;Sandbox 的 `.setup()` 负责当前实验的额外环境准备。MCP server、Skill model 等被测 Agent 配置仍然只从 Adapter 工厂参数传入。
113
135
 
114
136
  ## 预制环境与运行时 checkpoint
115
137
 
@@ -125,7 +147,7 @@ Docker image、Vercel 沙箱快照和 E2B template 的凭据、构建上下文
125
147
 
126
148
  ### 从官方基线继续构建以提速
127
149
 
128
- 稳定、体积大、每个 Attempt 都相同的内容——系统包、Agent CLI、编译好的二进制、大模型缓存——应在跑 eval 之前烘焙进 provider 的可发布制品,让每个 Attempt 从预制环境启动、跳过运行时安装。三个内置 provider 都能从官方基线继续派生,不必从空白环境装 Agent;但它们的构建工具、凭据和发布语义不同,NiceEval 只统一**消费**产物 ID(`image` / `snapshotId` / `template`),不伪造跨 provider 的构建 DSL。
150
+ 稳定、体积大、每个 Attempt 都相同的内容——系统包、Agent CLI、编译好的二进制、大模型缓存——应在跑评估用例之前烘焙进 provider 的可发布制品,让每个 Attempt 从预制环境启动、跳过运行时安装。三个内置 provider 都能从官方基线继续派生,不必从空白环境装 Agent;但它们的构建工具、凭据和发布语义不同,NiceEval 只统一**消费**产物 ID(`image` / `snapshotId` / `template`),不伪造跨 provider 的构建 DSL。
129
151
 
130
152
  Adapter 与 Sandbox 不互相猜配置:Adapter 负责检查所需 CLI,Sandbox spec 负责选择 provider 和制品。Claude Code 与 Codex 缺少 CLI 时会回退到运行时安装,所以烘焙纯粹是提速;Bub 还会核对版本、OTel 插件和 Python 插件集合的安装指纹,不能仅凭 `command -v bub` 跳过安装,必须用预制环境。三个 provider 的构建都只在环境依赖变化时跑一次,产物换一个版本化名字,不要塞进每个 Attempt 的 `.setup()`。
131
153
 
@@ -242,11 +264,11 @@ import { dockerSandbox } from "niceeval/sandbox";
242
264
  sandbox: dockerSandbox({ image: "acme-codex-evals:2026-07-13" })
243
265
  ```
244
266
 
245
- Docker 沙箱默认以非 root 的 `node` 用户(UID 1000)跑命令,并把 `/usr/local/bin` 放进 PATH,所以 `npm install -g` 装的全局二进制天然可见;要装到别处的 Agent(如落在 `~/.local/bin`)记得让它进 PATH。本地快速迭代可以直接省略 `image` 用默认 `node:*-slim`,稳定 CI 引用不可变 tag。
267
+ Docker Sandbox 默认以非 root 的 `node` 用户(UID 1000)跑命令,并把 `/usr/local/bin` 放进 PATH,所以 `npm install -g` 装的全局二进制天然可见;要装到别处的 Agent(如落在 `~/.local/bin`)记得让它进 PATH。本地快速迭代可以直接省略 `image` 用默认 `node:*-slim`,稳定 CI 引用不可变 tag。
246
268
 
247
269
  #### Vercel:从官方 runtime 拍快照
248
270
 
249
- Vercel 没有 E2B 式的 template registry,也没有 Dockerfile;沙箱快照是从一台跑起来的 microVM 拍出来的。用 Vercel SDK 从官方 runtime(`node24`)起一台沙箱,装好 Agent CLI,调 `.snapshot()` 拿到 `snap_...`,再把它交给 `vercelSandbox({ snapshotId })`:
271
+ Vercel 没有 E2B 式的 template registry,也没有 Dockerfile;沙箱快照是从一台跑起来的 microVM 拍出来的。用 Vercel SDK 从官方 runtime(`node24`)起一台 Sandbox,装好 Agent CLI,调 `.snapshot()` 拿到 `snap_...`,再把它交给 `vercelSandbox({ snapshotId })`:
250
272
 
251
273
  ```ts title="scripts/build-vercel-snapshot.ts"
252
274
  import { Sandbox } from "@vercel/sandbox";
@@ -291,11 +313,11 @@ await restoreCheckpoint(nextSandbox, data);
291
313
 
292
314
  ## 瞬时错误重试
293
315
 
294
- 内置 Provider 创建沙箱时,限流、`fetch failed`、连接重置、5xx、临时网络不可达这类瞬时失败会自动做指数退避重试;模板不存在、凭据缺失这类配置错误第一次就报错。重试用尽后该 Attempt 记为 errored。`defineSandbox` 自定义 Provider 的 `create` 是你自己的函数,NiceEval 不替它重试。
316
+ 内置 Provider 创建 Sandbox 时,限流、`fetch failed`、连接重置、5xx、临时网络不可达这类瞬时失败会自动做指数退避重试;模板不存在、凭据缺失这类配置错误第一次就报错。重试用尽后该 Attempt 记为 errored。`defineSandbox` 自定义 Provider 的 `create` 是你自己的函数,NiceEval 不替它重试。
295
317
 
296
318
  `readFile`、`downloadFile`、`uploadFile`、批量写入和目录上传会对 429、5xx、`fetch failed`、连接重置等瞬时传输错误自动做有限重试。文件不存在、权限错误、取消和 Sandbox terminated 不重试。
297
319
 
298
- `runCommand` 与 `runShell` 不自动重试。命令可能已经产生副作用,只有你能确认它可安全重复时,才在 hook 或 eval 中显式重试。
320
+ `runCommand` 与 `runShell` 不自动重试。命令可能已经产生副作用,只有你能确认它可安全重复时,才在 hook 或评估用例中显式重试。
299
321
 
300
322
  ## Docker
301
323
 
@@ -1,10 +1,10 @@
1
1
  ---
2
- title: "评分指南: 断言、judge 和成本限制"
3
- sidebarTitle: "评分指南"
4
- description: "用 NiceEval 的五种评分机制评估任意 eval:值断言、作用域断言、LLM-as-judge、test-as-scoring 和效率检查。"
2
+ title: "断言、judge 和成本限制"
3
+ sidebarTitle: "断言"
4
+ description: "值断言、作用域断言、LLM-as-judge、test-as-scoring 和效率检查。"
5
5
  ---
6
6
 
7
- 好的 eval 应该尽量把“是否成功”拆成可解释的信号。[NiceEval](https://niceeval.com/) 允许你混合精确断言、语义 judge、事件流检查和真实测试。
7
+ 好的评估用例应该尽量把”是否成功”拆成可解释的信号。[NiceEval](https://niceeval.com/) 允许你混合精确断言、语义 judge、事件流检查和真实测试。
8
8
 
9
9
  ## 选择断言类型
10
10