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
@@ -10,12 +10,37 @@
10
10
  // 只在 resolve 阶段被懒加载,永远不进渲染路径。
11
11
 
12
12
  import type { ReactNode } from "react";
13
- import type { AttemptLocator } from "../results/locator.ts";
14
- import type { Results, Scope } from "../results/types.ts";
15
- import { DEFAULT_REPORT_LOCALE, type ReportLocale } from "./locale.ts";
16
- import type { ReportInput } from "./types.ts";
13
+ import type { AttemptLocator } from "../../results/locator.ts";
14
+ import type { AttemptEvidence } from "../../results/attempt-evidence.ts";
15
+ import type { Results, Scope } from "../../results/types.ts";
16
+ import { DEFAULT_REPORT_LOCALE, type ReportLocale } from "../model/locale.ts";
17
+ import type { ReportInput } from "../model/types.ts";
17
18
  import type { ReportMeta } from "./report.ts";
18
19
 
20
+ // ───────────────────────── 当前页判别(PageContext) ─────────────────────────
21
+
22
+ /** scope-input page 的当前页上下文:消费宿主选择的 Scope,没有 locator/evidence。 */
23
+ export interface ScopePageContext {
24
+ id: string;
25
+ input: "scope";
26
+ }
27
+
28
+ /** attempt-input page 的当前页上下文:按 locator 消费一份 AttemptEvidence。 */
29
+ export interface AttemptPageContext {
30
+ id: string;
31
+ input: "attempt";
32
+ locator: AttemptLocator;
33
+ evidence: AttemptEvidence;
34
+ }
35
+
36
+ /**
37
+ * 当前渲染中的页判别联合(docs/feature/reports/library/shell.md「行为约束」、
38
+ * library/attempt-detail.md「page 输入与 spec / data 形态」)。经 ComposeContext.page 与
39
+ * ResolveContext.page 双双可见:组合组件靠它读当前页 id 与输入分支;attempt 叶子组件靠它
40
+ * 取省略 input 时的缺省 evidence。
41
+ */
42
+ export type PageContext = ScopePageContext | AttemptPageContext;
43
+
19
44
  // ───────────────────────── 节点形状 ─────────────────────────
20
45
 
21
46
  /** 标准 jsx-runtime 元素形状;text 宿主只认 type / props,不管 $$typeof。 */
@@ -67,18 +92,26 @@ export interface TextContext {
67
92
  locale: ReportLocale;
68
93
  /** 容器组件渲染 children 用,宽度显式传递。 */
69
94
  render(node: ReportNode, width?: number): string;
70
- /** 下钻命令,通证据室:`niceeval show @<locator>`。 */
71
- attemptCommand(locator: AttemptLocator): string;
95
+ /**
96
+ * 下钻命令,通 attempt-input page:`niceeval show @<locator>`。当前报告没有声明
97
+ * attempt-input page 时不存在——宿主不生成假命令,locator 只是文本(architecture.md
98
+ * 「Attempt 详情是一张参数化 page」)。
99
+ */
100
+ attemptCommand?(locator: AttemptLocator): string;
72
101
  /**
73
102
  * 组索引一类「按实验收窄」命令的生成;宿主注入以携带完整上下文(--results / --report /
74
- * --page 与位置参数),默认 `niceeval show --experiment <id>`。非契约字段,官方组件内部用。
103
+ * --page 与位置参数),默认 `niceeval show --exp <id>`。非契约字段,官方组件内部用。
75
104
  */
76
105
  experimentCommand(experimentIdPrefix: string): string;
77
106
  }
78
107
 
79
108
  export interface WebContext {
80
- /** 证据室深链,同 view 的 attempt 路由(`#/attempt/@<locator>`,单段、不透明)。 */
81
- attemptHref(locator: AttemptLocator): string;
109
+ /**
110
+ * attempt-input page 深链,同 view 的 attempt 路由(`#/attempt/@<locator>`,单段、不透明)
111
+ * 当前报告没有声明 attempt-input page 时不存在——宿主不生成空 href 或假链接,locator 只是
112
+ * 文本(architecture.md「Attempt 详情是一张参数化 page」)。
113
+ */
114
+ attemptHref?(locator: AttemptLocator): string;
82
115
  /** chrome 文案的 locale;官方组件渲染面经上下文读取,宿主外默认 "en"。 */
83
116
  locale: ReportLocale;
84
117
  }
@@ -86,6 +119,8 @@ export interface WebContext {
86
119
  /** 双面组件解析面的上下文:宿主注入的数据来源;props 显式给出 input 时以 props 为准。 */
87
120
  export interface ResolveContext {
88
121
  input: ReportInput;
122
+ /** 当前页判别;attempt 叶子组件省略 input 时从这里的 attempt 分支取缺省 evidence。 */
123
+ page: PageContext;
89
124
  }
90
125
 
91
126
  /** 组合组件的上下文:宿主 Scope、结果根完整读取面与规范化后的报告声明。 */
@@ -96,6 +131,8 @@ export interface ComposeContext {
96
131
  results: Results;
97
132
  /** 规范化后的报告声明,只读(docs/feature/reports/library/layout.md「自定义组件」)。 */
98
133
  report: ReportMeta;
134
+ /** 当前页判别:scope 分支只有 id;attempt 分支带 locator + evidence。 */
135
+ page: PageContext;
99
136
  }
100
137
 
101
138
  export interface ComponentFaces<P, R = P> {
@@ -125,9 +162,9 @@ export type ReportComponent<P> = ((props: P) => ReactNode) & {
125
162
  };
126
163
 
127
164
  // web 面的环境上下文:web 宿主渲染前设好;宿主之外(组件直接嵌进用户 React 应用)
128
- // 用默认值 —— attemptHref 默认 view 的 attempt 路由格式。
165
+ // 用默认值——没有 attemptHref,组件显式传 prop 才产生外部链接(architecture.md
166
+ // 「Attempt 详情是一张参数化 page」:没有 target 时 locator 只是文本,不生成假 href)。
129
167
  const DEFAULT_WEB_CONTEXT: WebContext = {
130
- attemptHref: (locator) => `#/attempt/${locator}`,
131
168
  locale: DEFAULT_REPORT_LOCALE,
132
169
  };
133
170
  let activeWebContext: WebContext | null = null;
@@ -143,11 +180,6 @@ export function runWithWebContext<T>(ctx: WebContext, fn: () => T): T {
143
180
  }
144
181
  }
145
182
 
146
- /** 官方组件的装配用:宿主上下文激活时才把 ctx.attemptHref 当默认下钻。 */
147
- export function isHostWebContextActive(): boolean {
148
- return activeWebContext !== null;
149
- }
150
-
151
183
  /** 函数形态:组合组件,只装配已有组件,可以异步;ctx 携带 scope / results / report。 */
152
184
  export function defineComponent<P>(
153
185
  compose: (props: P, context: ComposeContext) => ReportNode | Promise<ReportNode>,
@@ -269,11 +301,13 @@ export class ResolveMemo {
269
301
  }
270
302
  }
271
303
 
272
- /** resolveReportTree 的环境:宿主注入的 Scope / 读取面 / 规范化声明。 */
304
+ /** resolveReportTree 的环境:宿主注入的 Scope / 读取面 / 规范化声明 / 当前页判别。 */
273
305
  export interface ResolveEnv {
274
306
  scope: Scope;
275
307
  results: Results;
276
308
  report: ReportMeta;
309
+ /** 当前渲染的页:scope 分支只有 id;attempt 分支带 locator + evidence。 */
310
+ page: PageContext;
277
311
  /** 一次页渲染一份;跨页共享缓存时由宿主显式传同一实例。 */
278
312
  memo?: ResolveMemo;
279
313
  }
@@ -323,7 +357,7 @@ function bareTextError(value: string | number, path: string[]): Error {
323
357
  */
324
358
  export async function resolveReportTree(node: ReportNode, env: ResolveEnv): Promise<ReportNode> {
325
359
  const memo = env.memo ?? new ResolveMemo();
326
- const composeCtx: ComposeContext = { scope: env.scope, results: env.results, report: env.report };
360
+ const composeCtx: ComposeContext = { scope: env.scope, results: env.results, report: env.report, page: env.page };
327
361
  return resolveNode(node, { memo, composeCtx }, []);
328
362
  }
329
363
 
@@ -367,6 +401,7 @@ async function resolveNode(node: ReportNode | string | number, state: ResolveSta
367
401
  const input = ((props as { input?: unknown }).input as ReportInput | undefined) ?? state.composeCtx.scope;
368
402
  const ctx: InternalResolveContext = {
369
403
  input,
404
+ page: state.composeCtx.page,
370
405
  memoFetch: <T,>(dataFn: unknown, dataInput: unknown, options: unknown, compute: () => Promise<T>) =>
371
406
  state.memo.fetch(dataFn, dataInput, options, compute) as Promise<T>,
372
407
  };
@@ -528,11 +563,12 @@ function shellQuote(value: string): string {
528
563
  export function createTextContext(options?: TextRenderOptions): TextContext {
529
564
  const width = Math.max(20, options?.width ?? 80);
530
565
  const locale = options?.locale ?? DEFAULT_REPORT_LOCALE;
531
- // 默认下钻命令:AttemptLocator `@` 前缀的不透明短串,`niceeval show @<locator>` 是
532
- // show 已实现的真实 CLI 语法,不需要反查 eval id 再拼一条近似命令。
533
- const attemptCommand = options?.attemptCommand ?? ((locator: AttemptLocator) => `niceeval show ${locator}`);
566
+ // 没有默认值:当前报告没有声明 attempt-input page 时不存在下钻命令——宿主(report.ts /
567
+ // web.ts 的渲染入口)据规范化 definition 是否有 attempt page 决定要不要注入生成器,
568
+ // 这里只透传调用方给的值(architecture.md「Attempt 详情是一张参数化 page」)
569
+ const attemptCommand = options?.attemptCommand;
534
570
  const experimentCommand =
535
- options?.experimentCommand ?? ((prefix: string) => `niceeval show --experiment ${shellQuote(prefix)}`);
571
+ options?.experimentCommand ?? ((prefix: string) => `niceeval show --exp ${shellQuote(prefix)}`);
536
572
  const make = (w: number): TextContext => ({
537
573
  width: w,
538
574
  locale,
@@ -3,7 +3,7 @@
3
3
  //
4
4
  // import 边界即运行时边界:计算函数(*Data)会经句柄触碰文件系统(懒加载 artifact),
5
5
  // 只能进服务端 / 脚本;组件的渲染面纯同步零 IO。text 宿主遍历渲染不需要 react-dom
6
- // (renderReportToText);web 宿主的 renderReportToStaticHtml 在 ./web.ts,只有那一侧
6
+ // (renderReportToText);web 宿主的 renderReportToStaticHtml 在 ./runtime/web.ts,只有那一侧
7
7
  // import react-dom。写报告文件的项目要装 react(.tsx 编译产物 import react/jsx-runtime)。
8
8
 
9
9
  // 指标与维度读取器
@@ -18,59 +18,73 @@ export {
18
18
  repeatedFailedCommands,
19
19
  taskPassRate,
20
20
  tokens,
21
- } from "./metrics.ts";
22
- export { flag, numericFlag, numericRunConfig, runConfig } from "./flag.ts";
21
+ } from "./model/metrics.ts";
22
+ export { flag, label, numericFlag, numericLabel, numericRunConfig, runConfig } from "./model/flag.ts";
23
23
 
24
24
  // 报告定义与组件基座
25
25
  export {
26
26
  buildReportMeta,
27
27
  defineReport,
28
28
  isReportDefinition,
29
- pickReportPage,
30
- renderReportToText,
31
- renderReportTreeToText,
32
- reportTitleText,
33
29
  resolveReportTitle,
34
- ReportPageNotFoundError,
35
30
  DEFAULT_PAGE_ID,
36
- } from "./report.ts";
31
+ } from "./definition/report.ts";
37
32
  export type {
38
- HostCommandContext,
39
33
  NonEmptyArray,
40
- RenderReportTextOptions,
41
- RenderTreeTextOptions,
42
- ReportTreeHostContext,
43
34
  HeadTag,
44
35
  ReportAsset,
45
36
  ReportDef,
46
37
  ReportDefinition,
47
- ReportHostContext,
48
38
  ReportLink,
49
39
  ReportMeta,
40
+ ReportMetaPage,
50
41
  ReportPage,
42
+ ReportPageBase,
51
43
  ReportShell,
52
- } from "./report.ts";
53
- export { defineComponent, createTextContext, renderNodeToText, resolveReportTree, validateReportTree, ResolveMemo } from "./tree.ts";
44
+ } from "./definition/report.ts";
45
+ export {
46
+ pickReportPage,
47
+ renderReportToText,
48
+ renderReportTreeToText,
49
+ reportTitleText,
50
+ ReportPageNotFoundError,
51
+ ReportPageNeedsLocatorError,
52
+ } from "./runtime/text.ts";
53
+ export type {
54
+ HostCommandContext,
55
+ RenderReportTextOptions,
56
+ RenderTreeTextOptions,
57
+ ReportTreeHostContext,
58
+ ReportHostContext,
59
+ } from "./runtime/text.ts";
60
+ export { defineComponent, createTextContext, renderNodeToText, resolveReportTree, validateReportTree, ResolveMemo } from "./definition/tree.ts";
61
+ export type { AttemptEvidence, AttemptEvidenceCapabilities } from "../results/attempt-evidence.ts";
54
62
  export type {
63
+ AttemptPageContext,
55
64
  ComponentFaces,
56
65
  ComposeContext,
66
+ PageContext,
57
67
  ReportComponent,
58
68
  ReportElement,
59
69
  ReportNode,
60
70
  ResolveContext,
61
71
  ResolveEnv,
72
+ ScopePageContext,
62
73
  TextContext,
63
74
  TextRenderOptions,
64
75
  WebContext,
65
- } from "./tree.ts";
76
+ } from "./definition/tree.ts";
66
77
 
67
- // 排版原语(八个内置双面组件)
68
- export { Col, Row, Section, Style, Tab, Table, Tabs, Text } from "./primitives.tsx";
78
+ // 排版原语(十个内置双面组件)
79
+ export { Col, Grid, Row, Section, Stat, Style, Tab, Table, Tabs, Text } from "./definition/primitives.tsx";
69
80
  export type {
70
81
  ColProps,
82
+ GridProps,
71
83
  LayoutProps,
72
84
  RowProps,
73
85
  SectionProps,
86
+ StatProps,
87
+ StatTone,
74
88
  StyleProps,
75
89
  TabProps,
76
90
  TableColumn,
@@ -78,7 +92,7 @@ export type {
78
92
  TableRow,
79
93
  TabsProps,
80
94
  TextProps,
81
- } from "./primitives.tsx";
95
+ } from "./definition/primitives.tsx";
82
96
 
83
97
  // 文本排版工具箱:自定义组件的 text 面用的就是官方组件那把尺子。
84
98
  // 表格有 <Table> 承担,这里只给表以外的形态用 —— 尤其别拿 String.prototype.padEnd 对齐:
@@ -91,78 +105,90 @@ export {
91
105
  indentBlock as indent,
92
106
  textBar as bar,
93
107
  joinColumns as columns,
94
- } from "./text/layout.ts";
95
- export type { ColumnAlign } from "./text/layout.ts";
108
+ } from "./model/text-layout.ts";
109
+ export type { ColumnAlign } from "./model/text-layout.ts";
96
110
 
97
111
  // locale:官方组件 chrome 文案的语言(内置词典覆盖 en / zh-CN,其它 locale 走回退)
98
- export { DEFAULT_REPORT_LOCALE, localizedTextEquals, resolveLocalizedText, resolveMetricLabel } from "./locale.ts";
99
- export type { LocalizedText, ReportLocale } from "./locale.ts";
112
+ export { DEFAULT_REPORT_LOCALE, localizedTextEquals, resolveLocalizedText, resolveMetricLabel } from "./model/locale.ts";
113
+ export type { LocalizedText, ReportLocale } from "./model/locale.ts";
100
114
 
101
115
  // 官方双面组件(spec / data 双形态;配套 *Data 计算函数在下面成对导出)
102
116
  // 与站点组件(Hero / HeroCard / PoweredBy / ScopeWarnings / CopyFixPrompt / TraceWaterfall)
117
+ export { ScopeSummary, ExperimentComparison } from "./components/summaries/index.tsx";
118
+ export type { ScopeSummaryProps, ExperimentComparisonProps } from "./components/summaries/index.tsx";
119
+ export { AttemptList, EvalList, ExperimentList, FailureList } from "./components/entity-lists/index.tsx";
120
+ export type {
121
+ AttemptListProps,
122
+ EvalListProps,
123
+ ExperimentListProps,
124
+ FailureListProps,
125
+ } from "./components/entity-lists/index.tsx";
103
126
  export {
104
- AttemptList,
105
- CopyFixPrompt,
106
127
  DeltaTable,
107
- EvalList,
108
- ExperimentComparison,
109
- ExperimentList,
110
- FailureList,
111
- Hero,
112
- HeroCard,
113
128
  MetricBars,
114
129
  MetricLine,
115
130
  MetricMatrix,
116
131
  MetricScatter,
117
132
  MetricTable,
118
- PoweredBy,
119
133
  Scoreboard,
120
- ScopeSummary,
121
- ScopeWarnings,
122
- TraceWaterfall,
123
- } from "./components.tsx";
134
+ } from "./components/metric-views/index.tsx";
124
135
  export type {
125
- AttemptListProps,
126
- CopyFixPromptProps,
127
- DataProps,
128
136
  DeltaTableProps,
129
- EvalListProps,
130
- ExperimentComparisonProps,
131
- ExperimentListProps,
132
- FailureListProps,
133
- HeroCardProps,
134
- HeroProps,
135
137
  MetricBarsProps,
136
138
  MetricLineProps,
137
139
  MetricMatrixProps,
138
140
  MetricScatterProps,
139
141
  MetricTableProps,
140
142
  ScoreboardProps,
141
- ScopeSummaryProps,
143
+ } from "./components/metric-views/index.tsx";
144
+ export {
145
+ CopyFixPrompt,
146
+ Hero,
147
+ HeroCard,
148
+ PoweredBy,
149
+ ScopeWarnings,
150
+ TraceWaterfall,
151
+ } from "./components/site-components/index.tsx";
152
+ export type {
153
+ CopyFixPromptProps,
154
+ HeroCardProps,
155
+ HeroProps,
142
156
  ScopeWarningsProps,
143
157
  TraceWaterfallProps,
144
- } from "./components.tsx";
158
+ } from "./components/site-components/index.tsx";
159
+
160
+ // Attempt 详情组件族(docs/feature/reports/library/attempt-detail.md):11 个叶子 + 2 个
161
+ // 只装配叶子的组合组件(AttemptAssessment / AttemptDetail),都从 niceeval/report 导出。
162
+ export {
163
+ AttemptAssertions,
164
+ AttemptAssessment,
165
+ AttemptConversation,
166
+ AttemptDetail,
167
+ AttemptDiagnostics,
168
+ AttemptDiff,
169
+ AttemptError,
170
+ AttemptFixPrompt,
171
+ AttemptSource,
172
+ AttemptSummary,
173
+ AttemptTimeline,
174
+ AttemptTrace,
175
+ AttemptUsage,
176
+ } from "./components/attempt-detail/index.tsx";
177
+ export type { AttemptSectionProps } from "./components/attempt-detail/index.tsx";
145
178
 
146
179
  // 计算函数(组件解析面的具名形式,与组件成对;spec 形态下由管线代调,data 形态与
147
180
  // 嵌入场景下由作者手工调)
181
+ export { scopeSummaryData } from "./components/summaries/compute.ts";
182
+ export { attemptListData, evalListData, experimentListData } from "./components/entity-lists/compute.ts";
148
183
  export {
149
- attemptListData,
150
- copyFixPromptData,
151
184
  deltaTableData,
152
- evalListData,
153
- experimentComparisonData,
154
- experimentListData,
155
- heroData,
156
185
  metricLineData,
157
186
  metricMatrixData,
158
187
  metricScatterData,
159
188
  metricTableData,
160
189
  pairsByFlag,
161
- scopeSummaryData,
162
- scopeWarningsData,
163
190
  scoreboardData,
164
- traceWaterfallData,
165
- } from "./compute.ts";
191
+ } from "./components/metric-views/compute.ts";
166
192
  export type {
167
193
  DeltaTableOptions,
168
194
  MetricLineOptions,
@@ -170,7 +196,28 @@ export type {
170
196
  MetricScatterOptions,
171
197
  MetricTableOptions,
172
198
  ScoreboardOptions,
173
- } from "./compute.ts";
199
+ } from "./components/metric-views/compute.ts";
200
+ export {
201
+ copyFixPromptData,
202
+ heroData,
203
+ scopeWarningsData,
204
+ traceWaterfallData,
205
+ } from "./components/site-components/compute.ts";
206
+
207
+ // Attempt 详情组件族的计算函数:输入恒为单个 AttemptEvidence,同步纯派生(不读文件、不 fetch)。
208
+ export {
209
+ attemptAssertionsData,
210
+ attemptConversationData,
211
+ attemptDiagnosticsData,
212
+ attemptDiffData,
213
+ attemptErrorData,
214
+ attemptFixPromptData,
215
+ attemptSourceData,
216
+ attemptSummaryData,
217
+ attemptTimelineData,
218
+ attemptTraceData,
219
+ attemptUsageData,
220
+ } from "./components/attempt-detail/compute.ts";
174
221
 
175
222
  // 数据契约(组件的 data)
176
223
  export type {
@@ -186,8 +233,6 @@ export type {
186
233
  DimensionOptions,
187
234
  DimensionRef,
188
235
  EvalListItem,
189
- ExperimentComparisonData,
190
- ExperimentComparisonGroupData,
191
236
  ExperimentListEvalRow,
192
237
  ExperimentListItem,
193
238
  FlagPairs,
@@ -207,15 +252,30 @@ export type {
207
252
  ScopeSummaryData,
208
253
  ScopeWarning,
209
254
  ScoreboardData,
255
+ SeriesInput,
210
256
  TableData,
211
257
  TraceSpanSummary,
212
258
  TraceWaterfallRow,
213
259
  VerdictTally,
214
- } from "./types.ts";
260
+ } from "./model/types.ts";
261
+
262
+ // Attempt 详情组件族的数据契约
263
+ export type {
264
+ AttemptAssertionsData,
265
+ AttemptConversationData,
266
+ AttemptConversationReply,
267
+ AttemptConversationRound,
268
+ AttemptDiagnosticsData,
269
+ AttemptDiffData,
270
+ AttemptDiffFileEntry,
271
+ AttemptErrorData,
272
+ AttemptFixPromptData,
273
+ AttemptSourceData,
274
+ AttemptSummaryData,
275
+ AttemptTimelineData,
276
+ AttemptTraceData,
277
+ AttemptUsageData,
278
+ } from "./model/types.ts";
215
279
 
216
280
  // 数据层输入的类型(家在 niceeval/results,这里 re-export 方便写指标 / 报告)
217
281
  export type { AttemptHandle, Results, Scope, Snapshot } from "../results/types.ts";
218
-
219
- // experiment id 的组键推导(id 的目录前缀,如 `compare/bub-low` 的 `compare`)。
220
- // 重新导出,让自定义报告能按同一份口径把 experiment 分组,不必自己重写这两行逻辑。
221
- export { experimentGroupOf } from "../shared/aggregate.ts";
@@ -6,9 +6,9 @@
6
6
  // 和重试策略纠缠在一起(eval A=[1]、eval B=[0,0,0] 平铺 = 0.25,两级宏平均 = 0.5)。
7
7
  // 自定义维度把同一道题的 attempt 分进不同组时,第一级折叠发生在各组内部。
8
8
 
9
- import { dedupeAttempts } from "../results/select.ts";
10
- import type { AttemptHandle, Scope, ScopeWarning, Snapshot } from "../results/types.ts";
11
- import { encodeAttemptLocator, type AttemptLocator } from "../results/locator.ts";
9
+ import { dedupeAttempts } from "../../results/select.ts";
10
+ import type { AttemptHandle, Scope, ScopeWarning, Snapshot } from "../../results/types.ts";
11
+ import { encodeAttemptLocator, type AttemptLocator } from "../../results/locator.ts";
12
12
  import type {
13
13
  Aggregator,
14
14
  DimensionInput,
@@ -18,11 +18,12 @@ import type {
18
18
  MetricColumn,
19
19
  NumericAxis,
20
20
  ReportInput,
21
+ SeriesInput,
21
22
  } from "./types.ts";
22
- import { flagValueOf, runConfigValueOf } from "./flag.ts";
23
+ import { flagValueOf, labelValueOf, runConfigValueOf } from "./flag.ts";
23
24
  import { formatMetricValue, localizedDisplay } from "./format.ts";
24
25
  import { localeText, type LocalizedText } from "./locale.ts";
25
- import { evalPrefixPredicate } from "../shared/aggregate.ts";
26
+ import { evalPrefixPredicate } from "../../shared/aggregate.ts";
26
27
 
27
28
  // 复合键分隔符:NUL 不会出现在 eval id / experimentId / ISO 时间里,拼接键不会串味
28
29
  const KEY_SEP = "\u0000";
@@ -119,7 +120,9 @@ function isDimensionRef(dimension: DimensionInput): dimension is DimensionRef {
119
120
  return (
120
121
  typeof dimension === "object" &&
121
122
  "kind" in dimension &&
122
- ((dimension as DimensionRef).kind === "flag" || (dimension as DimensionRef).kind === "runConfig")
123
+ ((dimension as DimensionRef).kind === "flag" ||
124
+ (dimension as DimensionRef).kind === "runConfig" ||
125
+ (dimension as DimensionRef).kind === "label")
123
126
  );
124
127
  }
125
128
 
@@ -147,9 +150,9 @@ export function refDisplayKey(value: unknown): [display: string, canonical: stri
147
150
  }
148
151
 
149
152
  function refValueOf(ref: DimensionRef, item: Item): unknown {
150
- return ref.kind === "flag"
151
- ? flagValueOf(item.attempt, ref.name)
152
- : runConfigValueOf(item.attempt, ref.name as Parameters<typeof runConfigValueOf>[1]);
153
+ if (ref.kind === "flag") return flagValueOf(item.attempt, ref.name);
154
+ if (ref.kind === "label") return labelValueOf(item.attempt, ref.name);
155
+ return runConfigValueOf(item.attempt, ref.name as Parameters<typeof runConfigValueOf>[1]);
153
156
  }
154
157
 
155
158
  export function dimensionKey(dimension: DimensionInput, item: Item): string {
@@ -179,6 +182,25 @@ export function dimensionKey(dimension: DimensionInput, item: Item): string {
179
182
  }
180
183
  }
181
184
 
185
+ /**
186
+ * series 类选项(SeriesInput)的复合维度解析:数组形态的维度 name 依声明顺序以 ` × ` 连接,
187
+ * 每个 attempt 的维度值为各成员显示键以 ` · ` 连接(缺失成员沿用 `(missing)` 显示键参与
188
+ * 连接,与单维度缺失同一条规则)。单维度形态与 dimensionName / dimensionKey 严格等价。
189
+ */
190
+ export function seriesMembers(series: SeriesInput): readonly DimensionInput[] {
191
+ return Array.isArray(series) ? (series as readonly DimensionInput[]) : [series as DimensionInput];
192
+ }
193
+
194
+ export function seriesName(series: SeriesInput): string {
195
+ return seriesMembers(series).map(dimensionName).join(" × ");
196
+ }
197
+
198
+ export function seriesKey(series: SeriesInput, item: Item): string {
199
+ return seriesMembers(series)
200
+ .map((member) => dimensionKey(member, item))
201
+ .join(" · ");
202
+ }
203
+
182
204
  /**
183
205
  * 按维度分组;维度 domain 按稳定 key 字典序(Unicode)排列,不让文件扫描顺序渗进报告。
184
206
  * flag / runConfig 维度做显示键冲突检测:不同原始值生成同一显示键时报错并要求改用
@@ -4,7 +4,7 @@
4
4
  // flag() 只读 `ExperimentDef.flags` 里显式声明的 KV;model / reasoningEffort / budget / runs
5
5
  // 这类顶层运行配置不在 flags 里,用 runConfig() 读快照的 ExperimentRunInfo 投影。
6
6
 
7
- import type { AttemptHandle } from "../results/types.ts";
7
+ import type { AttemptHandle } from "../../results/types.ts";
8
8
  import type {
9
9
  DimensionOptions,
10
10
  DimensionRef,
@@ -20,6 +20,12 @@ export function flagValueOf(attempt: AttemptHandle, name: string): unknown {
20
20
  return info?.flags?.[name];
21
21
  }
22
22
 
23
+ /** experiment 声明的报告归类标注 labels(同 flags 的读取回退链;值域 string | number)。 */
24
+ export function labelValueOf(attempt: AttemptHandle, name: string): unknown {
25
+ const info = attempt.snapshot?.experiment ?? attempt.result.experiment;
26
+ return info?.labels?.[name];
27
+ }
28
+
23
29
  /**
24
30
  * runConfig() 的取值:读快照的 `ExperimentRunInfo` 投影,外加桥接到快照顶层权威字段的
25
31
  * `model` / `agent` 两个键(与 "model" / "agent" 内置维度同一读法,不另造第二套口径)。
@@ -54,6 +60,21 @@ export function flag(name: string, options?: DimensionOptions): DimensionRef {
54
60
  };
55
61
  }
56
62
 
63
+ /**
64
+ * 把 experiment 声明的一个报告标注(`ExperimentDef.labels` 的键)当分组维度,与 {@link flag}
65
+ * 同一套用法。labels 是纯报告侧的归类坐标:不透传运行时、不参与可比性配置;报告不从
66
+ * experiment id 字符串猜语义,归类只认声明(docs/feature/experiments/library.md「labels」)。
67
+ */
68
+ export function label(name: string, options?: DimensionOptions): DimensionRef {
69
+ assertName(name, "label", "the key declared in the experiment's labels");
70
+ return {
71
+ kind: "label",
72
+ name,
73
+ ...(options?.label !== undefined ? { label: options.label } : {}),
74
+ ...(options?.unit !== undefined ? { unit: options.unit } : {}),
75
+ };
76
+ }
77
+
57
78
  /**
58
79
  * 把一项顶层运行配置当分组维度,与 {@link flag} 同一套用法。读快照的 `ExperimentRunInfo`
59
80
  * 投影;可用键由 RunConfigKey 在类型层穷尽(那张接口的字段全集,外加桥接到快照顶层权威
@@ -86,6 +107,23 @@ export function numericFlag(name: string, options?: NumericAxisOptions): Numeric
86
107
  };
87
108
  }
88
109
 
110
+ /**
111
+ * MetricLine 的 x 轴:只接受 number 值的 label。labels 由作者亲手声明,要数值轴就直接
112
+ * 声明成 number,不设 map;字符串值返回 null(折线不绘该点并报告缺失)。
113
+ */
114
+ export function numericLabel(name: string, options?: NumericAxisOptions): NumericAxis {
115
+ assertName(name, "numericLabel", "the key declared in the experiment's labels");
116
+ return {
117
+ name,
118
+ ...(options?.label !== undefined ? { label: options.label } : {}),
119
+ ...(options?.unit !== undefined ? { unit: options.unit } : {}),
120
+ of(attempt) {
121
+ const value = labelValueOf(attempt, name);
122
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
123
+ },
124
+ };
125
+ }
126
+
89
127
  /**
90
128
  * 顶层运行配置作数值轴:数值配置直接返回该值;字符串配置必须显式给 `map`
91
129
  * (如 { low: 1, medium: 2, high: 3 })。未声明、未投影、非数值或未命中 map 的值返回 null。