niceeval 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/INDEX.md +31 -33
  2. package/dist/agents/types.d.ts +20 -17
  3. package/dist/context/types.d.ts +21 -21
  4. package/dist/i18n/en.d.ts +10 -2
  5. package/dist/i18n/zh-CN.d.ts +15 -7
  6. package/dist/o11y/execution-tree.d.ts +103 -0
  7. package/dist/o11y/otlp/select.d.ts +22 -0
  8. package/dist/report/{react → assets}/colors.d.ts +8 -0
  9. package/dist/report/{react → assets}/colors.js +23 -0
  10. package/dist/report/built-in/index.d.ts +2 -2
  11. package/dist/report/built-in/index.js +2 -2
  12. package/dist/report/built-in/standard.d.ts +8 -1
  13. package/dist/report/built-in/standard.js +17 -7
  14. package/dist/report/components/attempt-detail/AttemptAssertions.d.ts +6 -0
  15. package/dist/report/components/attempt-detail/AttemptAssertions.js +17 -0
  16. package/dist/report/components/attempt-detail/AttemptConversation.d.ts +6 -0
  17. package/dist/report/components/attempt-detail/AttemptConversation.js +34 -0
  18. package/dist/report/components/attempt-detail/AttemptDiagnostics.d.ts +6 -0
  19. package/dist/report/components/attempt-detail/AttemptDiagnostics.js +7 -0
  20. package/dist/report/components/attempt-detail/AttemptDiff.d.ts +6 -0
  21. package/dist/report/components/attempt-detail/AttemptDiff.js +11 -0
  22. package/dist/report/components/attempt-detail/AttemptError.d.ts +6 -0
  23. package/dist/report/components/attempt-detail/AttemptError.js +16 -0
  24. package/dist/report/components/attempt-detail/AttemptFixPrompt.d.ts +6 -0
  25. package/dist/report/components/attempt-detail/AttemptFixPrompt.js +7 -0
  26. package/dist/report/components/attempt-detail/AttemptSource.d.ts +6 -0
  27. package/dist/report/components/attempt-detail/AttemptSource.js +27 -0
  28. package/dist/report/components/attempt-detail/AttemptSummary.d.ts +8 -0
  29. package/dist/report/components/attempt-detail/AttemptSummary.js +20 -0
  30. package/dist/report/components/attempt-detail/AttemptTimeline.d.ts +6 -0
  31. package/dist/report/components/attempt-detail/AttemptTimeline.js +28 -0
  32. package/dist/report/components/attempt-detail/AttemptTrace.d.ts +6 -0
  33. package/dist/report/components/attempt-detail/AttemptTrace.js +29 -0
  34. package/dist/report/components/attempt-detail/AttemptUsage.d.ts +6 -0
  35. package/dist/report/components/attempt-detail/AttemptUsage.js +20 -0
  36. package/dist/report/components/attempt-detail/compute.d.ts +24 -0
  37. package/dist/report/components/attempt-detail/compute.js +254 -0
  38. package/dist/report/components/attempt-detail/faces.d.ts +14 -0
  39. package/dist/report/components/attempt-detail/faces.js +235 -0
  40. package/dist/report/components/attempt-detail/index.d.ts +38 -0
  41. package/dist/report/components/attempt-detail/index.js +527 -0
  42. package/dist/report/{react → components}/cell.d.ts +5 -3
  43. package/dist/report/{react → components}/cell.js +3 -3
  44. package/dist/report/{react → components/entity-lists}/AttemptList.d.ts +8 -4
  45. package/dist/report/{react → components/entity-lists}/AttemptList.js +16 -10
  46. package/dist/report/{react → components/entity-lists}/EvalList.d.ts +3 -3
  47. package/dist/report/{react → components/entity-lists}/EvalList.js +0 -0
  48. package/dist/report/{react → components/entity-lists}/ExperimentList.d.ts +3 -3
  49. package/dist/report/{react → components/entity-lists}/ExperimentList.js +10 -10
  50. package/dist/report/components/entity-lists/compute.d.ts +23 -0
  51. package/dist/report/components/entity-lists/compute.js +171 -0
  52. package/dist/report/components/entity-lists/faces.d.ts +5 -0
  53. package/dist/report/components/entity-lists/faces.js +174 -0
  54. package/dist/report/components/entity-lists/index.d.ts +51 -0
  55. package/dist/report/components/entity-lists/index.js +165 -0
  56. package/dist/report/{react → components}/fixtures.d.ts +2 -2
  57. package/dist/report/{react → components}/fixtures.js +1 -1
  58. package/dist/report/{react → components/metric-views}/DeltaTable.d.ts +2 -2
  59. package/dist/report/{react → components/metric-views}/DeltaTable.js +4 -4
  60. package/dist/report/{react → components/metric-views}/MetricBars.d.ts +3 -3
  61. package/dist/report/{react → components/metric-views}/MetricBars.js +3 -3
  62. package/dist/report/{react → components/metric-views}/MetricLine.d.ts +2 -2
  63. package/dist/report/{react → components/metric-views}/MetricLine.js +8 -5
  64. package/dist/report/{react → components/metric-views}/MetricMatrix.d.ts +3 -3
  65. package/dist/report/{react → components/metric-views}/MetricMatrix.js +4 -4
  66. package/dist/report/components/metric-views/MetricScatter.d.ts +11 -0
  67. package/dist/report/{react → components/metric-views}/MetricScatter.js +26 -23
  68. package/dist/report/{react → components/metric-views}/MetricTable.d.ts +3 -3
  69. package/dist/report/{react → components/metric-views}/MetricTable.js +4 -4
  70. package/dist/report/{react → components/metric-views}/Scoreboard.d.ts +2 -2
  71. package/dist/report/{react → components/metric-views}/Scoreboard.js +3 -3
  72. package/dist/report/components/metric-views/compute.d.ts +89 -0
  73. package/dist/report/{compute.js → components/metric-views/compute.js} +32 -415
  74. package/dist/report/components/metric-views/faces.d.ts +13 -0
  75. package/dist/report/components/metric-views/faces.js +381 -0
  76. package/dist/report/components/metric-views/index.d.ts +50 -0
  77. package/dist/report/components/metric-views/index.js +273 -0
  78. package/dist/report/{text → components/metric-views}/plot.js +1 -1
  79. package/dist/report/components/shared-compute.d.ts +22 -0
  80. package/dist/report/components/shared-compute.js +47 -0
  81. package/dist/report/components/shared-faces.d.ts +9 -0
  82. package/dist/report/components/shared-faces.js +26 -0
  83. package/dist/report/components/shared.d.ts +68 -0
  84. package/dist/report/components/shared.js +125 -0
  85. package/dist/report/{react → components/site-components}/CopyFixPrompt.d.ts +2 -2
  86. package/dist/report/{react → components/site-components}/CopyFixPrompt.js +2 -2
  87. package/dist/report/{react → components/site-components}/HeroCard.d.ts +2 -2
  88. package/dist/report/{react → components/site-components}/HeroCard.js +2 -2
  89. package/dist/report/{react → components/site-components}/ScopeWarnings.d.ts +2 -2
  90. package/dist/report/{react → components/site-components}/ScopeWarnings.js +3 -3
  91. package/dist/report/{react → components/site-components}/TraceWaterfall.d.ts +3 -3
  92. package/dist/report/{react → components/site-components}/TraceWaterfall.js +5 -5
  93. package/dist/report/components/site-components/compute.d.ts +28 -0
  94. package/dist/report/components/site-components/compute.js +132 -0
  95. package/dist/report/components/site-components/faces.d.ts +21 -0
  96. package/dist/report/components/site-components/faces.js +75 -0
  97. package/dist/report/components/site-components/index.d.ts +74 -0
  98. package/dist/report/components/site-components/index.js +220 -0
  99. package/dist/report/{scope-warnings.d.ts → components/site-components/scope-warnings.d.ts} +2 -2
  100. package/dist/report/{scope-warnings.js → components/site-components/scope-warnings.js} +2 -2
  101. package/dist/report/{react → components/summaries}/ScopeSummary.d.ts +2 -2
  102. package/dist/report/{react → components/summaries}/ScopeSummary.js +17 -8
  103. package/dist/report/components/summaries/compute.d.ts +7 -0
  104. package/dist/report/components/summaries/compute.js +51 -0
  105. package/dist/report/components/summaries/faces.d.ts +7 -0
  106. package/dist/report/components/summaries/faces.js +38 -0
  107. package/dist/report/components/summaries/index.d.ts +27 -0
  108. package/dist/report/components/summaries/index.js +78 -0
  109. package/dist/report/definition/grid-layout.d.ts +50 -0
  110. package/dist/report/definition/grid-layout.js +89 -0
  111. package/dist/report/{primitives.d.ts → definition/primitives.d.ts} +34 -4
  112. package/dist/report/{primitives.js → definition/primitives.js} +101 -10
  113. package/dist/report/{report.d.ts → definition/report.d.ts} +36 -65
  114. package/dist/report/{report.js → definition/report.js} +58 -90
  115. package/dist/report/{text/table.d.ts → definition/table-text.d.ts} +2 -2
  116. package/dist/report/{text/table.js → definition/table-text.js} +2 -2
  117. package/dist/report/{tree.d.ts → definition/tree.d.ts} +44 -12
  118. package/dist/report/{tree.js → definition/tree.js} +10 -12
  119. package/dist/report/index.d.ts +33 -18
  120. package/dist/report/index.js +23 -14
  121. package/dist/report/{aggregate.d.ts → model/aggregate.d.ts} +12 -4
  122. package/dist/report/{aggregate.js → model/aggregate.js} +28 -8
  123. package/dist/report/{flag.d.ts → model/flag.d.ts} +14 -1
  124. package/dist/report/{flag.js → model/flag.js} +35 -0
  125. package/dist/report/{format.d.ts → model/format.d.ts} +11 -5
  126. package/dist/report/{format.js → model/format.js} +48 -4
  127. package/dist/report/{locale.d.ts → model/locale.d.ts} +17 -17
  128. package/dist/report/{locale.js → model/locale.js} +31 -33
  129. package/dist/report/{metrics.d.ts → model/metrics.d.ts} +2 -2
  130. package/dist/report/{metrics.js → model/metrics.js} +2 -2
  131. package/dist/report/{types.d.ts → model/types.d.ts} +140 -20
  132. package/dist/report/react/index.d.ts +32 -21
  133. package/dist/report/react/index.js +33 -21
  134. package/dist/report/{load.d.ts → runtime/load.d.ts} +1 -1
  135. package/dist/report/{load.js → runtime/load.js} +1 -1
  136. package/dist/report/runtime/text.d.ts +67 -0
  137. package/dist/report/runtime/text.js +114 -0
  138. package/dist/report/runtime/web.d.ts +35 -0
  139. package/dist/report/runtime/web.js +70 -0
  140. package/dist/results/annotated-source.d.ts +87 -0
  141. package/dist/results/attempt-evidence.d.ts +74 -0
  142. package/dist/results/attempt-source.d.ts +15 -0
  143. package/dist/results/select.d.ts +12 -2
  144. package/dist/results/select.js +27 -5
  145. package/dist/runner/eval-selection.d.ts +26 -0
  146. package/dist/runner/feedback/sink.d.ts +26 -1
  147. package/dist/runner/types.d.ts +149 -23
  148. package/dist/sandbox/docker.d.ts +6 -0
  149. package/dist/sandbox/types.d.ts +23 -21
  150. package/dist/scoring/display.d.ts +7 -2
  151. package/dist/scoring/display.js +42 -4
  152. package/dist/scoring/types.d.ts +3 -3
  153. package/dist/shared/aggregate.d.ts +15 -1
  154. package/dist/shared/aggregate.js +32 -1
  155. package/dist/shared/types.d.ts +6 -1
  156. package/docs-site/images/logo-dark.svg +7 -0
  157. package/docs-site/images/logo.svg +6 -5
  158. package/docs-site/zh/README.md +8 -7
  159. package/docs-site/zh/examples/ai-agent-application.mdx +5 -5
  160. package/docs-site/zh/examples/coding-agent-extensions.mdx +4 -4
  161. package/docs-site/zh/examples/index.mdx +3 -3
  162. package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +1 -1
  163. package/docs-site/zh/examples/integrations/claude-sdk.mdx +3 -3
  164. package/docs-site/zh/examples/integrations/codex-sdk.mdx +3 -3
  165. package/docs-site/zh/examples/integrations/langgraph.mdx +3 -3
  166. package/docs-site/zh/examples/integrations/pi-sdk.mdx +2 -2
  167. package/docs-site/zh/explanation/adapter.mdx +19 -19
  168. package/docs-site/zh/explanation/assert.mdx +9 -9
  169. package/docs-site/zh/explanation/drive.mdx +4 -4
  170. package/docs-site/zh/explanation/evals.mdx +8 -8
  171. package/docs-site/zh/explanation/experiment.mdx +8 -8
  172. package/docs-site/zh/explanation/hitl.mdx +13 -13
  173. package/docs-site/zh/explanation/judge.mdx +3 -3
  174. package/docs-site/zh/explanation/overview.mdx +7 -7
  175. package/docs-site/zh/explanation/runner.mdx +11 -11
  176. package/docs-site/zh/explanation/tier.mdx +6 -6
  177. package/docs-site/zh/index.mdx +14 -14
  178. package/docs-site/zh/introduction.mdx +13 -16
  179. package/docs-site/zh/reference/builtin-agents.mdx +61 -28
  180. package/docs-site/zh/reference/capabilities.mdx +7 -27
  181. package/docs-site/zh/reference/cli.mdx +35 -32
  182. package/docs-site/zh/reference/define-agent.mdx +32 -31
  183. package/docs-site/zh/reference/define-config.mdx +6 -6
  184. package/docs-site/zh/reference/define-eval.mdx +33 -20
  185. package/docs-site/zh/reference/events.mdx +4 -4
  186. package/docs-site/zh/reference/expect.mdx +3 -3
  187. package/docs-site/zh/reference/official-adapters.mdx +17 -17
  188. package/docs-site/zh/reference/report-components.mdx +193 -121
  189. package/docs-site/zh/reference/results-data.mdx +13 -13
  190. package/docs-site/zh/troubleshooting/debug-sandbox.mdx +11 -11
  191. package/docs-site/zh/troubleshooting/debugging.mdx +43 -19
  192. package/docs-site/zh/{how-to → tutorials}/agent-feedback-loop.mdx +38 -38
  193. package/docs-site/zh/tutorials/agent-onboarding.mdx +100 -0
  194. package/docs-site/zh/tutorials/authoring.mdx +211 -0
  195. package/docs-site/zh/{how-to → tutorials}/ci-integration.mdx +8 -8
  196. package/docs-site/zh/{how-to → tutorials}/connect-otel.mdx +22 -22
  197. package/docs-site/zh/{how-to → tutorials}/connect-your-agent.mdx +58 -63
  198. package/docs-site/zh/tutorials/custom-reports.mdx +453 -0
  199. package/docs-site/zh/{how-to → tutorials}/dataset-fanout.mdx +4 -4
  200. package/docs-site/zh/tutorials/experiments.mdx +103 -0
  201. package/docs-site/zh/{how-to → tutorials}/fixtures.mdx +9 -9
  202. package/docs-site/zh/{how-to → tutorials}/publish-report.mdx +11 -5
  203. package/docs-site/zh/tutorials/quickstart.mdx +18 -18
  204. package/docs-site/zh/{how-to → tutorials}/reporters.mdx +6 -6
  205. package/docs-site/zh/{how-to → tutorials}/sandbox-agent.mdx +6 -6
  206. package/docs-site/zh/{how-to → tutorials}/sandbox-providers.mdx +41 -19
  207. package/docs-site/zh/{how-to → tutorials}/scoring-guide.mdx +4 -4
  208. package/docs-site/zh/{how-to → tutorials}/viewing-results.mdx +59 -50
  209. package/docs-site/zh/tutorials/write-experiment.mdx +355 -0
  210. package/docs-site/zh/{how-to → tutorials}/write-send.mdx +40 -40
  211. package/package.json +8 -4
  212. package/src/agents/bub.ts +21 -8
  213. package/src/agents/claude-code.ts +23 -10
  214. package/src/agents/codex.test.ts +22 -7
  215. package/src/agents/codex.ts +22 -9
  216. package/src/agents/index.ts +2 -2
  217. package/src/agents/openai-compat.ts +1 -1
  218. package/src/agents/post-setup.ts +45 -22
  219. package/src/agents/streaming.ts +1 -1
  220. package/src/agents/types.ts +20 -17
  221. package/src/agents/ui-message-stream.test.ts +10 -0
  222. package/src/agents/ui-message-stream.ts +12 -1
  223. package/src/cli.ts +77 -64
  224. package/src/context/types.ts +21 -21
  225. package/src/define.ts +13 -0
  226. package/src/i18n/en.ts +30 -15
  227. package/src/i18n/zh-CN.ts +30 -15
  228. package/src/index.ts +2 -0
  229. package/src/report/{react → assets}/colors.ts +22 -0
  230. package/src/report/{react → assets}/enhance.js +1 -33
  231. package/src/report/{react → assets}/styles.css +136 -112
  232. package/src/report/built-in/index.tsx +2 -2
  233. package/src/report/built-in/standard.tsx +18 -6
  234. package/src/report/components/attempt-detail/AttemptAssertions.tsx +67 -0
  235. package/src/report/components/attempt-detail/AttemptConversation.tsx +110 -0
  236. package/src/report/components/attempt-detail/AttemptDiagnostics.tsx +38 -0
  237. package/src/report/components/attempt-detail/AttemptDiff.tsx +35 -0
  238. package/src/report/components/attempt-detail/AttemptError.tsx +31 -0
  239. package/src/report/components/attempt-detail/AttemptFixPrompt.tsx +26 -0
  240. package/src/report/components/attempt-detail/AttemptSource.tsx +80 -0
  241. package/src/report/components/attempt-detail/AttemptSummary.tsx +74 -0
  242. package/src/report/components/attempt-detail/AttemptTimeline.tsx +108 -0
  243. package/src/report/components/attempt-detail/AttemptTrace.tsx +63 -0
  244. package/src/report/components/attempt-detail/AttemptUsage.tsx +29 -0
  245. package/src/report/components/attempt-detail/attempt-components.test.tsx +680 -0
  246. package/src/report/components/attempt-detail/compute.ts +287 -0
  247. package/src/report/components/attempt-detail/faces.ts +257 -0
  248. package/src/report/components/attempt-detail/index.tsx +583 -0
  249. package/src/report/components/attempt-detail/validate.test.ts +235 -0
  250. package/src/report/{react → components}/cell.tsx +6 -3
  251. package/src/report/{report.test.ts → components/compute.test.ts} +316 -46
  252. package/src/report/{react → components/entity-lists}/AttemptList.tsx +24 -16
  253. package/src/report/{react → components/entity-lists}/EvalList.tsx +0 -0
  254. package/src/report/{react → components/entity-lists}/ExperimentList.tsx +23 -20
  255. package/src/report/components/entity-lists/compute.ts +196 -0
  256. package/src/report/components/entity-lists/faces.ts +207 -0
  257. package/src/report/components/entity-lists/index.tsx +241 -0
  258. package/src/report/components/entity-lists/validate.test.ts +114 -0
  259. package/src/report/{react → components}/fixtures.ts +2 -2
  260. package/src/report/{react → components/metric-views}/DeltaTable.tsx +5 -5
  261. package/src/report/{react → components/metric-views}/MetricBars.tsx +5 -5
  262. package/src/report/{react → components/metric-views}/MetricLine.tsx +9 -6
  263. package/src/report/{react → components/metric-views}/MetricMatrix.tsx +6 -6
  264. package/src/report/{react → components/metric-views}/MetricScatter.tsx +41 -33
  265. package/src/report/{react → components/metric-views}/MetricTable.tsx +6 -6
  266. package/src/report/{react → components/metric-views}/Scoreboard.tsx +4 -4
  267. package/src/report/{compute.ts → components/metric-views/compute.ts} +51 -477
  268. package/src/report/components/metric-views/faces.ts +423 -0
  269. package/src/report/components/metric-views/index.tsx +352 -0
  270. package/src/report/{text → components/metric-views}/plot.ts +1 -1
  271. package/src/report/components/metric-views/validate.test.ts +211 -0
  272. package/src/report/{react → components}/render.test.tsx +47 -17
  273. package/src/report/components/shared-compute.ts +59 -0
  274. package/src/report/components/shared-faces.ts +30 -0
  275. package/src/report/components/shared.ts +192 -0
  276. package/src/report/{react → components/site-components}/CopyFixPrompt.tsx +3 -3
  277. package/src/report/{react → components/site-components}/HeroCard.tsx +3 -3
  278. package/src/report/{react → components/site-components}/ScopeWarnings.tsx +4 -4
  279. package/src/report/{react → components/site-components}/TraceWaterfall.tsx +13 -10
  280. package/src/report/components/site-components/compute.ts +144 -0
  281. package/src/report/components/site-components/faces.ts +80 -0
  282. package/src/report/components/site-components/index.tsx +265 -0
  283. package/src/report/{scope-warnings.ts → components/site-components/scope-warnings.ts} +3 -3
  284. package/src/report/{site-components.test.tsx → components/site-components/site-components.test.tsx} +23 -21
  285. package/src/report/components/site-components/validate.test.ts +89 -0
  286. package/src/report/{react → components/summaries}/ScopeSummary.tsx +26 -11
  287. package/src/report/components/summaries/compute.ts +56 -0
  288. package/src/report/components/summaries/faces.ts +48 -0
  289. package/src/report/components/summaries/index.tsx +127 -0
  290. package/src/report/components/summaries/validate.test.ts +49 -0
  291. package/src/report/definition/grid-layout.test.ts +124 -0
  292. package/src/report/definition/grid-layout.ts +146 -0
  293. package/src/report/{primitives.tsx → definition/primitives.tsx} +168 -18
  294. package/src/report/{report.ts → definition/report.ts} +98 -165
  295. package/src/report/{shell-head.test.ts → definition/shell-head.test.ts} +2 -2
  296. package/src/report/{text/table.ts → definition/table-text.ts} +4 -4
  297. package/src/report/{tree.ts → definition/tree.ts} +58 -22
  298. package/src/report/index.ts +126 -66
  299. package/src/report/{aggregate.ts → model/aggregate.ts} +31 -9
  300. package/src/report/{flag.ts → model/flag.ts} +39 -1
  301. package/src/report/{format.ts → model/format.ts} +59 -5
  302. package/src/report/{locale.ts → model/locale.ts} +34 -36
  303. package/src/report/{metrics.ts → model/metrics.ts} +3 -3
  304. package/src/report/{types.ts → model/types.ts} +143 -22
  305. package/src/report/react/index.tsx +52 -26
  306. package/src/report/{dual-render.test.tsx → runtime/dual-render.test.tsx} +564 -49
  307. package/src/report/runtime/host.test.ts +44 -0
  308. package/src/report/runtime/host.ts +138 -0
  309. package/src/report/{load.ts → runtime/load.ts} +1 -1
  310. package/src/report/runtime/text.ts +192 -0
  311. package/src/report/runtime/web.ts +106 -0
  312. package/src/results/attempt-evidence.ts +5 -1
  313. package/src/results/host-equivalence.test.ts +54 -3
  314. package/src/results/select.ts +30 -6
  315. package/src/runner/attempt.test.ts +48 -1
  316. package/src/runner/attempt.ts +62 -42
  317. package/src/runner/cleanup-timeout.test.ts +16 -0
  318. package/src/runner/cleanup-timeout.ts +23 -0
  319. package/src/runner/discover.ts +1 -2
  320. package/src/runner/eval-selection.test.ts +187 -0
  321. package/src/runner/eval-selection.ts +109 -0
  322. package/src/runner/experiment-cleanup-registry.test.ts +89 -0
  323. package/src/runner/experiment-cleanup-registry.ts +39 -0
  324. package/src/runner/experiment-labels.test.ts +71 -0
  325. package/src/runner/feedback/agent.test.ts +33 -1
  326. package/src/runner/feedback/agent.ts +12 -16
  327. package/src/runner/feedback/ci.test.ts +35 -1
  328. package/src/runner/feedback/ci.ts +16 -18
  329. package/src/runner/feedback/coordinator.ts +28 -0
  330. package/src/runner/feedback/human.test.ts +108 -1
  331. package/src/runner/feedback/human.ts +71 -21
  332. package/src/runner/feedback/reducer.test.ts +64 -0
  333. package/src/runner/feedback/reducer.ts +26 -0
  334. package/src/runner/feedback/sink.ts +40 -1
  335. package/src/runner/fingerprint.ts +2 -1
  336. package/src/runner/report.test.ts +14 -0
  337. package/src/runner/report.ts +3 -1
  338. package/src/runner/run.test.ts +390 -12
  339. package/src/runner/run.ts +259 -26
  340. package/src/runner/sandbox-selection.test.ts +13 -3
  341. package/src/runner/sandbox-selection.ts +4 -2
  342. package/src/runner/types.ts +158 -23
  343. package/src/sandbox/docker.ts +7 -0
  344. package/src/sandbox/e2b.ts +12 -13
  345. package/src/sandbox/types.ts +23 -21
  346. package/src/scoring/display.test.ts +28 -2
  347. package/src/scoring/display.ts +38 -5
  348. package/src/scoring/types.ts +3 -3
  349. package/src/shared/aggregate.test.ts +52 -0
  350. package/src/shared/aggregate.ts +30 -1
  351. package/src/shared/types.ts +6 -1
  352. package/src/show/command.test.ts +34 -0
  353. package/src/show/command.ts +16 -0
  354. package/src/show/compose.ts +1 -1
  355. package/src/show/index.ts +58 -22
  356. package/src/show/render.ts +16 -240
  357. package/src/show/show.test.ts +128 -35
  358. package/src/view/app/App.test.tsx +8 -7
  359. package/src/view/app/App.tsx +135 -51
  360. package/src/view/app/i18n.ts +7 -147
  361. package/src/view/app/lib/attempt-dialog.test.ts +65 -0
  362. package/src/view/app/lib/attempt-dialog.ts +69 -0
  363. package/src/view/app/main.tsx +0 -1
  364. package/src/view/app/types.ts +3 -86
  365. package/src/view/artifact-serving.test.ts +22 -38
  366. package/src/view/client-dist/app.css +1 -1
  367. package/src/view/client-dist/app.js +15 -22
  368. package/src/view/data.test.ts +48 -36
  369. package/src/view/data.ts +122 -89
  370. package/src/view/index.ts +3 -13
  371. package/src/view/server.ts +36 -6
  372. package/src/view/shared/types.ts +6 -31
  373. package/src/view/site-parity.test.ts +24 -1
  374. package/src/view/site.ts +144 -17
  375. package/src/view/styles.css +18 -806
  376. package/src/view/view-report.test.ts +182 -34
  377. package/dist/report/components.d.ts +0 -179
  378. package/dist/report/components.js +0 -544
  379. package/dist/report/compute.d.ts +0 -139
  380. package/dist/report/react/ExperimentComparison.d.ts +0 -10
  381. package/dist/report/react/ExperimentComparison.js +0 -12
  382. package/dist/report/react/MetricScatter.d.ts +0 -9
  383. package/dist/report/react/format.d.ts +0 -3
  384. package/dist/report/react/format.js +0 -7
  385. package/dist/report/text/faces.d.ts +0 -45
  386. package/dist/report/text/faces.js +0 -671
  387. package/dist/report/web.d.ts +0 -32
  388. package/dist/report/web.js +0 -48
  389. package/docs-site/zh/how-to/authoring.mdx +0 -162
  390. package/docs-site/zh/how-to/custom-reports.mdx +0 -414
  391. package/docs-site/zh/how-to/experiments.mdx +0 -86
  392. package/docs-site/zh/how-to/write-experiment.mdx +0 -164
  393. package/src/report/components.tsx +0 -925
  394. package/src/report/react/ExperimentComparison.tsx +0 -73
  395. package/src/report/react/format.ts +0 -9
  396. package/src/report/text/faces.ts +0 -767
  397. package/src/report/web.ts +0 -77
  398. package/src/show/report-host.test.ts +0 -205
  399. package/src/show/report-host.ts +0 -389
  400. package/src/view/app/components/AttemptModal.tsx +0 -496
  401. package/src/view/app/components/CodeView.test.tsx +0 -142
  402. package/src/view/app/components/CodeView.tsx +0 -310
  403. package/src/view/app/components/CopyControls.tsx +0 -106
  404. package/src/view/app/components/Trace.tsx +0 -100
  405. package/src/view/app/components/Transcript.tsx +0 -157
  406. package/src/view/app/components/ui/badge.tsx +0 -21
  407. package/src/view/app/lib/artifact-url.ts +0 -17
  408. package/src/view/app/lib/attempt-route.test.ts +0 -80
  409. package/src/view/app/lib/attempt-route.ts +0 -52
  410. package/src/view/app/lib/format.ts +0 -70
  411. package/src/view/app/lib/guards.test.ts +0 -108
  412. package/src/view/app/lib/guards.ts +0 -71
  413. package/src/view/app/lib/rows.ts +0 -22
  414. package/src/view/app/lib/transcript-data.tsx +0 -151
  415. package/src/view/app/lib/verdict.ts +0 -23
  416. package/src/view/app/shared.ts +0 -8
  417. /package/dist/report/{react → components/metric-views}/chart-math.d.ts +0 -0
  418. /package/dist/report/{react → components/metric-views}/chart-math.js +0 -0
  419. /package/dist/report/{text → components/metric-views}/plot.d.ts +0 -0
  420. /package/dist/report/{react → components/site-components}/PoweredBy.d.ts +0 -0
  421. /package/dist/report/{react → components/site-components}/PoweredBy.js +0 -0
  422. /package/dist/report/{text/layout.d.ts → model/text-layout.d.ts} +0 -0
  423. /package/dist/report/{text/layout.js → model/text-layout.js} +0 -0
  424. /package/dist/report/{types.js → model/types.js} +0 -0
  425. /package/src/report/{react → components/metric-views}/chart-math.test.ts +0 -0
  426. /package/src/report/{react → components/metric-views}/chart-math.ts +0 -0
  427. /package/src/report/{react → components/site-components}/PoweredBy.tsx +0 -0
  428. /package/src/report/{text/layout.ts → model/text-layout.ts} +0 -0
@@ -0,0 +1,165 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // 官方双面组件的装配点:web 面(./ExperimentList.tsx / EvalList.tsx / AttemptList.tsx 的纯
3
+ // React 组件)+ text 面(./faces.ts)+ resolve 解析面(spec 形态由管线代调配套 ./compute.ts)。
4
+ // FailureList 是组合组件,内部就是 attemptListData → 过滤 → AttemptList data 形态,不产生
5
+ // 自己的 data。
6
+ import { defineComponent } from "../../definition/tree.js";
7
+ import { collectItems, locatorOf, resolveInput } from "../../model/aggregate.js";
8
+ import { arrayProblem, cellProblem, isObject, makeDataComponent, hrefOf, tallyProblem, } from "../shared.js";
9
+ import { attemptListData, evalListData, experimentListData } from "./compute.js";
10
+ import { attemptListText, evalListText, experimentListText } from "./faces.js";
11
+ import { AttemptList as AttemptListWeb } from "./AttemptList.js";
12
+ import { EvalList as EvalListWeb } from "./EvalList.js";
13
+ import { ExperimentList as ExperimentListWeb } from "./ExperimentList.js";
14
+ /** AttemptListItem(src/report/model/types.ts):三个组件族共用的叶子形状(独立 data 或嵌套在 evalRows/attempts 里)。 */
15
+ function attemptListItemProblem(value, path) {
16
+ if (!isObject(value))
17
+ return `"${path}" must be an object`;
18
+ if (typeof value.experimentId !== "string")
19
+ return `"${path}.experimentId" must be a string`;
20
+ if (typeof value.evalId !== "string")
21
+ return `"${path}.evalId" must be a string`;
22
+ if (typeof value.attempt !== "number")
23
+ return `"${path}.attempt" must be a number`;
24
+ if (typeof value.agent !== "string")
25
+ return `"${path}.agent" must be a string`;
26
+ if (typeof value.verdict !== "string")
27
+ return `"${path}.verdict" must be a string`;
28
+ if (!(value.failureSummary === null || typeof value.failureSummary === "string")) {
29
+ return `"${path}.failureSummary" must be a string or null`;
30
+ }
31
+ if (typeof value.moreFailures !== "number")
32
+ return `"${path}.moreFailures" must be a number`;
33
+ const examScoreProblem = cellProblem(value.examScore, `${path}.examScore`);
34
+ if (examScoreProblem !== null)
35
+ return examScoreProblem;
36
+ if (typeof value.durationMs !== "number")
37
+ return `"${path}.durationMs" must be a number`;
38
+ if (!(value.costUSD === null || typeof value.costUSD === "number"))
39
+ return `"${path}.costUSD" must be a number or null`;
40
+ if (typeof value.locator !== "string")
41
+ return `"${path}.locator" must be a string`;
42
+ return null;
43
+ }
44
+ export const validateExperimentListData = (data) => arrayProblem(data, "data", (item, path) => {
45
+ if (!isObject(item))
46
+ return `"${path}" must be an object`;
47
+ if (typeof item.experimentId !== "string")
48
+ return `"${path}.experimentId" must be a string`;
49
+ if (typeof item.agent !== "string")
50
+ return `"${path}.agent" must be a string`;
51
+ const verdictsProblem = tallyProblem(item.evalVerdicts, `${path}.evalVerdicts`);
52
+ if (verdictsProblem !== null)
53
+ return verdictsProblem;
54
+ const passRateProblem = cellProblem(item.endToEndPassRate, `${path}.endToEndPassRate`);
55
+ if (passRateProblem !== null)
56
+ return passRateProblem;
57
+ const costProblem = cellProblem(item.costUSD, `${path}.costUSD`);
58
+ if (costProblem !== null)
59
+ return costProblem;
60
+ const durationProblem = cellProblem(item.durationMs, `${path}.durationMs`);
61
+ if (durationProblem !== null)
62
+ return durationProblem;
63
+ const tokensProblem = cellProblem(item.tokens, `${path}.tokens`);
64
+ if (tokensProblem !== null)
65
+ return tokensProblem;
66
+ if (typeof item.evals !== "number")
67
+ return `"${path}.evals" must be a number`;
68
+ if (typeof item.attempts !== "number")
69
+ return `"${path}.attempts" must be a number`;
70
+ if (typeof item.lastRunAt !== "string")
71
+ return `"${path}.lastRunAt" must be a string`;
72
+ return arrayProblem(item.evalRows, `${path}.evalRows`, (row, rowPath) => {
73
+ if (!isObject(row) || typeof row.evalId !== "string") {
74
+ return `"${rowPath}" must be an object with a string "evalId"`;
75
+ }
76
+ const rowDurationProblem = cellProblem(row.durationMs, `${rowPath}.durationMs`);
77
+ if (rowDurationProblem !== null)
78
+ return rowDurationProblem;
79
+ const rowCostProblem = cellProblem(row.costUSD, `${rowPath}.costUSD`);
80
+ if (rowCostProblem !== null)
81
+ return rowCostProblem;
82
+ return arrayProblem(row.attempts, `${rowPath}.attempts`, attemptListItemProblem);
83
+ });
84
+ });
85
+ export const validateEvalListData = (data) => arrayProblem(data, "data", (item, path) => {
86
+ if (!isObject(item))
87
+ return `"${path}" must be an object`;
88
+ if (typeof item.experimentId !== "string")
89
+ return `"${path}.experimentId" must be a string`;
90
+ if (typeof item.evalId !== "string")
91
+ return `"${path}.evalId" must be a string`;
92
+ if (typeof item.verdict !== "string")
93
+ return `"${path}.verdict" must be a string`;
94
+ const examScoreProblem = cellProblem(item.examScore, `${path}.examScore`);
95
+ if (examScoreProblem !== null)
96
+ return examScoreProblem;
97
+ const durationProblem = cellProblem(item.durationMs, `${path}.durationMs`);
98
+ if (durationProblem !== null)
99
+ return durationProblem;
100
+ const costProblem = cellProblem(item.costUSD, `${path}.costUSD`);
101
+ if (costProblem !== null)
102
+ return costProblem;
103
+ return arrayProblem(item.attempts, `${path}.attempts`, attemptListItemProblem);
104
+ });
105
+ export const validateAttemptListData = (data) => arrayProblem(data, "data", attemptListItemProblem);
106
+ /** 实验列表:每项一个 experiment,固定八列比较表 + 展开到 Eval / Attempt。 */
107
+ export const ExperimentList = makeDataComponent({
108
+ name: "ExperimentList",
109
+ dataFnName: "experimentListData",
110
+ shapeName: "ExperimentListItem[]",
111
+ dataFn: (input) => experimentListData(input),
112
+ specKeys: [],
113
+ validate: validateExperimentListData,
114
+ web: (props, ctx) => (_jsx(ExperimentListWeb, { data: props.data, filter: props.filter, relativeTo: props.relativeTo, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx), className: props.className })),
115
+ text: (props, ctx) => experimentListText(props.data, ctx, props.relativeTo),
116
+ });
117
+ /** Eval 列表:每项一个 experimentId + evalId,展开到这道题的 Attempt。 */
118
+ export const EvalList = makeDataComponent({
119
+ name: "EvalList",
120
+ dataFnName: "evalListData",
121
+ shapeName: "EvalListItem[]",
122
+ dataFn: (input) => evalListData(input),
123
+ specKeys: [],
124
+ validate: validateEvalListData,
125
+ web: (props, ctx) => (_jsx(EvalListWeb, { data: props.data, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx), className: props.className })),
126
+ text: (props, ctx) => evalListText(props.data, ctx),
127
+ });
128
+ /** Attempt 列表:实体列表的叶子层,每项一次 attempt 的判定、单行摘要与 locator。 */
129
+ export const AttemptList = makeDataComponent({
130
+ name: "AttemptList",
131
+ dataFnName: "attemptListData",
132
+ shapeName: "AttemptListItem[]",
133
+ dataFn: (input) => attemptListData(input),
134
+ specKeys: [],
135
+ validate: validateAttemptListData,
136
+ web: (props, ctx) => (_jsx(AttemptListWeb, { data: props.data, total: props.total, filter: props.filter, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx), className: props.className })),
137
+ text: (props, ctx) => attemptListText(props.data, props.total, ctx),
138
+ });
139
+ /**
140
+ * 「现在有哪些失败要处理」的成品组合件:内部就是 attemptListData → 过滤 → AttemptList
141
+ * data 形态,与手写组合严格等价、没有私有能力(docs/feature/reports/library/entity-lists.md)。
142
+ * verdict ∈ failed / errored,按 attempt 开始时间降序(同刻按 locator 字典序),
143
+ * 截断到 limit(默认 20),total 报告截断前总数。
144
+ */
145
+ export const FailureList = defineComponent(async (props, ctx) => {
146
+ const input = props.input ?? ctx.scope;
147
+ const all = await attemptListData(input);
148
+ // attempt 开始时间不在列表条目里(它不是列表展示字段);从同一 input 的读取面按 locator 对回。
149
+ const startedAtByLocator = new Map();
150
+ for (const item of collectItems(resolveInput(input).snapshots)) {
151
+ startedAtByLocator.set(locatorOf(item), item.attempt.result.startedAt ?? "");
152
+ }
153
+ const failures = all
154
+ .filter((item) => item.verdict === "failed" || item.verdict === "errored")
155
+ .sort((a, b) => {
156
+ const ta = startedAtByLocator.get(a.locator) ?? "";
157
+ const tb = startedAtByLocator.get(b.locator) ?? "";
158
+ if (ta !== tb)
159
+ return ta < tb ? 1 : -1; // 最近的失败在前
160
+ return a.locator < b.locator ? -1 : a.locator > b.locator ? 1 : 0;
161
+ });
162
+ const limit = props.limit ?? 20;
163
+ return (_jsx(AttemptList, { data: failures.slice(0, limit), total: failures.length, attemptHref: props.attemptHref, locale: props.locale, className: props.className }));
164
+ });
165
+ FailureList.displayName = "FailureList";
@@ -1,8 +1,8 @@
1
- import type { AttemptListItem, DeltaData, EvalListItem, ExperimentListItem, LineData, MatrixData, MetricColumn, ScatterData, ScopeSummaryData, ScoreboardData, TableData } from "../types.ts";
1
+ import type { AttemptListItem, DeltaData, EvalListItem, ExperimentListItem, LineData, MatrixData, MetricColumn, ScatterData, ScopeSummaryData, ScoreboardData, TableData } from "../model/types.ts";
2
2
  export declare const passRateColumn: MetricColumn;
3
3
  export declare const codeLinesColumn: MetricColumn;
4
4
  export declare const costColumn: MetricColumn;
5
- /** scopeSummaryData 的产物形态:两级计票恒随行,成功率与总成本是官方 MetricCell。 */
5
+ /** scopeSummaryData 的产物形态:两级计票恒随行,通过率与总成本是官方 MetricCell。 */
6
6
  export declare const scopeSummaryData: ScopeSummaryData;
7
7
  export declare const tableData: TableData;
8
8
  export declare const matrixData: MatrixData;
@@ -6,7 +6,7 @@ const locator = (s) => s;
6
6
  export const passRateColumn = { key: "task-pass-rate", label: "pass rate", unit: "%", better: "higher" };
7
7
  export const codeLinesColumn = { key: "code-lines", label: "code lines", unit: "lines", better: "lower" };
8
8
  export const costColumn = { key: "cost", label: "cost", unit: "$", better: "lower" };
9
- /** scopeSummaryData 的产物形态:两级计票恒随行,成功率与总成本是官方 MetricCell。 */
9
+ /** scopeSummaryData 的产物形态:两级计票恒随行,通过率与总成本是官方 MetricCell。 */
10
10
  export const scopeSummaryData = {
11
11
  range: { earliestStartedAt: "2026-07-01T10:00:00Z", latestStartedAt: "2026-07-01T11:30:00Z" },
12
12
  experiments: 2,
@@ -1,6 +1,6 @@
1
1
  import type { ReactElement } from "react";
2
- import type { DeltaData } from "../types.ts";
3
- import { type ReportLocale } from "../locale.ts";
2
+ import type { DeltaData } from "../../model/types.ts";
3
+ import { type ReportLocale } from "../../model/locale.ts";
4
4
  export declare function DeltaTable({ data, className, locale, }: {
5
5
  data: DeltaData;
6
6
  className?: string;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DEFAULT_REPORT_LOCALE, localeText, resolveLocalizedText, resolveMetricLabel } from "../locale.js";
3
- import { MetricCellView } from "./cell.js";
4
- import { colorClassForKey } from "./colors.js";
5
- import { cx } from "./format.js";
2
+ import { DEFAULT_REPORT_LOCALE, localeText, resolveLocalizedText, resolveMetricLabel } from "../../model/locale.js";
3
+ import { MetricCellView } from "../cell.js";
4
+ import { colorClassForKey } from "../../assets/colors.js";
5
+ import { cx } from "../shared.js";
6
6
  const OUTCOME_CLASS = {
7
7
  improved: "nre-delta-good",
8
8
  regressed: "nre-delta-bad",
@@ -1,7 +1,7 @@
1
1
  import type { ReactElement } from "react";
2
- import type { MatrixData } from "../types.ts";
3
- import type { AttemptLocator } from "../../results/locator.ts";
4
- import { type ReportLocale } from "../locale.ts";
2
+ import type { MatrixData } from "../../model/types.ts";
3
+ import type { AttemptLocator } from "../../../results/locator.ts";
4
+ import { type ReportLocale } from "../../model/locale.ts";
5
5
  export declare function MetricBars({ data, attemptHref, className, locale, }: {
6
6
  data: MatrixData;
7
7
  attemptHref?: (locator: AttemptLocator) => string;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DEFAULT_REPORT_LOCALE, resolveLocalizedText, resolveMetricLabel } from "../locale.js";
3
- import { colorClassForKey, seriesClassForKey } from "./colors.js";
4
- import { cx } from "./format.js";
2
+ import { DEFAULT_REPORT_LOCALE, resolveLocalizedText, resolveMetricLabel } from "../../model/locale.js";
3
+ import { colorClassForKey, seriesClassForKey } from "../../assets/colors.js";
4
+ import { cx } from "../shared.js";
5
5
  const WIDTH = 640;
6
6
  const HEIGHT = 320;
7
7
  const PLOT = { left: 16, right: WIDTH - 16, top: 28, bottom: HEIGHT - 40 };
@@ -1,6 +1,6 @@
1
1
  import type { ReactElement } from "react";
2
- import type { LineData } from "../types.ts";
3
- import { type ReportLocale } from "../locale.ts";
2
+ import type { LineData } from "../../model/types.ts";
3
+ import { type ReportLocale } from "../../model/locale.ts";
4
4
  export declare function MetricLine({ data, pointHref, className, locale, }: {
5
5
  data: LineData;
6
6
  pointHref?: (row: LineData["rows"][number]) => string;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DEFAULT_REPORT_LOCALE, countText, localeText, resolveLocalizedText, resolveMetricLabel } from "../locale.js";
3
- import { seriesClassForKey } from "./colors.js";
4
- import { cx } from "./format.js";
2
+ import { DEFAULT_REPORT_LOCALE, countText, localeText, resolveLocalizedText, resolveMetricLabel } from "../../model/locale.js";
3
+ import { colorIndicesForKeys } from "../../assets/colors.js";
4
+ import { cx } from "../shared.js";
5
5
  const WIDTH = 640;
6
6
  const HEIGHT = 360;
7
7
  const PLOT = { left: 64, right: WIDTH - 140, top: 24, bottom: HEIGHT - 56 };
@@ -52,6 +52,9 @@ export function MetricLine({ data, pointHref, className, locale = DEFAULT_REPORT
52
52
  }
53
53
  for (const list of bySeries.values())
54
54
  list.sort((a, b) => a.xValue - b.xValue);
55
+ // 同图撞色消解:散列格作起点,按图例顺序线性探测空格(colors.ts 的契约注释)
56
+ const colorIdx = colorIndicesForKeys(seriesOrder.filter((s) => s !== ""));
57
+ const seriesClassOf = (series) => (series === "" ? "nre-series-none" : `nre-series-c${colorIdx.get(series) ?? 0}`);
55
58
  const xTicks = xScale.lo === xScale.hi ? [xScale.lo] : [xScale.lo, xScale.hi];
56
59
  const yTicks = yScale.lo === yScale.hi ? [yScale.lo] : [yScale.lo, yScale.hi];
57
60
  const xDisplayFor = (value) => {
@@ -64,11 +67,11 @@ export function MetricLine({ data, pointHref, className, locale = DEFAULT_REPORT
64
67
  };
65
68
  return (_jsxs("figure", { className: cx("nre", "nre-metric-line", className), children: [_jsxs("svg", { className: "nre-line-svg", viewBox: `0 0 ${WIDTH} ${HEIGHT}`, role: "img", "aria-label": `${yLabel} by ${xLabel}`, children: [_jsx("rect", { className: "nre-line-plot", x: PLOT.left, y: PLOT.top, width: PLOT.right - PLOT.left, height: PLOT.bottom - PLOT.top, fill: "none" }), _jsxs("text", { className: "nre-line-xlabel", x: (PLOT.left + PLOT.right) / 2, y: HEIGHT - 8, textAnchor: "middle", children: [xLabel, data.x.unit ? `(${data.x.unit})` : ""] }), _jsxs("text", { className: "nre-line-ylabel", x: 16, y: (PLOT.top + PLOT.bottom) / 2, textAnchor: "middle", transform: `rotate(-90 16 ${(PLOT.top + PLOT.bottom) / 2})`, children: [yLabel, data.y.unit ? `(${data.y.unit})` : ""] }), xTicks.map((v) => (_jsx("text", { className: "nre-line-tick", x: xScale.scale(v), y: PLOT.bottom + 16, textAnchor: "middle", children: xDisplayFor(v) }, `x${v}`))), yTicks.map((v) => (_jsx("text", { className: "nre-line-tick", x: PLOT.left - 6, y: yScale.scale(v) + 4, textAnchor: "end", children: yDisplayFor(v) }, `y${v}`))), seriesOrder.map((series) => {
66
69
  const list = bySeries.get(series);
67
- const seriesClass = series === "" ? "nre-series-none" : seriesClassForKey(series);
70
+ const seriesClass = seriesClassOf(series);
68
71
  const labelAt = list.reduce((a, b) => (b.px > a.px ? b : a));
69
72
  return (_jsxs("g", { className: cx("nre-line-series", seriesClass), "data-series": series || undefined, children: [list.length > 1 && (_jsx("polyline", { className: "nre-line-path", points: list.map((p) => `${p.px},${p.py}`).join(" "), fill: "none" })), series !== "" && (_jsx("text", { className: "nre-line-series-label", x: labelAt.px + 8, y: labelAt.py + 4, children: series }))] }, series || "(single)"));
70
73
  }), points.map((p, i) => {
71
- const circle = (_jsx("circle", { className: cx("nre-line-point", p.series !== undefined ? seriesClassForKey(p.series) : "nre-series-none"), "data-key": p.key, cx: p.px, cy: p.py, r: 4, children: _jsx("title", { children: p.title }) }));
74
+ const circle = (_jsx("circle", { className: cx("nre-line-point", p.series !== undefined ? seriesClassOf(p.series) : "nre-series-none"), "data-key": p.key, cx: p.px, cy: p.py, r: 4, children: _jsx("title", { children: p.title }) }));
72
75
  const row = drawableRows[i];
73
76
  return pointHref ? (_jsx("a", { className: "nre-line-point-link", href: pointHref(row), children: circle }, `${p.key}:${i}`)) : (_jsx("g", { children: circle }, `${p.key}:${i}`));
74
77
  })] }), missingNote] }));
@@ -1,7 +1,7 @@
1
1
  import type { ReactElement } from "react";
2
- import type { MatrixData } from "../types.ts";
3
- import type { AttemptLocator } from "../../results/locator.ts";
4
- import { type ReportLocale } from "../locale.ts";
2
+ import type { MatrixData } from "../../model/types.ts";
3
+ import type { AttemptLocator } from "../../../results/locator.ts";
4
+ import { type ReportLocale } from "../../model/locale.ts";
5
5
  export declare function MetricMatrix({ data, attemptHref, className, locale, }: {
6
6
  data: MatrixData;
7
7
  attemptHref?: (locator: AttemptLocator) => string;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DEFAULT_REPORT_LOCALE, resolveMetricLabel } from "../locale.js";
3
- import { MetricCellView } from "./cell.js";
4
- import { colorClassForKey } from "./colors.js";
5
- import { cx } from "./format.js";
2
+ import { DEFAULT_REPORT_LOCALE, resolveMetricLabel } from "../../model/locale.js";
3
+ import { MetricCellView } from "../cell.js";
4
+ import { colorClassForKey } from "../../assets/colors.js";
5
+ import { cx } from "../shared.js";
6
6
  export function MetricMatrix({ data, attemptHref, className, locale = DEFAULT_REPORT_LOCALE, }) {
7
7
  // 稀疏 cells → 首次出现顺序的行/列键 + 查找表;组件只整理形状,不碰数值
8
8
  const rowKeys = [];
@@ -0,0 +1,11 @@
1
+ import type { ReactElement } from "react";
2
+ import type { ScatterData } from "../../model/types.ts";
3
+ import { type ReportLocale } from "../../model/locale.ts";
4
+ export declare function MetricScatter({ data, connect, pointHref, className, locale, }: {
5
+ data: ScatterData;
6
+ /** series 内按 x 升序连折线;默认 false,只给「线 = 同族变体」的 lineage series 用。 */
7
+ connect?: boolean;
8
+ pointHref?: (row: ScatterData["rows"][number]) => string;
9
+ className?: string;
10
+ locale?: ReportLocale;
11
+ }): ReactElement;
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { formatMetricValue } from "../format.js";
3
- import { DEFAULT_REPORT_LOCALE, countText, localeText, resolveLocalizedText, resolveMetricLabel } from "../locale.js";
2
+ import { formatMetricValue } from "../../model/format.js";
3
+ import { DEFAULT_REPORT_LOCALE, countText, localeText, resolveLocalizedText, resolveMetricLabel } from "../../model/locale.js";
4
4
  import { niceTicks, placePointLabels } from "./chart-math.js";
5
- import { colorClassForKey, seriesClassForKey } from "./colors.js";
6
- import { cx } from "./format.js";
7
- const WIDTH = 640;
8
- const HEIGHT = 360;
9
- const MARGIN = { top: 26, right: 24, bottom: 46, left: 62 };
5
+ import { colorIndicesForKeys } from "../../assets/colors.js";
6
+ import { cx } from "../shared.js";
7
+ const WIDTH = 760;
8
+ const HEIGHT = 400;
9
+ const MARGIN = { top: 28, right: 32, bottom: 48, left: 64 };
10
10
  const PLOT_W = WIDTH - MARGIN.left - MARGIN.right;
11
11
  const PLOT_H = HEIGHT - MARGIN.top - MARGIN.bottom;
12
12
  /**
@@ -62,7 +62,7 @@ function axisScale(values, pixelLo, pixelHi, invert) {
62
62
  };
63
63
  return { ticks, scale };
64
64
  }
65
- export function MetricScatter({ data, pointHref, className, locale = DEFAULT_REPORT_LOCALE, }) {
65
+ export function MetricScatter({ data, connect = false, pointHref, className, locale = DEFAULT_REPORT_LOCALE, }) {
66
66
  const missing = data.rows.filter((r) => r.x.value === null || r.y.value === null);
67
67
  const drawableRows = data.rows.filter((r) => r.x.value !== null && r.y.value !== null);
68
68
  const missingNote = missing.length > 0 ? (_jsx("p", { className: "nre-scatter-missing", title: missing.map((r) => r.key).join(", "), children: countText(locale, "pointsMissing", missing.length) })) : null;
@@ -97,31 +97,34 @@ export function MetricScatter({ data, pointHref, className, locale = DEFAULT_REP
97
97
  py: yScale.scale(yValue),
98
98
  };
99
99
  });
100
- // 同系列的点按 x 值排序连线;无系列的点只画点不连线
101
- const seriesOrder = [];
100
+ // 系列分组:图例与配色按显示键字典序;connect 时 series 内按 x 升序连折线
102
101
  const bySeries = new Map();
103
102
  for (const p of points) {
104
103
  if (p.series === undefined)
105
104
  continue;
106
- if (!bySeries.has(p.series)) {
107
- bySeries.set(p.series, []);
108
- seriesOrder.push(p.series);
109
- }
110
- bySeries.get(p.series).push(p);
105
+ const list = bySeries.get(p.series) ?? [];
106
+ list.push(p);
107
+ bySeries.set(p.series, list);
111
108
  }
109
+ const seriesOrder = [...bySeries.keys()].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
112
110
  for (const list of bySeries.values())
113
111
  list.sort((a, b) => a.xValue - b.xValue);
112
+ // 同图撞色消解:散列格作起点,按图例顺序线性探测空格(colors.ts 的契约注释)
113
+ const colorIdx = colorIndicesForKeys(seriesOrder);
114
+ const seriesClassOf = (series) => `nre-series-c${colorIdx.get(series) ?? 0}`;
115
+ const keyClassOf = (series) => `nre-c${colorIdx.get(series) ?? 0}`;
114
116
  // 直接标签的候选位择优布局:锚向、避让方向都由布局按空间决定,画布边界含边距
115
117
  const labels = placePointLabels(points.map((p) => ({ cx: p.px, cy: p.py, width: p.label.length * 6.4 + 10 })), { x0: 2, y0: 2, x1: WIDTH - 2, y1: HEIGHT - 2 });
116
- return (_jsxs("figure", { className: cx("nre", "nre-metric-scatter", className), children: [_jsxs("svg", { className: "nre-scatter-svg", viewBox: `0 0 ${WIDTH} ${HEIGHT}`, role: "img", "aria-label": `${axisLabel(xLabel, data.x)} × ${axisLabel(yLabel, data.y)}`, children: [_jsxs("g", { className: "nre-scatter-grid", children: [yScale.ticks.map((tick) => (_jsx("line", { x1: MARGIN.left, x2: MARGIN.left + PLOT_W, y1: yScale.scale(tick), y2: yScale.scale(tick) }, `gy${tick}`))), xScale.ticks.map((tick) => (_jsx("line", { y1: MARGIN.top, y2: MARGIN.top + PLOT_H, x1: xScale.scale(tick), x2: xScale.scale(tick) }, `gx${tick}`)))] }), showBetterHint && (_jsx("text", { className: "nre-scatter-better-hint", x: MARGIN.left + PLOT_W - 6, y: MARGIN.top + 14, textAnchor: "end", children: localeText(locale, "scatter.betterUpperRight") })), _jsx("g", { className: "nre-scatter-axis nre-scatter-axis-y", children: yScale.ticks.map((tick) => (_jsx("text", { className: "nre-scatter-tick", x: MARGIN.left - 8, y: yScale.scale(tick) + 3, textAnchor: "end", children: formatMetricValue(tick, data.y.unit) }, `ay${tick}`))) }), _jsx("g", { className: "nre-scatter-axis nre-scatter-axis-x", children: xScale.ticks.map((tick) => (_jsx("text", { className: "nre-scatter-tick", x: xScale.scale(tick), y: MARGIN.top + PLOT_H + 16, textAnchor: "middle", children: formatMetricValue(tick, data.x.unit) }, `ax${tick}`))) }), _jsx("text", { className: "nre-scatter-xlabel", x: MARGIN.left + PLOT_W / 2, y: HEIGHT - 8, textAnchor: "middle", children: axisLabel(xLabel, data.x) }), _jsx("text", { className: "nre-scatter-ylabel", x: 14, y: MARGIN.top + PLOT_H / 2, textAnchor: "middle", transform: `rotate(-90 14 ${MARGIN.top + PLOT_H / 2})`, children: axisLabel(yLabel, data.y) }), seriesOrder.map((series) => {
117
- const list = bySeries.get(series);
118
- if (list.length < 2)
119
- return null;
120
- return (_jsx("polyline", { className: cx("nre-scatter-line", seriesClassForKey(series)), "data-series": series, points: list.map((p) => `${p.px},${p.py}`).join(" "), fill: "none" }, series));
121
- }), points.map((p, i) => {
118
+ return (_jsxs("figure", { className: cx("nre", "nre-metric-scatter", className), children: [_jsxs("svg", { className: "nre-scatter-svg", viewBox: `0 0 ${WIDTH} ${HEIGHT}`, role: "img", "aria-label": `${axisLabel(xLabel, data.x)} × ${axisLabel(yLabel, data.y)}`, children: [_jsxs("g", { className: "nre-scatter-grid", children: [yScale.ticks.map((tick) => (_jsx("line", { x1: MARGIN.left, x2: MARGIN.left + PLOT_W, y1: yScale.scale(tick), y2: yScale.scale(tick) }, `gy${tick}`))), xScale.ticks.map((tick) => (_jsx("line", { y1: MARGIN.top, y2: MARGIN.top + PLOT_H, x1: xScale.scale(tick), x2: xScale.scale(tick) }, `gx${tick}`)))] }), showBetterHint && (_jsx("text", { className: "nre-scatter-better-hint", x: MARGIN.left + PLOT_W - 6, y: MARGIN.top + 14, textAnchor: "end", children: localeText(locale, "scatter.betterUpperRight") })), _jsx("g", { className: "nre-scatter-axis nre-scatter-axis-y", children: yScale.ticks.map((tick) => (_jsx("text", { className: "nre-scatter-tick", x: MARGIN.left - 8, y: yScale.scale(tick) + 3, textAnchor: "end", children: formatMetricValue(tick, data.y.unit) }, `ay${tick}`))) }), _jsx("g", { className: "nre-scatter-axis nre-scatter-axis-x", children: xScale.ticks.map((tick) => (_jsx("text", { className: "nre-scatter-tick", x: xScale.scale(tick), y: MARGIN.top + PLOT_H + 16, textAnchor: "middle", children: formatMetricValue(tick, data.x.unit) }, `ax${tick}`))) }), _jsx("text", { className: "nre-scatter-xlabel", x: MARGIN.left + PLOT_W / 2, y: HEIGHT - 8, textAnchor: "middle", children: axisLabel(xLabel, data.x) }), _jsx("text", { className: "nre-scatter-ylabel", x: 14, y: MARGIN.top + PLOT_H / 2, textAnchor: "middle", transform: `rotate(-90 14 ${MARGIN.top + PLOT_H / 2})`, children: axisLabel(yLabel, data.y) }), connect &&
119
+ seriesOrder.map((series) => {
120
+ const list = bySeries.get(series);
121
+ if (list.length < 2)
122
+ return null;
123
+ return (_jsx("polyline", { className: cx("nre-scatter-line", seriesClassOf(series)), "data-series": series, points: list.map((p) => `${p.px},${p.py}`).join(" "), fill: "none" }, series));
124
+ }), points.map((p, i) => {
122
125
  const label = labels[i];
123
- const group = (_jsxs("g", { className: cx("nre-scatter-point", p.series !== undefined ? seriesClassForKey(p.series) : "nre-series-none"), "data-key": p.key, children: [_jsx("title", { children: p.title }), label.leader && _jsx("line", { className: "nre-leader", x1: p.px, y1: p.py, x2: label.x, y2: label.y - 4 }), _jsx("circle", { className: "nre-scatter-hit", cx: p.px, cy: p.py, r: 12 }), _jsx("circle", { className: "nre-scatter-dot", cx: p.px, cy: p.py, r: 4.5 }), _jsx("text", { className: "nre-scatter-point-label", x: label.x, y: label.y, textAnchor: label.anchor, children: p.label })] }));
126
+ const group = (_jsxs("g", { className: cx("nre-scatter-point", p.series !== undefined ? seriesClassOf(p.series) : "nre-series-none"), "data-key": p.key, children: [_jsx("title", { children: p.title }), label.leader && _jsx("line", { className: "nre-leader", x1: p.px, y1: p.py, x2: label.x, y2: label.y - 4 }), _jsx("circle", { className: "nre-scatter-hit", cx: p.px, cy: p.py, r: 12 }), _jsx("circle", { className: "nre-scatter-dot", cx: p.px, cy: p.py, r: 4.5 }), _jsx("text", { className: "nre-scatter-point-label", x: label.x, y: label.y, textAnchor: label.anchor, children: p.label })] }));
124
127
  const row = drawableRows[i];
125
128
  return pointHref ? (_jsx("a", { className: "nre-scatter-point-link", href: pointHref(row), children: group }, p.key)) : (_jsx("g", { children: group }, p.key));
126
- })] }), seriesOrder.length > 0 && (_jsx("figcaption", { className: "nre-scatter-legend", children: seriesOrder.map((series) => (_jsx("span", { className: cx("nre-legend-key", "nre-key", colorClassForKey(series)), children: series }, series))) })), missingNote] }));
129
+ })] }), seriesOrder.length > 0 && (_jsx("figcaption", { className: "nre-scatter-legend", children: seriesOrder.map((series) => (_jsx("span", { className: cx("nre-legend-key", "nre-key", keyClassOf(series)), children: series }, series))) })), missingNote] }));
127
130
  }
@@ -1,7 +1,7 @@
1
1
  import type { ReactElement } from "react";
2
- import type { TableData } from "../types.ts";
3
- import type { AttemptLocator } from "../../results/locator.ts";
4
- import { type ReportLocale } from "../locale.ts";
2
+ import type { TableData } from "../../model/types.ts";
3
+ import type { AttemptLocator } from "../../../results/locator.ts";
4
+ import { type ReportLocale } from "../../model/locale.ts";
5
5
  export declare function MetricTable({ data, attemptHref, filter, className, locale, }: {
6
6
  data: TableData;
7
7
  attemptHref?: (locator: AttemptLocator) => string;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DEFAULT_REPORT_LOCALE, localeText, resolveMetricLabel } from "../locale.js";
3
- import { MetricCellView } from "./cell.js";
4
- import { colorClassForKey } from "./colors.js";
5
- import { cx } from "./format.js";
2
+ import { DEFAULT_REPORT_LOCALE, localeText, resolveMetricLabel } from "../../model/locale.js";
3
+ import { MetricCellView } from "../cell.js";
4
+ import { colorClassForKey } from "../../assets/colors.js";
5
+ import { cx } from "../shared.js";
6
6
  export function MetricTable({ data, attemptHref, filter, className, locale = DEFAULT_REPORT_LOCALE, }) {
7
7
  const table = (_jsxs("table", { className: cx("nre", "nre-metric-table", !filter && className), children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", className: "nre-dimension", "data-nre-sort": "", children: data.rowDimension }), data.columns.map((col) => (_jsxs("th", { scope: "col", className: "nre-metric-col", "data-nre-sort": "", children: [resolveMetricLabel(col.label, locale, col.key), col.unit && _jsxs("span", { className: "nre-unit", children: ["(", col.unit, ")"] }), col.better && (_jsx("span", { className: "nre-better", title: localeText(locale, col.better === "higher" ? "table.higherBetter" : "table.lowerBetter"), children: col.better === "higher" ? "↑" : "↓" }))] }, col.key)))] }) }), _jsx("tbody", { children: data.rows.map((row) => (_jsxs("tr", { children: [_jsx("th", { scope: "row", className: cx("nre-row-key", "nre-key", colorClassForKey(row.key)), "data-sort-value": row.key, children: row.key }), data.columns.map((col) => {
8
8
  const cell = row.cells[col.key];
@@ -1,6 +1,6 @@
1
1
  import type { ReactElement } from "react";
2
- import type { ScoreboardData } from "../types.ts";
3
- import { type ReportLocale } from "../locale.ts";
2
+ import type { ScoreboardData } from "../../model/types.ts";
3
+ import { type ReportLocale } from "../../model/locale.ts";
4
4
  export declare function Scoreboard({ data, className, locale, }: {
5
5
  data: ScoreboardData;
6
6
  className?: string;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DEFAULT_REPORT_LOCALE, countText, localeText, resolveLocalizedText } from "../locale.js";
3
- import { colorClassForKey } from "./colors.js";
4
- import { cx } from "./format.js";
2
+ import { DEFAULT_REPORT_LOCALE, countText, localeText, resolveLocalizedText } from "../../model/locale.js";
3
+ import { colorClassForKey } from "../../assets/colors.js";
4
+ import { cx } from "../shared.js";
5
5
  export function Scoreboard({ data, className, locale = DEFAULT_REPORT_LOCALE, }) {
6
6
  // 科目列 = 各行 subjects 的并集,按首次出现顺序;固定分母下各行本应一致,这里防御性合并
7
7
  const subjectKeys = [];
@@ -0,0 +1,89 @@
1
+ import type { DeltaData, DeltaPair, DimensionInput, FlagPairs, LineData, MatrixData, Metric, NumericAxis, ReportInput, ScatterData, ScoreboardData, SeriesInput, TableData } from "../../model/types.ts";
2
+ import type { JsonValue } from "../../../types.ts";
3
+ export interface MetricTableOptions {
4
+ /** 行维度(内置 / 自定义 / flag() / runConfig())。 */
5
+ rows: DimensionInput;
6
+ /** 每列一个指标;非空元组,元素是静态 import 的 Metric 实例。 */
7
+ columns: readonly [Metric, ...Metric[]];
8
+ /**
9
+ * 初始行序:必须是 columns 中同一个 Metric 实例且声明了 better,方向随 better
10
+ * (「好」的一头在上),缺数据行沉底;省略时按行 key 字典序。
11
+ */
12
+ sort?: Metric;
13
+ /** eval id 前缀过滤,同 CLI 位置参数语义;在聚合之前收窄题集。 */
14
+ evals?: string | readonly string[];
15
+ }
16
+ export declare function metricTableData(input: ReportInput, options: MetricTableOptions): Promise<TableData>;
17
+ export interface MetricMatrixOptions {
18
+ rows: DimensionInput;
19
+ columns: DimensionInput;
20
+ cell: Metric;
21
+ /** eval id 前缀过滤,同 CLI 位置参数语义。 */
22
+ evals?: string | readonly string[];
23
+ }
24
+ export declare function metricMatrixData(input: ReportInput, options: MetricMatrixOptions): Promise<MatrixData>;
25
+ export interface ScoreboardOptions {
26
+ rows: DimensionInput;
27
+ /** 固定题集;eval id 必须唯一。元素引用运行时数据,类型放宽为普通数组,空数组在计算时报错。 */
28
+ questions: readonly string[];
29
+ /** 分科函数;默认与 evalGroup 维度同一条规则:取 eval id 的完整父路径,无 `/` 取完整 id。 */
30
+ subject?: (evalId: string) => string;
31
+ /** 权重按 eval id 前缀匹配,多个命中时最长前缀生效;默认 1。 */
32
+ weights?: Readonly<Record<string, number>>;
33
+ fullMarks?: number;
34
+ score?: Metric;
35
+ }
36
+ /**
37
+ * 固定题集分母:未跑题按 0 分计入 `notRun`,跑了但指标为 null 的题按 0 分计入 `unscorable`,
38
+ * 两个计数不合并——成绩单能回答「这 0 分是没去考还是考了判不了」。组件不从已观测 attempt
39
+ * 的并集猜分母;Scope 中题集之外的 eval 被忽略并计入 `ignoredEvals`。
40
+ */
41
+ export declare function scoreboardData(input: ReportInput, options: ScoreboardOptions): Promise<ScoreboardData>;
42
+ export interface MetricScatterOptions {
43
+ /** 点维度:每个点 = 该组 attempt 的聚合。 */
44
+ points: DimensionInput;
45
+ /** 决定颜色和图例归类,默认不连线(连线是呈现 prop `connect`);数组形态解析为复合维度。 */
46
+ series?: SeriesInput;
47
+ x: Metric;
48
+ y: Metric;
49
+ /** eval id 前缀过滤,同 CLI 位置参数语义。 */
50
+ evals?: string | readonly string[];
51
+ }
52
+ export declare function metricScatterData(input: ReportInput, options: MetricScatterOptions): Promise<ScatterData>;
53
+ export interface MetricLineOptions {
54
+ /** x 轴:NumericAxis(numericFlag() / numericLabel() / numericRunConfig() 或自定义 of),不解析 experiment 命名。 */
55
+ x: NumericAxis;
56
+ /** 数组形态解析为复合维度。 */
57
+ series?: SeriesInput;
58
+ y: Metric;
59
+ /** eval id 前缀过滤,同 CLI 位置参数语义。 */
60
+ evals?: string | readonly string[];
61
+ }
62
+ /**
63
+ * 点身份 = (series, x):落进同一桶的全部 attempt 先在各自 experiment × eval 内 perEval 聚合,
64
+ * 再 acrossEvals 跨题折成该点唯一的 y——聚合顺序是 (series, x, experiment, eval),同一桶里有
65
+ * 多个 experiment 时它们合成一个点,不画垂直来回线。前提是 x 在同一 experiment × eval 内恒定:
66
+ * 自定义 NumericAxis.of() 对同一 experiment × eval 的不同 attempt 返回不同值时按完整用户反馈失败。
67
+ * x 为 null 的 attempt 不伪造 x 值,归入该 series 的未绘制行,组件报告未绘制数量。
68
+ */
69
+ export declare function metricLineData(input: ReportInput, options: MetricLineOptions): Promise<LineData>;
70
+ /**
71
+ * 按 flag 派生 A/B 对(docs/feature/reports/library/metric-views.md「DeltaTable」):
72
+ * 配对域 = input Scope 内删除该 flag 后可比性配置深相等(不额外按 experiment id 的目录前缀分组
73
+ * ——architecture.md「Scope 是默认报告的比较边界」同一条契约);a 取 baseline(缺省 = 未声明该
74
+ * flag),b 侧该 flag 的每个其它取值各成一对;label 自动 `<完整 a experiment id> · <flag>=<显示键>`,
75
+ * 排序仍按 a 的末段、再按 flag 显示键(不受完整 id 的字符串差异影响)。
76
+ */
77
+ export declare function pairsByFlag(name: string, options?: {
78
+ baseline?: JsonValue;
79
+ }): FlagPairs;
80
+ export interface DeltaTableOptions {
81
+ /** 显式维度,必填——"baseline" 不会被猜成 experiment、agent、flag 或 snapshot 中的某一种。 */
82
+ by: DimensionInput;
83
+ /** 字面 pair 数组(自定义 label),或 pairsByFlag() 的派生声明;空数组在计算时报错。 */
84
+ pairs: readonly DeltaPair[] | FlagPairs;
85
+ metrics: readonly [Metric, ...Metric[]];
86
+ /** eval id 前缀过滤,同 CLI 位置参数语义。 */
87
+ evals?: string | readonly string[];
88
+ }
89
+ export declare function deltaTableData(input: ReportInput, options: DeltaTableOptions): Promise<DeltaData>;