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
package/INDEX.md CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
5
  以下路径都相对于包根 `node_modules/niceeval/`。文档位于 `docs-site/zh/`,与当前安装的 NiceEval 版本一起发布。下面的树列出全部随包页面,每行是「路径 — 标题:一句话自述」。分区含义:
6
6
 
7
- - `tutorials/` 第一次跑通;`explanation/` 概念、边界与原理;`how-to/` 按任务的操作步骤;`reference/` API、CLI 与数据形状的精确事实;`troubleshooting/` 按症状排查失败;`examples/` 真实项目的接入案例。
7
+ - `tutorials/` 第一次跑通和按任务操作;`explanation/` 概念、边界与原理;`reference/` API、CLI 与数据形状的精确事实;`troubleshooting/` 按症状排查失败;`examples/` 真实项目的接入案例。
8
8
 
9
- 按当前任务从树里挑 1–3 页读取(通常是一页 how-to 或 explanation 搭一页 reference);页面再引用其它概念或参考时,继续读取包内文件。
9
+ 按当前任务从树里挑 1–3 页读取(通常是一页 tutorial 或 explanation 搭一页 reference);页面再引用其它概念或参考时,继续读取包内文件。
10
10
 
11
11
  <!-- GENERATED:BEGIN bundled-docs-tree -->
12
12
 
@@ -14,66 +14,64 @@
14
14
 
15
15
  ## `docs-site/zh/tutorials/`
16
16
 
17
- - `docs-site/zh/tutorials/quickstart.mdx` — 为你的 Agent 项目设置评估:安装 NiceEval,写三个文件,10 分钟内对你自己的应用跑通第一条 eval。
17
+ - `docs-site/zh/tutorials/agent-feedback-loop.mdx` — Coding Agent 编写评估用例并迭代程序:让 Coding Agent 读取随包文档,用 Bash 运行实验、查看结果、定位失败并持续迭代,最后通过全量重跑确认结果。
18
+ - `docs-site/zh/tutorials/agent-onboarding.mdx` — Coding Agent 从零接入项目:给 Coding Agent 的完整接入流程:探索项目、与用户确认路径、配置 Judge、写出 Adapter / Experiment / 评估用例并跑通第一个实验。
19
+ - `docs-site/zh/tutorials/authoring.mdx` — 编写评估用例: 单轮、多轮和数据集模式:用 defineEval 编写评估用例,包括单轮对话、多轮对话、数据驱动测试、Sandbox Workspace 和评估的生命周期与 Fixture。
20
+ - `docs-site/zh/tutorials/ci-integration.mdx` — 在 GitHub Actions 和 CI 中运行 NiceEval:把 NiceEval 接入 GitHub Actions 或任意 CI。评估用例失败时非零退出,输出 JUnit XML,并通过缓存加速重复运行。
21
+ - `docs-site/zh/tutorials/connect-otel.mdx` — OTel 接入:把应用已有的 OTel span 发送给 NiceEval,在 niceeval view 中查看每轮调用瀑布图;评估用例断言仍以 Send 返回的事件和用量为准。
22
+ - `docs-site/zh/tutorials/connect-your-agent.mdx` — 接入你的 Agent:写一个 Adapter、配置一个 Experiment,并运行第一条评估用例;再把配置和参数从 Experiment 传给 Adapter 与被测应用。
23
+ - `docs-site/zh/tutorials/custom-reports.mdx` — 编写自定义报告:用 defineReport、内置报告组件和双面组件编写一份同时用于 niceeval show 与 niceeval view 的自定义报告。
24
+ - `docs-site/zh/tutorials/dataset-fanout.mdx` — 数据驱动测试(dataset fan-out):用多份数据运行同一套评估用例:从 .eval.ts 文件导出数组或 keyed record,将一套评估逻辑展开为多个 case。用 loadYaml 或 loadJson 读取外部数据集,并获得稳定 ID。
25
+ - `docs-site/zh/tutorials/experiments.mdx` — 实验矩阵:用运行矩阵比较 agents 和 models:使用 NiceEval experiments 让同一批评估用例横跨多个 agents、models 和 flags,比较 pass rate、成本和延迟。
26
+ - `docs-site/zh/tutorials/fixtures.mdx` — Sandbox Fixture:用任务评估 coding agents:用 .eval.ts 给 coding agent 准备隔离 workspace、发送真实任务,并用 Sandbox 文件、命令、diff 和 judge 验证结果。
27
+ - `docs-site/zh/tutorials/publish-report.mdx` — 通过 CI 发布报告:把经过 copySnapshots 大小预检的结果目录提交进仓库,CI 用一行 view --results 导出报告站;超大文件在 commit 前就会得到可执行错误。
28
+ - `docs-site/zh/tutorials/quickstart.mdx` — 为你的 Agent 项目设置评估:安装 NiceEval,写三个文件,10 分钟内对你自己的应用跑通第一条评估用例。
29
+ - `docs-site/zh/tutorials/reporters.mdx` — 把结果上报到 Braintrust 与其它目的地:用内置 reporters 把评估用例结果送到 Braintrust 实验、JUnit XML 或自定义目的地。
30
+ - `docs-site/zh/tutorials/sandbox-agent.mdx` — Sandbox Agent:评估 Claude Code、Codex 和 bub:使用 NiceEval 内置 agents 或自定义 adapter,在 Docker 或云端 sandbox 中运行 coding-agent CLI。
31
+ - `docs-site/zh/tutorials/sandbox-providers.mdx` — Sandbox:官方 Sandbox Docker、Vercel 或 E2B Provider。通过预制快照加速评估
32
+ - `docs-site/zh/tutorials/scoring-guide.mdx` — 断言、judge 和成本限制:值断言、作用域断言、LLM-as-judge、test-as-scoring 和效率检查。
33
+ - `docs-site/zh/tutorials/viewing-results.mdx` — 查看 NiceEval 结果并调试 agent 行为:用 niceeval show 在终端按 @<locator> 查看 Attempt 的评估用例源码、执行记录与 diff,或用 niceeval view 在网页中查看同一份证据。
34
+ - `docs-site/zh/tutorials/write-experiment.mdx` — 实验与生命周期:如何写好实验。选择 Agent、传递 model 和 flags,设置 runs、预算、并发与 Sandbox,并用 setup / teardown 起停实验级共享服务。
35
+ - `docs-site/zh/tutorials/write-send.mdx` — 编写 Send:分七步编写 Adapter 的 send 函数:发送消息、续接会话、记录用量、映射工具事件、处理人工介入(HITL)、接入 OTel trace,并透传 Experiment flags。
18
36
 
19
37
  ## `docs-site/zh/explanation/`
20
38
 
21
39
  - `docs-site/zh/explanation/adapter.mdx` — Adapter:把 Agent 接入 NiceEval:Adapter 是你写的适配器。本文讲清楚 send 函数传入什么返回什么、被测系统配置怎么传、三个接入等级,以及 t 上的能力从哪来。
22
40
  - `docs-site/zh/explanation/assert.mdx` — NiceEval 断言:值、作用域事实、测试与成本:NiceEval 的断言词汇——值断言、作用域断言、test-as-scoring 和效率断言——以及 gate / soft 严重度和判定 verdict 的规则。
23
41
  - `docs-site/zh/explanation/drive.mdx` — NiceEval 里怎么驱动 agent:send、session 与 HITL:t.send() 和它返回的 Turn、t.sendFile()、多轮对话、t.newSession(),以及 respond() 处理的人工介入(HITL)。
24
- - `docs-site/zh/explanation/evals.mdx` — NiceEval 中的 eval:生命周期、verdict 与文件:eval 是一个测试用例:描述和 test 函数,agent-neutral。了解 eval 如何被发现、调度、评分和报告。
25
- - `docs-site/zh/explanation/experiment.mdx` — 实验(Experiment):评谁、怎么跑:Experiment 是可签入的运行配置:同一批 eval 对着哪个 agent、哪个模型、开哪些 flags、跑几次。eval experiment 分开的原因——晚绑定,让同一份 eval 换着对象跑。
42
+ - `docs-site/zh/explanation/evals.mdx` — NiceEval 中的评估用例:生命周期、verdict 与文件:评估用例是一个测试用例:描述和 test 函数,agent-neutral。了解评估用例如何被发现、调度、评分和报告。
43
+ - `docs-site/zh/explanation/experiment.mdx` — 实验(Experiment):评谁、怎么跑:Experiment 是可签入的运行配置:同一批评估用例对着哪个 agent、哪个模型、开哪些 flags、跑几次。评估用例与 experiment 分开的原因——晚绑定,让同一份评估用例换着对象跑。
26
44
  - `docs-site/zh/explanation/hitl.mdx` — 人工介入(HITL):停轮、回答、继续:什么是 Human-in-the-loop,Claude Code / Codex / AI SDK 应用里它长什么样;NiceEval 如何把它变成可评的路径——waiting 停轮、input.requested 说明在等什么、t.respond 替人回答后同一轮继续。
27
45
  - `docs-site/zh/explanation/judge.mdx` — NiceEval 里的 LLM-as-judge: 给开放式输出打分:t.judge / session.judge / turn.judge 如何用独立裁判模型评估事实性、闭合式质量和摘要忠实度,以及模型解析优先级和严重度。
28
- - `docs-site/zh/explanation/overview.mdx` — NiceEval 架构:evals、agents 与 sandboxes:理解 NiceEval、Adapter 和 Sandbox Provider 如何配合,用统一 API 评估任意 AI Agent。
29
- - `docs-site/zh/explanation/runner.mdx` — NiceEval runner 如何调度和执行 eval:NiceEval runner 发现 eval,用有界并发调度,缓存结果,重试脆弱基础设施,并执行预算保护。
46
+ - `docs-site/zh/explanation/overview.mdx` — NiceEval 架构:评估用例、agents 与 sandboxes:理解 NiceEval、Adapter 和 Sandbox Provider 如何配合,用统一 API 评估任意 AI Agent。
47
+ - `docs-site/zh/explanation/runner.mdx` — NiceEval runner 如何调度和执行评估用例:NiceEval runner 发现评估用例,用有界并发调度,缓存结果,重试脆弱基础设施,并执行预算保护。
30
48
  - `docs-site/zh/explanation/tier.mdx` — 接入等级(Tier):三级投入,三组能力:按「Adapter 接到哪里、额外拿到什么观测数据」接入分三级:Tier 1 只接 send,Tier 2 加 OTel,Tier 3 侵入改造暴露 experiment flags。每档买到什么、什么时候升级。
31
49
 
32
- ## `docs-site/zh/how-to/`
33
-
34
- - `docs-site/zh/how-to/agent-feedback-loop.mdx` — 让 AI 写 Eval 并自主优化:让 coding agent 读取随包文档,用 bash 运行实验、下钻结果、定位失败并持续迭代,最后用全量重跑确认收敛。
35
- - `docs-site/zh/how-to/authoring.mdx` — 编写 eval: 单轮、多轮和数据集模式:学习如何用 defineEval 编写 NiceEval eval,包括单轮断言、多轮对话、数据驱动测试和 sandbox workspace。
36
- - `docs-site/zh/how-to/ci-integration.mdx` — 在 GitHub Actions 和 CI 中运行 NiceEval:把 NiceEval 接入 GitHub Actions 或任意 CI。eval 失败时非零退出,输出 JUnit XML,并通过缓存加速重复运行。
37
- - `docs-site/zh/how-to/connect-otel.mdx` — OTel 接入:把应用已经在发的 OTel span 也发给 NiceEval 一份,niceeval view 里就有每轮的调用瀑布图。断言不从这里来——接好 send 那一刻断言就齐了。
38
- - `docs-site/zh/how-to/connect-your-agent.mdx` — 接入你的 Agent:接入的全景:写一个 adapter、配一个 experiment、跑通第一条 eval;配置和参数怎么在 experiment 里声明、在 Adapter 里消费。事件流、多轮、HITL、tracing 是增量,各有专章。
39
- - `docs-site/zh/how-to/custom-reports.mdx` — 用报告积木搭自己的口径:一份报告就是一个报告文件:官方宿主打开结果、注入数据,双面组件让同一份自定义报告同时用于 niceeval show 与 niceeval view。
40
- - `docs-site/zh/how-to/dataset-fanout.mdx` — 数据驱动测试(dataset fan-out):用多份数据运行同一套 eval:从 .eval.ts 文件导出数组或 keyed record,将一套 eval 逻辑展开为多个 case。用 loadYaml 或 loadJson 读取外部数据集,并获得稳定 ID。
41
- - `docs-site/zh/how-to/experiments.mdx` — 实验矩阵:用运行矩阵比较 agents 和 models:使用 NiceEval experiments 让同一批 eval 横跨多个 agents、models 和 flags,比较 pass rate、成本和延迟。
42
- - `docs-site/zh/how-to/fixtures.mdx` — 沙箱 Fixture:用任务评估 coding agents:用 .eval.ts 给 coding agent 准备隔离 workspace、发送真实任务,并用 sandbox 文件、命令、diff 和 judge 验证结果。
43
- - `docs-site/zh/how-to/publish-report.mdx` — 通过 CI 发布报告:把经过 copySnapshots 大小预检的结果目录提交进仓库,CI 用一行 view --results 导出报告站;超大文件在 commit 前就会得到可执行错误。
44
- - `docs-site/zh/how-to/reporters.mdx` — 把结果上报到 Braintrust 与其它目的地:用内置 reporters 把 eval 结果送到 Braintrust 实验、JUnit XML 或自定义目的地。
45
- - `docs-site/zh/how-to/sandbox-agent.mdx` — 沙箱 Agent:评估 Claude Code、Codex 和 bub:使用 NiceEval 内置 agents 或自定义 adapter,在 Docker 或云端 sandbox 中运行 coding-agent CLI。
46
- - `docs-site/zh/how-to/sandbox-providers.mdx` — Sandbox provider:Docker、Vercel 与第三方:NiceEval 在 Docker 或 Vercel sandbox 中运行 coding agents。了解如何选择 provider、配置权限,并通过 warm pools 改善性能。
47
- - `docs-site/zh/how-to/scoring-guide.mdx` — 评分指南: 断言、judge 和成本限制:用 NiceEval 的五种评分机制评估任意 eval:值断言、作用域断言、LLM-as-judge、test-as-scoring 和效率检查。
48
- - `docs-site/zh/how-to/viewing-results.mdx` — 查看 NiceEval 结果并调试 agent 行为:每次运行写入 .niceeval/ 的结构化 artifact 有两扇门:niceeval show 在终端用 @<locator> 精确定位一次 Attempt,逐级下钻 Eval 源码、执行记录与 diff;niceeval view 在网页看同一份证据。
49
- - `docs-site/zh/how-to/write-experiment.mdx` — 写实验:用 defineExperiment 固定运行配置:学习如何在 experiments/ 里用 defineExperiment 选择 agent、传 model 和 flags、设置 runs、预算、并发与 sandbox。
50
- - `docs-site/zh/how-to/write-send.mdx` — 如何写好 Send:手写 Adapter 的 send 函数,一条主线七步走:发消息拿回复、接上之前的消息、记录消费、把工具解析成事件、人工介入(HITL)、接上 OTel trace、透传 experiment 的 flags。每一步只在上一步的代码上多几行,每一步解锁一组断言。
51
-
52
50
  ## `docs-site/zh/reference/`
53
51
 
54
52
  - `docs-site/zh/reference/builtin-agents.mdx` — 内置 Agent 能力参考:NiceEval 内置的 claude-code、codex、bub 适配器分别做到了哪些能力,对应哪些断言,以及已知限制。
55
53
  - `docs-site/zh/reference/capabilities.mdx` — 能力位参考:NiceEval 怎么知道你的 adapter 做到了什么:没有声明式能力位,全部由构造和实际行为证明。
56
- - `docs-site/zh/reference/cli.mdx` — NiceEval CLI:命令、flags 和退出码参考:NiceEval CLI 参考:exp、show、view、init、list 和 clean 命令,以及结果下钻、experiment、eval 过滤、并发、预算和 CI 输出。
54
+ - `docs-site/zh/reference/cli.mdx` — NiceEval CLI:命令、flags 和退出码参考:NiceEval CLI 参考:exp、show、view、init、list 和 clean 命令,以及结果下钻、experiment、评估用例过滤、并发、预算和 CI 输出。
57
55
  - `docs-site/zh/reference/define-agent.mdx` — defineAgent 和 defineSandboxAgent:adapter 参考:defineAgent 和 defineSandboxAgent 参考:AgentContext、AgentSession、Sandbox 接口和共享 sandbox helpers。
58
56
  - `docs-site/zh/reference/define-config.mdx` — defineConfig:项目默认配置:defineConfig 参考:judge、reporters、并发、超时和 sandbox 默认值。
59
- - `docs-site/zh/reference/define-eval.mdx` — defineEval:声明、配置并运行 NiceEval eval:defineEval 参考:选项、test context t、Turn 返回值、sandbox helper,以及数组和 keyed record 数据集导出。
57
+ - `docs-site/zh/reference/define-eval.mdx` — defineEval:声明、配置并运行 NiceEval 评估用例:defineEval 参考:选项、test context t、Turn 返回值、Sandbox helper,以及数组和 keyed record 数据集导出。
60
58
  - `docs-site/zh/reference/events.mdx` — 标准事件流参考:StreamEvent 的十种事件:每种的字段、什么时候吐、哪些断言消费它。adapter 的核心工作就是产出这条流。
61
59
  - `docs-site/zh/reference/expect.mdx` — niceeval/expect matchers 与自定义断言参考:niceeval/expect 参考:includes、equals、matches、similarity、satisfies。可链式调用 .gate() 或 .atLeast(0.7),也可以用 makeAssertion 构建自定义 matcher。
62
60
  - `docs-site/zh/reference/official-adapters.mdx` — 官方适配器一览:NiceEval 内置的 Sandbox 和非 Sandbox 适配器分别是什么、怎么鉴权,Sandbox 型里怎么装 MCP server、Skill、插件,怎么使用 Agent 官方配置文件。
63
61
  - `docs-site/zh/reference/report-components.mdx` — 报告组件一览:报告文件里能摆的全部官方双面组件:每个组件回答什么问题、怎么调用、网页面长什么样、终端字符输出长什么样。
64
- - `docs-site/zh/reference/results-data.mdx` — 用 niceeval/results 直接读写结果数据:报告积木脚下的数据层:openResults 把 .niceeval/ 的落盘 artifact parse 成「实验 → 结果快照 → eval → attempt」的类型化层次,createResultsWriter 把别家结果写成 NiceEval 格式,copySnapshots 负责发布瘦身。
62
+ - `docs-site/zh/reference/results-data.mdx` — 用 niceeval/results 直接读写结果数据:报告积木脚下的数据层:openResults 把 .niceeval/ 的落盘 artifact parse 成「实验 → 结果快照 → 评估 → attempt」的类型化层次,createResultsWriter 把别家结果写成 NiceEval 格式,copySnapshots 负责发布瘦身。
65
63
 
66
64
  ## `docs-site/zh/troubleshooting/`
67
65
 
68
- - `docs-site/zh/troubleshooting/debug-sandbox.mdx` — 保留沙箱现场排查问题:用 --keep-sandbox 把失败 Attempt 的沙箱保留成可随时唤醒的现场,用 niceeval sandbox enter 进去手动排查,用 sandbox list / stop 查看和清理。
69
- - `docs-site/zh/troubleshooting/debugging.mdx` — 排查失败与复盘历史运行:一份按场景组织的排查手册:断言失败怎么定位、环境错误怎么进沙箱、agent 改了什么怎么看、旧的运行怎么翻出来复盘——每一步都有命令顺序和输出示例。
66
+ - `docs-site/zh/troubleshooting/debug-sandbox.mdx` — 保留 Sandbox 现场排查问题:用 --keep-sandbox 把失败 Attempt Sandbox 保留成可随时唤醒的现场,用 niceeval sandbox enter 进去手动排查,用 sandbox list / stop 查看和清理。
67
+ - `docs-site/zh/troubleshooting/debugging.mdx` — 排查失败与复盘历史运行:一份按场景组织的排查手册:断言失败怎么定位、环境错误怎么进 Sandbox、agent 改了什么怎么看、旧的运行怎么翻出来复盘——每一步都有命令顺序和输出示例。
70
68
 
71
69
  ## `docs-site/zh/examples/`
72
70
 
73
71
  - `docs-site/zh/examples/ai-agent-application.mdx` — 自写 Adapter 评估 AI Agent 应用:一个可运行的 AI SDK v6 Web Agent 评测项目,覆盖自写 Adapter、工具调用、图片理解、多轮会话、模型对比和双路可观测。
74
72
  - `docs-site/zh/examples/coding-agent-extensions.mdx` — 评估 Coding Agent 扩展:用真实 Workspace、基线实验和自定义报告,评估 Skill、提示词与 Plugin Benchmark 是否改善 Coding Agent 的任务结果。
75
73
  - `docs-site/zh/examples/integrations/ai-sdk-v7.mdx` — AI SDK v7 如何非侵入式接入 NiceEval:一个 AI SDK v7 聊天应用,对着它的 HTTP 接口无侵入接入 NiceEval 前后的完整代码 diff:应用侧一行没改。
76
- - `docs-site/zh/examples/integrations/claude-sdk.mdx` — Claude Agent SDK 如何非侵入式接入 NiceEval:一个 Claude Agent SDK 助手后端,接入 NiceEval 前后的完整代码 diff:应用侧一行没改,全部新增在 eval 侧。
74
+ - `docs-site/zh/examples/integrations/claude-sdk.mdx` — Claude Agent SDK 如何非侵入式接入 NiceEval:一个 Claude Agent SDK 助手后端,接入 NiceEval 前后的完整代码 diff:应用侧一行没改,全部新增在评估用例侧。
77
75
  - `docs-site/zh/examples/integrations/codex-sdk.mdx` — Codex SDK 如何非侵入式接入 NiceEval:一个 Codex SDK(目录里的编码 agent)后端,接入 NiceEval 前后的完整代码 diff:应用侧一行没改。
78
76
  - `docs-site/zh/examples/integrations/langgraph.mdx` — LangGraph 如何非侵入式接入 NiceEval:一个纯 Python LangGraph + LangSmith OTel 导出的应用,接入 NiceEval 前后的完整代码 diff。
79
77
  - `docs-site/zh/examples/integrations/pi-sdk.mdx` — pi-agent-core 如何非侵入式接入 NiceEval:一个 pi-agent-core(@earendil-works)助手后端,接入 NiceEval 前后的完整代码 diff:应用侧只加了一个 devDependency。
@@ -1,4 +1,4 @@
1
- import type { Cleanup, DiagnosticInput, ProgressUpdate } from "../shared/types.ts";
1
+ import type { DiagnosticInput, ProgressUpdate } from "../shared/types.ts";
2
2
  import type { StreamEvent, TraceSpan, Usage } from "../o11y/types.ts";
3
3
  import type { Sandbox } from "../sandbox/types.ts";
4
4
  /**
@@ -266,10 +266,10 @@ export interface AgentSession {
266
266
  }
267
267
  export interface AgentContext {
268
268
  /**
269
- * 软取消信号:合并了 attempt 超时、run 级中断(用户 Ctrl+C)与 eval 自身的中断请求
269
+ * 软取消信号:合并了 attempt 超时、run 级中断(用户 Ctrl+C)与评估用例自身的中断请求
270
270
  * (见 src/runner/attempt.ts)。adapter 可以选择性检查它(或直接传给 `fetch`)以提前
271
271
  * 优雅退出,但这不是唯一的硬边界——即便 adapter 完全忽略它,运行器也会用
272
- * `Effect.timeoutTo` 兜底强制收尾(停沙箱容器)。
272
+ * `Effect.timeoutTo` 兜底强制收尾(停 Sandbox 容器)。
273
273
  */
274
274
  readonly signal: AbortSignal;
275
275
  /** 本次 attempt 用的模型名,透传自 experiment 的 `model` 字段。sandbox 型 agent 通常在 setup 里用它写配置,remote 型通常在 send 里用它选模型。 */
@@ -286,13 +286,13 @@ export interface AgentContext {
286
286
  /**
287
287
  * 路径推导出的实验 id(与结果归属 `runWho` / `AgentRun.experimentId` 同源);不经
288
288
  * experiment 跑(如脱离 CLI、直接构造 `AgentRun` 的场景)时为 undefined。典型用途:
289
- * `SandboxSpec.setup` 钩子按实验隔离跨 attempt 的状态(缓存目录名、快照 tag 等按
289
+ * `SandboxSpec.setup` Hook 按实验隔离跨 attempt 的状态(缓存目录名、快照 tag 等按
290
290
  * `ctx.experimentId` 分区),或 adapter 按实验切换鉴权 / 路由。与 `flags`(实验条件的
291
291
  * 具体取值)是两个维度——这里只是「跑的是哪个实验」的稳定标识,不携带条件内容。
292
292
  */
293
293
  readonly experimentId?: string;
294
294
  /**
295
- * 所有 agent 都有:沙箱型是运行器按项目/experiment 配置备好的真实沙箱句柄,remote 型是
295
+ * 所有 agent 都有:Sandbox 型是运行器按项目/experiment 配置备好的真实 Sandbox 句柄,remote 型是
296
296
  * `createRemoteSandbox()` 产出的 stub(仅含 `workdir`/`sandboxId`/`otlpHost`/`stop` 等
297
297
  * 元信息,其余方法调用即抛错)。
298
298
  */
@@ -330,10 +330,12 @@ export interface AgentContext {
330
330
  * agent 自己的沙箱生命周期(每个沙箱一次,与「每轮 send」分开):
331
331
  * `setup` 装 CLI、写配置(model/base/auth 等本轮内不变的东西),`send` 只管把一轮 prompt
332
332
  * 跑起来(第一次 fresh / 后续 resume)+ 解析 transcript,`teardown` 清理。
333
- * 运行器在备好沙箱(上传 / 基线 / eval.setup)后、第一次 send 前调一次 `setup`;
334
- * `setup` 可返回 cleanup 闭包,与 `teardown` 都在 finally 跑。
333
+ * 运行器在备好沙箱(上传 / 基线 / eval.setup)后、第一次 send 前调一次 `setup`,不返回值;
334
+ * `teardown` 当且仅当本 attempt 走到过 `setup` 时点才执行(`setup` 抛错不豁免——半初始化
335
+ * 的现场同样要扫尾),在 finally 里跑。要把 `setup` 里创建的句柄传给 `teardown`,以
336
+ * `sandbox` 实例为键存取(同一个 Agent 实例服务并发 attempt,不要用实例字段或模块变量)。
335
337
  */
336
- export type AgentSetup = (sandbox: Sandbox, ctx: AgentContext) => Promise<void | Cleanup> | void | Cleanup;
338
+ export type AgentSetup = (sandbox: Sandbox, ctx: AgentContext) => Promise<void> | void;
337
339
  export type AgentTeardown = (sandbox: Sandbox, ctx: AgentContext) => Promise<void> | void;
338
340
  /**
339
341
  * 本 agent 的原生 OTLP span → canonical GenAI semconv 的薄 mapper。
@@ -367,18 +369,19 @@ export interface SandboxAgentDef {
367
369
  /** 该 Adapter 的常态证据覆盖声明(完整采集的用 `completeCoverage` 常量);省略 = 全通道 unknown。 */
368
370
  coverage?: EvidenceCoverage;
369
371
  /**
370
- * 每个沙箱一次(不是每轮一次):装 CLI、写 config.toml / 鉴权配置(model/base/auth 等
371
- * 本轮内不变的东西)。运行器在沙箱备好(上传/基线/eval.setup 之后)、第一次 send 前
372
- * 调用一次。可返回一个 cleanup 闭包,与 `teardown` 一起在 finally 里跑。
372
+ * 每个 Sandbox 一次(不是每轮一次):装 CLI、写 config.toml / 鉴权配置(model/base/auth 等
373
+ * 本轮内不变的东西)。运行器在 Sandbox 备好(上传/基线/eval.setup 之后)、第一次 send 前
374
+ * 调用一次,不返回值。
373
375
  */
374
376
  setup?: AgentSetup;
375
- /** OTLP 导出配置:沙箱里怎么让 CLI 把 trace 发到 endpoint(env / 配置文件),从 setup 拆出。 */
377
+ /** OTLP 导出配置:Sandbox 里怎么让 CLI 把 trace 发到 endpoint(env / 配置文件),从 setup 拆出。 */
376
378
  tracing?: AgentTracing;
377
379
  /** 原生 span → canonical 的薄 mapper;省略走通用 heuristic。只影响瀑布图。 */
378
380
  spanMapper?: SpanMapper;
379
381
  /** 每轮一次:跑 prompt(fresh / resume)+ 解析成 events。 */
380
382
  send(input: TurnInput, ctx: AgentContext): Promise<Turn>;
381
- /** 沙箱销毁前的清理(与 setup 返回的 cleanup 一起、都在 finally 里跑一次)。 */
383
+ /** Sandbox 销毁前的清理,当且仅当本 attempt 走到过 `setup` 时点才执行(`setup` 抛错不豁免),
384
+ * 在 finally 里跑一次。 */
382
385
  teardown?: AgentTeardown;
383
386
  }
384
387
  /** `defineAgent()` 的入参形状(见 src/define.ts)——`kind: "remote"` 由 define 固定填入,不由用户声明。 */
@@ -388,10 +391,9 @@ export interface RemoteAgentDef {
388
391
  /** 该 Adapter 的常态证据覆盖声明(完整采集的用 `completeCoverage` 常量);省略 = 全通道 unknown。 */
389
392
  coverage?: EvidenceCoverage;
390
393
  /**
391
- * 每个 attempt 一次(remote agent 没有真实沙箱,运行器会传入一个仅含 `workdir`/`sandboxId`/
394
+ * 每个 attempt 一次(remote agent 没有真实 Sandbox,运行器会传入一个仅含 `workdir`/`sandboxId`/
392
395
  * `otlpHost`/`stop` 等元信息的 stub `Sandbox`,其余方法调用即抛错——不要在这里调用
393
- * 文件/命令类沙箱方法)。常用于建立连接、鉴权等一次性准备。可返回一个 cleanup 闭包,
394
- * 与 `teardown` 都在 finally 里跑。
396
+ * 文件/命令类 Sandbox 方法)。常用于建立连接、鉴权等一次性准备,不返回值。
395
397
  */
396
398
  setup?: AgentSetup;
397
399
  /** OTLP 导出配置:远程被测对象怎么把 trace 发到 endpoint(env-based 注入 / file-based 配置)。 */
@@ -400,6 +402,7 @@ export interface RemoteAgentDef {
400
402
  spanMapper?: SpanMapper;
401
403
  /** 每轮一次:把一轮 prompt 发给远程被测对象(HTTP/SDK 等),解析响应成 events。 */
402
404
  send(input: TurnInput, ctx: AgentContext): Promise<Turn>;
403
- /** 运行结束前的清理(与 setup 返回的 cleanup 一起、都在 finally 里跑一次)。 */
405
+ /** 运行结束前的清理,当且仅当本 attempt 走到过 `setup` 时点才执行(`setup` 抛错不豁免),
406
+ * 在 finally 里跑一次。 */
404
407
  teardown?: AgentTeardown;
405
408
  }
@@ -135,37 +135,37 @@ export interface RespondAnswer {
135
135
  readonly optionId?: string;
136
136
  readonly text?: string;
137
137
  }
138
- /** eval 作者可见的受限沙箱视图:能执行命令 / 文件 IO / 读最终 diff,但不能 stop。 */
138
+ /** 评估用例作者可见的受限 Sandbox 视图:能执行命令 / 文件 IO / 读最终 diff,但不能 stop。 */
139
139
  export interface SandboxHandle {
140
- /** 沙箱内的工作目录绝对路径。 */
140
+ /** Sandbox 内的工作目录绝对路径。 */
141
141
  readonly workdir: string;
142
- /** 在沙箱里执行一条命令(argv 形式,不经 shell)。装系统依赖等需要 root 时传 `{ root: true }`。 */
142
+ /** 在 Sandbox 里执行一条命令(argv 形式,不经 shell)。装系统依赖等需要 root 时传 `{ root: true }`。 */
143
143
  runCommand(cmd: string, args?: string[], opts?: CommandOptions): Promise<CommandResult>;
144
- /** 在沙箱里执行一段 shell 脚本(经 shell 解释,支持管道 / 重定向)。 */
144
+ /** Sandbox 里执行一段 shell 脚本(经 shell 解释,支持管道 / 重定向)。 */
145
145
  runShell(script: string, opts?: CommandOptions): Promise<CommandResult>;
146
- /** 读沙箱内某文件此刻的文本内容(实时读,不是 diff 快照)。 */
146
+ /** 读 Sandbox 内某文件此刻的文本内容(实时读,不是 diff 快照)。 */
147
147
  readFile(path: string): Promise<string>;
148
- /** 沙箱内某路径此刻是否存在。 */
148
+ /** Sandbox 内某路径此刻是否存在。 */
149
149
  fileExists(path: string): Promise<boolean>;
150
- /** 按选项批量读回沙箱里的源文件,供比对 / judge 用材料。 */
150
+ /** 按选项批量读回 Sandbox 里的源文件,供比对 / judge 用材料。 */
151
151
  readSourceFiles(opts?: ReadSourceFilesOptions): Promise<SourceFiles>;
152
- /** 把一组内容写进沙箱(路径相对 targetDir,默认 workdir)。 */
152
+ /** 把一组内容写进 Sandbox(路径相对 targetDir,默认 workdir)。 */
153
153
  writeFiles(files: Record<string, string>, targetDir?: string): Promise<void>;
154
- /** 把一批内存中的文件上传进沙箱。 */
154
+ /** 把一批内存中的文件上传进 Sandbox。 */
155
155
  uploadFiles(files: SandboxFile[], targetDir?: string): Promise<void>;
156
- /** 把本地目录整体上传进沙箱;`opts.ignore` 排除指定路径。 */
156
+ /** 把本地目录整体上传进 Sandbox;`opts.ignore` 排除指定路径。 */
157
157
  uploadDirectory(localDir: string, targetDir?: string, opts?: {
158
158
  ignore?: string[];
159
159
  }): Promise<void>;
160
- /** 从沙箱下载某文件内容。 */
160
+ /** Sandbox 下载某文件内容。 */
161
161
  downloadFile(path: string): Promise<Buffer>;
162
- /** 把一段内容上传成沙箱里的单个文件。 */
162
+ /** 把一段内容上传成 Sandbox 里的单个文件。 */
163
163
  uploadFile(path: string, content: Buffer): Promise<void>;
164
- /** 沙箱 provider 分配的实例 id,用于排查 / 关联日志。 */
164
+ /** Sandbox provider 分配的实例 id,用于排查 / 关联日志。 */
165
165
  readonly sandboxId: string;
166
166
  /** 相对 git 基线的最终 diff 视图(test() 跑完、finalize 前才落定)。 */
167
167
  readonly diff: DiffView;
168
- /** 取沙箱内某文件的最终内容,占位延迟到 finalize 才真正读取;只能配合 t.check 使用。 */
168
+ /** Sandbox 内某文件的最终内容,占位延迟到 finalize 才真正读取;只能配合 t.check 使用。 */
169
169
  file(path: string): string;
170
170
  /** 断言 diff 里某路径发生了变化(新增或修改)。 */
171
171
  fileChanged(path: string): AssertionHandle;
@@ -173,7 +173,7 @@ export interface SandboxHandle {
173
173
  fileDeleted(path: string): AssertionHandle;
174
174
  /** 断言 diff 的路径与内容都不匹配给定正则(常用来否定式检查不该出现的改动)。 */
175
175
  notInDiff(re: RegExp): AssertionHandle;
176
- /** 断言沙箱里执行过的命令都没有失败退出。 */
176
+ /** 断言 Sandbox 里执行过的命令都没有失败退出。 */
177
177
  noFailedShellCommands(): AssertionHandle;
178
178
  }
179
179
  /**
@@ -279,7 +279,7 @@ export interface TestContext {
279
279
  /** 本次 attempt 生效的实验 flags(experiment.flags 的只读视图;实验条件,非命令行开关)。 */
280
280
  readonly flags: Readonly<Record<string, unknown>>;
281
281
  /**
282
- * 作用域反馈:报告 eval 自己执行的长步骤(上传 fixture、跑构建……)。短命状态,scope 固定
282
+ * 作用域反馈:报告评估用例自己执行的长步骤(上传 Fixture、跑构建……)。短命状态,scope 固定
283
283
  * 为 `eval.run`;只报告不断言(见 docs/feature/eval/library/context.md「向运行反馈长步骤」)。
284
284
  */
285
285
  progress(update: ProgressUpdate): void;
@@ -290,16 +290,16 @@ export interface TestContext {
290
290
  diagnostic(input: DiagnosticInput): void;
291
291
  /** `progress({ message: msg })` 的别名(调试日志),不出现在最终结果里。 */
292
292
  log(msg: string): void;
293
- /** 立即中止本 eval 并标记为 skipped(verdict / EvalResult.skipReason),reason 不能为空。 */
293
+ /** 立即中止本评估用例并标记为 skipped(verdict / EvalResult.skipReason),reason 不能为空。 */
294
294
  skip(reason: string): never;
295
295
  /**
296
296
  * 对任意值跑一个 ValueAssertion,返回可链 `.gate()` / `.atLeast()` 的 AssertionHandle。
297
- * 打分延迟到 eval 结束后统一 finalize,调用本身同步、不抛错——不通过只是记一条失败断言,
298
- * 不会中止后续代码。要「不满足就立即中止 eval」用 require。
297
+ * 打分延迟到评估用例结束后统一 finalize,调用本身同步、不抛错——不通过只是记一条失败断言,
298
+ * 不会中止后续代码。要「不满足就立即中止评估用例」用 require。
299
299
  */
300
300
  check(value: unknown, assertion: ValueAssertion): AssertionHandle;
301
301
  /**
302
- * 对任意值跑一个 ValueAssertion,立即(await 时)求值;不满足就抛错中止整个 eval 剩余步骤
302
+ * 对任意值跑一个 ValueAssertion,立即(await 时)求值;不满足就抛错中止整个评估用例剩余步骤
303
303
  * (仍会把这条断言计入报告,不影响已记录的其它断言)。跟 check 的区别:check 只记录、
304
304
  * 从不抛错,打分留到最后统一算;require 当场判定、失败即中止,适合「前置条件不满足,
305
305
  * 后面写了也没意义」的场景。
@@ -342,7 +342,7 @@ export interface TestContext {
342
342
  eventOrder(types: StreamEvent["type"][]): AssertionHandle;
343
343
  /** 用自定义谓词对默认会话累计的整段事件流断言;label 必填、进断言标题。 */
344
344
  eventsSatisfy(label: string, predicate: (events: readonly StreamEvent[]) => boolean): AssertionHandle;
345
- /** 受限沙箱视图:能执行命令 / 读写文件 / 看最终 diff,不能 stop 沙箱本身(见 SandboxHandle)。 */
345
+ /** 受限 Sandbox 视图:能执行命令 / 读写文件 / 看最终 diff,不能 stop Sandbox 本身(见 SandboxHandle)。 */
346
346
  readonly sandbox: SandboxHandle;
347
347
  /** 默认会话累计的 token 用量与估算成本。 */
348
348
  readonly usage: Usage;
package/dist/i18n/en.d.ts CHANGED
@@ -46,6 +46,10 @@ export declare const en: {
46
46
  "cli.flag.invalidNumber": string;
47
47
  "cli.flag.invalidOutput": string;
48
48
  "runner.budgetUnenforceable": string;
49
+ "runner.experimentTeardownFailed": string;
50
+ "runner.cleanupTimeout": string;
51
+ "runner.setupReturnedCleanup": string;
52
+ "runner.experimentTeardownLate": string;
49
53
  "judge.modelMissing": string;
50
54
  "loaders.yamlMissing": string;
51
55
  "cli.flag.parseError": string;
@@ -96,6 +100,8 @@ export declare const en: {
96
100
  "define.evalTestRequired": string;
97
101
  "define.experimentAgentRequired": string;
98
102
  "define.experimentFlagNotJson": string;
103
+ "define.experimentLabelInvalid": string;
104
+ "define.experimentSetupNotFunction": string;
99
105
  "define.experimentIdRejected": string;
100
106
  "define.sandboxAgentNameRequired": string;
101
107
  "define.sandboxCreateRequired": string;
@@ -133,6 +139,10 @@ export declare const en: {
133
139
  "feedback.phase.evalSetup": string;
134
140
  "feedback.phase.sandboxCreate": string;
135
141
  "feedback.phase.sandboxQueue": string;
142
+ "feedback.phase.experimentSetup": string;
143
+ "feedback.phase.experimentTeardown": string;
144
+ "feedback.human.hookDone": string;
145
+ "feedback.human.hookFailed": string;
136
146
  "feedback.phase.sandboxSetup": string;
137
147
  "feedback.phase.scoring": string;
138
148
  "feedback.phase.teardown": string;
@@ -212,8 +222,6 @@ export declare const en: {
212
222
  "runner.startSandboxTeardown": string;
213
223
  "runner.timeout": string;
214
224
  "runner.traceSelected": string;
215
- "runner.resumeCarry": string;
216
- "runner.resumeCarryDetail": string;
217
225
  "runner.useRemoteAgent": string;
218
226
  "sandbox.providerNotImplemented": string;
219
227
  "sandbox.missingSpec": string;
@@ -46,6 +46,10 @@ export declare const zhCN: {
46
46
  readonly "cli.flag.invalidNumber": "标志 --{{flag}} 需要数字,收到 \"{{value}}\"。\n";
47
47
  readonly "cli.flag.invalidOutput": "标志 --output 需要 auto|human|agent|ci 之一,收到 \"{{value}}\"。\n";
48
48
  readonly "runner.budgetUnenforceable": "{{budgetKey}} 的 budget:连续多个 attempt 完成后都拿不到成本数据(agent 不上报用量且模型不在价格表)——该 agent 的 budget 无法执行,取消护栏继续跑。\n";
49
+ readonly "runner.experimentTeardownFailed": "实验 {{experimentId}} 的 teardown 执行失败:{{message}}。结果不受影响,但该实验起的宿主机资源可能没有回收,请手动检查。\n";
50
+ readonly "runner.cleanupTimeout": "cleanup 执行超过 {{timeoutMs}}ms 清理超时\n";
51
+ readonly "runner.setupReturnedCleanup": "{{layer}} 返回了一个函数。setup 不承载收尾,返回值不会被执行——收尾写在同层成对的 teardown 里({{hint}});见 docs-site 的实验教程或 docs/runner.md「环境预置」。\n";
52
+ readonly "runner.experimentTeardownLate": "实验 {{experimentId}} 的 teardown 未被正常计数路径触发,已在运行收尾兜底执行。结果不受影响;这行出现说明命中了一个未定位的调度间歇问题,请把本次运行信息记入 memory 台账。\n";
49
53
  readonly "judge.modelMissing": string;
50
54
  readonly "loaders.yamlMissing": "loadYaml(\"{{path}}\") 需要 YAML 解析器:请先 `pnpm add yaml`(或改用 loadJson + JSON 数据集)。";
51
55
  readonly "cli.flag.parseError": "{{message}}\n运行 `niceeval --help` 查看用法。\n";
@@ -64,10 +68,10 @@ export declare const zhCN: {
64
68
  readonly "cli.eval.noMatchKnown": "已发现 {{count}} 个 eval:{{evals}}\n";
65
69
  readonly "cli.exp.agentModelFlagUnsupported": "experiment 运行不支持 --agent / --model。请新增或复制一个 experiment 文件并修改 model。\n";
66
70
  readonly "cli.exp.viewerFlagUnsupported": "`{{flag}}` 只适用于 niceeval {{command}},不能用于 niceeval exp。\n";
67
- readonly "cli.experiment.noMatch": "没有匹配的实验:{{arg}}。已发现:{{experiments}}\n";
71
+ readonly "cli.experiment.noMatch": string;
68
72
  readonly "cli.experiment.viewerCommandHint": "你可能想运行:niceeval {{command}}{{args}}\n";
69
- readonly "cli.experiment.noEvalsSelected": "未选择任何 eval:{{selection}} 匹配到 0 个 eval。可用实验:{{experiments}}。\n";
70
- readonly "cli.experimentGroup": "";
73
+ readonly "cli.experiment.noEvalsSelected": string;
74
+ readonly "cli.experimentGroup": "路径";
71
75
  readonly "cli.fallbackCleanupTimeout": "\ngraceful 清理超时,强制清理沙箱…\n";
72
76
  readonly "cli.forceCleanupExit": "\n强制清理沙箱并退出…\n";
73
77
  readonly "cli.init.done": "已就绪:evals/、niceeval.config.ts,以及 AGENTS.md 里的 niceeval agent 指引区块(指向 node_modules/niceeval/docs-site/zh)。\n";
@@ -96,6 +100,8 @@ export declare const zhCN: {
96
100
  readonly "define.evalTestRequired": "defineEval 需要一个 async test(t) 函数。";
97
101
  readonly "define.experimentAgentRequired": "defineExperiment 需要 agent。";
98
102
  readonly "define.experimentFlagNotJson": "experiment.flags.{{key}} 不是可 JSON 序列化的值(函数 / undefined / 循环引用 / bigint 不允许);flags 会原样进入结果快照,必须是纯 JSON。";
103
+ readonly "define.experimentLabelInvalid": "experiment.labels.{{key}} 必须是字符串或有限数字;labels 是报告侧的归类坐标,会原样进入结果快照。";
104
+ readonly "define.experimentSetupNotFunction": "experiment.setup 必须是函数((ctx) => void);要清理请挂 experiment.teardown;要按实验准备沙箱内环境请挂 sandbox spec 的 .setup() 钩子链。";
99
105
  readonly "define.experimentIdRejected": "defineExperiment 不接受 id —— id 由文件路径推导。";
100
106
  readonly "define.sandboxAgentNameRequired": "defineSandboxAgent 需要 name。";
101
107
  readonly "define.sandboxCreateRequired": "defineSandbox 需要一个 create() 函数。";
@@ -108,7 +114,7 @@ export declare const zhCN: {
108
114
  readonly "docker.unsupportedRuntime": "Unsupported runtime: {{runtime}}";
109
115
  readonly "feedback.human.active": "ACTIVE";
110
116
  readonly "feedback.human.budgetExhausted": "{{experimentId}} 预算已耗尽(已花 {{spent}},未跑 {{unstarted}})";
111
- readonly "feedback.human.compare": "Compare: niceeval view {{group}}";
117
+ readonly "feedback.human.compare": "Compare: niceeval view";
112
118
  readonly "feedback.human.counts": "共 {{total}} · 复用 {{reused}} · 运行中 {{running}} · 排队 {{queued}} · 已完成 {{completed}}";
113
119
  readonly "feedback.human.diffHint": "Diff: niceeval show {{locator}} --diff";
114
120
  readonly "feedback.human.evalHint": "Eval: niceeval show {{locator}} --source";
@@ -133,6 +139,10 @@ export declare const zhCN: {
133
139
  readonly "feedback.phase.evalSetup": "eval 预置";
134
140
  readonly "feedback.phase.sandboxCreate": "创建沙箱";
135
141
  readonly "feedback.phase.sandboxQueue": "排队等沙箱";
142
+ readonly "feedback.phase.experimentSetup": "实验预置";
143
+ readonly "feedback.phase.experimentTeardown": "实验收尾";
144
+ readonly "feedback.human.hookDone": "完成";
145
+ readonly "feedback.human.hookFailed": "失败";
136
146
  readonly "feedback.phase.sandboxSetup": "沙箱预置";
137
147
  readonly "feedback.phase.scoring": "评分";
138
148
  readonly "feedback.phase.teardown": "清理中";
@@ -212,8 +222,6 @@ export declare const zhCN: {
212
222
  readonly "runner.startSandboxTeardown": "sandbox teardown(环境预置钩子)…";
213
223
  readonly "runner.timeout": "attempt 超时({{timeoutMs}}ms)\n最近进度:\n{{recentLogs}}";
214
224
  readonly "runner.traceSelected": " → 留 {{count}}(按语义)";
215
- readonly "runner.resumeCarry": " · 复用上次 {{carried}} 个已判定的结果,重跑 {{retry}} 个 eval\n";
216
- readonly "runner.resumeCarryDetail": " 复用 [{{experiment}}] {{evals}}\n";
217
225
  readonly "runner.useRemoteAgent": "使用 remote agent(不创建沙箱)…";
218
226
  readonly "sandbox.providerNotImplemented": "{{provider}} sandbox provider not implemented; use docker, vercel, or e2b";
219
227
  readonly "sandbox.missingSpec": string;
@@ -0,0 +1,103 @@
1
+ import type { InputRequest, JsonValue, StreamEvent, ToolName, TraceSpan } from "../types.ts";
2
+ interface ExecutionNodeBase {
3
+ /** 本函数内确定性生成,同一份 (events, spans) 输入永远产出同一批 id(不是全局稳定 id,
4
+ * 不跨调用持久化——目前没有下游需要跨次运行比对同一个节点)。 */
5
+ id: string;
6
+ /** 唯一关联上的 OTel span(供下钻;渲染层用 endMs - startMs 算耗时)。action 节点的
7
+ * span.attributes 额外补了 io.tool/io.input/io.output/io.status(见 withIoAttributes);
8
+ * 其余节点原样保留。缺失 = timing unavailable——要么这次运行没有 OTel 接入,要么有 span
9
+ * 但没能唯一关联到这个节点上;两种情况都不是「假装有耗时」,统一表现为字段不存在。 */
10
+ span?: TraceSpan;
11
+ }
12
+ export interface ExecutionMessageNode extends ExecutionNodeBase {
13
+ kind: "message";
14
+ role: "assistant" | "user";
15
+ text: string;
16
+ }
17
+ export interface ExecutionThinkingNode extends ExecutionNodeBase {
18
+ kind: "thinking";
19
+ text: string;
20
+ }
21
+ /** Skill 加载节点——一等,直接来自 StreamEvent 的 "skill.loaded",不靠工具名/文本猜。 */
22
+ export interface ExecutionSkillNode extends ExecutionNodeBase {
23
+ kind: "skill.loaded";
24
+ skill: string;
25
+ /**
26
+ * 仅当原生协议把 Skill 加载表达成可关联的工具调用时才有,和 StreamEvent 同名字段同一含义。
27
+ * 存在时参与和 action/subagent 节点同一套 callId 关联(见主函数 nodeByCallId):Claude Code
28
+ * 的 Skill 调用本身就是一次 tool_use,OTel mapper 同样会把它的 tool_use_id 复制成
29
+ * span.attributes.call_id,唯一命中时这个节点也应该拿到 timing,不因为节点 kind 是
30
+ * skill.loaded 就被排除在 enrichment 之外。
31
+ */
32
+ callId?: string;
33
+ }
34
+ /**
35
+ * action.called + action.result 按 callId 合并成一个节点。`status` 多了 "pending"
36
+ * (StreamEvent 的 action.result.status 没有这一档)——这是 ExecutionTree 独有的中间态,
37
+ * 表示这次运行结束时结果始终没有回来(如超时截断的 transcript),诚实地区分「还没完成」
38
+ * 和「跑完但失败/被拒绝」。
39
+ */
40
+ export interface ExecutionActionNode extends ExecutionNodeBase {
41
+ kind: "action";
42
+ callId: string;
43
+ /** 原始工具名(未归一化),对齐 StreamEvent.action.called.name。 */
44
+ name: string;
45
+ /** 归一化后的规范工具名,省略表示 adapter 没能归一(等同 ToolCall.name 缺省为 "unknown")。 */
46
+ tool?: ToolName;
47
+ input: JsonValue;
48
+ output?: JsonValue;
49
+ status: "pending" | "completed" | "failed" | "rejected";
50
+ }
51
+ /** subagent.called + subagent.completed 按 callId 合并;pending 语义同 ExecutionActionNode。 */
52
+ export interface ExecutionSubagentNode extends ExecutionNodeBase {
53
+ kind: "subagent";
54
+ callId: string;
55
+ name: string;
56
+ remoteUrl?: string;
57
+ output?: JsonValue;
58
+ status: "pending" | "completed" | "failed";
59
+ }
60
+ export interface ExecutionInputRequestedNode extends ExecutionNodeBase {
61
+ kind: "input.requested";
62
+ request: InputRequest;
63
+ }
64
+ export interface ExecutionCompactionNode extends ExecutionNodeBase {
65
+ kind: "compaction";
66
+ reason?: string;
67
+ }
68
+ export interface ExecutionErrorNode extends ExecutionNodeBase {
69
+ kind: "error";
70
+ message: string;
71
+ }
72
+ /**
73
+ * span 存在、有意义,但唯一关联不到任何骨架节点——原样保留成独立节点,清楚标注「只有遥测、
74
+ * 没有对应事件」,不悄悄猜着并进某个骨架节点。`span` 是必填字段:这类节点的全部内容就是
75
+ * 这一条 span 本身,没有骨架事件可以叠加。
76
+ */
77
+ export interface ExecutionTelemetryNode {
78
+ kind: "telemetry";
79
+ id: string;
80
+ span: TraceSpan;
81
+ }
82
+ export type ExecutionNode = ExecutionMessageNode | ExecutionThinkingNode | ExecutionSkillNode | ExecutionActionNode | ExecutionSubagentNode | ExecutionInputRequestedNode | ExecutionCompactionNode | ExecutionErrorNode | ExecutionTelemetryNode;
83
+ export interface ExecutionTree {
84
+ /**
85
+ * 骨架节点在前,顺序 = 事件出现顺序;telemetry-only 节点(未能唯一关联的 span)
86
+ * 按 span.startMs 追加在骨架之后——它们不属于骨架,不改变骨架的节点/顺序/内容,
87
+ * 只是叠加在末尾的额外证据。
88
+ */
89
+ nodes: ExecutionNode[];
90
+ /**
91
+ * 这次运行是否提供过任何 span——不代表关联成功,只代表「OTel 接入过」。供渲染层区分
92
+ * 两种不同的诚实提示:整体没有 OTel 接入(该字段为 false,所有节点自然都没有 span),
93
+ * 和 OTel 接入了但这一个节点恰好关联不上(该字段为 true,该节点的 span 仍缺失)。
94
+ */
95
+ timingAvailable: boolean;
96
+ }
97
+ /**
98
+ * 纯函数:把标准事件流(骨架)与一批已挑选好的 OTel span(可选 enrichment)合成一棵
99
+ * ExecutionTree。events 决定节点的存在、顺序与内容;spans 只能给已存在的节点补时间,
100
+ * 从不新增、删除或重排骨架节点。
101
+ */
102
+ export declare function buildExecutionTree(events: readonly StreamEvent[], spans: readonly TraceSpan[]): ExecutionTree;
103
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { ToolCall, TraceSpan } from "../../types.ts";
2
+ /**
3
+ * 选出要保留并落盘的 span。
4
+ * 小 trace 原样返回;大 trace 按 canonical kind 过滤(kind ≠ "other" 留);
5
+ * 没 mapper(kind 全 "other")则回落到 firehose 频率过滤;仍过多再按耗时硬截断。
6
+ * 最后一律按起点排序,view 直接当瀑布图渲染。
7
+ */
8
+ export declare function selectTraceSpans(spans: TraceSpan[]): TraceSpan[];
9
+ /**
10
+ * I/O 文本上限:文件内容/命令输出可能很大,截一下别把 trace 撑爆。导出给
11
+ * `execution-tree.ts` 复用——ExecutionTree 的 action 节点给合并上去的 span 补同一份
12
+ * io.* attributes,必须和这里同一个截断预算,不能另立一个数字。
13
+ */
14
+ export declare const IO_MAX = 4000;
15
+ export declare function ioText(v: unknown): string;
16
+ /**
17
+ * 给工具执行 span 补上真实「入参/出参」:codex 等的 OTLP span 只带 tool_name/call_id,
18
+ * 命令文本与输出在 stdout transcript(events)里 —— 按 call_id 把 deriveRunFacts 的
19
+ * ToolCall.input/output join 到对应 span 的 attributes(io.input / io.output / io.tool)。
20
+ * 没匹配上的 span 原样返回。
21
+ */
22
+ export declare function enrichTraceWithIO(spans: TraceSpan[], toolCalls: readonly ToolCall[]): TraceSpan[];
@@ -3,6 +3,14 @@ export declare const NRE_PALETTE: readonly ["#2a78d6", "#1baf7a", "#eda100", "#0
3
3
  export declare const NRE_PALETTE_SIZE: 6;
4
4
  /** FNV-1a 32 位散列:输入相同永远得到相同下标,与运行顺序无关。 */
5
5
  export declare function colorIndexForKey(key: string): number;
6
+ /**
7
+ * 同一张图内 series 键集合的配色:每个键仍以稳定散列为起点(无冲突时与跨图配色一致),
8
+ * 图内撞色时按传入顺序(图例顺序)线性探测下一个空色格——跨图稳定让位给图内可辨;
9
+ * 键数超过色板后无空格可探,回落散列格(复用不可避免)。返回键 → 色板下标。
10
+ * 契约见 docs/feature/reports/library/metric-views.md「MetricScatter」;
11
+ * 修法台账见 memory/scatter-series-color-collision.md。
12
+ */
13
+ export declare function colorIndicesForKeys(keys: readonly string[]): Map<string, number>;
6
14
  /** 键对应的稳定 class 名("nre-c3"),配 styles.css 的 .nre-cN 上文字色。 */
7
15
  export declare function colorClassForKey(key: string): string;
8
16
  /**
@@ -28,6 +28,29 @@ export function colorIndexForKey(key) {
28
28
  }
29
29
  return hash % NRE_PALETTE_SIZE;
30
30
  }
31
+ /**
32
+ * 同一张图内 series 键集合的配色:每个键仍以稳定散列为起点(无冲突时与跨图配色一致),
33
+ * 图内撞色时按传入顺序(图例顺序)线性探测下一个空色格——跨图稳定让位给图内可辨;
34
+ * 键数超过色板后无空格可探,回落散列格(复用不可避免)。返回键 → 色板下标。
35
+ * 契约见 docs/feature/reports/library/metric-views.md「MetricScatter」;
36
+ * 修法台账见 memory/scatter-series-color-collision.md。
37
+ */
38
+ export function colorIndicesForKeys(keys) {
39
+ const used = new Set();
40
+ const out = new Map();
41
+ for (const key of keys) {
42
+ if (out.has(key))
43
+ continue;
44
+ let idx = colorIndexForKey(key);
45
+ if (used.size < NRE_PALETTE_SIZE) {
46
+ while (used.has(idx))
47
+ idx = (idx + 1) % NRE_PALETTE_SIZE;
48
+ }
49
+ used.add(idx);
50
+ out.set(key, idx);
51
+ }
52
+ return out;
53
+ }
31
54
  /** 键对应的稳定 class 名("nre-c3"),配 styles.css 的 .nre-cN 上文字色。 */
32
55
  export function colorClassForKey(key) {
33
56
  return `nre-c${colorIndexForKey(key)}`;
@@ -1,3 +1,3 @@
1
- import { standard } from "./standard.tsx";
2
- export { standard };
1
+ import { standard, standardAttemptPage } from "./standard.tsx";
2
+ export { standard, standardAttemptPage };
3
3
  export default standard;