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
@@ -1,6 +1,6 @@
1
- import type { Results, Scope } from "../results/types.ts";
2
- import { type ReportNode, type TextRenderOptions } from "./tree.ts";
3
- import { type LocalizedText, type ReportLocale } from "./locale.ts";
1
+ import type { Scope } from "../../results/types.ts";
2
+ import type { ReportNode } from "./tree.ts";
3
+ import { type LocalizedText } from "../model/locale.ts";
4
4
  export interface ReportLink {
5
5
  label: LocalizedText;
6
6
  href: string;
@@ -55,7 +55,7 @@ export interface ReportShell {
55
55
  styles?: ReportAsset[];
56
56
  }
57
57
  export type NonEmptyArray<T> = readonly [T, ...T[]];
58
- export interface ReportPage {
58
+ export interface ReportPageBase {
59
59
  /** 页面身份:`--page <id>` 的取值、web 路由 `#/page/<id>` 与导航锚。小写字母、数字与连字符。 */
60
60
  id: string;
61
61
  /** 导航中的页名。 */
@@ -63,6 +63,21 @@ export interface ReportPage {
63
63
  /** 这一页的报告树;ReportDefinition 不是 ReportNode,页装不进外壳。 */
64
64
  content: ReportNode;
65
65
  }
66
+ /**
67
+ * 页按输入分两种形态,仍是同一个类型族,走同一条 resolve → validate → render 管线
68
+ * (docs/feature/reports/architecture.md「Attempt 详情是一张参数化 page」):
69
+ * - `input` 省略或为 `"scope"`:消费宿主选择的 Scope;省略时规范化为 `navigation: true`。
70
+ * - `input: "attempt"`:以 locator 为参数,消费一份 AttemptEvidence;没有 locator 时不能打开,
71
+ * 必须显式 `navigation: false`,不进导航。
72
+ * 一份报告至多声明一张 attempt-input page。
73
+ */
74
+ export type ReportPage = (ReportPageBase & {
75
+ input?: "scope";
76
+ navigation?: boolean;
77
+ }) | (ReportPageBase & {
78
+ input: "attempt";
79
+ navigation: false;
80
+ });
66
81
  /** content / pages / extends 三选一由类型表达,不把非法状态留到运行期。 */
67
82
  export type ReportDef = ReportShell & ({
68
83
  /** 单页缩写,等价于只含 id `report` 的页列表。 */
@@ -70,7 +85,7 @@ export type ReportDef = ReportShell & ({
70
85
  pages?: never;
71
86
  extends?: never;
72
87
  } | {
73
- /** 非空页列表;导航按数组顺序显示。 */
88
+ /** 非空页列表;`navigation !== false` 的项按数组顺序显示。 */
74
89
  pages: NonEmptyArray<ReportPage>;
75
90
  content?: never;
76
91
  extends?: never;
@@ -100,20 +115,26 @@ export interface ReportDefinition {
100
115
  readonly styles: readonly ReportAsset[];
101
116
  readonly pages: NonEmptyArray<ReportPage>;
102
117
  }
103
- /** 规范化后的报告声明,经组合组件 ctx.report 只读可见(scripts / styles 是注入资产,不进)。 */
118
+ /** 规范化后页列表在 ctx.report 上的元数据形态(id / 导航页名 / 输入声明 / 导航资格)。 */
119
+ export interface ReportMetaPage {
120
+ id: string;
121
+ title: LocalizedText;
122
+ input: "scope" | "attempt";
123
+ navigation: boolean;
124
+ }
125
+ /**
126
+ * 规范化后的报告声明,经组合组件 ctx.report 只读可见(scripts / styles 是注入资产,不进)。
127
+ * 不携带"当前是哪一页"——那由 ctx.page(PageContext)表达,两者不是同一份状态
128
+ * (docs/feature/reports/library/shell.md「行为约束」)。
129
+ */
104
130
  export interface ReportMeta {
105
131
  /** 走完回退链(声明 title → 唯一快照 name → 内置文案「Eval 运行结果 / Eval Results」)后的标题。 */
106
132
  title: LocalizedText;
107
133
  /** 页头外链;声明省略时为空数组。 */
108
134
  links: readonly ReportLink[];
109
135
  footer?: LocalizedText;
110
- /** 规范化后的页列表(id 与导航页名),恒非空。 */
111
- pages: NonEmptyArray<{
112
- id: string;
113
- title: LocalizedText;
114
- }>;
115
- /** 当前渲染中的页 id。 */
116
- pageId: string;
136
+ /** 规范化后的页列表,恒非空。 */
137
+ pages: NonEmptyArray<ReportMetaPage>;
117
138
  }
118
139
  /** 单页缩写展开出的唯一页 id 与内置页名。 */
119
140
  export declare const DEFAULT_PAGE_ID = "report";
@@ -129,55 +150,5 @@ export declare const FALLBACK_REPORT_TITLE: LocalizedText;
129
150
  * 都落到内置文案,不按数组顺序挑。
130
151
  */
131
152
  export declare function resolveReportTitle(definition: ReportDefinition, scope: Scope): LocalizedText;
132
- /** 规范化声明 → 组合组件可见的 ReportMeta(scripts / styles 是注入资产,不进)。 */
133
- export declare function buildReportMeta(definition: ReportDefinition, scope: Scope, pageId: string): ReportMeta;
134
- /** `--page` 未命中:宿主据此按用法错误退出并列出可用页 id。 */
135
- export declare class ReportPageNotFoundError extends Error {
136
- readonly pageId: string;
137
- readonly available: string[];
138
- constructor(pageId: string, available: string[]);
139
- }
140
- export declare function pickReportPage(definition: ReportDefinition, pageId?: string): ReportPage;
141
- /** 宿主注入的渲染上下文:官方口径挑好的 Scope 与结果根完整读取面。 */
142
- export interface ReportHostContext {
143
- scope: Scope;
144
- /** 组合组件 ctx.results 的来源;历史视图从这里自行挑 Snapshot[]。 */
145
- results: Results;
146
- }
147
- export interface RenderReportTextOptions extends TextRenderOptions {
148
- /** 渲染哪一页;缺省第一页。未命中抛 ReportPageNotFoundError。 */
149
- pageId?: string;
150
- }
151
- /**
152
- * text 宿主的装载语义:选页 → resolve(组合展开 + spec 取数,唯一的 await 边界)→ 树校验 →
153
- * 遍历渲染 text 面。不需要 react-dom。宿主不在报告树外另设警告通道——挑选警告的呈现件是
154
- * `ScopeWarnings` 组件,内建报告每页都放它,自定义报告放不放是作者义务
155
- * (docs/feature/reports/architecture.md「Scope 是计算入口」)。
156
- */
157
- export declare function renderReportToText(definition: ReportDefinition, ctx: ReportHostContext, options?: RenderReportTextOptions): Promise<string>;
158
- /** 页索引标题行(show 多页索引 / view 导航共用的解析结果):按 locale 解析的标题字符串。 */
159
- export declare function reportTitleText(definition: ReportDefinition, scope: Scope, locale: ReportLocale): string;
160
- /** 宿主索引命令的完整上下文(docs/feature/reports/show/reports.md「索引命令携带完整上下文」)。 */
161
- export interface HostCommandContext {
162
- patterns: string[];
163
- results?: string;
164
- experiment?: string;
165
- report?: string;
166
- page?: string;
167
- }
168
- /** 逐页渲染的宿主上下文:官方口径的 Scope、结果根读取面与规范化声明(ctx.report)。 */
169
- export interface ReportTreeHostContext {
170
- scope: Scope;
171
- results: Results;
172
- report: ReportMeta;
173
- }
174
- export interface RenderTreeTextOptions extends TextRenderOptions {
175
- /** 组索引命令的完整上下文;给了就按它拼命令,experimentCommand 显式注入时以后者为准。 */
176
- commandContext?: HostCommandContext;
177
- }
178
- /**
179
- * 渲染一页报告树的 text 面(宿主逐页调用;页选择归宿主):
180
- * resolve(组合展开 + spec 取数)→ validate → render。宿主不在报告树外另设警告通道,
181
- * 挑选警告由页内的 `ScopeWarnings` 组件呈现(内建报告每页都放它)。
182
- */
183
- export declare function renderReportTreeToText(tree: ReportNode, ctx: ReportTreeHostContext, options?: RenderTreeTextOptions): Promise<string>;
153
+ /** 规范化声明 → 组合组件可见的 ReportMeta(scripts / styles 是注入资产,不进;不携带当前页)。 */
154
+ export declare function buildReportMeta(definition: ReportDefinition, scope: Scope): ReportMeta;
@@ -5,11 +5,10 @@
5
5
  // `extends` 在另一份报告上叠外壳——页归 base、外壳逐字段覆盖,合并在调用时折叠完成,
6
6
  // 宿主装载看到的永远是已折叠的普通产物。
7
7
  //
8
- // renderReportToText text 宿主(show)的装载入口;web 宿主(view)的
9
- // renderReportToStaticHtml ./web.ts(那一侧才 import react-dom)。管线以页为单位执行:
10
- // 装载(规范化 + 静态校验)→ resolve → validate → render。
11
- import { createTextContext, renderNodeToText, resolveReportTree, validateReportTree, ResolveMemo, } from "./tree.js";
12
- import { localizedTextEquals, resolveLocalizedText, } from "./locale.js";
8
+ // text/web 两个宿主的渲染入口(renderReportToText / renderReportToStaticHtml) ../runtime/
9
+ // (text.ts / web.ts);这里只有 ReportDefinition 的类型体系、装载规范化与元数据折叠
10
+ // (buildReportMeta / resolveReportTitle),不做任何渲染。
11
+ import { localizedTextEquals } from "../model/locale.js";
13
12
  const REPORT_DEFINITION = Symbol.for("niceeval.report.definition");
14
13
  /** 单页缩写展开出的唯一页 id 与内置页名。 */
15
14
  export const DEFAULT_PAGE_ID = "report";
@@ -152,6 +151,45 @@ function assertHeadTags(tags) {
152
151
  }
153
152
  return tags;
154
153
  }
154
+ /**
155
+ * page 的 input / navigation 规范化(shell.md「page 显式声明输入」):省略或 "scope" 时补
156
+ * `input: "scope"`,`navigation` 缺省为 true;"attempt" 必须显式 `navigation: false`——
157
+ * 没有 locator 时不可打开,不能悄悄挤进导航,省略或传 true 都在装载期报错。
158
+ */
159
+ function normalizePageInputAndNavigation(page) {
160
+ const input = page.input;
161
+ if (input === undefined || input === "scope") {
162
+ return {
163
+ id: page.id,
164
+ title: page.title,
165
+ content: page.content,
166
+ input: "scope",
167
+ navigation: page.navigation !== false,
168
+ };
169
+ }
170
+ if (input === "attempt") {
171
+ if (page.navigation !== false) {
172
+ throw new Error(`Report page "${page.id}" declares input: "attempt" but not navigation: false — an attempt-input page has no content without a locator, so it must not appear in navigation. Add navigation: false.`);
173
+ }
174
+ return {
175
+ id: page.id,
176
+ title: page.title,
177
+ content: page.content,
178
+ input: "attempt",
179
+ navigation: false,
180
+ };
181
+ }
182
+ throw new Error(`Report page "${page.id}" input ${JSON.stringify(input)} is not valid — input is omitted, "scope", or "attempt".`);
183
+ }
184
+ /** 一份报告至多一张 attempt-input page,避免 show @<locator> 与 locator 链接出现多个目标。 */
185
+ function assertAtMostOneAttemptPage(pages) {
186
+ const attemptPages = pages.filter((p) => p.input === "attempt");
187
+ if (attemptPages.length > 1) {
188
+ throw new Error(`A report can declare at most one input: "attempt" page — got ${attemptPages.length} (${attemptPages
189
+ .map((p) => `"${p.id}"`)
190
+ .join(", ")}). Keep one and remove the others, or fold their content into a single attempt-input page.`);
191
+ }
192
+ }
155
193
  export function defineReport(input) {
156
194
  assertNotDefinition(input, "defineReport(...)");
157
195
  const def = isReportNodeInput(input)
@@ -186,7 +224,9 @@ export function defineReport(input) {
186
224
  }
187
225
  else if (hasContent) {
188
226
  assertNotDefinition(def.content, 'defineReport "content"');
189
- pages = [{ id: DEFAULT_PAGE_ID, title: DEFAULT_PAGE_TITLE, content: def.content }];
227
+ pages = [
228
+ { id: DEFAULT_PAGE_ID, title: DEFAULT_PAGE_TITLE, input: "scope", navigation: true, content: def.content },
229
+ ];
190
230
  }
191
231
  else {
192
232
  const raw = def.pages;
@@ -194,6 +234,7 @@ export function defineReport(input) {
194
234
  throw new Error(`defineReport "pages" must be a non-empty array of { id, title, content }. ${EXTENDS_NEXT_STEP}`);
195
235
  }
196
236
  const seen = new Set();
237
+ const normalized = [];
197
238
  for (const page of raw) {
198
239
  if (typeof page?.id !== "string" || !PAGE_ID_PATTERN.test(page.id)) {
199
240
  throw new Error(`Report page id ${JSON.stringify(page?.id)} is invalid: ids are lowercase letters, digits and hyphens (they become --page values and #/page/<id> routes). Rename it, e.g. "overview".`);
@@ -204,9 +245,11 @@ export function defineReport(input) {
204
245
  seen.add(page.id);
205
246
  assertLocalizedText(page.title, `Report page "${page.id}" title`);
206
247
  assertNotDefinition(page.content, `Report page "${page.id}" content`);
248
+ normalized.push(normalizePageInputAndNavigation(page));
207
249
  }
208
- pages = raw;
250
+ pages = normalized;
209
251
  }
252
+ assertAtMostOneAttemptPage(pages);
210
253
  if (def.title !== undefined)
211
254
  assertLocalizedText(def.title, "defineReport title");
212
255
  if (def.footer !== undefined)
@@ -279,92 +322,17 @@ export function resolveReportTitle(definition, scope) {
279
322
  const first = names[0];
280
323
  return names.every((name) => localizedTextEquals(name, first)) ? first : FALLBACK_REPORT_TITLE;
281
324
  }
282
- /** 规范化声明 → 组合组件可见的 ReportMeta(scripts / styles 是注入资产,不进)。 */
283
- export function buildReportMeta(definition, scope, pageId) {
325
+ /** 规范化声明 → 组合组件可见的 ReportMeta(scripts / styles 是注入资产,不进;不携带当前页)。 */
326
+ export function buildReportMeta(definition, scope) {
284
327
  return {
285
328
  title: resolveReportTitle(definition, scope),
286
329
  links: definition.links,
287
330
  ...(definition.footer !== undefined ? { footer: definition.footer } : {}),
288
- pages: definition.pages.map((page) => ({ id: page.id, title: page.title })),
289
- pageId,
290
- };
291
- }
292
- // ───────────────────────── 页选择与 text 宿主入口 ─────────────────────────
293
- /** `--page` 未命中:宿主据此按用法错误退出并列出可用页 id。 */
294
- export class ReportPageNotFoundError extends Error {
295
- pageId;
296
- available;
297
- constructor(pageId, available) {
298
- super(`page "${pageId}" not found. Available pages: ${available.join(", ")}`);
299
- this.pageId = pageId;
300
- this.available = available;
301
- }
302
- }
303
- export function pickReportPage(definition, pageId) {
304
- if (pageId === undefined)
305
- return definition.pages[0];
306
- const page = definition.pages.find((p) => p.id === pageId);
307
- if (!page) {
308
- throw new ReportPageNotFoundError(pageId, definition.pages.map((p) => p.id));
309
- }
310
- return page;
311
- }
312
- /**
313
- * text 宿主的装载语义:选页 → resolve(组合展开 + spec 取数,唯一的 await 边界)→ 树校验 →
314
- * 遍历渲染 text 面。不需要 react-dom。宿主不在报告树外另设警告通道——挑选警告的呈现件是
315
- * `ScopeWarnings` 组件,内建报告每页都放它,自定义报告放不放是作者义务
316
- * (docs/feature/reports/architecture.md「Scope 是计算入口」)。
317
- */
318
- export async function renderReportToText(definition, ctx, options) {
319
- const page = pickReportPage(definition, options?.pageId);
320
- const meta = buildReportMeta(definition, ctx.scope, page.id);
321
- const resolved = await resolveReportTree(page.content, {
322
- scope: ctx.scope,
323
- results: ctx.results,
324
- report: meta,
325
- memo: new ResolveMemo(),
326
- });
327
- validateReportTree(resolved);
328
- return renderNodeToText(resolved, createTextContext(options));
329
- }
330
- /** 页索引标题行(show 多页索引 / view 导航共用的解析结果):按 locale 解析的标题字符串。 */
331
- export function reportTitleText(definition, scope, locale) {
332
- return resolveLocalizedText(resolveReportTitle(definition, scope), locale);
333
- }
334
- function quoteArg(value) {
335
- return /^[A-Za-z0-9._/@-]+$/.test(value) ? value : `'${value.replaceAll("'", `'"'"'`)}'`;
336
- }
337
- /** 按上下文拼组索引的可复制命令:`niceeval show <patterns> --exp <id> [--results/--report/--page]`。 */
338
- function experimentCommandFor(ctx) {
339
- return (prefix) => {
340
- const parts = ["niceeval show", ...ctx.patterns.map(quoteArg), `--exp ${quoteArg(prefix)}`];
341
- if (ctx.results !== undefined)
342
- parts.push(`--results ${quoteArg(ctx.results)}`);
343
- if (ctx.report !== undefined)
344
- parts.push(`--report ${quoteArg(ctx.report)}`);
345
- if (ctx.page !== undefined)
346
- parts.push(`--page ${quoteArg(ctx.page)}`);
347
- return parts.join(" ");
331
+ pages: definition.pages.map((page) => ({
332
+ id: page.id,
333
+ title: page.title,
334
+ input: page.input ?? "scope",
335
+ navigation: page.navigation ?? true,
336
+ })),
348
337
  };
349
338
  }
350
- /**
351
- * 渲染一页报告树的 text 面(宿主逐页调用;页选择归宿主):
352
- * resolve(组合展开 + spec 取数)→ validate → render。宿主不在报告树外另设警告通道,
353
- * 挑选警告由页内的 `ScopeWarnings` 组件呈现(内建报告每页都放它)。
354
- */
355
- export async function renderReportTreeToText(tree, ctx, options) {
356
- const resolved = await resolveReportTree(tree, {
357
- scope: ctx.scope,
358
- results: ctx.results,
359
- report: ctx.report,
360
- memo: new ResolveMemo(),
361
- });
362
- validateReportTree(resolved);
363
- const textCtx = createTextContext({
364
- ...options,
365
- ...(options?.experimentCommand === undefined && options?.commandContext !== undefined
366
- ? { experimentCommand: experimentCommandFor(options.commandContext) }
367
- : {}),
368
- });
369
- return renderNodeToText(resolved, textCtx);
370
- }
@@ -1,5 +1,5 @@
1
- import type { TableProps } from "../primitives.tsx";
2
- import type { TextContext } from "../tree.ts";
1
+ import type { TableProps } from "./primitives.tsx";
2
+ import type { TextContext } from "./tree.ts";
3
3
  /**
4
4
  * <Table> 的 text 面:columns × rows → 对齐的字符表。
5
5
  * 有任一行带 locator 时追加一列 attempt(locator 本身就是 `niceeval show <locator>`
@@ -5,8 +5,8 @@
5
5
  //
6
6
  // 列宽按显示宽度算(CJK 记 2 列);null 渲染 —,不补 0;超宽先折最宽的左对齐列,
7
7
  // 压到下限仍放不下就从右侧丢列并如实报数(「截断报剩余」是既有契约,不在这里破例)。
8
- import { countText, localeText, resolveLocalizedText } from "../locale.js";
9
- import { charDisplayWidth, renderAlignedRows, stringWidth, wrapDisplay } from "./layout.js";
8
+ import { countText, localeText, resolveLocalizedText } from "../model/locale.js";
9
+ import { charDisplayWidth, renderAlignedRows, stringWidth, wrapDisplay } from "../model/text-layout.js";
10
10
  const MISSING_MARK = "—";
11
11
  /** 列间距,与 renderAlignedRows 的 join(" ") 一致。 */
12
12
  const COLUMN_GAP = 3;
@@ -1,9 +1,29 @@
1
1
  import type { ReactNode } from "react";
2
- import type { AttemptLocator } from "../results/locator.ts";
3
- import type { Results, Scope } from "../results/types.ts";
4
- import { type ReportLocale } from "./locale.ts";
5
- import type { ReportInput } from "./types.ts";
2
+ import type { AttemptLocator } from "../../results/locator.ts";
3
+ import type { AttemptEvidence } from "../../results/attempt-evidence.ts";
4
+ import type { Results, Scope } from "../../results/types.ts";
5
+ import { type ReportLocale } from "../model/locale.ts";
6
+ import type { ReportInput } from "../model/types.ts";
6
7
  import type { ReportMeta } from "./report.ts";
8
+ /** scope-input page 的当前页上下文:消费宿主选择的 Scope,没有 locator/evidence。 */
9
+ export interface ScopePageContext {
10
+ id: string;
11
+ input: "scope";
12
+ }
13
+ /** attempt-input page 的当前页上下文:按 locator 消费一份 AttemptEvidence。 */
14
+ export interface AttemptPageContext {
15
+ id: string;
16
+ input: "attempt";
17
+ locator: AttemptLocator;
18
+ evidence: AttemptEvidence;
19
+ }
20
+ /**
21
+ * 当前渲染中的页判别联合(docs/feature/reports/library/shell.md「行为约束」、
22
+ * library/attempt-detail.md「page 输入与 spec / data 形态」)。经 ComposeContext.page 与
23
+ * ResolveContext.page 双双可见:组合组件靠它读当前页 id 与输入分支;attempt 叶子组件靠它
24
+ * 取省略 input 时的缺省 evidence。
25
+ */
26
+ export type PageContext = ScopePageContext | AttemptPageContext;
7
27
  /** 标准 jsx-runtime 元素形状;text 宿主只认 type / props,不管 $$typeof。 */
8
28
  export interface ReportElement {
9
29
  type: unknown;
@@ -34,8 +54,12 @@ export interface TextContext {
34
54
  locale: ReportLocale;
35
55
  /** 容器组件渲染 children 用,宽度显式传递。 */
36
56
  render(node: ReportNode, width?: number): string;
37
- /** 下钻命令,通证据室:`niceeval show @<locator>`。 */
38
- attemptCommand(locator: AttemptLocator): string;
57
+ /**
58
+ * 下钻命令,通 attempt-input page:`niceeval show @<locator>`。当前报告没有声明
59
+ * attempt-input page 时不存在——宿主不生成假命令,locator 只是文本(architecture.md
60
+ * 「Attempt 详情是一张参数化 page」)。
61
+ */
62
+ attemptCommand?(locator: AttemptLocator): string;
39
63
  /**
40
64
  * 组索引一类「按实验收窄」命令的生成;宿主注入以携带完整上下文(--results / --report /
41
65
  * --page 与位置参数),默认 `niceeval show --exp <id>`。非契约字段,官方组件内部用。
@@ -43,14 +67,20 @@ export interface TextContext {
43
67
  experimentCommand(experimentIdPrefix: string): string;
44
68
  }
45
69
  export interface WebContext {
46
- /** 证据室深链,同 view 的 attempt 路由(`#/attempt/@<locator>`,单段、不透明)。 */
47
- attemptHref(locator: AttemptLocator): string;
70
+ /**
71
+ * attempt-input page 深链,同 view 的 attempt 路由(`#/attempt/@<locator>`,单段、不透明)
72
+ * 当前报告没有声明 attempt-input page 时不存在——宿主不生成空 href 或假链接,locator 只是
73
+ * 文本(architecture.md「Attempt 详情是一张参数化 page」)。
74
+ */
75
+ attemptHref?(locator: AttemptLocator): string;
48
76
  /** chrome 文案的 locale;官方组件渲染面经上下文读取,宿主外默认 "en"。 */
49
77
  locale: ReportLocale;
50
78
  }
51
79
  /** 双面组件解析面的上下文:宿主注入的数据来源;props 显式给出 input 时以 props 为准。 */
52
80
  export interface ResolveContext {
53
81
  input: ReportInput;
82
+ /** 当前页判别;attempt 叶子组件省略 input 时从这里的 attempt 分支取缺省 evidence。 */
83
+ page: PageContext;
54
84
  }
55
85
  /** 组合组件的上下文:宿主 Scope、结果根完整读取面与规范化后的报告声明。 */
56
86
  export interface ComposeContext {
@@ -60,6 +90,8 @@ export interface ComposeContext {
60
90
  results: Results;
61
91
  /** 规范化后的报告声明,只读(docs/feature/reports/library/layout.md「自定义组件」)。 */
62
92
  report: ReportMeta;
93
+ /** 当前页判别:scope 分支只有 id;attempt 分支带 locator + evidence。 */
94
+ page: PageContext;
63
95
  }
64
96
  export interface ComponentFaces<P, R = P> {
65
97
  /**
@@ -86,8 +118,6 @@ export type ReportComponent<P> = ((props: P) => ReactNode) & {
86
118
  };
87
119
  /** web 宿主用:在给定 WebContext 下同步渲染(React 静态渲染本身是同步的)。 */
88
120
  export declare function runWithWebContext<T>(ctx: WebContext, fn: () => T): T;
89
- /** 官方组件的装配用:宿主上下文激活时才把 ctx.attemptHref 当默认下钻。 */
90
- export declare function isHostWebContextActive(): boolean;
91
121
  /** 函数形态:组合组件,只装配已有组件,可以异步;ctx 携带 scope / results / report。 */
92
122
  export declare function defineComponent<P>(compose: (props: P, context: ComposeContext) => ReportNode | Promise<ReportNode>): ReportComponent<P>;
93
123
  /** 对象形态:双面组件,自己渲染;text 与 web 两面必填,可选 resolve 承担取数。 */
@@ -105,11 +135,13 @@ export declare class ResolveMemo {
105
135
  private readonly entries;
106
136
  fetch(fn: unknown, input: unknown, spec: unknown, compute: () => Promise<unknown>): Promise<unknown>;
107
137
  }
108
- /** resolveReportTree 的环境:宿主注入的 Scope / 读取面 / 规范化声明。 */
138
+ /** resolveReportTree 的环境:宿主注入的 Scope / 读取面 / 规范化声明 / 当前页判别。 */
109
139
  export interface ResolveEnv {
110
140
  scope: Scope;
111
141
  results: Results;
112
142
  report: ReportMeta;
143
+ /** 当前渲染的页:scope 分支只有 id;attempt 分支带 locator + evidence。 */
144
+ page: PageContext;
113
145
  /** 一次页渲染一份;跨页共享缓存时由宿主显式传同一实例。 */
114
146
  memo?: ResolveMemo;
115
147
  }
@@ -8,7 +8,7 @@
8
8
  // 同层并行保声明序,按「同引用 input + 深相等 spec」记忆化)→ validate(两面资格)→
9
9
  // render(纯同步)。渲染面是纯同步函数:零 IO、零 await —— 可达百 MB 的 artifact
10
10
  // 只在 resolve 阶段被懒加载,永远不进渲染路径。
11
- import { DEFAULT_REPORT_LOCALE } from "./locale.js";
11
+ import { DEFAULT_REPORT_LOCALE } from "../model/locale.js";
12
12
  // react/jsx-runtime 的 Fragment 是注册符号,跨 react 版本稳定;不 import react 也认得它
13
13
  const REACT_FRAGMENT = Symbol.for("react.fragment");
14
14
  function isReportElement(node) {
@@ -32,9 +32,9 @@ export const COMPONENT_ROLE = Symbol.for("niceeval.report.role");
32
32
  */
33
33
  export const COMPONENT_RAW_CHILDREN = Symbol.for("niceeval.report.rawChildren");
34
34
  // web 面的环境上下文:web 宿主渲染前设好;宿主之外(组件直接嵌进用户 React 应用)
35
- // 用默认值 —— attemptHref 默认 view 的 attempt 路由格式。
35
+ // 用默认值——没有 attemptHref,组件显式传 prop 才产生外部链接(architecture.md
36
+ // 「Attempt 详情是一张参数化 page」:没有 target 时 locator 只是文本,不生成假 href)。
36
37
  const DEFAULT_WEB_CONTEXT = {
37
- attemptHref: (locator) => `#/attempt/${locator}`,
38
38
  locale: DEFAULT_REPORT_LOCALE,
39
39
  };
40
40
  let activeWebContext = null;
@@ -49,10 +49,6 @@ export function runWithWebContext(ctx, fn) {
49
49
  activeWebContext = prev;
50
50
  }
51
51
  }
52
- /** 官方组件的装配用:宿主上下文激活时才把 ctx.attemptHref 当默认下钻。 */
53
- export function isHostWebContextActive() {
54
- return activeWebContext !== null;
55
- }
56
52
  export function defineComponent(input) {
57
53
  if (typeof input === "function") {
58
54
  const component = ((_props) => {
@@ -176,7 +172,7 @@ function bareTextError(value, path) {
176
172
  */
177
173
  export async function resolveReportTree(node, env) {
178
174
  const memo = env.memo ?? new ResolveMemo();
179
- const composeCtx = { scope: env.scope, results: env.results, report: env.report };
175
+ const composeCtx = { scope: env.scope, results: env.results, report: env.report, page: env.page };
180
176
  return resolveNode(node, { memo, composeCtx }, []);
181
177
  }
182
178
  async function resolveNode(node, state, path) {
@@ -214,6 +210,7 @@ async function resolveNode(node, state, path) {
214
210
  const input = props.input ?? state.composeCtx.scope;
215
211
  const ctx = {
216
212
  input,
213
+ page: state.composeCtx.page,
217
214
  memoFetch: (dataFn, dataInput, options, compute) => state.memo.fetch(dataFn, dataInput, options, compute),
218
215
  };
219
216
  const resolved = await state.memo.fetch(resolveFn, input, props, async () => resolveFn(props, ctx));
@@ -348,9 +345,10 @@ function shellQuote(value) {
348
345
  export function createTextContext(options) {
349
346
  const width = Math.max(20, options?.width ?? 80);
350
347
  const locale = options?.locale ?? DEFAULT_REPORT_LOCALE;
351
- // 默认下钻命令:AttemptLocator `@` 前缀的不透明短串,`niceeval show @<locator>` 是
352
- // show 已实现的真实 CLI 语法,不需要反查 eval id 再拼一条近似命令。
353
- const attemptCommand = options?.attemptCommand ?? ((locator) => `niceeval show ${locator}`);
348
+ // 没有默认值:当前报告没有声明 attempt-input page 时不存在下钻命令——宿主(report.ts /
349
+ // web.ts 的渲染入口)据规范化 definition 是否有 attempt page 决定要不要注入生成器,
350
+ // 这里只透传调用方给的值(architecture.md「Attempt 详情是一张参数化 page」)
351
+ const attemptCommand = options?.attemptCommand;
354
352
  const experimentCommand = options?.experimentCommand ?? ((prefix) => `niceeval show --exp ${shellQuote(prefix)}`);
355
353
  const make = (w) => ({
356
354
  width: w,
@@ -1,19 +1,34 @@
1
- export { assistantTurns, costUSD, defineMetric, durationMs, endToEndPassRate, examScore, executionReliability, repeatedFailedCommands, taskPassRate, tokens, } from "./metrics.ts";
2
- export { flag, numericFlag, numericRunConfig, runConfig } from "./flag.ts";
3
- export { buildReportMeta, defineReport, isReportDefinition, pickReportPage, renderReportToText, renderReportTreeToText, reportTitleText, resolveReportTitle, ReportPageNotFoundError, DEFAULT_PAGE_ID, } from "./report.ts";
4
- export type { HostCommandContext, NonEmptyArray, RenderReportTextOptions, RenderTreeTextOptions, ReportTreeHostContext, HeadTag, ReportAsset, ReportDef, ReportDefinition, ReportHostContext, ReportLink, ReportMeta, ReportPage, ReportShell, } from "./report.ts";
5
- export { defineComponent, createTextContext, renderNodeToText, resolveReportTree, validateReportTree, ResolveMemo } from "./tree.ts";
6
- export type { ComponentFaces, ComposeContext, ReportComponent, ReportElement, ReportNode, ResolveContext, ResolveEnv, TextContext, TextRenderOptions, WebContext, } from "./tree.ts";
7
- export { Col, Row, Section, Style, Tab, Table, Tabs, Text } from "./primitives.tsx";
8
- export type { ColProps, LayoutProps, RowProps, SectionProps, StyleProps, TabProps, TableColumn, TableProps, TableRow, TabsProps, TextProps, } from "./primitives.tsx";
9
- export { stringWidth, padDisplay as padEnd, padStartDisplay as padStart, wrapDisplay as wrapText, indentBlock as indent, textBar as bar, joinColumns as columns, } from "./text/layout.ts";
10
- export type { ColumnAlign } from "./text/layout.ts";
11
- export { DEFAULT_REPORT_LOCALE, localizedTextEquals, resolveLocalizedText, resolveMetricLabel } from "./locale.ts";
12
- export type { LocalizedText, ReportLocale } from "./locale.ts";
13
- export { AttemptList, CopyFixPrompt, DeltaTable, EvalList, ExperimentComparison, ExperimentList, FailureList, Hero, HeroCard, MetricBars, MetricLine, MetricMatrix, MetricScatter, MetricTable, PoweredBy, Scoreboard, ScopeSummary, ScopeWarnings, TraceWaterfall, } from "./components.tsx";
14
- export type { AttemptListProps, CopyFixPromptProps, DataProps, DeltaTableProps, EvalListProps, ExperimentComparisonProps, ExperimentListProps, FailureListProps, HeroCardProps, HeroProps, MetricBarsProps, MetricLineProps, MetricMatrixProps, MetricScatterProps, MetricTableProps, ScoreboardProps, ScopeSummaryProps, ScopeWarningsProps, TraceWaterfallProps, } from "./components.tsx";
15
- export { attemptListData, copyFixPromptData, deltaTableData, evalListData, experimentComparisonData, experimentListData, heroData, metricLineData, metricMatrixData, metricScatterData, metricTableData, pairsByFlag, scopeSummaryData, scopeWarningsData, scoreboardData, traceWaterfallData, } from "./compute.ts";
16
- export type { DeltaTableOptions, MetricLineOptions, MetricMatrixOptions, MetricScatterOptions, MetricTableOptions, ScoreboardOptions, } from "./compute.ts";
17
- export type { Aggregator, AttemptListItem, AttemptLocator, BuiltInDimension, CopyFixPromptData, CustomDimension, DeltaData, DeltaPair, DimensionInput, DimensionOptions, DimensionRef, EvalListItem, ExperimentComparisonData, ExperimentComparisonGroupData, ExperimentListEvalRow, ExperimentListItem, FlagPairs, HeroData, LineData, MatrixData, Metric, MetricAggregate, MetricCell, MetricColumn, NumericAxis, NumericAxisOptions, NumericRunConfigAxisOptions, ReportInput, RunConfigKey, ScatterData, ScopeSummaryData, ScopeWarning, ScoreboardData, TableData, TraceSpanSummary, TraceWaterfallRow, VerdictTally, } from "./types.ts";
1
+ export { assistantTurns, costUSD, defineMetric, durationMs, endToEndPassRate, examScore, executionReliability, repeatedFailedCommands, taskPassRate, tokens, } from "./model/metrics.ts";
2
+ export { flag, label, numericFlag, numericLabel, numericRunConfig, runConfig } from "./model/flag.ts";
3
+ export { buildReportMeta, defineReport, isReportDefinition, resolveReportTitle, DEFAULT_PAGE_ID, } from "./definition/report.ts";
4
+ export type { NonEmptyArray, HeadTag, ReportAsset, ReportDef, ReportDefinition, ReportLink, ReportMeta, ReportMetaPage, ReportPage, ReportPageBase, ReportShell, } from "./definition/report.ts";
5
+ export { pickReportPage, renderReportToText, renderReportTreeToText, reportTitleText, ReportPageNotFoundError, ReportPageNeedsLocatorError, } from "./runtime/text.ts";
6
+ export type { HostCommandContext, RenderReportTextOptions, RenderTreeTextOptions, ReportTreeHostContext, ReportHostContext, } from "./runtime/text.ts";
7
+ export { defineComponent, createTextContext, renderNodeToText, resolveReportTree, validateReportTree, ResolveMemo } from "./definition/tree.ts";
8
+ export type { AttemptEvidence, AttemptEvidenceCapabilities } from "../results/attempt-evidence.ts";
9
+ export type { AttemptPageContext, ComponentFaces, ComposeContext, PageContext, ReportComponent, ReportElement, ReportNode, ResolveContext, ResolveEnv, ScopePageContext, TextContext, TextRenderOptions, WebContext, } from "./definition/tree.ts";
10
+ export { Col, Grid, Row, Section, Stat, Style, Tab, Table, Tabs, Text } from "./definition/primitives.tsx";
11
+ export type { ColProps, GridProps, LayoutProps, RowProps, SectionProps, StatProps, StatTone, StyleProps, TabProps, TableColumn, TableProps, TableRow, TabsProps, TextProps, } from "./definition/primitives.tsx";
12
+ export { stringWidth, padDisplay as padEnd, padStartDisplay as padStart, wrapDisplay as wrapText, indentBlock as indent, textBar as bar, joinColumns as columns, } from "./model/text-layout.ts";
13
+ export type { ColumnAlign } from "./model/text-layout.ts";
14
+ export { DEFAULT_REPORT_LOCALE, localizedTextEquals, resolveLocalizedText, resolveMetricLabel } from "./model/locale.ts";
15
+ export type { LocalizedText, ReportLocale } from "./model/locale.ts";
16
+ export { ScopeSummary, ExperimentComparison } from "./components/summaries/index.tsx";
17
+ export type { ScopeSummaryProps, ExperimentComparisonProps } from "./components/summaries/index.tsx";
18
+ export { AttemptList, EvalList, ExperimentList, FailureList } from "./components/entity-lists/index.tsx";
19
+ export type { AttemptListProps, EvalListProps, ExperimentListProps, FailureListProps, } from "./components/entity-lists/index.tsx";
20
+ export { DeltaTable, MetricBars, MetricLine, MetricMatrix, MetricScatter, MetricTable, Scoreboard, } from "./components/metric-views/index.tsx";
21
+ export type { DeltaTableProps, MetricBarsProps, MetricLineProps, MetricMatrixProps, MetricScatterProps, MetricTableProps, ScoreboardProps, } from "./components/metric-views/index.tsx";
22
+ export { CopyFixPrompt, Hero, HeroCard, PoweredBy, ScopeWarnings, TraceWaterfall, } from "./components/site-components/index.tsx";
23
+ export type { CopyFixPromptProps, HeroCardProps, HeroProps, ScopeWarningsProps, TraceWaterfallProps, } from "./components/site-components/index.tsx";
24
+ export { AttemptAssertions, AttemptAssessment, AttemptConversation, AttemptDetail, AttemptDiagnostics, AttemptDiff, AttemptError, AttemptFixPrompt, AttemptSource, AttemptSummary, AttemptTimeline, AttemptTrace, AttemptUsage, } from "./components/attempt-detail/index.tsx";
25
+ export type { AttemptSectionProps } from "./components/attempt-detail/index.tsx";
26
+ export { scopeSummaryData } from "./components/summaries/compute.ts";
27
+ export { attemptListData, evalListData, experimentListData } from "./components/entity-lists/compute.ts";
28
+ export { deltaTableData, metricLineData, metricMatrixData, metricScatterData, metricTableData, pairsByFlag, scoreboardData, } from "./components/metric-views/compute.ts";
29
+ export type { DeltaTableOptions, MetricLineOptions, MetricMatrixOptions, MetricScatterOptions, MetricTableOptions, ScoreboardOptions, } from "./components/metric-views/compute.ts";
30
+ export { copyFixPromptData, heroData, scopeWarningsData, traceWaterfallData, } from "./components/site-components/compute.ts";
31
+ export { attemptAssertionsData, attemptConversationData, attemptDiagnosticsData, attemptDiffData, attemptErrorData, attemptFixPromptData, attemptSourceData, attemptSummaryData, attemptTimelineData, attemptTraceData, attemptUsageData, } from "./components/attempt-detail/compute.ts";
32
+ export type { Aggregator, AttemptListItem, AttemptLocator, BuiltInDimension, CopyFixPromptData, CustomDimension, DeltaData, DeltaPair, DimensionInput, DimensionOptions, DimensionRef, EvalListItem, ExperimentListEvalRow, ExperimentListItem, FlagPairs, HeroData, LineData, MatrixData, Metric, MetricAggregate, MetricCell, MetricColumn, NumericAxis, NumericAxisOptions, NumericRunConfigAxisOptions, ReportInput, RunConfigKey, ScatterData, ScopeSummaryData, ScopeWarning, ScoreboardData, SeriesInput, TableData, TraceSpanSummary, TraceWaterfallRow, VerdictTally, } from "./model/types.ts";
33
+ export type { AttemptAssertionsData, AttemptConversationData, AttemptConversationReply, AttemptConversationRound, AttemptDiagnosticsData, AttemptDiffData, AttemptDiffFileEntry, AttemptErrorData, AttemptFixPromptData, AttemptSourceData, AttemptSummaryData, AttemptTimelineData, AttemptTraceData, AttemptUsageData, } from "./model/types.ts";
18
34
  export type { AttemptHandle, Results, Scope, Snapshot } from "../results/types.ts";
19
- export { experimentGroupOf } from "../shared/aggregate.ts";