niceeval 0.9.1 → 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 +14 -6
  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} +43 -11
  118. package/dist/report/{tree.js → definition/tree.js} +9 -11
  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 +11 -1
  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 +14 -0
  154. package/dist/shared/aggregate.js +31 -0
  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 +40 -16
  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 +6 -6
  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 +49 -49
  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 +71 -57
  224. package/src/context/types.ts +21 -21
  225. package/src/define.ts +13 -0
  226. package/src/i18n/en.ts +27 -12
  227. package/src/i18n/zh-CN.ts +27 -12
  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 +124 -106
  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} +56 -20
  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 +53 -2
  314. package/src/results/select.ts +29 -5
  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 +29 -0
  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 +56 -20
  356. package/src/show/render.ts +15 -239
  357. package/src/show/show.test.ts +127 -34
  358. package/src/view/app/App.test.tsx +1 -1
  359. package/src/view/app/App.tsx +119 -47
  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 +105 -83
  370. package/src/view/index.ts +1 -1
  371. package/src/view/server.ts +32 -2
  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 +0 -805
  376. package/src/view/view-report.test.ts +141 -22
  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
@@ -6,7 +6,7 @@ description: "defineAgent 和 defineSandboxAgent 参考:AgentContext、AgentSe
6
6
 
7
7
  每个 [NiceEval](https://niceeval.com/) agent 都是一个 adapter:一段知道如何驱动特定 backend,并把输出转成标准事件流的代码。runner 只调用 `agent.send(input, ctx)`。
8
8
 
9
- ![一次 t.send 的完整往返:eval 调用 t.send,运行器组装 TurnInput 与 ctx,adapter 返回标准事件流 Turn。](/images/agent-turn-roundtrip-zh.svg)
9
+ ![一次 t.send 的完整往返:评估用例调用 t.send,运行器组装 TurnInput 与 ctx,adapter 返回标准事件流 Turn。](/images/agent-turn-roundtrip-zh.svg)
10
10
 
11
11
  ## `defineAgent`
12
12
 
@@ -106,10 +106,9 @@ coverage?: EvidenceCoverage;
106
106
  setup?: AgentSetup;
107
107
  ```
108
108
 
109
- 每个 attempt 一次(remote agent 没有真实沙箱,运行器会传入一个仅含 `workdir`/`sandboxId`/
109
+ 每个 attempt 一次(remote agent 没有真实 Sandbox,运行器会传入一个仅含 `workdir`/`sandboxId`/
110
110
  `otlpHost`/`stop` 等元信息的 stub `Sandbox`,其余方法调用即抛错——不要在这里调用
111
- 文件/命令类沙箱方法)。常用于建立连接、鉴权等一次性准备。可返回一个 cleanup 闭包,
112
- 与 `teardown` 都在 finally 里跑。
111
+ 文件/命令类 Sandbox 方法)。常用于建立连接、鉴权等一次性准备,不返回值。
113
112
 
114
113
  #### `tracing`
115
114
 
@@ -141,7 +140,8 @@ send(input: TurnInput, ctx: AgentContext): Promise<Turn>;
141
140
  teardown?: AgentTeardown;
142
141
  ```
143
142
 
144
- 运行结束前的清理(与 setup 返回的 cleanup 一起、都在 finally 里跑一次)
143
+ 运行结束前的清理,当且仅当本 attempt 走到过 `setup` 时点才执行(`setup` 抛错不豁免),
144
+ 在 finally 里跑一次。
145
145
 
146
146
  ### `SandboxAgentDef`
147
147
 
@@ -167,9 +167,9 @@ coverage?: EvidenceCoverage;
167
167
  setup?: AgentSetup;
168
168
  ```
169
169
 
170
- 每个沙箱一次(不是每轮一次):装 CLI、写 config.toml / 鉴权配置(model/base/auth 等
171
- 本轮内不变的东西)。运行器在沙箱备好(上传/基线/eval.setup 之后)、第一次 send 前
172
- 调用一次。可返回一个 cleanup 闭包,与 `teardown` 一起在 finally 里跑。
170
+ 每个 Sandbox 一次(不是每轮一次):装 CLI、写 config.toml / 鉴权配置(model/base/auth 等
171
+ 本轮内不变的东西)。运行器在 Sandbox 备好(上传/基线/eval.setup 之后)、第一次 send 前
172
+ 调用一次,不返回值。
173
173
 
174
174
  #### `tracing`
175
175
 
@@ -177,7 +177,7 @@ setup?: AgentSetup;
177
177
  tracing?: AgentTracing;
178
178
  ```
179
179
 
180
- OTLP 导出配置:沙箱里怎么让 CLI 把 trace 发到 endpoint(env / 配置文件),从 setup 拆出。
180
+ OTLP 导出配置:Sandbox 里怎么让 CLI 把 trace 发到 endpoint(env / 配置文件),从 setup 拆出。
181
181
 
182
182
  #### `spanMapper`
183
183
 
@@ -201,7 +201,8 @@ send(input: TurnInput, ctx: AgentContext): Promise<Turn>;
201
201
  teardown?: AgentTeardown;
202
202
  ```
203
203
 
204
- 沙箱销毁前的清理(与 setup 返回的 cleanup 一起、都在 finally 里跑一次)
204
+ Sandbox 销毁前的清理,当且仅当本 attempt 走到过 `setup` 时点才执行(`setup` 抛错不豁免),
205
+ 在 finally 里跑一次。
205
206
 
206
207
  ### `AgentContext`
207
208
 
@@ -211,10 +212,10 @@ teardown?: AgentTeardown;
211
212
  readonly signal: AbortSignal;
212
213
  ```
213
214
 
214
- 软取消信号:合并了 attempt 超时、run 级中断(用户 Ctrl+C)与 eval 自身的中断请求
215
+ 软取消信号:合并了 attempt 超时、run 级中断(用户 Ctrl+C)与评估用例自身的中断请求
215
216
  (见 src/runner/attempt.ts)。adapter 可以选择性检查它(或直接传给 `fetch`)以提前
216
217
  优雅退出,但这不是唯一的硬边界——即便 adapter 完全忽略它,运行器也会用
217
- `Effect.timeoutTo` 兜底强制收尾(停沙箱容器)。
218
+ `Effect.timeoutTo` 兜底强制收尾(停 Sandbox 容器)。
218
219
 
219
220
  #### `model`
220
221
 
@@ -251,7 +252,7 @@ readonly experimentId?: string;
251
252
 
252
253
  路径推导出的实验 id(与结果归属 `runWho` / `AgentRun.experimentId` 同源);不经
253
254
  experiment 跑(如脱离 CLI、直接构造 `AgentRun` 的场景)时为 undefined。典型用途:
254
- `SandboxSpec.setup` 钩子按实验隔离跨 attempt 的状态(缓存目录名、快照 tag 等按
255
+ `SandboxSpec.setup` Hook 按实验隔离跨 attempt 的状态(缓存目录名、快照 tag 等按
255
256
  `ctx.experimentId` 分区),或 adapter 按实验切换鉴权 / 路由。与 `flags`(实验条件的
256
257
  具体取值)是两个维度——这里只是「跑的是哪个实验」的稳定标识,不携带条件内容。
257
258
 
@@ -261,7 +262,7 @@ experiment 跑(如脱离 CLI、直接构造 `AgentRun` 的场景)时为 undefine
261
262
  readonly sandbox: Sandbox;
262
263
  ```
263
264
 
264
- 所有 agent 都有:沙箱型是运行器按项目/experiment 配置备好的真实沙箱句柄,remote 型是
265
+ 所有 agent 都有:Sandbox 型是运行器按项目/experiment 配置备好的真实 Sandbox 句柄,remote 型是
265
266
  `createRemoteSandbox()` 产出的 stub(仅含 `workdir`/`sandboxId`/`otlpHost`/`stop` 等
266
267
  元信息,其余方法调用即抛错)。
267
268
 
@@ -316,7 +317,7 @@ log(msg: string): void;
316
317
 
317
318
  {/* GENERATED:END agent-def */}
318
319
 
319
- `ctx.session`(`AgentSession`)是一条会话线的状态槽:同一条会话线的每次 `send` 拿到同一个 `ctx.session`,新会话线(eval 第一轮 / `t.newSession()` 之后)拿到一个全新的。存取器:
320
+ `ctx.session`(`AgentSession`)是一条会话线的状态槽:同一条会话线的每次 `send` 拿到同一个 `ctx.session`,新会话线(评估用例第一轮 / `t.newSession()` 之后)拿到一个全新的。存取器:
320
321
 
321
322
  - `id?: string` / `capture(id): void` —— 会话续接·服务端记历史时用:`id` 是本线记过的会话 id(新线是 `undefined`),`capture` 记回传的 id(只在还没记过时落地)。
322
323
  - `history<TMsg>(): { get(): TMsg[]; commit(messages: TMsg[]): void }` —— 会话续接·客户端带全量历史时用。
@@ -327,7 +328,7 @@ log(msg: string): void;
327
328
 
328
329
  ## Sandbox 接口
329
330
 
330
- 沙箱型 agent 的 `ctx.sandbox`(`Sandbox`)是当前隔离环境的句柄;`CommandOptions` 是 `runCommand` / `runShell` 的可选项:
331
+ Sandbox agent 的 `ctx.sandbox`(`Sandbox`)是当前隔离环境的句柄;`CommandOptions` 是 `runCommand` / `runShell` 的可选项:
331
332
 
332
333
  {/* GENERATED:BEGIN sandbox-methods */}
333
334
 
@@ -341,7 +342,7 @@ log(msg: string): void;
341
342
  readonly workdir: string;
342
343
  ```
343
344
 
344
- 沙箱内项目/工作区根目录的绝对路径(agent 命令的默认 cwd,也是 git baseline 提交的位置)。各方法的相对路径都以此为基准解析,省略 `cwd`/`targetDir` 时也落到这里。
345
+ Sandbox 内项目/工作区根目录的绝对路径(agent 命令的默认 cwd,也是 git baseline 提交的位置)。各方法的相对路径都以此为基准解析,省略 `cwd`/`targetDir` 时也落到这里。
345
346
 
346
347
  #### `runCommand`
347
348
 
@@ -367,7 +368,7 @@ runShell(script: string, opts?: CommandOptions): Promise<CommandResult>;
367
368
  readFile(path: string): Promise<string>;
368
369
  ```
369
370
 
370
- 读取沙箱内文件的文本内容(UTF-8)。文件不存在时抛错,不返回空字符串——需要容错请自行 `.catch()`。
371
+ 读取 Sandbox 内文件的文本内容(UTF-8)。文件不存在时抛错,不返回空字符串——需要容错请自行 `.catch()`。
371
372
 
372
373
  #### `fileExists`
373
374
 
@@ -375,7 +376,7 @@ readFile(path: string): Promise<string>;
375
376
  fileExists(path: string): Promise<boolean>;
376
377
  ```
377
378
 
378
- 检查沙箱内路径是否存在。跨 provider 语义不完全一致:仅保证对普通文件可靠,对目录路径的行为不同 provider 不保证一致。
379
+ 检查 Sandbox 内路径是否存在。跨 provider 语义不完全一致:仅保证对普通文件可靠,对目录路径的行为不同 provider 不保证一致。
379
380
 
380
381
  #### `readSourceFiles`
381
382
 
@@ -384,7 +385,7 @@ readSourceFiles(opts?: ReadSourceFilesOptions): Promise<SourceFiles>;
384
385
  ```
385
386
 
386
387
  一次 shell 往返读全部源码文件(按扩展名收、按目录/文件名忽略)。
387
- 取代每个 eval 目录里手写的 find + 逐文件 readFile。
388
+ 取代每个评估用例目录里手写的 find + 逐文件 readFile。
388
389
 
389
390
  #### `writeFiles`
390
391
 
@@ -408,7 +409,7 @@ uploadFiles(files: SandboxFile[], targetDir?: string): Promise<void>;
408
409
  uploadDirectory(localDir: string, targetDir?: string, opts?: { ignore?: string[] }): Promise<void>;
409
410
  ```
410
411
 
411
- 把本地磁盘上的一个目录整体上传进沙箱(递归读取本地文件后按 `uploadFiles` 写入);`opts.ignore` 是排除规则,省略 `targetDir` 落到 workdir。
412
+ 把本地磁盘上的一个目录整体上传进 Sandbox(递归读取本地文件后按 `uploadFiles` 写入);`opts.ignore` 是排除规则,省略 `targetDir` 落到 workdir。
412
413
 
413
414
  #### `stop`
414
415
 
@@ -416,7 +417,7 @@ uploadDirectory(localDir: string, targetDir?: string, opts?: { ignore?: string[]
416
417
  stop(): Promise<void>;
417
418
  ```
418
419
 
419
- 销毁沙箱占用的计算资源(容器/microVM)。调用后沙箱不可再用;是否可安全重复调用因 provider 而异,不要依赖这一点。
420
+ 销毁 Sandbox 占用的计算资源(容器/microVM)。调用后 Sandbox 不可再用;是否可安全重复调用因 provider 而异,不要依赖这一点。
420
421
 
421
422
  #### `sandboxId`
422
423
 
@@ -424,7 +425,7 @@ stop(): Promise<void>;
424
425
  readonly sandboxId: string;
425
426
  ```
426
427
 
427
- 本沙箱的稳定标识(各 provider 原生 ID,如 Docker 容器 ID 前缀);用于跨调用关联同一沙箱的会话状态,也用于日志展示。
428
+ 本 Sandbox 的稳定标识(各 provider 原生 ID,如 Docker 容器 ID 前缀);用于跨调用关联同一 Sandbox 的会话状态,也用于日志展示。
428
429
 
429
430
  #### `otlpHost`
430
431
 
@@ -433,8 +434,8 @@ readonly otlpHost: string | null;
433
434
  ```
434
435
 
435
436
  本地 OTLP 接收器的目标 host。
436
- - `string`:沙箱内可通过该 hostname 回连宿主 OTLP 端口(如 docker 的 `host.docker.internal`)。
437
- - `null`:沙箱运行在远程云端(如 e2b/vercel),无法访问宿主本地端口 → 跳过 tracing。
437
+ - `string`:Sandbox 内可通过该 hostname 回连宿主 OTLP 端口(如 docker 的 `host.docker.internal`)。
438
+ - `null`:Sandbox 运行在远程云端(如 e2b/vercel),无法访问宿主本地端口 → 跳过 tracing。
438
439
  可通过环境变量 `NICEEVAL_OTLP_HOST` 强制覆盖(如配置 tunnel 时)。
439
440
 
440
441
  #### `appendLog`
@@ -452,7 +453,7 @@ Docker UI 的 Logs 标签页能实时看到 agent 逐轮活动。docker provider
452
453
  downloadFile(path: string): Promise<Buffer>;
453
454
  ```
454
455
 
455
- 从沙箱内任意路径读取文件,返回二进制 Buffer。
456
+ Sandbox 内任意路径读取文件,返回二进制 Buffer。
456
457
  对应各 provider:Docker getArchive / Vercel readFileToBuffer / e2b files.read(bytes) / …
457
458
 
458
459
  #### `uploadFile`
@@ -461,7 +462,7 @@ downloadFile(path: string): Promise<Buffer>;
461
462
  uploadFile(path: string, content: Buffer): Promise<void>;
462
463
  ```
463
464
 
464
- 向沙箱内任意路径写入文件(二进制)。
465
+ 向 Sandbox 内任意路径写入文件(二进制)。
465
466
  对应各 provider:Docker putArchive / Vercel fs.writeFile(Buffer) / e2b files.write / …
466
467
 
467
468
  ### `CommandOptions`
@@ -472,7 +473,7 @@ uploadFile(path: string, content: Buffer): Promise<void>;
472
473
  env?: Record<string, string>;
473
474
  ```
474
475
 
475
- 追加/覆盖本命令的环境变量(与沙箱默认环境叠加,不清空默认值;各 provider 会保留自己固定的 `PATH` 等变量,不保证能被这里覆盖)。
476
+ 追加/覆盖本命令的环境变量( Sandbox 默认环境叠加,不清空默认值;各 provider 会保留自己固定的 `PATH` 等变量,不保证能被这里覆盖)。
476
477
 
477
478
  #### `cwd`
478
479
 
@@ -488,7 +489,7 @@ cwd?: string;
488
489
  stream?: boolean;
489
490
  ```
490
491
 
491
- 把本命令的输出也送进沙箱的「原生日志流」(于是 `docker logs` / Docker UI 的 Logs
492
+ 把本命令的输出也送进 Sandbox 的「原生日志流」(于是 `docker logs` / Docker UI 的 Logs
492
493
  标签页能实时看到它)。给 agent 命令(codex exec / bub run / claude)开它,就能在容器
493
494
  日志里看到 agent 的【原始输出】。provider 各自实现(docker:tee 到 PID1 tail 的文件;
494
495
  不支持的 provider 忽略)—— 日志怎么浮现是 provider 的事,adapter 只声明意图。
@@ -517,7 +518,7 @@ onStderr?: (chunk: string) => void | Promise<void>;
517
518
  root?: boolean;
518
519
  ```
519
520
 
520
- 以 root 跑本命令。默认 `false` —— 命令以沙箱的标准**非 root** 用户跑(agent 的自然环境)。
521
+ 以 root 跑本命令。默认 `false` —— 命令以 Sandbox 的标准**非 root** 用户跑(agent 的自然环境)。
521
522
  给 setup 阶段装系统依赖用(`apt-get install …`、`pip install --break-system-packages …`)。
522
523
 
523
524
  语义跨 provider 一致:"本命令以 root 跑,否则以标准非 root 用户跑"。各 provider 映射到自己的原生机制
@@ -529,4 +530,4 @@ root?: boolean;
529
530
 
530
531
  ## ctx 与 t
531
532
 
532
- `ctx` 是 adapter 侧看到的运行上下文;`t` 是 eval 作者看到的测试上下文。两者使用同一批运行数据,但职责不同。
533
+ `ctx` 是 adapter 侧看到的运行上下文;`t` 是评估用例作者看到的测试上下文。两者使用同一批运行数据,但职责不同。
@@ -37,7 +37,7 @@ name?: LocalizedText;
37
37
  sandbox?: SandboxOption;
38
38
  ```
39
39
 
40
- 项目级默认沙箱 provider(docker / vercel / e2b / custom);experiment 可覆盖。
40
+ 项目级默认 Sandbox provider(docker / vercel / e2b / custom);experiment 可覆盖。
41
41
 
42
42
  #### `workspace`
43
43
 
@@ -45,7 +45,7 @@ sandbox?: SandboxOption;
45
45
  workspace?: string;
46
46
  ```
47
47
 
48
- 上传进沙箱的工作区根目录,省略则用项目根;eval sandbox 视图从这里起步。
48
+ 上传进 Sandbox 的工作区根目录,省略则用项目根;评估用例的 sandbox 视图从这里起步。
49
49
 
50
50
  #### `judge`
51
51
 
@@ -53,7 +53,7 @@ workspace?: string;
53
53
  judge?: JudgeConfig;
54
54
  ```
55
55
 
56
- 项目级默认 judge 配置(model / baseUrl / apiKeyEnv);EvalDef.judge 可按 eval 覆盖。
56
+ 项目级默认 judge 配置(model / baseUrl / apiKeyEnv);EvalDef.judge 可按评估用例覆盖。
57
57
 
58
58
  #### `reporters`
59
59
 
@@ -87,11 +87,11 @@ telemetry?: { host?: string; port?: number };
87
87
 
88
88
  OTLP 接收配置,niceeval 项目内唯一入口(不读 NICEEVAL_OTLP_* 环境变量)。
89
89
  `port` 钉住接收端口(固定端口模式:长驻服务把 OTEL_EXPORTER_OTLP_ENDPOINT 一次性指到
90
- `http://localhost:<port>/v1/traces`,跑多少次 eval 都不用改)。省略 = 每次运行动态分配
90
+ `http://localhost:<port>/v1/traces`,跑多少次评估用例都不用改)。省略 = 每次运行动态分配
91
91
  临时端口(经 ctx.telemetry 交给 adapter)。代价:固定端口下同机同时只能跑一个 niceeval 进程,
92
92
  且该端口被别的进程占用时会报错——换一个空闲端口写回这里即可。
93
93
  `host` 是报给 adapter 的接收端 hostname(而非监听地址,监听地址恒为 0.0.0.0):默认
94
- "127.0.0.1";docker 沙箱型 tracing 需要 "host.docker.internal" 之类的场景,或配了隧道
94
+ "127.0.0.1";docker Sandbox tracing 需要 "host.docker.internal" 之类的场景,或配了隧道
95
95
  的远程接入,在这里覆盖。
96
96
 
97
97
  #### `pricing`
@@ -106,4 +106,4 @@ pricing?: Record<string, PriceOverride>;
106
106
 
107
107
  {/* GENERATED:END config-fields */}
108
108
 
109
- [NiceEval](https://niceeval.com/) 把环境准备放在普通代码里:eval 自己需要的文件写在 `test(t)`,agent 自己的准备写在 adapter 的 `setup`。sandbox provider 只来自代码里的 `sandbox` 字段,不做环境变量自动探测,也没有对应的 CLI flag——用 `niceeval/sandbox` 里的 `dockerSandbox()` / `vercelSandbox()` / `e2bSandbox()` 构造后填进 `sandbox` 字段(可以直接写在 experiment 上,也可以只写在这里作为项目级兜底:`exp.sandbox ?? config.sandbox`)。
109
+ [NiceEval](https://niceeval.com/) 把环境准备放在普通代码里:评估用例自己需要的文件写在 `test(t)`,agent 自己的准备写在 adapter 的 `setup`。sandbox provider 只来自代码里的 `sandbox` 字段,不做环境变量自动探测,也没有对应的 CLI flag——用 `niceeval/sandbox` 里的 `dockerSandbox()` / `vercelSandbox()` / `e2bSandbox()` 构造后填进 `sandbox` 字段(可以直接写在 experiment 上,也可以只写在这里作为项目级兜底:`exp.sandbox ?? config.sandbox`)。
@@ -1,10 +1,10 @@
1
1
  ---
2
- title: "defineEval:声明、配置并运行 NiceEval eval"
2
+ title: "defineEval:声明、配置并运行 NiceEval 评估用例"
3
3
  sidebarTitle: "defineEval"
4
- description: "defineEval 参考:选项、test context t、Turn 返回值、sandbox helper,以及数组和 keyed record 数据集导出。"
4
+ description: "defineEval 参考:选项、test context t、Turn 返回值、Sandbox helper,以及数组和 keyed record 数据集导出。"
5
5
  ---
6
6
 
7
- `defineEval` 是编写 eval 的主要入口。每个 eval 文件调用一次,传入描述和 `test(t)`,并默认导出结果。
7
+ `defineEval` 是编写评估用例的主要入口。每个评估用例文件调用一次,传入描述和 `test(t)`,并默认导出结果。
8
8
 
9
9
  ```ts
10
10
  import { defineEval } from "niceeval";
@@ -19,7 +19,7 @@ export default defineEval({
19
19
  ```
20
20
 
21
21
  <Note>
22
- 不要提供 `id` 或 `name`。[NiceEval](https://niceeval.com/) 从文件路径推导 eval ID。
22
+ 不要提供 `id` 或 `name`。[NiceEval](https://niceeval.com/) 从文件路径推导评估用例 ID。
23
23
  </Note>
24
24
 
25
25
  ## `defineEval` 选项
@@ -58,7 +58,7 @@ tags?: string[];
58
58
  environment?: string;
59
59
  ```
60
60
 
61
- 这条 eval 需要的环境 profile id(provider-neutral,如 `"python-3.9-astropy-4.2"`);由 sandbox spec 的 `environments` 表翻译成该 provider 的预制产物。
61
+ 这条评估用例需要的环境 profile id(provider-neutral,如 `"python-3.9-astropy-4.2"`);由 sandbox spec 的 `environments` 表翻译成该 provider 的预制产物。
62
62
 
63
63
  #### `judge`
64
64
 
@@ -66,7 +66,7 @@ environment?: string;
66
66
  judge?: JudgeConfig;
67
67
  ```
68
68
 
69
- 覆盖项目级 Config.judge,只对这一个 eval 生效(如换个更贵的评审模型)。
69
+ 覆盖项目级 Config.judge,只对这一条评估用例生效(如换个更贵的评审模型)。
70
70
 
71
71
  #### `reporters`
72
72
 
@@ -74,7 +74,7 @@ judge?: JudgeConfig;
74
74
  reporters?: Reporter[];
75
75
  ```
76
76
 
77
- 覆盖 / 追加项目级 Config.reporters,只对这一个 eval 生效。
77
+ 覆盖 / 追加项目级 Config.reporters,只对这一条评估用例生效。
78
78
 
79
79
  #### `timeoutMs`
80
80
 
@@ -82,7 +82,7 @@ reporters?: Reporter[];
82
82
  timeoutMs?: number;
83
83
  ```
84
84
 
85
- 覆盖项目级 / CLI 的单次 attempt 超时(毫秒),只对这一个 eval 生效。
85
+ 覆盖项目级 / CLI 的单次 attempt 超时(毫秒),只对这一条评估用例生效。
86
86
 
87
87
  #### `metadata`
88
88
 
@@ -98,7 +98,7 @@ metadata?: Record<string, unknown>;
98
98
  diff?: { include?: string[]; ignore?: string[] };
99
99
  ```
100
100
 
101
- 调整 agent diff 的归因排除清单(仅沙箱型;见 docs/feature/eval/README.md):两个数组都是
101
+ 调整 agent diff 的归因排除清单( Sandbox 型;见 docs/feature/eval/README.md):两个数组都是
102
102
  gitignore 风格 glob(workdir 相对)。默认排除 .git/node_modules/构建产物/包管理器缓存;
103
103
  `ignore` 在默认清单上追加排除;`include` 优先级最高,把匹配路径显式加回。
104
104
  合成规则固定为「默认 ∪ ignore,再被 include 打洞」,清单在分类账锚点时冻结。
@@ -106,14 +106,27 @@ gitignore 风格 glob(workdir 相对)。默认排除 .git/node_modules/构建产
106
106
  #### `setup`
107
107
 
108
108
  ```ts
109
- setup?: (sandbox: Sandbox, ctx: SandboxHookContext) => Promise<void | Cleanup> | void | Cleanup;
109
+ setup?: (sandbox: Sandbox, ctx: SandboxHookContext) => Promise<void> | void;
110
110
  ```
111
111
 
112
- eval 级预置:拿到沙箱(已上传 workspace + git 基线 + 装好依赖前)。
112
+ 评估用例级预置:拿到 Sandbox(已上传 workspace + git 基线 + 装好依赖前)。
113
113
  默认命令以非 root 跑(agent 的自然环境);装系统依赖时给 `runCommand` 传 `{ root: true }`
114
114
  (如 `runCommand("apt-get", ["install", …], { root: true })`),跨 provider 语义一致。
115
115
  第二个参数是绑定到 `eval.setup` 的窄上下文(`ctx.progress` / `ctx.diagnostic`,
116
- 见 docs/feature/eval/README.md);可返回 cleanup 闭包,归因到 `eval.teardown`。
116
+ 见 docs/feature/eval/README.md)。setup 不返回值;要把产物传给 teardown,
117
+ 以 `sandbox` 实例作键存取(并发 attempt 共享同一模块,普通模块变量会互相覆写)。
118
+
119
+ #### `teardown`
120
+
121
+ ```ts
122
+ teardown?: (sandbox: Sandbox, ctx: SandboxHookContext) => Promise<void> | void;
123
+ ```
124
+
125
+ 评估用例级收尾:attempt 收尾链的第一段(`eval.teardown` → `agent.teardown` →
126
+ `sandbox.teardown`),Sandbox 此刻还活着。当且仅当 `eval.setup` 时点走到过才执行——
127
+ `setup` / `test` 抛错都不豁免,未声明 `setup` 不影响触发;抛错或超 30s 清理上限
128
+ 只记 `teardown-failed` 诊断,不改判定。管 Sandbox 外的临时 Fixture(临时 repo / bucket),
129
+ Sandbox 内的东西随销毁自动回收、不需要它。
117
130
 
118
131
  #### `test`
119
132
 
@@ -121,13 +134,13 @@ eval 级预置:拿到沙箱(已上传 workspace + git 基线 + 装好依赖前)
121
134
  test(t: TestContext): Promise<void> | void;
122
135
  ```
123
136
 
124
- eval 主体:拿到 TestContext,驱动对话 / 沙箱操作并就地断言。
137
+ 评估用例主体:拿到 TestContext,驱动对话 / Sandbox 操作并就地断言。
125
138
 
126
139
  {/* GENERATED:END defineeval-options */}
127
140
 
128
141
  ## Test context: `t`
129
142
 
130
- `t`(`TestContext`)是 eval 作者拿到的高层上下文。运行器按 agent 的实际能力组装它——`t.sandbox` 这类字段只在 `defineSandboxAgent` 构造的 agent 上才有意义,完整规则见[能力位参考](/zh/reference/capabilities)。全部成员:
143
+ `t`(`TestContext`)是评估用例作者拿到的高层上下文。运行器按 agent 的实际能力组装它——`t.sandbox` 这类字段只在 `defineSandboxAgent` 构造的 agent 上才有意义,完整规则见[能力位参考](/zh/reference/capabilities)。全部成员:
131
144
 
132
145
  {/* GENERATED:BEGIN test-context */}
133
146
 
@@ -246,7 +259,7 @@ readonly flags: Readonly<Record<string, unknown>>;
246
259
  progress(update: ProgressUpdate): void;
247
260
  ```
248
261
 
249
- 作用域反馈:报告 eval 自己执行的长步骤(上传 fixture、跑构建……)。短命状态,scope 固定
262
+ 作用域反馈:报告评估用例自己执行的长步骤(上传 Fixture、跑构建……)。短命状态,scope 固定
250
263
  为 `eval.run`;只报告不断言(见 docs/feature/eval/library/context.md「向运行反馈长步骤」)。
251
264
 
252
265
  #### `diagnostic`
@@ -272,7 +285,7 @@ log(msg: string): void;
272
285
  skip(reason: string): never;
273
286
  ```
274
287
 
275
- 立即中止本 eval 并标记为 skipped(verdict / EvalResult.skipReason),reason 不能为空。
288
+ 立即中止本评估用例并标记为 skipped(verdict / EvalResult.skipReason),reason 不能为空。
276
289
 
277
290
  #### `check`
278
291
 
@@ -281,8 +294,8 @@ check(value: unknown, assertion: ValueAssertion): AssertionHandle;
281
294
  ```
282
295
 
283
296
  对任意值跑一个 ValueAssertion,返回可链 `.gate()` / `.atLeast()` 的 AssertionHandle。
284
- 打分延迟到 eval 结束后统一 finalize,调用本身同步、不抛错——不通过只是记一条失败断言,
285
- 不会中止后续代码。要「不满足就立即中止 eval」用 require。
297
+ 打分延迟到评估用例结束后统一 finalize,调用本身同步、不抛错——不通过只是记一条失败断言,
298
+ 不会中止后续代码。要「不满足就立即中止评估用例」用 require。
286
299
 
287
300
  #### `require`
288
301
 
@@ -290,7 +303,7 @@ check(value: unknown, assertion: ValueAssertion): AssertionHandle;
290
303
  require(value: unknown, assertion: ValueAssertion): Promise<unknown>;
291
304
  ```
292
305
 
293
- 对任意值跑一个 ValueAssertion,立即(await 时)求值;不满足就抛错中止整个 eval 剩余步骤
306
+ 对任意值跑一个 ValueAssertion,立即(await 时)求值;不满足就抛错中止整个评估用例剩余步骤
294
307
  (仍会把这条断言计入报告,不影响已记录的其它断言)。跟 check 的区别:check 只记录、
295
308
  从不抛错,打分留到最后统一算;require 当场判定、失败即中止,适合「前置条件不满足,
296
309
  后面写了也没意义」的场景。
@@ -430,7 +443,7 @@ eventsSatisfy(label: string, predicate: (events: readonly StreamEvent[]) => bool
430
443
  readonly sandbox: SandboxHandle;
431
444
  ```
432
445
 
433
- 受限沙箱视图:能执行命令 / 读写文件 / 看最终 diff,不能 stop 沙箱本身(见 SandboxHandle)。
446
+ 受限 Sandbox 视图:能执行命令 / 读写文件 / 看最终 diff,不能 stop Sandbox 本身(见 SandboxHandle)。
434
447
 
435
448
  #### `usage`
436
449
 
@@ -212,7 +212,7 @@ token 用量或 OTel span 反推得到)。存在时优先于按价格表(`define
212
212
  } }
213
213
  ```
214
214
 
215
- agent 停轮等人时,每个待回答的问题吐一条,同时该 Turn 的 `status` 返回 `"waiting"`。`t.requireInputRequest(filter)` 的 filter 逐字段匹配这个 `request`——**能填的字段尽量填**,否则 eval 侧筛选不到。接法见[接入教程的 HITL 部分](/zh/how-to/connect-your-agent)。
215
+ agent 停轮等人时,每个待回答的问题吐一条,同时该 Turn 的 `status` 返回 `"waiting"`。`t.requireInputRequest(filter)` 的 filter 逐字段匹配这个 `request`——**能填的字段尽量填**,否则评估用例侧筛选不到。接法见[接入教程的 HITL 部分](/zh/tutorials/connect-your-agent)。
216
216
 
217
217
  ### `thinking` / `compaction` / `error`
218
218
 
@@ -237,7 +237,7 @@ agent 返回里带步骤记录时,映射就是一段小循环:
237
237
  ```ts
238
238
  import type { StreamEvent } from "niceeval";
239
239
 
240
- function toStreamEvents(body: MyBotResponse): StreamEvent[] {
240
+ function toStreamEvents(body: MyAgentResponse): StreamEvent[] {
241
241
  const events: StreamEvent[] = [];
242
242
  for (const step of body.steps) {
243
243
  if (step.type === "tool_call") {
@@ -257,6 +257,6 @@ function toStreamEvents(body: MyBotResponse): StreamEvent[] {
257
257
 
258
258
  ## 相关阅读
259
259
 
260
- - [接入你的 agent](/zh/how-to/connect-your-agent) —— 从零跑通的教程。
260
+ - [接入你的 agent](/zh/tutorials/connect-your-agent) —— 从零跑通的教程。
261
261
  - [能力位](/zh/reference/capabilities) —— 声明"事件流是完整的"意味着什么。
262
- - [编写 eval](/zh/how-to/authoring) —— 消费这条流的断言全集。
262
+ - [编写评估用例](/zh/tutorials/authoring) —— 消费这条流的断言全集。
@@ -200,7 +200,7 @@ score(value: unknown): number | Promise<number>;
200
200
  gate(threshold?: number): ValueAssertion;
201
201
  ```
202
202
 
203
- 转成硬门槛断言:未达阈值(省略 threshold 则按 score &gt; 0 判定)整条 eval 判为 failed。返回新实例,不改原对象。
203
+ 转成硬门槛断言:未达阈值(省略 threshold 则按 score &gt; 0 判定)整条评估用例判为 failed。返回新实例,不改原对象。
204
204
 
205
205
  #### `atLeast`
206
206
 
@@ -208,8 +208,8 @@ gate(threshold?: number): ValueAssertion;
208
208
  atLeast(threshold: number): ValueAssertion;
209
209
  ```
210
210
 
211
- 转成软阈值断言:未达 threshold 时该条记为 failed,但默认不拖累整条 eval 的 verdict;
212
- `--strict` 运行下,软阈值失败也会把整条 eval 的 verdict 计为 failed。返回新实例,不改原对象。
211
+ 转成软阈值断言:未达 threshold 时该条记为 failed,但默认不拖累整条评估用例的 verdict;
212
+ `--strict` 运行下,软阈值失败也会把整条评估用例的 verdict 计为 failed。返回新实例,不改原对象。
213
213
 
214
214
  #### `optional`
215
215
 
@@ -4,23 +4,23 @@ sidebarTitle: "官方适配器"
4
4
  description: "NiceEval 内置的 Sandbox 和非 Sandbox 适配器分别是什么、怎么鉴权,Sandbox 型里怎么装 MCP server、Skill、插件,怎么使用 Agent 官方配置文件。"
5
5
  ---
6
6
 
7
- [NiceEval](https://niceeval.com/) 随包带几个官方 Adapter(`niceeval/adapter` 导出的工厂函数),按被测对象要不要隔离工作区分两类:**Sandbox 型**(`claude-code` / `codex` / `bub`)在 Docker 或云端沙箱里跑 coding-agent CLI,能装 MCP server、Skill、Python 插件;**非 Sandbox 型**无侵入连一个已经在跑的 HTTP 服务,或者帮你手写 adapter 时省掉事件流映射。这篇按类型和具体 Adapter 分节,重点是每个 Adapter 的配置项——怎么选、怎么跑通第一条 eval,见[接入你的 Agent](/zh/how-to/connect-your-agent)。
7
+ [NiceEval](https://niceeval.com/) 随包带几个官方 Adapter(`niceeval/adapter` 导出的工厂函数),按被测对象要不要隔离工作区分两类:**Sandbox 型**(`claude-code` / `codex` / `bub`)在 Docker 或云端 Sandbox 里跑 coding-agent CLI,能装 MCP server、Skill、Python 插件;**非 Sandbox 型**无侵入连一个已经在跑的 HTTP 服务,或者帮你手写 adapter 时省掉事件流映射。这篇按类型和具体 Adapter 分节,重点是每个 Adapter 的配置项——怎么选、怎么跑通第一条评估用例,见[接入你的 Agent](/zh/tutorials/connect-your-agent)。
8
8
 
9
9
  ## Sandbox 适配器
10
10
 
11
- 三个内置 Sandbox agent 都用 `defineSandboxAgent` 构造,鉴权走环境变量(可用工厂参数覆盖),并且都支持在沙箱 `setup` 阶段装扩展。怎么运行内置 Sandbox agent、目录结构和自定义 Sandbox adapter,见 [Sandbox Agent](/zh/how-to/sandbox-agent);这里只讲每个 Adapter 能装什么、配置项怎么写。
11
+ 三个内置 Sandbox agent 都用 `defineSandboxAgent` 构造,鉴权走环境变量(可用工厂参数覆盖),并且都支持在 Sandbox `setup` 阶段装扩展。怎么运行内置 Sandbox agent、目录结构和自定义 Sandbox adapter,见 [Sandbox Agent](/zh/tutorials/sandbox-agent);这里只讲每个 Adapter 能装什么、配置项怎么写。
12
12
 
13
- 本页的 `settingsFile` / `configFile` 都相对 NiceEval 项目根解析。项目根是执行 `niceeval` 时的当前工作目录,也就是包含 `niceeval.config.ts` 的目录,不是 Eval 或 Experiment 文件所在目录。例如 Experiment 在 `experiments/web/no-search.ts`、配置在 `configs/codex/no-web.toml` 时,仍写 `configFile: "configs/codex/no-web.toml"`。
13
+ 本页的 `settingsFile` / `configFile` 都相对 NiceEval 项目根解析。项目根是执行 `niceeval` 时的当前工作目录,也就是包含 `niceeval.config.ts` 的目录,不是评估用例或 Experiment 文件所在目录。例如 Experiment 在 `experiments/web/no-search.ts`、配置在 `configs/codex/no-web.toml` 时,仍写 `configFile: "configs/codex/no-web.toml"`。
14
14
 
15
15
  ### claude-code
16
16
 
17
17
  - **鉴权**:`ANTHROPIC_API_KEY`(工厂参数 `apiKey` 可覆盖),可选 `ANTHROPIC_BASE_URL`(工厂参数 `baseUrl`)。
18
- - **装 MCP server**:`mcpServers` 配置项,`setup` 阶段写进沙箱里用户级的 `~/.claude.json`(顶层 `mcpServers` 字段)。两种形态按字段区分:本地 stdio 进程写 `command`(可带 `args` / `env`);远程 Streamable HTTP 端点写 `url`(可带 `headers`,逐字进请求头,常用于 `Authorization`),写成 `{ "type": "http", "url": …, "headers": … }` 条目。`url` 要沙箱内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。
19
- - **装 Skill**:`skills: SkillSpec[]`——本地 Skill(`{ kind: "local", path }`,从项目根读文件或目录)或 Repo Skill(`{ kind: "repo", source, ref, skills }`,可钉 commit/tag、可只启用多 Skill 仓库里的一部分)。装进沙箱的 project 级 `.claude/skills/<name>/`,claude CLI 原生发现(原生 `Skill` 工具调用被 adapter 归一为 `skill.loaded` 事件,不重复记成工具调用;用 `t.loadedSkill()` 断言,不是 `t.calledTool("Skill", ...)`)。
18
+ - **装 MCP server**:`mcpServers` 配置项,`setup` 阶段写进 Sandbox 里用户级的 `~/.claude.json`(顶层 `mcpServers` 字段)。两种形态按字段区分:本地 stdio 进程写 `command`(可带 `args` / `env`);远程 Streamable HTTP 端点写 `url`(可带 `headers`,逐字进请求头,常用于 `Authorization`),写成 `{ "type": "http", "url": …, "headers": … }` 条目。`url` Sandbox 内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。
19
+ - **装 Skill**:`skills: SkillSpec[]`——本地 Skill(`{ kind: "local", path }`,从项目根读文件或目录)或 Repo Skill(`{ kind: "repo", source, ref, skills }`,可钉 commit/tag、可只启用多 Skill 仓库里的一部分)。装进 Sandbox 的 project 级 `.claude/skills/<name>/`,claude CLI 原生发现(原生 `Skill` 工具调用被 adapter 归一为 `skill.loaded` 事件,不重复记成工具调用;用 `t.loadedSkill()` 断言,不是 `t.calledTool("Skill", ...)`)。
20
20
  - **装原生 Plugin**:`plugins: ClaudeCodePluginSpec[]`,每一项声明 Marketplace 连接(`name` / `source` / 可选 `ref`)和其中的 Plugin 名。这个类型只属于 claude-code,传不进 codex。
21
21
  - **官方配置文件**:`settingsFile` 是运行 NiceEval 的机器上的本地项目路径,不是 Sandbox 内路径;它指向一份完整的 Claude Code `settings.json`。路径相对项目根,只允许普通相对路径或 `./` 前缀;`..`、绝对路径、`~` 和解析后逃出项目根的符号链接都会报错。Adapter 从本地读取后上传文件,原样替换 Sandbox 中原本为空的用户级 `~/.claude/settings.json`;不继承宿主机配置,也不 deep merge 或重新序列化。`model` 和 `env` 归 Experiment 和 Adapter 管,出现在文件里会在 `setup` 阶段报错并点名冲突键。Secret 走环境变量,别写进配置文件。
22
- - **安装后脚本**:`postSetup: SandboxHook[]`,在写 settings、挂 MCP、装 Skill 与 Plugin 全部完成后,按数组顺序在沙箱里跑你的钩子函数。典型用途是运行插件自带的 setup 脚本(比如它要往全局配置里登记 hook)——这类脚本必须等安装产物就位才能跑。钩子抛错算基础设施错误(Attempt 记 errored),不算 agent 答题失败。
23
- - **tracing**:claude CLI 的 beta 原生遥测(`CLAUDE_CODE_ENHANCED_TELEMETRY_BETA`),span 只有结构和计时,细节见 [OTel 接入](/zh/how-to/connect-otel)。
22
+ - **安装后脚本**:`postSetup: SandboxHook[]`,在写 settings、挂 MCP、装 Skill 与 Plugin 全部完成后,按数组顺序在 Sandbox 里跑你的 Hook 函数。典型用途是运行插件自带的 setup 脚本(比如它要往全局配置里登记 hook)——这类脚本必须等安装产物就位才能跑。与它成对的收尾是 `preTeardown: SandboxHook[]`:按逆序、在 agent 自己的 teardown 步骤之前执行,当且仅当 `postSetup` 的时点已经走到才触发。Hook 抛错算基础设施错误(Attempt 记 errored),不算 agent 答题失败。
23
+ - **tracing**:claude CLI 的 beta 原生遥测(`CLAUDE_CODE_ENHANCED_TELEMETRY_BETA`),span 只有结构和计时,细节见 [OTel 接入](/zh/tutorials/connect-otel)。
24
24
 
25
25
  例如,用 `configs/claude-code/no-web.json` 关闭内置联网检索:
26
26
 
@@ -61,7 +61,7 @@ export default defineExperiment({
61
61
  ### codex
62
62
 
63
63
  - **鉴权**:`CODEX_API_KEY`(工厂参数 `apiKey` 可覆盖,不是 `OPENAI_API_KEY`),可选 `CODEX_BASE_URL`(工厂参数 `baseUrl`)接 OpenAI 兼容代理。
64
- - **装 MCP server**:`mcpServers` 配置项,`setup` 阶段追加进 `~/.codex/config.toml` 的 `[mcp_servers.<name>]` 段。两种形态按字段区分:本地 stdio 进程写 `command`(可带 `args` / `env`);远程 Streamable HTTP 端点写 `url`(可带 `headers`,写成 `[mcp_servers.<name>.http_headers]` 子表)。`url` 要沙箱内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。
64
+ - **装 MCP server**:`mcpServers` 配置项,`setup` 阶段追加进 `~/.codex/config.toml` 的 `[mcp_servers.<name>]` 段。两种形态按字段区分:本地 stdio 进程写 `command`(可带 `args` / `env`);远程 Streamable HTTP 端点写 `url`(可带 `headers`,写成 `[mcp_servers.<name>.http_headers]` 子表)。`url` Sandbox 内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。
65
65
 
66
66
  <Warning>
67
67
  是复数 `mcp_servers`:单数 `[mcp_server.x]` 会被 codex CLI 静默忽略,MCP 压根挂不上,且不会报错——自查用 `codex mcp list`。
@@ -70,7 +70,7 @@ export default defineExperiment({
70
70
  - **装 Skill**:`skills: SkillSpec[]`,与 claude-code 同一个类型。装进 `.agents/skills/<name>/`,并把发现指引写进 AGENTS.md——codex 没有 claude-code 那种原生 Skill 工具,只把文件装进去它不会主动去读;断言"用没用到"看它是否真的执行过读那个文件的 shell 命令,没有工具调用可以直接认。
71
71
  - **装原生 Plugin**:`plugins: CodexPluginSpec[]`,声明 Marketplace 连接(`name` / `source` / 可选 `ref` / 可选 `sparse`)和其中的 Plugin 名。`sparse` 是路径数组(如 `[".agents", "plugins/repo-map"]`),每项让 `codex plugin marketplace add` 带一个 `--sparse <path>`,大仓库只拉插件所需路径,装出来的内容不变。这个类型只属于 codex,传不进 claude-code。
72
72
  - **官方配置文件**:`configFile` 是运行 NiceEval 的机器上的本地项目路径,不是 Sandbox 内路径;它指向一份完整的 Codex `config.toml`。路径相对项目根,只允许普通相对路径或 `./` 前缀;`..`、绝对路径、`~` 和解析后逃出项目根的符号链接都会报错。Adapter 从本地读取后上传文件,原样替换 Sandbox 中原本为空的用户级 `~/.codex/config.toml`;不继承宿主机配置,也不拼接、deep merge 或解析后重写。`model`、`model_provider`、`model_providers`、`model_reasoning_effort`、`mcp_servers`、`otel` 归 Experiment 和 Adapter 管,出现在文件里会在 `setup` 阶段报错并点名冲突键。Secret 走环境变量,别写进配置文件。
73
- - **安装后脚本**:`postSetup: SandboxHook[]`,语义与 claude-code 相同:全部安装步骤完成后按序在沙箱里跑你的钩子函数,适合运行插件自带的 setup 脚本。脚本往 codex 全局配置登记的 hook 不需要交互式信任确认——运行时 `codex exec` 已绕过 hook 信任门槛,hook 直接生效。
73
+ - **安装后脚本**:`postSetup: SandboxHook[]`,语义与 claude-code 相同:全部安装步骤完成后按序在 Sandbox 里跑你的 Hook 函数,适合运行插件自带的 setup 脚本;成对的 `preTeardown: SandboxHook[]` 按逆序在 agent teardown 之前收尾,当且仅当 `postSetup` 的时点已经走到才触发。脚本往 codex 全局配置登记的 hook 不需要交互式信任确认——运行时 `codex exec` 已绕过 hook 信任门槛,hook 直接生效。
74
74
  - **tracing**:内置,通过 `config.toml` 的 `[otel.trace_exporter.otlp-http]` 段配置,协议 `http/json`。
75
75
 
76
76
  例如,用 `configs/codex/no-web.toml` 关闭内置联网检索:
@@ -110,10 +110,10 @@ export default defineExperiment({
110
110
  - **鉴权**:`BUB_API_KEY` + `BUB_API_BASE`(OpenAI 兼容代理),工厂参数 `apiKey` / `apiBase` 可覆盖。
111
111
  - **装 Skill**:`skills: SkillSpec[]`,与另外两个 Adapter 同一个类型。装进 `.agents/skills/<name>/`,发现指引写进 AGENTS.md。
112
112
  - **装插件**:`pythonPlugins: PythonPluginSpec[]`(`{ package }`:PyPI 包、版本约束或 git URL),`setup` 阶段进 `uv tool install … --with <package>`。这个类型只属于 bub;package 集合进安装 checkpoint key,插件不同的两个变体不会复用同一份安装缓存。
113
- - **预制 Bub**:NiceEval 的 E2B 配方会把 Bub、OTel 插件和 Python 插件集合算成安装指纹。Adapter 只复用指纹完全一致的环境;仅在 PATH 里放一个 `bub` 不足以证明兼容。构建入口见 [沙箱 provider · 从官方基线继续构建以提速](/zh/how-to/sandbox-providers#从官方基线继续构建以提速)。
113
+ - **预制 Bub**:NiceEval 的 E2B 配方会把 Bub、OTel 插件和 Python 插件集合算成安装指纹。Adapter 只复用指纹完全一致的环境;仅在 PATH 里放一个 `bub` 不足以证明兼容。构建入口见 [Sandbox provider · 从官方基线继续构建以提速](/zh/tutorials/sandbox-providers#从官方基线继续构建以提速)。
114
114
  - bub 没有 `mcpServers`——MCP 只属于支持它的 Adapter,Config 上压根没有这个字段。
115
- - **安装后脚本**:`postSetup: SandboxHook[]`,语义与另外两个 Adapter 相同:全部安装步骤完成后按序在沙箱里跑你的钩子函数。
116
- - **安装方式**:走 `uv tool install`(PyPI 包,不是 npm 包),首次安装会建 checkpoint 缓存加速后续沙箱。
115
+ - **安装后脚本**:`postSetup: SandboxHook[]`,语义与另外两个 Adapter 相同:全部安装步骤完成后按序在 Sandbox 里跑你的 Hook 函数;成对的 `preTeardown: SandboxHook[]` 按逆序在 agent teardown 之前收尾,当且仅当 `postSetup` 的时点已经走到才触发。
116
+ - **安装方式**:走 `uv tool install`(PyPI 包,不是 npm 包),首次安装会建 checkpoint 缓存加速后续 Sandbox。
117
117
  - **tracing**:内置,通过环境变量注入,协议 `http/protobuf`。
118
118
 
119
119
  ```ts
@@ -141,11 +141,11 @@ export default defineExperiment({
141
141
  | 原生 Plugin | ✅ `plugins: ClaudeCodePluginSpec[]` | ✅ `plugins: CodexPluginSpec[]` | ❌ |
142
142
  | 官方配置文件 | ✅ `settingsFile`(完整 settings.json) | ✅ `configFile`(完整 config.toml) | ❌ |
143
143
  | Python Plugin | ❌ | ❌ | ✅ `pythonPlugins: PythonPluginSpec[]` |
144
- | 安装后脚本 | ✅ `postSetup: SandboxHook[]` | ✅ `postSetup: SandboxHook[]` | ✅ `postSetup: SandboxHook[]` |
144
+ | 安装后脚本 | ✅ `postSetup` / `preTeardown` | ✅ `postSetup` / `preTeardown` | ✅ `postSetup` / `preTeardown` |
145
145
  | tracing | ✅(beta,仅结构与计时) | ✅ | ✅ |
146
146
  | 安装方式 | npm 全局包 | npm 全局包 | `uv tool install`(PyPI) |
147
147
 
148
- 装了什么有据可查:Adapter 在 `setup` 收尾把安装清单写进沙箱的 `__niceeval__/agent-setup.json`,运行器把它存成 Attempt Artifact `agent-setup.json`(库里读 `attempt.agentSetup()`)。清单只记来源、ref、Skill/Plugin 名、解析出的版本,以及官方配置文件的项目相对路径和 SHA-256;不保存配置正文、API Key 或环境变量值。MCP server 同理只记非敏感字段:stdio 形态记 `name` / `command` / `args` 不记 `env`,HTTP 形态记 `name` / `url` 不记 `headers`。
148
+ 装了什么有据可查:Adapter 在 `setup` 收尾把安装清单写进 Sandbox 的 `__niceeval__/agent-setup.json`,运行器把它存成 Attempt Artifact `agent-setup.json`(库里读 `attempt.agentSetup()`)。清单只记来源、ref、Skill/Plugin 名、解析出的版本,以及官方配置文件的项目相对路径和 SHA-256;不保存配置正文、API Key 或环境变量值。MCP server 同理只记非敏感字段:stdio 形态记 `name` / `command` / `args` 不记 `env`,HTTP 形态记 `name` / `url` 不记 `headers`。
149
149
 
150
150
  ## 非 Sandbox 适配器
151
151
 
@@ -176,8 +176,8 @@ export default defineExperiment({
176
176
 
177
177
  ## 相关阅读
178
178
 
179
- - [接入你的 Agent](/zh/how-to/connect-your-agent) — 全景:experiment 怎么配、eval 怎么写。
180
- - [Sandbox Agent](/zh/how-to/sandbox-agent) — 怎么运行内置 Sandbox agent,以及怎么写自己的。
179
+ - [接入你的 Agent](/zh/tutorials/connect-your-agent) — 全景:experiment 怎么配、评估用例怎么写。
180
+ - [Sandbox Agent](/zh/tutorials/sandbox-agent) — 怎么运行内置 Sandbox agent,以及怎么写自己的。
181
181
  - [内置 Agent 能力参考](/zh/reference/builtin-agents) — 每个适配器逐能力盘点、非 Sandbox 适配器的完整代码示例。
182
- - [OTel 接入](/zh/how-to/connect-otel) — 把 span 发给 [NiceEval](https://niceeval.com/),换 `niceeval view` 的调用瀑布图。
182
+ - [OTel 接入](/zh/tutorials/connect-otel) — 把 span 发给 [NiceEval](https://niceeval.com/),换 `niceeval view` 的调用瀑布图。
183
183
  - [defineAgent 参考](/zh/reference/define-agent) — `defineAgent` / `defineSandboxAgent` 完整参数。