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
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 64" role="img" aria-label="NiceEval">
2
+ <rect x="6" y="9" width="52" height="9" fill="#f5f5f1"/>
3
+ <rect x="6" y="26" width="30" height="9" fill="#f5f5f1"/>
4
+ <rect x="6" y="43" width="16" height="9" fill="#f5f5f1"/>
5
+ <polyline points="33 43, 42 52, 57 29" fill="none" stroke="#b9ff3d" stroke-width="9" stroke-linecap="square" stroke-linejoin="miter"/>
6
+ <text x="76" y="41" fill="#f5f5f1" font-family="Avenir Next, Segoe UI, Arial, sans-serif" font-size="30" font-weight="700">NiceEval</text>
7
+ </svg>
@@ -1,6 +1,7 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 56" role="img" aria-label="niceeval">
2
- <rect width="56" height="56" rx="12" fill="#11161e"/>
3
- <path d="M15 14h28v7H25v7h15v7H25v13H15z" fill="#f8fafc"/>
4
- <path d="M31 35h14v7H31z" fill="#848c8e"/>
5
- <text x="72" y="37" fill="#11161e" font-family="Inter, Arial, sans-serif" font-size="28" font-weight="700">niceeval</text>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 64" role="img" aria-label="NiceEval">
2
+ <rect x="6" y="9" width="52" height="9" fill="#11161e"/>
3
+ <rect x="6" y="26" width="30" height="9" fill="#11161e"/>
4
+ <rect x="6" y="43" width="16" height="9" fill="#11161e"/>
5
+ <polyline points="33 43, 42 52, 57 29" fill="none" stroke="#b9ff3d" stroke-width="9" stroke-linecap="square" stroke-linejoin="miter"/>
6
+ <text x="76" y="41" fill="#11161e" font-family="Avenir Next, Segoe UI, Arial, sans-serif" font-size="30" font-weight="700">NiceEval</text>
6
7
  </svg>
@@ -2,26 +2,27 @@
2
2
 
3
3
  `zh/` 按读者此刻的需求组织,不按 NiceEval 的内部模块组织。判断一页放在哪里时,先问读者是在学习、完成任务、查事实、理解原理,还是修复问题。
4
4
 
5
- ## 五个正文分区
5
+ ## 五种正文类型
6
6
 
7
7
  | 目录 | 页面类型 | 读者要什么 | 本站边界 |
8
8
  | --- | --- | --- | --- |
9
- | `tutorials/` | Tutorial | 跟着一条安全路径拿到第一次成功 | 当前只有 `quickstart.mdx`。不为凑齐目录增加第二条入门路径 |
10
- | `how-to/` | How-to | 完成一个现实任务 | 标题用任务表述;步骤、验证方式和失败后的下一步要清楚 |
9
+ | `tutorials/` | Tutorial / How-to | 拿到第一次成功,或完成一个现实任务 | `quickstart.mdx` 负责最短成功路径;其余页面按具体任务组织,步骤、验证方式和失败后的下一步要清楚 |
11
10
  | `explanation/` | Explanation | 理解概念、边界和运行原理 | 不承担完整操作步骤或字段罗列 |
12
11
  | `reference/` | Technical Reference | 快速查准确、完整的事实 | API 签名、字段、类型和 CLI flags 以源码为权威来源 |
13
12
  | `troubleshooting/` | Troubleshooting | 从可见症状定位并修复问题 | 按症状组织,不按内部模块组织 |
14
13
 
15
14
  `index.mdx` 和 `introduction.mdx` 是站点入口,不硬归入正文类型。`examples/` 是独立资源入口,不属于 Diátaxis 的四种正文类型。
16
15
 
16
+ Tutorial 和 How-to 都属于用户完成任务时阅读的教程,因此统一放进 `tutorials/`,并在导航中合并到 `Tutorials` 标签。`quickstart.mdx` 负责第一次成功,其余页面负责已有基础后的具体任务。目录合并不改变两种页面的写作边界,也不把 Reference 或 Explanation 内容混进教程。
17
+
17
18
  ## Examples 的收录标准
18
19
 
19
- `examples/` 只收录有真实可运行源码的项目。一个案例页只回答四件事:被测对象是什么、这个项目证明什么、源码在哪里、怎么运行。操作步骤的通用版本链接 How-to,字段和配置全集链接 Reference,不在案例页复制。
20
+ `examples/` 只收录有真实可运行源码的项目。一个案例页只说明被测对象、验证目标、源码位置和运行方式。操作步骤的通用版本链接对应任务教程,字段和配置全集链接 Reference,不在案例页复制。
20
21
 
21
22
  - 接入前后能从仓库源码计算时,由生成器产出 diff 页面,不手抄代码。
22
23
  - 同一个可运行项目只保留一张案例页。Skill、Plugin 等相邻主题共享实验设计时合并,不复制两份近似正文。
23
24
  - 只有一个条目的 Showcase 不单独成页,真实项目直接列在 `examples/index.mdx`。
24
- - 没有可运行源码、只有片段或设想的内容不进 Examples。片段进入对应 How-to,未实现方向留在 Roadmap。
25
+ - 没有可运行源码、只有片段或设想的内容不进 Examples。片段进入对应任务教程,未实现方向留在 Roadmap。
25
26
 
26
27
  ## Reference 的生成边界
27
28
 
@@ -38,7 +39,7 @@ Technical Reference 不等于整页都由生成器拼出来。页面仍可手写
38
39
 
39
40
  - `explanation/runner.mdx` 解释执行引擎如何发现、调度、缓存和产出结果,不是一步一任务的操作指南。
40
41
  - `reference/official-adapters.mdx`、`reference/report-components.mdx` 和 `reference/results-data.mdx` 用于查能力、组件或数据 API,不能留在 How-to。
41
- - `troubleshooting/debugging.mdx` 与 `troubleshooting/debug-sandbox.mdx` 从失败症状出发,目录独立,在导航中归入 How-to Guides。
42
- - `how-to/sandbox-providers.mdx` 目前保留在 How-to,因为主问题是选择并配置 Provider;若以后字段表继续增长,再拆出独立 Provider Reference。
42
+ - `troubleshooting/debugging.mdx` 与 `troubleshooting/debug-sandbox.mdx` 从失败症状出发,目录独立,在导航中归入 `Tutorials` 标签下的“问题排查”。
43
+ - `tutorials/sandbox-providers.mdx` How-to 写,因为主任务是选择并配置 Provider;若以后字段表继续增长,再拆出独立 Provider Reference。
43
44
 
44
45
  新增或移动页面时,同时更新 `docs-site/docs.json` 和旧路径 redirect。校验命令以 [`../AGENTS.md`](../AGENTS.md) 为准。
@@ -19,11 +19,11 @@ description: "一个可运行的 AI SDK v6 Web Agent 评测项目,覆盖自写
19
19
  | --- | --- |
20
20
  | 被测应用 | AI SDK v6 Web Agent,HTTP `POST /api/turn` |
21
21
  | Adapter | `defineAgent` + 自定义 `AgentEvent` → `StreamEvent` 映射 |
22
- | Eval | 天气工具、图片理解、多轮文本、多轮图片上下文 |
22
+ | 评估用例 | 天气工具、图片理解、多轮文本、多轮图片上下文 |
23
23
  | Experiment | 每个文件固定一个模型,同组比较 DeepSeek 与 GPT |
24
24
  | 可观测 | 应用继续上报 Langfuse,同时把本轮 OTLP 数据发给 NiceEval |
25
25
 
26
- Adapter 只负责连接和翻译。URL 与模型属于 Experiment;Eval 只描述交互与好结果。这个分层让同一批 Eval 可以复用到不同模型和部署实例。
26
+ Adapter 只负责连接和翻译。URL 与模型属于 Experiment;评估用例只描述交互与好结果。这个分层让同一批评估用例可以复用到不同模型和部署实例。
27
27
 
28
28
  ## 目录
29
29
 
@@ -58,6 +58,6 @@ pnpm exec niceeval view
58
58
 
59
59
  ## 继续阅读
60
60
 
61
- - [接入你的 Agent](/zh/how-to/connect-your-agent):从最小 Adapter 开始接入自己的协议。
62
- - [如何写好 Send](/zh/how-to/write-send):逐步补齐会话、工具、HITL 和 OTel。
63
- - [实验矩阵](/zh/how-to/experiments):组织模型和配置对比。
61
+ - [接入你的 Agent](/zh/tutorials/connect-your-agent):从最小 Adapter 开始接入自己的协议。
62
+ - [编写 Send](/zh/tutorials/write-send):逐步补齐会话、工具、HITL 和 OTel。
63
+ - [实验矩阵](/zh/tutorials/experiments):组织模型和配置对比。
@@ -7,7 +7,7 @@ description: "用真实 Workspace、基线实验和自定义报告,评估 Skil
7
7
  这个案例把扩展内容作为 Experiment 变量,让同一个 Coding Agent 在同一批真实开发任务上运行,再比较任务成功率、成本、耗时和行为差异。
8
8
 
9
9
  - [查看完整源码](https://github.com/CorrectRoadH/coding-agent-skill)
10
- - [查看 Fixtures 指南](/zh/how-to/fixtures)
10
+ - [查看 Fixtures 指南](/zh/tutorials/fixtures)
11
11
 
12
12
  ## 两组实验
13
13
 
@@ -20,7 +20,7 @@ Ponytail 这一组迁移自第三方 Plugin 的 Agentic Benchmark,但这个仓
20
20
 
21
21
  ## 实验设计
22
22
 
23
- 每个 Arm 固定相同的模型、Sandbox、任务集、Runs 和预算,只改变注入内容。Eval 不读取“当前是哪个 Arm”,也不为实验组降低验收标准。
23
+ 每个 Arm 固定相同的模型、Sandbox、任务集、Runs 和预算,只改变注入内容。评估用例不读取“当前是哪个 Arm”,也不为某个对照配置降低验收标准。
24
24
 
25
25
  ```text
26
26
  coding-agent-skill/
@@ -51,7 +51,7 @@ pnpm exec niceeval view --report reports/benchmark.tsx
51
51
 
52
52
  ## 从这个案例复用什么
53
53
 
54
- - 用 Experiment 表达有扩展和无扩展的对照,不让 Eval 知道实验条件。
54
+ - 用 Experiment 表达有扩展和无扩展的对照,不让评估用例知道实验条件。
55
55
  - Prompt 不泄露答案;验证阶段再检查测试、源码、Diff 和行为证据。
56
56
  - 把任务成功率作为主指标,把 Token、成本、耗时和行为作为解释指标。
57
- - [评分指南](/zh/how-to/scoring-guide) 负责选择 Gate、Soft 和 Judge;本页不复制评分 API。
57
+ - [评分指南](/zh/tutorials/scoring-guide) 负责选择 Gate、Soft 和 Judge;本页不复制评分 API。
@@ -6,7 +6,7 @@ description: "按被测对象选择可运行的 NiceEval 示例:Agent Framewor
6
6
 
7
7
  这里的每个示例都有真实可运行源码。先按被测对象选择,不必从头依次阅读。
8
8
 
9
- 如果你还没有跑通过第一条 Eval,先读 [Quickstart](/zh/tutorials/quickstart)。如果你已经知道要完成什么,直接进入对应的 [How-to Guides](/zh/how-to/connect-your-agent)
9
+ 如果你还没有跑通过第一条评估用例,先读 [Quickstart](/zh/tutorials/quickstart)。已经明确任务时,直接进入对应的 [Tutorials](/zh/tutorials/connect-your-agent) 页面。
10
10
 
11
11
  ## 接入已有 Agent Framework
12
12
 
@@ -42,9 +42,9 @@ description: "按被测对象选择可运行的 NiceEval 示例:Agent Framewor
42
42
  - [查看在线报告](https://niceeval.com/showcase/memory)
43
43
  - [查看项目源码](https://github.com/CorrectRoadH/coding-agent-memory-evals)
44
44
 
45
- ## 什么不放在 Examples
45
+ ## Examples 的收录边界
46
46
 
47
- - 单段 API 用法放进 How-to 或 Reference。
47
+ - 单段 API 用法放进任务教程或 Reference。
48
48
  - 没有可运行源码的伪项目不收录。
49
49
  - Roadmap 和尚未实现的接入不收录。
50
50
  - 同一个项目不为 Skill、Plugin、Hook 等相邻叫法复制多张案例页。
@@ -8,7 +8,7 @@ description: "一个 AI SDK v7 聊天应用,对着它的 HTTP 接口无侵入
8
8
 
9
9
  对比对象:
10
10
 
11
- - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/ai-sdk-v7](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/ai-sdk-v7) —— 普通的 AI SDK v7 聊天应用(HTTP 服务器 + React 聊天 UI),还没接任何 eval。
11
+ - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/ai-sdk-v7](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/ai-sdk-v7) —— 普通的 AI SDK v7 聊天应用(HTTP 服务器 + React 聊天 UI),还没接任何评估用例。
12
12
  - **after**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/ai-sdk-v7](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/ai-sdk-v7) —— 同一个应用接入 NiceEval 之后的样子。
13
13
 
14
14
  **接入方式**:内置 **`uiMessageStreamAgent`**——AI SDK UI Message Stream 协议(`useChat`
@@ -1,20 +1,20 @@
1
1
  ---
2
2
  title: "Claude Agent SDK 如何非侵入式接入 NiceEval"
3
3
  sidebarTitle: "Claude Agent SDK 如何接入"
4
- description: "一个 Claude Agent SDK 助手后端,接入 NiceEval 前后的完整代码 diff:应用侧一行没改,全部新增在 eval 侧。"
4
+ description: "一个 Claude Agent SDK 助手后端,接入 NiceEval 前后的完整代码 diff:应用侧一行没改,全部新增在评估用例侧。"
5
5
  ---
6
6
 
7
7
  {/* 本文件由 scripts/gen-diff-code.ts 生成(pnpm run gen:diff-code),不要手工编辑 */}
8
8
 
9
9
  对比对象:
10
10
 
11
- - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/claude-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/claude-sdk) —— 独立的 `@anthropic-ai/claude-agent-sdk` HTTP 服务,还没接任何 eval。
11
+ - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/claude-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/claude-sdk) —— 独立的 `@anthropic-ai/claude-agent-sdk` HTTP 服务,还没接任何评估用例。
12
12
  - **after**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/claude-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/claude-sdk) —— 同一个应用接入 NiceEval 之后的样子。
13
13
 
14
14
  **接入方式**:官方转换器——Claude Agent SDK 原生 `SDKMessage` → 标准事件的映射是
15
15
  `fromClaudeSdkMessages`(`"niceeval/adapter"` 导出)的事,adapter 只剩传输粘合与
16
16
  HITL 停轮判定(`calculate` 经官方 `canUseTool` 回调门控)。应用由你自己按它的方式启动
17
- (`pnpm start`),eval 不代管进程。应用侧 `src/backend/*` 逐字节未变。
17
+ (`pnpm start`),评估用例不代管进程。应用侧 `src/backend/*` 逐字节未变。
18
18
 
19
19
  接入的全部代码变更(生成时从两个目录实测统计):
20
20
 
@@ -8,15 +8,15 @@ description: "一个 Codex SDK(目录里的编码 agent)后端,接入 Nice
8
8
 
9
9
  对比对象:
10
10
 
11
- - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/codex-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/codex-sdk) —— 独立的 `@openai/codex-sdk` HTTP 服务,还没接任何 eval。
11
+ - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/codex-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/codex-sdk) —— 独立的 `@openai/codex-sdk` HTTP 服务,还没接任何评估用例。
12
12
  - **after**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/codex-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/codex-sdk) —— 同一个应用接入 NiceEval 之后的样子。
13
13
 
14
14
  **接入方式**:官方转换器——codex 原生 `ThreadEvent` → 标准事件的映射是
15
15
  `fromCodexThreadEvents`(`"niceeval/adapter"` 导出)的事:消息文本、工具项
16
16
  (`command_execution` / `mcp_tool_call` / `file_change` → 配对的 `action.*`)和
17
17
  `turn.completed` 的 usage 全部来自这条流,adapter 只剩传输粘合。没有 HITL
18
- (Codex SDK 不支持)。eval 测的是真实编码任务(在工作目录里写文件、跑命令),断言
19
- 直接读磁盘验证。应用由你自己启动(`pnpm start`),eval 不代管进程。应用侧
18
+ (Codex SDK 不支持)。评估用例测的是真实编码任务(在工作目录里写文件、跑命令),断言
19
+ 直接读磁盘验证。应用由你自己启动(`pnpm start`),评估用例不代管进程。应用侧
20
20
  `src/backend/*` 逐字节未变。要 OTel 瀑布图见 `tier2/`,feature A/B 见 `tier3/`。
21
21
 
22
22
  接入的全部代码变更(生成时从两个目录实测统计):
@@ -8,18 +8,18 @@ description: "一个纯 Python LangGraph + LangSmith OTel 导出的应用,接
8
8
 
9
9
  对比对象:
10
10
 
11
- - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/langgraph](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/langgraph) —— 纯 Python 的 `create_agent`(LangChain 1.x / LangGraph)HTTP 服务,还没接任何 eval。
11
+ - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/langgraph](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/langgraph) —— 纯 Python 的 `create_agent`(LangChain 1.x / LangGraph)HTTP 服务,还没接任何评估用例。
12
12
  - **after**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/langgraph](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/langgraph) —— 同一个应用接入 NiceEval 之后的样子。
13
13
 
14
14
  **接入方式**:手写帧映射——server.py 的自定义 JSON 帧逐帧翻成标准事件(`tool-input` →
15
15
  `action.called`、`tool-output` → `action.result`、`text-delta` 累积成 `message`、
16
16
  `tool-approval-request` → 停轮 + `input.requested`),HITL 停轮现场的存取走 `ctx.session`。
17
- 被测应用是 Python,eval 侧是另起的独立 TS 项目,应用侧 `src/backend/*.py` 逐字节未变。
17
+ 被测应用是 Python,评估用例侧是另起的独立 TS 项目,应用侧 `src/backend/*.py` 逐字节未变。
18
18
  要 OTel 瀑布图见 `tier2/`,feature A/B 见 `tier3/`。
19
19
 
20
20
  接入的全部代码变更(生成时从两个目录实测统计):
21
21
 
22
- <table className="gd-summary"><tbody><tr><th>{"类别"}</th><th>{"文件数"}</th><th>{"行数"}</th></tr><tr><td>{"eval TS 项目脚手架(必要:被测应用是 Python,全新文件)"}</td><td>{"3"}</td><td>{"+42"}</td></tr><tr><td>{"adapter(必要:传输粘合,协议映射在官方包里)"}</td><td>{"2"}</td><td>{"+182"}</td></tr><tr><td>{"evals 与 experiments(评测内容,按需增长)"}</td><td>{"6"}</td><td>{"+118"}</td></tr><tr className="gd-total"><td>{"合计"}</td><td>{"11"}</td><td>{"+342"}</td></tr></tbody></table>
22
+ <table className="gd-summary"><tbody><tr><th>{"类别"}</th><th>{"文件数"}</th><th>{"行数"}</th></tr><tr><td>{"评估用例侧 TS 项目脚手架(必要:被测应用是 Python,全新文件)"}</td><td>{"3"}</td><td>{"+42"}</td></tr><tr><td>{"adapter(必要:传输粘合,协议映射在官方包里)"}</td><td>{"2"}</td><td>{"+182"}</td></tr><tr><td>{"evals 与 experiments(评测内容,按需增长)"}</td><td>{"6"}</td><td>{"+118"}</td></tr><tr className="gd-total"><td>{"合计"}</td><td>{"11"}</td><td>{"+342"}</td></tr></tbody></table>
23
23
 
24
24
  ## 文件清单
25
25
 
@@ -8,13 +8,13 @@ description: "一个 pi-agent-core(@earendil-works)助手后端,接入 NiceEva
8
8
 
9
9
  对比对象:
10
10
 
11
- - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/pi-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/pi-sdk) —— 独立的 `@earendil-works/pi-agent-core` HTTP 服务,还没接任何 eval。
11
+ - **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/pi-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/pi-sdk) —— 独立的 `@earendil-works/pi-agent-core` HTTP 服务,还没接任何评估用例。
12
12
  - **after**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/pi-sdk](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/pi-sdk) —— 同一个应用接入 NiceEval 之后的样子。
13
13
 
14
14
  **接入方式**:官方转换器——pi 原生 `AgentEvent` → 标准事件的映射是
15
15
  `fromPiAgentEvents`(`"niceeval/adapter"` 导出)的事,adapter 只剩传输粘合:
16
16
  应用在哪个 URL、审批打哪个端点(`calculate` 工具走 HITL 审批)。应用由你自己按它的
17
- 方式启动(`pnpm start`),eval 不代管进程。应用侧 `src/backend/*` 逐字节未变。
17
+ 方式启动(`pnpm start`),评估用例不代管进程。应用侧 `src/backend/*` 逐字节未变。
18
18
 
19
19
  接入的全部代码变更(生成时从两个目录实测统计):
20
20
 
@@ -4,18 +4,18 @@ sidebarTitle: "Adapter"
4
4
  description: "Adapter 是你写的适配器。本文讲清楚 send 函数传入什么返回什么、被测系统配置怎么传、三个接入等级,以及 t 上的能力从哪来。"
5
5
  ---
6
6
 
7
- 在 [NiceEval](https://niceeval.com/) 里,`Adapter` 是连接运行器和被测系统的适配层。Adapter 需要实现 `send` 函数:把 `t.send()` eval 侧动作发给你的应用,再把应用返回翻译成 [NiceEval](https://niceeval.com/) 的标准 `Turn`。
7
+ 在 [NiceEval](https://niceeval.com/) 里,`Adapter` 是连接运行器和被测系统的适配层。Adapter 需要实现 `send` 函数:把 `t.send()` 等评估侧动作发给你的应用,再把应用返回翻译成 [NiceEval](https://niceeval.com/) 的标准 `Turn`。
8
8
 
9
- 后续阅读[写 send](/zh/how-to/write-send)
9
+ 后续阅读[写 send](/zh/tutorials/write-send)
10
10
 
11
11
  ## 适配器
12
12
  如果被测系统使用标准的 OpenAI Chat Completions 或 Responses 协议,可以直接用官方适配器。自己实现的前后端协议(HTTP、gRPC、WebSocket 都行)则写一个 Adapter:它知道怎么鉴权、怎么调用你的应用、怎么把返回翻译成标准事件流。
13
13
 
14
14
  一次 `t.send()` 的完整往返,穿过这条边界两次:
15
15
 
16
- ![一次 t.send 的完整往返:eval 调用 t.send,运行器组装 TurnInput 与 ctx,adapter 调用你的应用并返回标准事件流 Turn。](/images/agent-turn-roundtrip-zh.svg)
16
+ ![一次 t.send 的完整往返:评估用例调用 t.send,运行器组装 TurnInput 与 ctx,adapter 调用你的应用并返回标准事件流 Turn。](/images/agent-turn-roundtrip-zh.svg)
17
17
 
18
- 去程:eval 里的驱动动词(`t.send` / `t.sendFile` / `t.respond`)组装 `TurnInput` 和本会话线的 `ctx`,调一次 Adapter 的 `send`。
18
+ 去程:评估用例里的驱动动词(`t.send` / `t.sendFile` / `t.respond`)组装 `TurnInput` 和本会话线的 `ctx`,调一次 Adapter 的 `send`。
19
19
 
20
20
  回程:Adapter 把应用的原始返回翻译成 `Turn`——其中 `events` 是一个按发生顺序排列的事件对象数组(下文有实际值)
21
21
 
@@ -96,14 +96,14 @@ export default defineExperiment({
96
96
 
97
97
  按「Adapter 接到哪里、额外拿到什么观测数据」,接入分三级:**Tier 1 只接 send**(应用代码一行不改,全套断言在这一级就齐了)、**Tier 2 send + OTel**(应用把 span 发给 [NiceEval](https://niceeval.com/),换 `niceeval view` 的调用瀑布图)、**Tier 3 侵入改造 + experiment flags**(feature A/B)。每档投入什么、买到什么、什么时候升级,见 [Tier](/zh/explanation/tier)。
98
98
 
99
- eval 侧的驱动 API——`t.send()`、`t.sendFile()`、`t.newSession()`、HITL 的 `t.respond()` / `t.respondAll()`
99
+ 评估侧的驱动 API——`t.send()`、`t.sendFile()`、`t.newSession()`、HITL 的 `t.respond()` / `t.respondAll()`
100
100
  统一都是调用 Adapter 的 `send`。
101
101
 
102
- 怎么收敛、send 里怎么接,见[写 send](/zh/how-to/write-send)。
102
+ 怎么收敛、send 里怎么接,见[写 send](/zh/tutorials/write-send)。
103
103
 
104
104
  ## send 函数
105
105
 
106
- 不管 Adapter 连的是 HTTP 服务还是沙箱里的 CLI,暴露给运行器的接口完全一致:
106
+ 不管 Adapter 连的是 HTTP 服务还是 Sandbox 里的 CLI,暴露给运行器的接口完全一致:
107
107
 
108
108
  ```ts
109
109
  interface Agent {
@@ -119,7 +119,7 @@ interface Agent {
119
119
  `send` 是唯一要实现的函数。它的签名里只有三个类型,分开看。
120
120
 
121
121
  <Note>
122
- 这里的 `setup` / `teardown` 是 Agent 自己"怎么连自己"的私事(装 CLI、写鉴权配置)。按实验变化的环境准备(装某个实验专属的二进制、预热、跨 attempt 保存状态)不写在 Agent 上,挂在 `sandbox` 字段那个 Sandbox spec 自己的 `.setup()` / `.teardown()` 链式方法上,见 [沙箱 provider · 环境钩子](/zh/how-to/sandbox-providers#环境钩子)。
122
+ 这里的 `setup` / `teardown` 是 Agent 自己"怎么连自己"的私事(装 CLI、写鉴权配置)。按实验变化的环境准备(装某个实验专属的二进制、预热、跨 attempt 保存状态)不写在 Agent 上,挂在 `sandbox` 字段那个 Sandbox spec 自己的 `.setup()` / `.teardown()` 链式方法上,见 [Sandbox provider · 生命周期](/zh/tutorials/sandbox-providers#生命周期)。
123
123
  </Note>
124
124
 
125
125
  ### 传入:`TurnInput`
@@ -145,11 +145,11 @@ interface InputResponse {
145
145
  }
146
146
  ```
147
147
 
148
- eval 侧不管调的是 `t.send()`、`t.sendFile()` 还是 `t.respond()`,到 Adapter 时都是一次普通的 `send`,差别全在字段上:
148
+ 评估侧不管调的是 `t.send()`、`t.sendFile()` 还是 `t.respond()`,到 Adapter 时都是一次普通的 `send`,差别全在字段上:
149
149
 
150
150
  如果你的应用接口不收文件就忽略 `files`。
151
151
 
152
- | eval | `text` | `files` | `responses` | `outputSchema` |
152
+ | 评估侧 | `text` | `files` | `responses` | `outputSchema` |
153
153
  |---|---|---|---|---|
154
154
  | `t.send(text)` | 发送文本 | — | — | 声明了 `output` 才有 |
155
155
  | `t.sendFile(path, text?)` | 附言(可为空串) | 有 | — | 同上 |
@@ -160,7 +160,7 @@ eval 侧不管调的是 `t.send()`、`t.sendFile()` 还是 `t.respond()`,到 A
160
160
 
161
161
  #### 不同回答的入参
162
162
 
163
- HITL 回答轮里,人的裁决以结构化形式随 `input.responses` 到达——Adapter 不需要解析 `text` 去猜哪句回答对应哪个请求、算不算批准。每条回答必带 `requestId`;`optionId` 和 `text` 二选一:回答命中请求 `options` 里的某个 id 就是 `optionId`(eval 侧已校验过存在,不会有打错的字静默传进来),否则整句作为自由文本落在 `text`。四种典型形态:
163
+ HITL 回答轮里,人的裁决以结构化形式随 `input.responses` 到达——Adapter 不需要解析 `text` 去猜哪句回答对应哪个请求、算不算批准。每条回答必带 `requestId`;`optionId` 和 `text` 二选一:回答命中请求 `options` 里的某个 id 就是 `optionId`(评估侧已校验过存在,不会有打错的字静默传进来),否则整句作为自由文本落在 `text`。四种典型形态:
164
164
 
165
165
  ```ts
166
166
  // ① 单个待处理请求,回答命中选项(approve / deny 同理,只是 optionId 不同)
@@ -232,9 +232,9 @@ interface AgentSession {
232
232
 
233
233
  Runner 为 Agent 的 `setup`、每次 `send` 和 `teardown` 分别绑定 lifecycle scope。Adapter 只报告当前回调内部的 progress/diagnostic,不能传 phase、颜色或输出流。`progress` 不落盘;diagnostic 会进入 Attempt 的 `result.json`。无法继续时抛错,由 runner 保存结构化 error 并把 Attempt 标为 `errored`。
234
234
 
235
- `ctx` 里没有要你检查的标志位。三个档位字段都是"透传"语义:`model`、`flags` 由 experiment 声明、运行器原样递过来,Adapter 只负责随请求转发给应用,不解释它们的含义;`telemetry` 仅在配置了 OTel 接入时出现,`send` 里只需要把 `headers` spread 进请求头——接收端点在 `defineConfig` 里固定、由应用启动时指向,不从这里传,见[OTel 接入](/zh/how-to/connect-otel)。`experimentId` 是路径推导出的稳定标识,典型用途是在 Sandbox 的环境钩子里按实验隔离跨 attempt 的状态(缓存目录名、沙箱快照 tag 按它分区),见 [沙箱 provider · 环境钩子](/zh/how-to/sandbox-providers#环境钩子)。
235
+ `ctx` 里没有要你检查的标志位。三个档位字段都是"透传"语义:`model`、`flags` 由 experiment 声明、运行器原样递过来,Adapter 只负责随请求转发给应用,不解释它们的含义;`telemetry` 仅在配置了 OTel 接入时出现,`send` 里只需要把 `headers` spread 进请求头——接收端点在 `defineConfig` 里固定、由应用启动时指向,不从这里传,见[OTel 接入](/zh/tutorials/connect-otel)。`experimentId` 是路径推导出的稳定标识,典型用途是在 Sandbox 的生命周期里按实验隔离跨 attempt 的状态(缓存目录名、Sandbox 快照 tag 按它分区),见 [Sandbox provider · 生命周期](/zh/tutorials/sandbox-providers#生命周期)。
236
236
 
237
- `session` 是本条会话线的自有状态,[NiceEval](https://niceeval.com/) 对它只承诺一件事:**同一条会话线的每次 `send` 拿到同一个 `ctx.session`,新会话线(eval 的第一轮,或 `t.newSession()` 之后)拿到一个全新的。** 会话续接(`id`/`capture`、`history`)和 HITL 停轮现场(`hold`/`take`)的存取器都在它上面,"第一轮"就是新会话线的自然形态——`id` 是 `undefined`、`history.get()` 是空数组,没有要判断的分支;`state` 是这些存取器之外的逃生舱,框架从不往里写数据。
237
+ `session` 是本条会话线的自有状态,[NiceEval](https://niceeval.com/) 对它只承诺一件事:**同一条会话线的每次 `send` 拿到同一个 `ctx.session`,新会话线(评估用例的第一轮,或 `t.newSession()` 之后)拿到一个全新的。** 会话续接(`id`/`capture`、`history`)和 HITL 停轮现场(`hold`/`take`)的存取器都在它上面,"第一轮"就是新会话线的自然形态——`id` 是 `undefined`、`history.get()` 是空数组,没有要判断的分支;`state` 是这些存取器之外的逃生舱,框架从不往里写数据。
238
238
 
239
239
  ### 返回:`Turn`
240
240
 
@@ -257,9 +257,9 @@ interface Turn {
257
257
  ]
258
258
  ```
259
259
 
260
- 对象统共十种类型(`message`、`action.*`、`input.requested`……完整清单见[事件流参考](/zh/reference/events))。断言读的就是这个数组:`t.calledTool("get_weather")` 数 `action.called`,`t.reply` 取最后一条 assistant `message`。注意 `send` 每次只返回**本轮**的数组——跨轮拼成整条会话线是运行器的事,见下一节。多数情况下你也不手写这些对象:官方转换器的返回值就是一个填好 `events`、`usage`、`status` 的完整 `Turn`,怎么选转换器见[写 send](/zh/how-to/write-send)。
260
+ 对象统共十种类型(`message`、`action.*`、`input.requested`……完整清单见[事件流参考](/zh/reference/events))。断言读的就是这个数组:`t.calledTool("get_weather")` 数 `action.called`,`t.reply` 取最后一条 assistant `message`。注意 `send` 每次只返回**本轮**的数组——跨轮拼成整条会话线是运行器的事,见下一节。多数情况下你也不手写这些对象:官方转换器的返回值就是一个填好 `events`、`usage`、`status` 的完整 `Turn`,怎么选转换器见[写 send](/zh/tutorials/write-send)。
261
261
 
262
- `data` 不是"随便放点什么"的口袋,它只有一条规则:**要什么,由 eval 在 send 上用 schema 声明;声明了才有 data,拿到手就是声明的类型。**
262
+ `data` 不是"随便放点什么"的口袋,它只有一条规则:**要什么,由评估用例在 send 上用 schema 声明;声明了才有 data,拿到手就是声明的类型。**
263
263
 
264
264
  ```ts
265
265
  // eval 侧:output 声明既是给应用的要求,也是 turn.data 的类型来源
@@ -275,7 +275,7 @@ turn.data.amount; // 类型是 number——不是 unknown,不用手动收窄
275
275
 
276
276
  `send` 一 return,Adapter 的工作就结束了——剩下全是运行器的事。四个字段各有明确去向:
277
277
 
278
- | Turn 字段 | 运行器拿它做什么 | eval 作者在哪感知到 |
278
+ | Turn 字段 | 运行器拿它做什么 | 评估用例作者在哪感知到 |
279
279
  |---|---|---|
280
280
  | `events` | 追加进本会话线的事件流,`deriveRunFacts` 折叠成事实(`toolCalls`、`parked`、`messageCount`…);最后一条 assistant `message` 同时更新 `t.reply` | 全部作用域断言:`t.calledTool()`、`t.messageIncludes()`…;`t.events` 可直接查 |
281
281
  | `status` | 记录本轮终态;`"waiting"` 时把本轮的 `input.requested` 收进待答列表 | `t.succeeded()` / `t.parked()`;`"waiting"` 之后用 `t.respond()` 接 |
@@ -302,8 +302,8 @@ turn.data.amount; // 类型是 number——不是 unknown,不用手动收窄
302
302
 
303
303
  ## 相关阅读
304
304
 
305
- - [写 send](/zh/how-to/write-send) — 实操教程:从发一条消息到完整接入,七步递进,每步解锁一组断言。
306
- - [接入你的 Agent](/zh/how-to/connect-your-agent) — 接入全景:最小接入、参数通道与增量地图。
307
- - [Drive](/zh/explanation/drive) — eval 侧视角:`t.send()`、`t.newSession()` 与 HITL 怎么用。
305
+ - [写 send](/zh/tutorials/write-send) — 实操教程:从发一条消息到完整接入,七步递进,每步解锁一组断言。
306
+ - [接入你的 Agent](/zh/tutorials/connect-your-agent) — 接入全景:最小接入、参数通道与增量地图。
307
+ - [Drive](/zh/explanation/drive) — 评估侧视角:`t.send()`、`t.newSession()` 与 HITL 怎么用。
308
308
  - [Assert](/zh/explanation/assert) — 标准事件流驱动的完整断言词汇。
309
309
  - [架构概览](/zh/explanation/overview) — 四层架构和边界。
@@ -4,7 +4,7 @@ sidebarTitle: "断言"
4
4
  description: "NiceEval 的断言词汇——值断言、作用域断言、test-as-scoring 和效率断言——以及 gate / soft 严重度和判定 verdict 的规则。"
5
5
  ---
6
6
 
7
- 断言把 agent 在一次 eval 里做的一切——每条消息、每次工具调用、每处文件改动、每一分 token——折叠成一个可解释的结果。[NiceEval](https://niceeval.com/) 提供四种互补的断言机制:有的立即检查一个值,有的在整轮跑完后评估整次运行,有的在沙箱里跑测试,有的衡量效率。四种都产出同一种 `Assertion` 类型,都进同一套判定规则。第五种机制——让语言模型评判开放式质量——见 [Judge](/zh/explanation/judge)。
7
+ 断言把 agent 在一次评估用例里做的一切——每条消息、每次工具调用、每处文件改动、每一分 token——折叠成一个可解释的结果。[NiceEval](https://niceeval.com/) 提供四种互补的断言机制:有的立即检查一个值,有的在整轮跑完后评估整次运行,有的在 Sandbox 里跑测试,有的衡量效率。四种都产出同一种 `Assertion` 类型,都进同一套判定规则。第五种机制——让语言模型评判开放式质量——见 [Judge](/zh/explanation/judge)。
8
8
 
9
9
  ## 四种断言机制
10
10
 
@@ -16,7 +16,7 @@ description: "NiceEval 的断言词汇——值断言、作用域断言、test-a
16
16
  `t.succeeded()`、`t.calledTool()`、`t.messageIncludes()` 等在 `test(t)` 里注册,但在函数返回**之后**才对完整轮次数据统一评估,适合整次运行的事实。
17
17
  </Card>
18
18
  <Card title="3. Test-as-scoring" icon="flask">
19
- sandbox eval 里,从 `test(t)` 跑项目测试、构建脚本或临时探针命令——适合代码任务,文件内容和构建结果就是事实标准。
19
+ Sandbox 型评估用例里,从 `test(t)` 跑项目测试、构建脚本或临时探针命令——适合代码任务,文件内容和构建结果就是事实标准。
20
20
  </Card>
21
21
  <Card title="4. 效率断言" icon="gauge">
22
22
  `t.maxTokens()` 和 `t.maxCost()` 把 token 用量和估算成本变成可评分的维度。答对了但烧掉十倍 token 的 agent,不该跟省着用的拿一样的分。
@@ -29,12 +29,12 @@ description: "NiceEval 的断言词汇——值断言、作用域断言、test-a
29
29
 
30
30
  <Tabs>
31
31
  <Tab title="gate">
32
- gate 是硬性要求。一旦失败,整个 eval 立刻判为 `failed`——不管其它断言表现如何。适合必须为真的事实:“调用了正确的工具”“输出解析为合法 JSON”“没有 shell 命令报错”。
32
+ gate 是硬性要求。一旦失败,整个评估用例立刻判为 `failed`——不管其它断言表现如何。适合必须为真的事实:“调用了正确的工具”“输出解析为合法 JSON”“没有 shell 命令报错”。
33
33
 
34
34
  `niceeval/expect` 里大多数匹配器(`includes`、`equals`、`matches`、`satisfies`)默认 gate;`t.succeeded()`、`t.calledTool()` 这类作用域断言也默认 gate。
35
35
  </Tab>
36
36
  <Tab title="soft">
37
- soft 是带数值阈值的质量分。分数低于阈值时,eval 变成 `passed` 而不是 `failed`——是质量回归的信号,但不算硬性破坏。soft 失败只在 `--strict` 下才算数。
37
+ soft 是带数值阈值的质量分。分数低于阈值时,评估用例变成 `passed` 而不是 `failed`——是质量回归的信号,但不算硬性破坏。soft 失败只在 `--strict` 下才算数。
38
38
 
39
39
  适合“好不好”而不是“对不对”的连续判断:相似度打分、LLM-as-judge 的事实性评分、想跟踪但不想拦 CI 的成本预算。
40
40
 
@@ -183,9 +183,9 @@ t.sandbox.noFailedShellCommands();
183
183
 
184
184
  作用域断言到处遵守同一条规则:**接收者决定作用域,不是断言名字决定作用域。** `t.*` 聚合这次 eval run 的全部轮次(含 `t.newSession()` 开的额外 session);`session.*`(`t.newSession()` 的返回值)只看这一条 session;`turn.*`(`t.send()` 的返回值)只看这一轮自己。同一套词汇,不同接收者——各接收者是什么见 [Drive](/zh/explanation/drive)。
185
185
 
186
- ## 3. Test-as-scoring(沙箱型 eval)
186
+ ## 3. Test-as-scoring(Sandbox 型评估用例)
187
187
 
188
- 沙箱型代码 eval 里,在 `test(t)` 内跑验证命令,把结果记成断言:
188
+ Sandbox 型代码评估用例里,在 `test(t)` 内跑验证命令,把结果记成断言:
189
189
 
190
190
  ```ts
191
191
  import { commandSucceeded, includes } from "niceeval/expect";
@@ -210,7 +210,7 @@ t.maxTokens(80_000).atLeast(0.7); // soft 变体——照样跟踪,只有
210
210
  t.check(t.usage.outputTokens, satisfies((n) => n < 10_000, "not verbose"));
211
211
  ```
212
212
 
213
- `t.usage` 在 `test(t)` 里随处可用,暴露 `{ inputTokens, outputTokens, cacheReadTokens?, … }`。沙箱型 agent 的 token 数由 adapter 从 transcript 里抠出;远程 agent 直接在 `Turn.usage` 里返回。
213
+ `t.usage` 在 `test(t)` 里随处可用,暴露 `{ inputTokens, outputTokens, cacheReadTokens?, … }`。Sandbox agent 的 token 数由 adapter 从 transcript 里抠出;远程 agent 直接在 `Turn.usage` 里返回。
214
214
 
215
215
  ## 自定义评分器
216
216
 
@@ -240,5 +240,5 @@ t.check(t.reply, jsonValid());
240
240
 
241
241
  - [Drive](/zh/explanation/drive) — `t.send()`、`t.newSession()` 和 HITL:这些断言读的 Turn 数据是怎么产出的。
242
242
  - [Judge](/zh/explanation/judge) — 第五种评分机制,评无法写成固定规则的开放式质量。
243
- - [写 send](/zh/how-to/write-send) — 标准事件流如何产出,作用域断言依赖它什么。
244
- - [Evals](/zh/explanation/evals) — 断言如何折进 eval 生命周期和 verdict 类型。
243
+ - [写 send](/zh/tutorials/write-send) — 标准事件流如何产出,作用域断言依赖它什么。
244
+ - [评估](/zh/explanation/evals) — 断言如何折进评估用例生命周期和 verdict 类型。
@@ -40,7 +40,7 @@ adapter 返回后运行器立刻按声明校验:`data` 不匹配,本轮直
40
40
 
41
41
  ## 带文件的一轮 —— `t.sendFile()`
42
42
 
43
- `t.sendFile(path, text?)` 读一个本地文件(相对 eval 所在目录),按扩展名推断 MIME 类型,把它作为 data URL 附加到这一轮的输入里:
43
+ `t.sendFile(path, text?)` 读一个本地文件(相对评估用例所在目录),按扩展名推断 MIME 类型,把它作为 data URL 附加到这一轮的输入里:
44
44
 
45
45
  ```ts
46
46
  const turn = await t.sendFile("fixtures/invoice.png", "这张发票的总额是多少?");
@@ -61,7 +61,7 @@ await t.send("好,发出去。");
61
61
  t.calledTool("send_email");
62
62
  ```
63
63
 
64
- 多轮 `t.send()` 能不能真的续上上文,取决于 Adapter 的 `send` 是否接了 `ctx.session` 的会话续接存取器(`history()` 或 `id` + `capture()`)——没接时每轮各是一场新对话。怎么接见 [Adapter](/zh/explanation/adapter) 与[写 send](/zh/how-to/write-send)。
64
+ 多轮 `t.send()` 能不能真的续上上文,取决于 Adapter 的 `send` 是否接了 `ctx.session` 的会话续接存取器(`history()` 或 `id` + `capture()`)——没接时每轮各是一场新对话。怎么接见 [Adapter](/zh/explanation/adapter) 与[写 send](/zh/tutorials/write-send)。
65
65
 
66
66
  ## 独立会话 —— `t.newSession()`
67
67
 
@@ -78,12 +78,12 @@ t.check(fresh.reply, satisfies((r) => !r.includes("小明"), "没有记忆泄漏
78
78
  ```
79
79
 
80
80
  <Warning>
81
- 常见错误是想当然认为 `t.newSession()` 天然保证隔离。运行器保证的只是新会话线的状态是空的——真正对应用开一条新对话是 adapter 的事。一个不看自己的会话状态、永远续接同一个底层上下文的 adapter,会让 `t.newSession()` 悄悄共享状态,且不会报错。写 adapter 时,先用上面这条 eval 验一下隔离,再信任它。
81
+ 常见错误是想当然认为 `t.newSession()` 天然保证隔离。运行器保证的只是新会话线的状态是空的——真正对应用开一条新对话是 adapter 的事。一个不看自己的会话状态、永远续接同一个底层上下文的 adapter,会让 `t.newSession()` 悄悄共享状态,且不会报错。写 adapter 时,先用上面这条评估用例验一下隔离,再信任它。
82
82
  </Warning>
83
83
 
84
84
  ## 人工介入(HITL)
85
85
 
86
- 有些 agent 会在一轮执行中间停下来,等审批或缺失信息,而不是直接跑完。这时这一轮以 `status: "waiting"` 结束,并带一条或多条 `input.requested` 事件说明在等什么。完整的心智模型(握手时序、Adapter 侧义务、rejected 语义)见 [HITL](/zh/explanation/hitl),这里讲 eval 侧怎么用。
86
+ 有些 agent 会在一轮执行中间停下来,等审批或缺失信息,而不是直接跑完。这时这一轮以 `status: "waiting"` 结束,并带一条或多条 `input.requested` 事件说明在等什么。完整的心智模型(握手时序、Adapter 侧义务、rejected 语义)见 [HITL](/zh/explanation/hitl),这里讲评估侧怎么用。
87
87
 
88
88
  ```ts
89
89
  const draft = await t.send("拟一封跟进邮件,但先别发,等我确认。");
@@ -1,12 +1,12 @@
1
1
  ---
2
- title: "NiceEval 中的 eval:生命周期、verdict 与文件"
2
+ title: "NiceEval 中的评估用例:生命周期、verdict 与文件"
3
3
  sidebarTitle: "评估"
4
- description: "eval 是一个测试用例:描述和 test 函数,agent-neutral。了解 eval 如何被发现、调度、评分和报告。"
4
+ description: "评估用例是一个测试用例:描述和 test 函数,agent-neutral。了解评估用例如何被发现、调度、评分和报告。"
5
5
  ---
6
6
 
7
7
  一个 eval 是一个可运行的测试用例。它通常由一个 `*.eval.ts` 文件导出,通过 `defineEval` 声明。
8
8
 
9
- ## eval 的组成
9
+ ## 评估用例的组成
10
10
 
11
11
  ```ts
12
12
  import { defineEval } from "niceeval";
@@ -31,7 +31,7 @@ export default defineEval({
31
31
  | `environment` | 可选的环境需求 profile,由 sandbox spec 的 `environments` 表映射到具体预制环境 |
32
32
  | `test(t)` | 交互和断言逻辑 |
33
33
 
34
- eval 本身不声明用哪个 Agent——它默认保持 agent-neutral,同一个 eval 可以在不同 experiment 下跑不同 Agent。选哪个 Agent 是 experiment 的字段,不由 CLI 临时覆盖。
34
+ 评估用例本身不声明用哪个 Agent——它默认保持 agent-neutral,同一个评估用例可以在不同 experiment 下跑不同 Agent。选哪个 Agent 是 experiment 的字段,不由 CLI 临时覆盖。
35
35
 
36
36
  <Note>
37
37
  不要手写 `id` 或 `name`。[NiceEval](https://niceeval.com/) 从文件路径推导 ID。
@@ -84,7 +84,7 @@ npx niceeval exp local weather/brooklyn
84
84
  执行异常、超时或作者错误,本次执行无法形成可信结论。
85
85
  </Card>
86
86
  <Card title="skipped" icon="forward" color="#6b7280">
87
- eval 主动跳过,通常通过 `t.skip(reason)`。
87
+ 评估用例主动跳过,通常通过 `t.skip(reason)`。
88
88
  </Card>
89
89
  </CardGroup>
90
90
 
@@ -94,7 +94,7 @@ npx niceeval exp local weather/brooklyn
94
94
 
95
95
  ## `*.eval.ts` 约定
96
96
 
97
- 只有以 `.eval.ts` 结尾的文件会被发现。用目录表达分组:
97
+ 只有以 `.eval.ts` 结尾的文件会被发现。目录只形成 ID 前缀:
98
98
 
99
99
  ```text
100
100
  evals/
@@ -118,9 +118,9 @@ export default rows.map((row) =>
118
118
  );
119
119
  ```
120
120
 
121
- 生成 ID 类似 `sql/0000`、`sql/0001`。详见 [数据驱动测试](/zh/how-to/dataset-fanout)。
121
+ 生成 ID 类似 `sql/0000`、`sql/0001`。详见 [数据驱动测试](/zh/tutorials/dataset-fanout)。
122
122
 
123
123
  ## 相关阅读
124
124
 
125
- - [实验](/zh/explanation/experiment) — 另一半:评谁、怎么跑;为什么和 eval 分开(晚绑定)。
125
+ - [实验](/zh/explanation/experiment) — 另一半:评谁、怎么跑;为什么和评估用例分开(晚绑定)。
126
126
  - [Assert](/zh/explanation/assert) — gate 与 soft 的完整判定规则。
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "实验(Experiment):评谁、怎么跑"
3
3
  sidebarTitle: "实验"
4
- description: "Experiment 是可签入的运行配置:同一批 eval 对着哪个 agent、哪个模型、开哪些 flags、跑几次。eval experiment 分开的原因——晚绑定,让同一份 eval 换着对象跑。"
4
+ description: "Experiment 是可签入的运行配置:同一批评估用例对着哪个 agent、哪个模型、开哪些 flags、跑几次。评估用例与 experiment 分开的原因——晚绑定,让同一份评估用例换着对象跑。"
5
5
  ---
6
6
 
7
7
  **experiment** 对着哪个 agent、用哪个模型、开哪些 flags、跑几次。用于做 AB 测试、模型对比、feature 对比——`flags` 就是 A/B 测试里的 feature flag,一个 experiment 是一组 flag 取值。
@@ -23,19 +23,19 @@ export default defineExperiment({
23
23
 
24
24
  - `agent`:评谁。放的是已经配置好的实例——被测系统的 URL、鉴权传给 Adapter 工厂,不进 experiment 的其它字段。
25
25
  - `model` / `flags`:透传语义。[NiceEval](https://niceeval.com/) 不解释它们的含义,原样经 `ctx` 递给 Adapter,由 Adapter 随请求转发、应用按需切换——这正是 [Tier](/zh/explanation/tier) 里模型对比(Tier 1)和 feature A/B(Tier 3)的通道。
26
- - `runs`、`budget`、并发、`sandbox` 等运行参数:怎么跑、跑多少。完整字段见[写实验](/zh/how-to/write-experiment)。
26
+ - `runs`、`budget`、并发、`sandbox` 等运行参数:怎么跑、跑多少。完整字段见[写实验](/zh/tutorials/write-experiment)。
27
27
 
28
- Experiment 是纯配置数据,没有 `setup` / `teardown` 这类生命周期字段。要按实验准备环境(装二进制、预热、跨 attempt 存取状态),挂在 `sandbox` 字段的 spec 上——`dockerSandbox()` 等工厂返回的对象可以链 `.setup()` / `.teardown()`,见 [沙箱 provider · 环境钩子](/zh/how-to/sandbox-providers#环境钩子)。
28
+ Experiment 还有一对实验级 Hook `setup` / `teardown`:整个实验只跑一次,在你自己的机器上执行,用来起停所有 Attempt 共享的服务(比如一条到内网服务的隧道、一个实验专用的 mock server)——`setup` 在本实验第一个 Attempt 派发前执行,`teardown` 在全部 Attempt 收尾后执行(中断也执行),当且仅当 `setup` 的时点已经走到才触发。要按实验在 Sandbox 里准备环境(装二进制、预热、跨 attempt 存取状态),则挂在 `sandbox` 字段的 spec 上——`dockerSandbox()` 等工厂返回的对象可以链 `.setup()` / `.teardown()`。两者的边界与写法见[写实验 · 启动 Experiment 共享服务](/zh/tutorials/write-experiment#启动-experiment-共享服务)与[Sandbox provider · 生命周期](/zh/tutorials/sandbox-providers#生命周期)。
29
29
 
30
- 同一实验里的 eval 需要不同预制环境时,eval 只声明 provider-neutral 的 `environment` profile;sandbox spec 的 `environments` 表再把 profile 映射到 Docker image、E2B template 或 Vercel sandbox snapshot。这样任务需求留在 eval,provider 产物留在 spec,一个实验仍覆盖全部 eval、对比不拆分。写法见[写实验 · 让不同 eval 使用不同预制环境](/zh/how-to/write-experiment#让不同-eval-使用不同预制环境)。
30
+ 同一实验里的评估用例需要不同预制环境时,评估用例只声明 provider-neutral 的 `environment` profile;sandbox spec 的 `environments` 表再把 profile 映射到 Docker image、E2B template 或 Vercel Sandbox snapshot。这样任务需求留在评估用例,provider 产物留在 spec,一个实验仍覆盖全部评估用例、对比不拆分。写法见[写实验 · 让不同评估用例使用不同预制环境](/zh/tutorials/write-experiment#让不同评估用例使用不同预制环境)。
31
31
 
32
32
  ## 矩阵对比
33
33
 
34
- 要比较的每个变体写一个 experiment 文件:两个模型就是两个文件,只差 `model` 一行;prompt A/B 就是只差一个参数。同一批 eval 在多个 experiment 下各跑一遍,pass rate、成本、延迟就有了可比的横截面——`niceeval view` 里叠着看。适合比什么、结果怎么读,见[实验矩阵](/zh/how-to/experiments)。
34
+ 要比较的每个变体写一个 experiment 文件:两个模型就是两个文件,只差 `model` 一行;prompt A/B 就是只差一个参数。同一批 eval 在多个 experiment 下各跑一遍,pass rate、成本、延迟就有了可比的横截面——`niceeval view` 里叠着看。适合比什么、结果怎么读,见[实验矩阵](/zh/tutorials/experiments)。
35
35
 
36
36
  ## 相关阅读
37
37
 
38
- - [写实验](/zh/how-to/write-experiment) — `defineExperiment` 的完整字段:runs、预算、并发与 sandbox。
39
- - [实验矩阵](/zh/how-to/experiments) — 跨 agent / model / flags 的对比怎么组织、怎么读结果。
40
- - [评估](/zh/explanation/evals) — 另一半:eval 是什么、生命周期与 verdict。
38
+ - [写实验](/zh/tutorials/write-experiment) — `defineExperiment` 的完整字段:runs、预算、并发与 sandbox。
39
+ - [实验矩阵](/zh/tutorials/experiments) — 跨 agent / model / flags 的对比怎么组织、怎么读结果。
40
+ - [评估](/zh/explanation/evals) — 另一半:评估用例是什么、生命周期与 verdict。
41
41
  - [Tier](/zh/explanation/tier) — `model` / `flags` 各在哪一档生效。