niceeval 0.13.3-canary.37 → 0.13.3

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 (383) hide show
  1. package/dist/agents/bub.cjs +4 -4
  2. package/dist/agents/bub.cjs.map +1 -1
  3. package/dist/agents/bub.d.cts +2 -2
  4. package/dist/agents/bub.d.mts +2 -2
  5. package/dist/agents/bub.d.ts +2 -2
  6. package/dist/agents/codex-app-server.cjs +2 -3
  7. package/dist/agents/codex-app-server.cjs.map +1 -1
  8. package/dist/agents/codex.cjs +4 -4
  9. package/dist/agents/codex.cjs.map +1 -1
  10. package/dist/agents/codex.d.cts +3 -3
  11. package/dist/agents/codex.d.mts +3 -3
  12. package/dist/agents/codex.d.ts +3 -3
  13. package/dist/agents/sdk-streams.cjs +11 -4
  14. package/dist/agents/sdk-streams.cjs.map +1 -1
  15. package/dist/analysis/bindings.cjs +74 -19
  16. package/dist/analysis/bindings.cjs.map +1 -1
  17. package/dist/analysis/bindings.d.cts +534 -156
  18. package/dist/analysis/bindings.d.mts +534 -156
  19. package/dist/analysis/bindings.d.ts +534 -156
  20. package/dist/analysis/domain-view.cjs.map +1 -1
  21. package/dist/analysis/domain-view.d.cts +137 -8
  22. package/dist/analysis/domain-view.d.mts +137 -8
  23. package/dist/analysis/domain-view.d.ts +137 -8
  24. package/dist/analysis/index.cjs.map +1 -1
  25. package/dist/analysis/index.d.cts +1 -1
  26. package/dist/analysis/index.d.mts +1 -1
  27. package/dist/analysis/index.d.ts +1 -1
  28. package/dist/assertions/api.cjs.map +1 -1
  29. package/dist/assertions/api.d.cts +62 -0
  30. package/dist/assertions/api.d.mts +62 -0
  31. package/dist/assertions/api.d.ts +62 -0
  32. package/dist/assertions/judge.cjs +56 -5
  33. package/dist/assertions/judge.cjs.map +1 -1
  34. package/dist/assertions/match.cjs +66 -42
  35. package/dist/assertions/match.cjs.map +1 -1
  36. package/dist/assertions/match.d.cts +13 -0
  37. package/dist/assertions/match.d.mts +13 -0
  38. package/dist/assertions/match.d.ts +13 -0
  39. package/dist/assertions/record/attachment.cjs +104 -33
  40. package/dist/assertions/record/attachment.cjs.map +1 -1
  41. package/dist/assertions/record/attachment.d.cts +294 -57
  42. package/dist/assertions/record/attachment.d.mts +294 -57
  43. package/dist/assertions/record/attachment.d.ts +294 -57
  44. package/dist/assertions/record/codec.cjs +91 -17
  45. package/dist/assertions/record/codec.cjs.map +1 -1
  46. package/dist/assertions/record/codec.d.cts +280 -52
  47. package/dist/assertions/record/codec.d.mts +280 -52
  48. package/dist/assertions/record/codec.d.ts +280 -52
  49. package/dist/assertions/record/index.js +2 -0
  50. package/dist/assertions/record/model.cjs +16 -0
  51. package/dist/assertions/record/model.cjs.map +1 -1
  52. package/dist/assertions/record/model.d.cts +120 -13
  53. package/dist/assertions/record/model.d.mts +120 -13
  54. package/dist/assertions/record/model.d.ts +120 -13
  55. package/dist/assertions/record/model.js +2 -0
  56. package/dist/assertions/record/producer.cjs +70 -50
  57. package/dist/assertions/record/producer.cjs.map +1 -1
  58. package/dist/assertions/record/producer.d.cts +8 -7
  59. package/dist/assertions/record/producer.d.mts +8 -7
  60. package/dist/assertions/record/producer.d.ts +8 -7
  61. package/dist/assertions/runtime.cjs +49 -7
  62. package/dist/assertions/runtime.cjs.map +1 -1
  63. package/dist/cli/application.cjs +40 -0
  64. package/dist/cli/application.cjs.map +1 -0
  65. package/dist/cli/application.d.cts +129 -0
  66. package/dist/cli/application.d.mts +129 -0
  67. package/dist/cli/application.d.ts +129 -0
  68. package/dist/cli/application.js +24 -0
  69. package/dist/cli/application.js.map +1 -0
  70. package/dist/cli/bootstrap.cjs +10 -4
  71. package/dist/cli/bootstrap.cjs.map +1 -1
  72. package/dist/cli/node-application.cjs +123 -0
  73. package/dist/cli/node-application.cjs.map +1 -0
  74. package/dist/cli/node-application.d.cts +14 -0
  75. package/dist/cli/node-application.d.mts +14 -0
  76. package/dist/cli/node-application.d.ts +14 -0
  77. package/dist/cli/node-application.js +26 -0
  78. package/dist/cli/node-application.js.map +1 -0
  79. package/dist/cli/program.cjs +2807 -0
  80. package/dist/cli/program.cjs.map +1 -0
  81. package/dist/cli/program.d.cts +352 -0
  82. package/dist/cli/program.d.mts +352 -0
  83. package/dist/cli/program.d.ts +352 -0
  84. package/dist/cli/program.js +36 -0
  85. package/dist/cli/program.js.map +1 -0
  86. package/dist/cli/project-configuration.cjs +134 -0
  87. package/dist/cli/project-configuration.cjs.map +1 -0
  88. package/dist/cli/project-configuration.d.cts +64 -0
  89. package/dist/cli/project-configuration.d.mts +64 -0
  90. package/dist/cli/project-configuration.d.ts +64 -0
  91. package/dist/cli/project-configuration.js +22 -0
  92. package/dist/cli/project-configuration.js.map +1 -0
  93. package/dist/cli/record.cjs +20 -4
  94. package/dist/cli/record.cjs.map +1 -1
  95. package/dist/cli/record.d.cts +3 -3
  96. package/dist/cli/record.d.mts +3 -3
  97. package/dist/cli/record.d.ts +3 -3
  98. package/dist/cli.cjs +19 -3130
  99. package/dist/cli.cjs.map +1 -1
  100. package/dist/cli.d.cts +2 -148
  101. package/dist/cli.d.mts +2 -148
  102. package/dist/cli.d.ts +2 -148
  103. package/dist/cli.js +22 -30
  104. package/dist/context/assert-first.cjs +20 -15
  105. package/dist/context/assert-first.cjs.map +1 -1
  106. package/dist/eval/record/verdict.cjs +3 -2
  107. package/dist/eval/record/verdict.cjs.map +1 -1
  108. package/dist/experiment/host/index.cjs +1 -6
  109. package/dist/experiment/host/index.cjs.map +1 -1
  110. package/dist/experiment/host/index.d.cts +1 -0
  111. package/dist/experiment/host/index.d.mts +1 -0
  112. package/dist/experiment/host/index.d.ts +1 -0
  113. package/dist/load-config.cjs +13 -4
  114. package/dist/load-config.cjs.map +1 -1
  115. package/dist/load-config.d.cts +4 -3
  116. package/dist/load-config.d.mts +4 -3
  117. package/dist/load-config.d.ts +4 -3
  118. package/dist/load-config.js +4 -2
  119. package/dist/o11y/parsers/codex.cjs +29 -7
  120. package/dist/o11y/parsers/codex.cjs.map +1 -1
  121. package/dist/record/codec/core.d.cts +0 -2
  122. package/dist/record/codec/core.d.mts +0 -2
  123. package/dist/record/codec/core.d.ts +0 -2
  124. package/dist/record/codec/identifiers.cjs +2 -3
  125. package/dist/record/codec/identifiers.cjs.map +1 -1
  126. package/dist/record/codec/identifiers.d.cts +1 -2
  127. package/dist/record/codec/identifiers.d.mts +1 -2
  128. package/dist/record/codec/identifiers.d.ts +1 -2
  129. package/dist/record/codec/identifiers.js +10 -12
  130. package/dist/record/codec/index.js +42 -44
  131. package/dist/record/definition/attachment.cjs +1 -0
  132. package/dist/record/definition/attachment.cjs.map +1 -1
  133. package/dist/record/definition/attachment.d.cts +14 -0
  134. package/dist/record/definition/attachment.d.mts +14 -0
  135. package/dist/record/definition/attachment.d.ts +14 -0
  136. package/dist/record/family/assertions-v1.cjs +104 -0
  137. package/dist/record/family/assertions-v1.cjs.map +1 -0
  138. package/dist/record/family/assertions-v1.d.cts +2 -0
  139. package/dist/record/family/assertions-v1.d.mts +2 -0
  140. package/dist/record/family/assertions-v1.d.ts +2 -0
  141. package/dist/record/family/assertions-v1.js +6 -0
  142. package/dist/record/family/assertions-v1.js.map +1 -0
  143. package/dist/record/family/assertions.cjs +16 -5
  144. package/dist/record/family/assertions.cjs.map +1 -1
  145. package/dist/record/family/assertions.d.cts +510 -56
  146. package/dist/record/family/assertions.d.mts +510 -56
  147. package/dist/record/family/assertions.d.ts +510 -56
  148. package/dist/record/family/assertions.js +14 -10
  149. package/dist/record/family/catalog.cjs +17 -1
  150. package/dist/record/family/catalog.cjs.map +1 -1
  151. package/dist/record/family/catalog.d.cts +1292 -104
  152. package/dist/record/family/catalog.d.mts +1292 -104
  153. package/dist/record/family/catalog.d.ts +1292 -104
  154. package/dist/record/family/catalog.js +22 -20
  155. package/dist/record/family/index.js +144 -138
  156. package/dist/record/family/observability-v1.cjs +5 -0
  157. package/dist/record/family/observability-v1.cjs.map +1 -1
  158. package/dist/record/family/observability.cjs +1 -1
  159. package/dist/record/family/observability.cjs.map +1 -1
  160. package/dist/record/host/runtime.cjs +323 -173
  161. package/dist/record/host/runtime.cjs.map +1 -1
  162. package/dist/record/host/types.cjs.map +1 -1
  163. package/dist/record/host/types.d.cts +9 -7
  164. package/dist/record/host/types.d.mts +9 -7
  165. package/dist/record/host/types.d.ts +9 -7
  166. package/dist/record/model/core.cjs.map +1 -1
  167. package/dist/record/model/core.d.cts +1 -2
  168. package/dist/record/model/core.d.mts +1 -2
  169. package/dist/record/model/core.d.ts +1 -2
  170. package/dist/record/model/definition.cjs +1 -2
  171. package/dist/record/model/definition.cjs.map +1 -1
  172. package/dist/record/model/definition.d.cts +1 -7
  173. package/dist/record/model/definition.d.mts +1 -7
  174. package/dist/record/model/definition.d.ts +1 -7
  175. package/dist/record/model/identifiers.cjs +2 -3
  176. package/dist/record/model/identifiers.cjs.map +1 -1
  177. package/dist/record/model/identifiers.d.cts +1 -3
  178. package/dist/record/model/identifiers.d.mts +1 -3
  179. package/dist/record/model/identifiers.d.ts +1 -3
  180. package/dist/record/model/identifiers.js +36 -38
  181. package/dist/record/model/index.js +60 -62
  182. package/dist/record/platform/node.cjs +17 -7
  183. package/dist/record/platform/node.cjs.map +1 -1
  184. package/dist/record/platform/services.cjs.map +1 -1
  185. package/dist/record/platform/services.d.cts +8 -3
  186. package/dist/record/platform/services.d.mts +8 -3
  187. package/dist/record/platform/services.d.ts +8 -3
  188. package/dist/record/reader/format.cjs +16 -65
  189. package/dist/record/reader/format.cjs.map +1 -1
  190. package/dist/record/reader/format.d.cts +5 -9
  191. package/dist/record/reader/format.d.mts +5 -9
  192. package/dist/record/reader/format.d.ts +5 -9
  193. package/dist/record/reader/index.js +10 -8
  194. package/dist/record/reader/runtime.cjs +63 -32
  195. package/dist/record/reader/runtime.cjs.map +1 -1
  196. package/dist/record/reader/runtime.d.cts +40 -4
  197. package/dist/record/reader/runtime.d.mts +40 -4
  198. package/dist/record/reader/runtime.d.ts +40 -4
  199. package/dist/record/reader/runtime.js +6 -4
  200. package/dist/report/assets/enhance.js +5 -5
  201. package/dist/report/assets/styles.css +186 -24
  202. package/dist/report/built-in/result-components.cjs +8 -5
  203. package/dist/report/built-in/result-components.cjs.map +1 -1
  204. package/dist/report/built-in/standard.cjs +3 -0
  205. package/dist/report/built-in/standard.cjs.map +1 -1
  206. package/dist/report/built-in/standard.d.cts +2 -0
  207. package/dist/report/built-in/standard.d.mts +2 -0
  208. package/dist/report/built-in/standard.d.ts +2 -0
  209. package/dist/report/client-dist/app.js +53 -0
  210. package/dist/report/components/attempt-detail/compute.cjs +106 -231
  211. package/dist/report/components/attempt-detail/compute.cjs.map +1 -1
  212. package/dist/report/components/attempt-detail/compute.d.cts +9 -43
  213. package/dist/report/components/attempt-detail/compute.d.mts +9 -43
  214. package/dist/report/components/attempt-detail/compute.d.ts +9 -43
  215. package/dist/report/components/attempt-detail/compute.js +2 -4
  216. package/dist/report/components/attempt-detail/content.cjs +3 -4
  217. package/dist/report/components/attempt-detail/content.cjs.map +1 -1
  218. package/dist/report/components/attempt-detail/validate.cjs +44 -2
  219. package/dist/report/components/attempt-detail/validate.cjs.map +1 -1
  220. package/dist/report/components/entity-lists/compute.cjs +9 -15
  221. package/dist/report/components/entity-lists/compute.cjs.map +1 -1
  222. package/dist/report/components/entity-lists/content.cjs +53 -40
  223. package/dist/report/components/entity-lists/content.cjs.map +1 -1
  224. package/dist/report/components/entity-lists/index.cjs +1 -3
  225. package/dist/report/components/entity-lists/index.cjs.map +1 -1
  226. package/dist/report/components/experiment-detail/compute.cjs +4 -6
  227. package/dist/report/components/experiment-detail/compute.cjs.map +1 -1
  228. package/dist/report/definition/cell.cjs +14 -7
  229. package/dist/report/definition/cell.cjs.map +1 -1
  230. package/dist/report/definition/cell.d.cts +4 -0
  231. package/dist/report/definition/cell.d.mts +4 -0
  232. package/dist/report/definition/cell.d.ts +4 -0
  233. package/dist/report/definition/primitives/assertion-evidence.cjs +96 -0
  234. package/dist/report/definition/primitives/assertion-evidence.cjs.map +1 -0
  235. package/dist/report/definition/primitives/assertion-evidence.d.cts +11 -0
  236. package/dist/report/definition/primitives/assertion-evidence.d.mts +11 -0
  237. package/dist/report/definition/primitives/assertion-evidence.d.ts +11 -0
  238. package/dist/report/definition/primitives/assertion-evidence.js +6 -0
  239. package/dist/report/definition/primitives/assertion-evidence.js.map +1 -0
  240. package/dist/report/definition/primitives.cjs +14 -1
  241. package/dist/report/definition/primitives.cjs.map +1 -1
  242. package/dist/report/definition/report.cjs +16 -8
  243. package/dist/report/definition/report.cjs.map +1 -1
  244. package/dist/report/definition/report.d.cts +6 -0
  245. package/dist/report/definition/report.d.mts +6 -0
  246. package/dist/report/definition/report.d.ts +6 -0
  247. package/dist/report/definition/table-text.cjs +12 -3
  248. package/dist/report/definition/table-text.cjs.map +1 -1
  249. package/dist/report/definition/table-text.d.cts +6 -1
  250. package/dist/report/definition/table-text.d.mts +6 -1
  251. package/dist/report/definition/table-text.d.ts +6 -1
  252. package/dist/report/execution/model.cjs +6 -14
  253. package/dist/report/execution/model.cjs.map +1 -1
  254. package/dist/report/execution/model.d.cts +5 -10
  255. package/dist/report/execution/model.d.mts +5 -10
  256. package/dist/report/execution/model.d.ts +5 -10
  257. package/dist/report/execution/model.js +6 -6
  258. package/dist/report/execution/paths.cjs +0 -11
  259. package/dist/report/execution/paths.cjs.map +1 -1
  260. package/dist/report/execution/paths.d.cts +0 -1
  261. package/dist/report/execution/paths.d.mts +0 -1
  262. package/dist/report/execution/paths.d.ts +0 -1
  263. package/dist/report/execution/paths.js +6 -8
  264. package/dist/report/host/execute.cjs +13 -22
  265. package/dist/report/host/execute.cjs.map +1 -1
  266. package/dist/report/host/execute.d.cts +1 -4
  267. package/dist/report/host/execute.d.mts +1 -4
  268. package/dist/report/host/execute.d.ts +1 -4
  269. package/dist/report/host/from-record.cjs +3 -0
  270. package/dist/report/host/from-record.cjs.map +1 -1
  271. package/dist/report/host/from-record.d.cts +4 -1
  272. package/dist/report/host/from-record.d.mts +4 -1
  273. package/dist/report/host/from-record.d.ts +4 -1
  274. package/dist/report/host/site-assets.cjs +1 -2
  275. package/dist/report/host/site-assets.cjs.map +1 -1
  276. package/dist/report/host/site-assets.d.cts +0 -1
  277. package/dist/report/host/site-assets.d.mts +0 -1
  278. package/dist/report/host/site-assets.d.ts +0 -1
  279. package/dist/report/host/site-assets.js +2 -4
  280. package/dist/report/host/static.cjs +71 -346
  281. package/dist/report/host/static.cjs.map +1 -1
  282. package/dist/report/host/static.d.cts +1 -3
  283. package/dist/report/host/static.d.mts +1 -3
  284. package/dist/report/host/static.d.ts +1 -3
  285. package/dist/report/host/static.js +2 -2
  286. package/dist/report/host/view-session.cjs.map +1 -1
  287. package/dist/report/host/view-session.d.cts +1 -1
  288. package/dist/report/host/view-session.d.mts +1 -1
  289. package/dist/report/host/view-session.d.ts +1 -1
  290. package/dist/report/model/locale.cjs +1 -1
  291. package/dist/report/model/locale.cjs.map +1 -1
  292. package/dist/report/model/locale.d.cts +1 -1
  293. package/dist/report/model/locale.d.mts +1 -1
  294. package/dist/report/model/locale.d.ts +1 -1
  295. package/dist/report/model/pricing.cjs +2 -2
  296. package/dist/report/model/pricing.cjs.map +1 -1
  297. package/dist/report/react/enhance.js +5 -5
  298. package/dist/report/react/styles.css +186 -24
  299. package/dist/runner/adoption.cjs +4 -7
  300. package/dist/runner/adoption.cjs.map +1 -1
  301. package/dist/runner/feedback/failure.cjs +77 -2
  302. package/dist/runner/feedback/failure.cjs.map +1 -1
  303. package/dist/runner/feedback/failure.d.cts +2 -1
  304. package/dist/runner/feedback/failure.d.mts +2 -1
  305. package/dist/runner/feedback/failure.d.ts +2 -1
  306. package/dist/runner/project-current.cjs +2 -13
  307. package/dist/runner/project-current.cjs.map +1 -1
  308. package/dist/runner/project-current.d.cts +4 -2
  309. package/dist/runner/project-current.d.mts +4 -2
  310. package/dist/runner/project-current.d.ts +4 -2
  311. package/dist/runner/reporters/braintrust.cjs +7 -7
  312. package/dist/runner/reporters/braintrust.cjs.map +1 -1
  313. package/dist/runner/reuse-readback.cjs +3 -4
  314. package/dist/runner/reuse-readback.cjs.map +1 -1
  315. package/dist/runner/run.cjs +5 -2
  316. package/dist/runner/run.cjs.map +1 -1
  317. package/dist/view/server.cjs +2 -37
  318. package/dist/view/server.cjs.map +1 -1
  319. package/dist/view/server.d.cts +0 -3
  320. package/dist/view/server.d.mts +0 -3
  321. package/dist/view/server.d.ts +0 -3
  322. package/docs-site/zh/reference/builtin-agents.mdx +7 -7
  323. package/docs-site/zh/reference/official-adapters.mdx +4 -4
  324. package/docs-site/zh/reference/report-components.mdx +2 -2
  325. package/docs-site/zh/tutorials/configuration.mdx +2 -2
  326. package/docs-site/zh/tutorials/deploy-report-site.mdx +24 -2
  327. package/docs-site/zh/tutorials/publish-report.mdx +4 -4
  328. package/docs-site/zh/tutorials/sandbox-agent.mdx +5 -5
  329. package/docs-site/zh/tutorials/theming.mdx +2 -2
  330. package/package.json +4 -6
  331. package/dist/record/migration/index.cjs +0 -5
  332. package/dist/record/migration/index.cjs.map +0 -1
  333. package/dist/record/migration/index.d.cts +0 -11
  334. package/dist/record/migration/index.d.mts +0 -11
  335. package/dist/record/migration/index.d.ts +0 -11
  336. package/dist/record/migration/index.js +0 -6
  337. package/dist/record/migration/index.js.map +0 -1
  338. package/dist/report/host/site-runtime.cjs +0 -92
  339. package/dist/report/host/site-runtime.cjs.map +0 -1
  340. package/dist/report/host/site-runtime.d.cts +0 -9
  341. package/dist/report/host/site-runtime.d.mts +0 -9
  342. package/dist/report/host/site-runtime.d.ts +0 -9
  343. package/dist/report/host/site-runtime.js +0 -10
  344. package/dist/report/host/site-runtime.js.map +0 -1
  345. package/dist/view/client-dist/app.css +0 -2
  346. package/dist/view/client-dist/app.js +0 -49
  347. package/dist/view/data.cjs +0 -3
  348. package/dist/view/data.cjs.map +0 -1
  349. package/dist/view/data.d.cts +0 -9
  350. package/dist/view/data.d.mts +0 -9
  351. package/dist/view/data.d.ts +0 -9
  352. package/dist/view/data.js +0 -4
  353. package/dist/view/data.js.map +0 -1
  354. package/dist/view/index.cjs +0 -24
  355. package/dist/view/index.cjs.map +0 -1
  356. package/dist/view/index.d.cts +0 -9
  357. package/dist/view/index.d.mts +0 -9
  358. package/dist/view/index.d.ts +0 -9
  359. package/dist/view/index.js +0 -28
  360. package/dist/view/index.js.map +0 -1
  361. package/dist/view/report-view-cache.cjs +0 -200
  362. package/dist/view/report-view-cache.cjs.map +0 -1
  363. package/dist/view/report-view-cache.d.cts +0 -67
  364. package/dist/view/report-view-cache.d.mts +0 -67
  365. package/dist/view/report-view-cache.d.ts +0 -67
  366. package/dist/view/report-view-cache.js +0 -8
  367. package/dist/view/report-view-cache.js.map +0 -1
  368. package/dist/view/shared/types.cjs +0 -3
  369. package/dist/view/shared/types.cjs.map +0 -1
  370. package/dist/view/shared/types.d.cts +0 -51
  371. package/dist/view/shared/types.d.mts +0 -51
  372. package/dist/view/shared/types.d.ts +0 -51
  373. package/dist/view/shared/types.js +0 -4
  374. package/dist/view/shared/types.js.map +0 -1
  375. package/dist/view/site.cjs +0 -32
  376. package/dist/view/site.cjs.map +0 -1
  377. package/dist/view/site.d.cts +0 -24
  378. package/dist/view/site.d.mts +0 -24
  379. package/dist/view/site.d.ts +0 -24
  380. package/dist/view/site.js +0 -8
  381. package/dist/view/site.js.map +0 -1
  382. package/dist/view/styles.css +0 -170
  383. package/dist/view/template.html +0 -17
@@ -7,7 +7,6 @@ const tree_ts_1 = require("../../definition/tree.cjs");
7
7
  const primitives_tsx_1 = require("../../definition/primitives.cjs");
8
8
  const compute_ts_1 = require("./compute.cjs");
9
9
  const content_ts_1 = require("./content.cjs");
10
- const format_ts_1 = require("../../model/format.cjs");
11
10
  var compute_ts_2 = require("./compute.cjs");
12
11
  Object.defineProperty(exports, "attemptListData", { enumerable: true, get: function () { return compute_ts_2.attemptListData; } });
13
12
  Object.defineProperty(exports, "experimentListData", { enumerable: true, get: function () { return compute_ts_2.experimentListData; } });
@@ -45,8 +44,7 @@ exports.ExperimentTable = (0, tree_ts_1.defineComponent)(async (props, ctx) => {
45
44
  }
46
45
  const sample = (0, experiment_groups_ts_1.sampleForExperimentComparisonScope)(props.comparison);
47
46
  const rows = await (0, compute_ts_1.experimentListData)(sample, ctx.report.pricing);
48
- const composition = (0, format_ts_1.experimentListEvaluationKindComposition)(rows.map((row) => ({ evaluationKind: row.evaluationKind, attempts: row.evalRows.length })));
49
- const defaultSort = composition === "pass" ? "passRate" : "totalScore";
47
+ const defaultSort = "summary";
50
48
  return (0, jsx_runtime_1.jsx)(primitives_tsx_1.TableContentView, { data: (0, content_ts_1.experimentListContent)(rows), sort: props.sort ?? defaultSort, searchable: props.searchable ?? true, locale: props.locale, className: props.className });
51
49
  });
52
50
  exports.ExperimentTable.displayName = "ExperimentTable";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":";;;;AAIA,iFAA4F;AAC5F,sDAA2D;AAC3D,mEAAyE;AAEzE,6CAAmH;AACnH,6CAAyE;AACzE,qDAAgF;AAChF,2CAA6G;AAApG,6GAAA,eAAe,OAAA;AAAE,gHAAA,kBAAkB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AAErF,2CAAyE;AAAhE,gHAAA,kBAAkB,OAAA;AAAE,mHAAA,qBAAqB,OAAA;AAUlD,sEAAsE;AACzD,QAAA,WAAW,GAAG,IAAA,yBAAe,EAAmB,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;IAC9E,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC;IACxC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,IAAA,4BAAe,EAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,GAAG;SACf,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC;SACzE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACtB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,iBAAiB,CAAC;QAC/D,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC,iBAAiB,CAAC;QACjE,IAAI,WAAW,KAAK,YAAY;YAC5B,OAAO,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,OAAO,uBAAC,iCAAgB,IAAC,IAAI,EAAE,IAAA,+BAAkB,EAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC;AACrI,CAAC,CAAC,CAAC;AACH,mBAAW,CAAC,WAAW,GAAG,aAAa,CAAC;AASxC,iDAAiD;AACpC,QAAA,WAAW,GAAG,IAAA,yBAAe,EAAmB,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;IAC9E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,IAAA,4BAAe,EAAC,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/F,OAAO,uBAAC,iCAAgB,IAAC,IAAI,EAAE,IAAA,+BAAkB,EAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC;AACjH,CAAC,CAAC,CAAC;AACH,mBAAW,CAAC,WAAW,GAAG,aAAa,CAAC;AAS3B,QAAA,eAAe,GAAG,IAAA,yBAAe,EAAuB,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;IACtF,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,KAAK,gBAAgB,EAAE,CAAC;QACzD,OAAO,uBAAC,qBAAI,IAAC,SAAS,EAAE,KAAK,CAAC,SAAS,YACxC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GACtE,CAAC;IACR,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,yDAAkC,EAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,MAAM,IAAA,+BAAkB,EAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,IAAA,mDAAuC,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACxJ,MAAM,WAAW,GAAG,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;IACvE,OAAO,uBAAC,iCAAgB,IAAC,IAAI,EAAE,IAAA,kCAAqB,EAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC;AAC3L,CAAC,CAAC,CAAC;AACH,uBAAe,CAAC,WAAW,GAAG,iBAAiB,CAAC","sourcesContent":["// 实体列表组合件:FailureList / AttemptList / ExperimentTable。\n// 列表本体是中立 Table 原语(TableContentView);语义全部住在 compute.ts 与\n// content.ts 的投影层,docs/feature/reports/library.md。\nimport type { ExperimentComparisonScope, Sample } from \"../../../analysis/index.ts\";\nimport { sampleForExperimentComparisonScope } from \"../../../analysis/experiment-groups.ts\";\nimport { defineComponent } from \"../../definition/tree.ts\";\nimport { TableContentView, Text } from \"../../definition/primitives.tsx\";\nimport type { ReportLocale } from \"../../model/locale.ts\";\nimport { attemptListData, experimentListData, type AttemptListItem, type ExperimentListItem, } from \"./compute.ts\";\nimport { attemptListContent, experimentListContent } from \"./content.ts\";\nimport { experimentListEvaluationKindComposition } from \"../../model/format.ts\";\nexport { attemptListData, experimentListData, experimentEvalLayout, relativeEvalLabel, } from \"./compute.ts\";\nexport type { AttemptListItem, EvalLayoutNode, EvaluationKindComposition, ExperimentListEvalRow, ExperimentListItem, ExperimentMetrics, } from \"./compute.ts\";\nexport { attemptListContent, experimentListContent } from \"./content.ts\";\nexport interface FailureListProps {\n readonly limit?: number;\n /** 显式 Sample;省略时用当前组合上下文的 `ctx.scope`。 */\n readonly input?: Sample;\n /** 已闭合的行;省略时按 `input` 计算。 */\n readonly rows?: readonly AttemptListItem[];\n readonly locale?: ReportLocale;\n readonly className?: string;\n}\n/** 失败处理台:只列 failed / errored attempt,按 startedAt 新到旧、locator 升序收口。 */\nexport const FailureList = defineComponent<FailureListProps>(async (props, ctx) => {\n const sample = props.input ?? ctx.scope;\n const all = props.rows ?? await attemptListData(sample, ctx.report.pricing);\n const failures = all\n .filter((item) => item.verdict === \"failed\" || item.verdict === \"errored\")\n .sort((left, right) => {\n const leftStarted = left.startedAt ?? Number.NEGATIVE_INFINITY;\n const rightStarted = right.startedAt ?? Number.NEGATIVE_INFINITY;\n if (leftStarted !== rightStarted)\n return leftStarted > rightStarted ? -1 : 1;\n return left.locator < right.locator ? -1 : left.locator > right.locator ? 1 : 0;\n });\n const limit = props.limit ?? 20;\n return <TableContentView data={attemptListContent(failures.slice(0, limit))} locale={props.locale} className={props.className}/>;\n});\nFailureList.displayName = \"FailureList\";\nexport interface AttemptListProps {\n /** 显式 Sample;省略时用当前组合上下文的 `ctx.scope`。 */\n readonly input?: Sample;\n /** 已闭合的行;省略时按 `input` 计算。 */\n readonly rows?: readonly AttemptListItem[];\n readonly locale?: ReportLocale;\n readonly className?: string;\n}\n/** 薄组合:attemptListData + Table。顺序保持传入顺序(不重排)。 */\nexport const AttemptList = defineComponent<AttemptListProps>(async (props, ctx) => {\n const rows = props.rows ?? await attemptListData(props.input ?? ctx.scope, ctx.report.pricing);\n return <TableContentView data={attemptListContent(rows)} locale={props.locale} className={props.className}/>;\n});\nAttemptList.displayName = \"AttemptList\";\nexport interface ExperimentTableProps {\n readonly comparison: ExperimentComparisonScope;\n /** 显示排序列;省略时按列表自身题型选择 passRate 或 totalScore。 */\n readonly sort?: string;\n readonly searchable?: boolean;\n readonly locale?: ReportLocale;\n readonly className?: string;\n}\nexport const ExperimentTable = defineComponent<ExperimentTableProps>(async (props, ctx) => {\n if (props.comparison.comparison.state === \"non-comparable\") {\n return <Text className={props.className}>\n {props.comparison.comparison.issues.map((issue) => issue.reason).join(\", \")}\n </Text>;\n }\n const sample = sampleForExperimentComparisonScope(props.comparison);\n const rows = await experimentListData(sample, ctx.report.pricing);\n const composition = experimentListEvaluationKindComposition(rows.map((row) => ({ evaluationKind: row.evaluationKind, attempts: row.evalRows.length })));\n const defaultSort = composition === \"pass\" ? \"passRate\" : \"totalScore\";\n return <TableContentView data={experimentListContent(rows)} sort={props.sort ?? defaultSort} searchable={props.searchable ?? true} locale={props.locale} className={props.className}/>;\n});\nExperimentTable.displayName = \"ExperimentTable\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"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","sourcesContent":["// 实体列表组合件:FailureList / AttemptList / ExperimentTable。\n// 列表本体是中立 Table 原语(TableContentView);语义全部住在 compute.ts 与\n// content.ts 的投影层,docs/feature/reports/library.md。\nimport type { ExperimentComparisonScope, Sample } from \"../../../analysis/index.ts\";\nimport { sampleForExperimentComparisonScope } from \"../../../analysis/experiment-groups.ts\";\nimport { defineComponent } from \"../../definition/tree.ts\";\nimport { TableContentView, Text } from \"../../definition/primitives.tsx\";\nimport type { ReportLocale } from \"../../model/locale.ts\";\nimport { attemptListData, experimentListData, type AttemptListItem, type ExperimentListItem, } from \"./compute.ts\";\nimport { attemptListContent, experimentListContent } from \"./content.ts\";\nexport { attemptListData, experimentListData, experimentEvalLayout, relativeEvalLabel, } from \"./compute.ts\";\nexport type { AttemptListItem, EvalLayoutNode, EvaluationKindComposition, ExperimentListEvalRow, ExperimentListItem, ExperimentMetrics, } from \"./compute.ts\";\nexport { attemptListContent, experimentListContent } from \"./content.ts\";\nexport interface FailureListProps {\n readonly limit?: number;\n /** 显式 Sample;省略时用当前组合上下文的 `ctx.scope`。 */\n readonly input?: Sample;\n /** 已闭合的行;省略时按 `input` 计算。 */\n readonly rows?: readonly AttemptListItem[];\n readonly locale?: ReportLocale;\n readonly className?: string;\n}\n/** 失败处理台:只列 failed / errored attempt,按 startedAt 新到旧、locator 升序收口。 */\nexport const FailureList = defineComponent<FailureListProps>(async (props, ctx) => {\n const sample = props.input ?? ctx.scope;\n const all = props.rows ?? await attemptListData(sample, ctx.report.pricing);\n const failures = all\n .filter((item) => item.verdict === \"failed\" || item.verdict === \"errored\")\n .sort((left, right) => {\n const leftStarted = left.startedAt ?? Number.NEGATIVE_INFINITY;\n const rightStarted = right.startedAt ?? Number.NEGATIVE_INFINITY;\n if (leftStarted !== rightStarted)\n return leftStarted > rightStarted ? -1 : 1;\n return left.locator < right.locator ? -1 : left.locator > right.locator ? 1 : 0;\n });\n const limit = props.limit ?? 20;\n return <TableContentView data={attemptListContent(failures.slice(0, limit))} locale={props.locale} className={props.className}/>;\n});\nFailureList.displayName = \"FailureList\";\nexport interface AttemptListProps {\n /** 显式 Sample;省略时用当前组合上下文的 `ctx.scope`。 */\n readonly input?: Sample;\n /** 已闭合的行;省略时按 `input` 计算。 */\n readonly rows?: readonly AttemptListItem[];\n readonly locale?: ReportLocale;\n readonly className?: string;\n}\n/** 薄组合:attemptListData + Table。顺序保持传入顺序(不重排)。 */\nexport const AttemptList = defineComponent<AttemptListProps>(async (props, ctx) => {\n const rows = props.rows ?? await attemptListData(props.input ?? ctx.scope, ctx.report.pricing);\n return <TableContentView data={attemptListContent(rows)} locale={props.locale} className={props.className}/>;\n});\nAttemptList.displayName = \"AttemptList\";\nexport interface ExperimentTableProps {\n readonly comparison: ExperimentComparisonScope;\n /** 显示排序列;省略时按列表自身题型选择 passRate 或 totalScore。 */\n readonly sort?: string;\n readonly searchable?: boolean;\n readonly locale?: ReportLocale;\n readonly className?: string;\n}\nexport const ExperimentTable = defineComponent<ExperimentTableProps>(async (props, ctx) => {\n if (props.comparison.comparison.state === \"non-comparable\") {\n return <Text className={props.className}>\n {props.comparison.comparison.issues.map((issue) => issue.reason).join(\", \")}\n </Text>;\n }\n const sample = sampleForExperimentComparisonScope(props.comparison);\n const rows = await experimentListData(sample, ctx.report.pricing);\n const defaultSort = \"summary\";\n return <TableContentView data={experimentListContent(rows)} sort={props.sort ?? defaultSort} searchable={props.searchable ?? true} locale={props.locale} className={props.className}/>;\n});\nExperimentTable.displayName = \"ExperimentTable\";\n"]}
@@ -18,23 +18,21 @@ function loadExperimentMetrics(sample, pricing) {
18
18
  : { passRate: metrics_ts_1.passRate, durationMs: metrics_ts_1.durationMs, tokens: metrics_ts_1.tokens, totalCostUSD: (0, metrics_ts_1.totalCostUSD)(pricing) },
19
19
  });
20
20
  }
21
- /** 一份闭合 evidence entry 的可读 sealed 断言清单(DomainView 边界是 JsonValue)。 */
21
+ /** 一份闭合 evidence entry 的 typed sealed 断言清单。 */
22
22
  function sealedEntriesOf(entry) {
23
23
  if (entry?.state !== "available")
24
24
  return [];
25
- return entry.detail.entries
26
- .map(compute_ts_1.assertionEntryViewOf)
27
- .filter((sealed) => sealed !== undefined);
25
+ return entry.detail.entries.map(compute_ts_1.assertionEntryViewOf);
28
26
  }
29
27
  /** sealed score 状态 → 题型:任一 entry 有非 not-scored 的 score 就是计分制。 */
30
28
  function evaluationKindOf(entries) {
31
- return entries.some((entry) => entry.result.score.state !== "not-scored") ? "points" : "pass";
29
+ return entries.some((entry) => entry.decision.contribution.state !== "not-scored") ? "points" : "pass";
32
30
  }
33
31
  /** 闭合断言 entries 的本轮挣分合计(纯闭合值求和,无分母语义)。 */
34
32
  function earnedTotalOf(entries) {
35
33
  let total = 0;
36
34
  for (const entry of entries) {
37
- const score = entry.result.score;
35
+ const score = entry.decision.contribution;
38
36
  if (score.state === "earned" && score.earned !== undefined)
39
37
  total += score.earned;
40
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compute.js","sourceRoot":"","sources":["compute.ts"],"names":[],"mappings":"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","sourcesContent":["// Experiment 详情组合件的计算函数(docs/feature/reports/library.md)。\n// `experimentDetailsData(sample, experimentId)` 把固定 Sample 上属于该 experiment 的闭合\n// rows / DomainView 折成六区块共享的一份普通值;六区块只投影这份结果,不各自取数。组件源码\n// 取不到 Record reader、path、AttemptHandle 或 Effect Scope。\nimport { aggregate, attemptEvidenceView, query, type AttemptEvidenceDomainView, type CostMetricValue, type ExperimentId, type JsonValue, type MetricValue, type PricingProfile, type Sample, type SampleSnapshot, } from \"../../../analysis/index.ts\";\nimport type { VerdictState } from \"../../../eval/record/verdict.ts\";\nimport type { AttemptLocator } from \"../../../attempt-locator.ts\";\nimport { experiment } from \"../../model/aggregate.ts\";\nimport { durationMs, passRate, tokens, totalCostUSD } from \"../../model/metrics.ts\";\nimport { experimentListEvaluationKindComposition } from \"../../model/format.ts\";\nimport type { CalloutGroup } from \"../../definition/primitives/callouts-logic.ts\";\nimport type { VerdictCounts } from \"../../definition/cell.ts\";\nimport { assertionEntryViewOf, type SealedAssertionEntryView, } from \"../attempt-detail/compute.ts\";\nexport interface ExperimentIdentityView {\n readonly experimentId: ExperimentId;\n readonly agent: string;\n readonly model?: string;\n readonly reasoningEffort?: string;\n readonly flags?: Readonly<Record<string, JsonValue>>;\n}\n/** 读数摘要:全部是 Analysis 已关闭的 MetricValue,或闭合证据派生的展示值。 */\nexport interface ExperimentMetricsView {\n readonly passRate?: MetricValue;\n /** 计分制合计挣分(闭合断言 entries 的 earned 求和);通过制省略。 */\n readonly totalScore?: number;\n readonly costUSD?: CostMetricValue;\n readonly tokens?: MetricValue;\n readonly durationMs?: MetricValue;\n}\nexport interface ExperimentAttemptView {\n readonly locator: AttemptLocator;\n readonly attemptOrdinal: number;\n readonly verdict: VerdictState | \"unknown\";\n}\nexport interface ExperimentEvalView {\n readonly evalId: string;\n readonly verdict: VerdictState | \"unknown\";\n readonly attempts: readonly ExperimentAttemptView[];\n}\nexport interface ExperimentDetailsView {\n readonly identity: ExperimentIdentityView;\n readonly evaluationKind: \"pass\" | \"points\" | \"mixed\";\n /** 该 experiment 最近一次 selected run 的完成时间(epoch ms);没有 run 时为 null。 */\n readonly lastRunAt: number | null;\n readonly evals: number;\n readonly attempts: number;\n readonly evalVerdicts: VerdictCounts;\n readonly metrics: ExperimentMetricsView;\n /** Eval → Attempt 层级清单,供题目清单表格。 */\n readonly evalsView: readonly ExperimentEvalView[];\n readonly missingEvalIds: readonly string[];\n}\nexport interface ExperimentDetailsData {\n readonly experiment: ExperimentDetailsView;\n readonly catchUpCommand: string | null;\n readonly notices: readonly CalloutGroup[];\n readonly diagnostics: readonly CalloutGroup[];\n}\nexport type ExperimentMetricRow = Awaited<ReturnType<typeof loadExperimentMetrics>>[number];\ntype IncludedSlot = Extract<SampleSnapshot[\"slots\"][number], {\n readonly state: \"included\";\n}>;\ntype NotRecordedSlot = Extract<SampleSnapshot[\"slots\"][number], {\n readonly state: \"not-recorded\";\n}>;\ntype EvidenceEntry = AttemptEvidenceDomainView[\"entries\"][number];\nfunction loadExperimentMetrics(sample: Sample, pricing: PricingProfile | null) {\n return aggregate(sample, {\n by: { experiment },\n values: pricing === null\n ? { passRate, durationMs, tokens }\n : { passRate, durationMs, tokens, totalCostUSD: totalCostUSD(pricing) },\n });\n}\n/** 一份闭合 evidence entry 的可读 sealed 断言清单(DomainView 边界是 JsonValue)。 */\nfunction sealedEntriesOf(entry: EvidenceEntry | undefined): readonly SealedAssertionEntryView[] {\n if (entry?.state !== \"available\")\n return [];\n return entry.detail.entries\n .map(assertionEntryViewOf)\n .filter((sealed): sealed is SealedAssertionEntryView => sealed !== undefined);\n}\n/** sealed score 状态 → 题型:任一 entry 有非 not-scored 的 score 就是计分制。 */\nfunction evaluationKindOf(entries: readonly SealedAssertionEntryView[]): \"pass\" | \"points\" {\n return entries.some((entry) => entry.result.score.state !== \"not-scored\") ? \"points\" : \"pass\";\n}\n/** 闭合断言 entries 的本轮挣分合计(纯闭合值求和,无分母语义)。 */\nfunction earnedTotalOf(entries: readonly SealedAssertionEntryView[]): number {\n let total = 0;\n for (const entry of entries) {\n const score = entry.result.score;\n if (score.state === \"earned\" && score.earned !== undefined)\n total += score.earned;\n }\n return total;\n}\nfunction evidenceEntryOf(evidence: AttemptEvidenceDomainView, locator: AttemptLocator): EvidenceEntry | undefined {\n return evidence.entries.find((entry) => entry.attempt.locator === locator);\n}\nfunction verdictOf(entry: EvidenceEntry | undefined): VerdictState | \"unknown\" {\n return entry?.state === \"available\" ? entry.detail.verdict : \"unknown\";\n}\nfunction experimentSlots(sample: Sample, experimentId: ExperimentId) {\n return sample.snapshot.slots.filter((slot) => slot.state !== \"excluded\" && slot.experimentId === experimentId);\n}\nfunction experimentRuns(sample: Sample, experimentId: ExperimentId) {\n return sample.snapshot.runs.filter((run) => run.experimentId === experimentId);\n}\nfunction identityOf(sample: Sample, experimentId: ExperimentId): ExperimentIdentityView {\n const runWithContext = experimentRuns(sample, experimentId).find((run) => run.context !== null);\n const context = runWithContext?.context;\n const model = context?.execution.model;\n const reasoningEffort = context?.execution.reasoningEffort;\n return {\n experimentId,\n agent: context?.execution.agentId ?? \"unknown\",\n ...(model === null || model === undefined ? {} : { model }),\n ...(reasoningEffort === null || reasoningEffort === undefined ? {} : { reasoningEffort }),\n ...(context === undefined || context === null ? {} : { flags: context.execution.flags }),\n };\n}\nfunction lastRunAtOf(sample: Sample, experimentId: ExperimentId): number | null {\n const runs = experimentRuns(sample, experimentId);\n if (runs.length === 0)\n return null;\n return runs.reduce((latest, run) => (run.completedAt > latest ? run.completedAt : latest), runs[0]!.completedAt);\n}\nfunction evalsViewOf(sample: Sample, experimentId: ExperimentId, evidence: AttemptEvidenceDomainView): ExperimentEvalView[] {\n const slots = experimentSlots(sample, experimentId);\n const byEval = new Map<string, IncludedSlot[]>();\n for (const slot of slots) {\n if (slot.state !== \"included\")\n continue;\n const list = byEval.get(slot.evalId) ?? [];\n list.push(slot);\n byEval.set(slot.evalId, list);\n }\n const rows: ExperimentEvalView[] = [];\n for (const [evalId, members] of [...byEval.entries()].sort(([left], [right]) => compareText(left, right))) {\n // 每个 eval 的判定取最高 attempt 序号的那条 included attempt(closed verdict 是\n // terminal fact,不重跑 fold)。\n const attempts = [...members].sort((left, right) => left.attemptOrdinal - right.attemptOrdinal).map((slot) => ({\n locator: slot.attempt.locator,\n attemptOrdinal: slot.attemptOrdinal,\n verdict: verdictOf(evidenceEntryOf(evidence, slot.attempt.locator)),\n }));\n const evalVerdict = attempts.at(-1)?.verdict ?? \"unknown\";\n rows.push({ evalId, verdict: evalVerdict, attempts });\n }\n return rows;\n}\nfunction evalVerdictsOf(evals: readonly ExperimentEvalView[]): VerdictCounts {\n const counts: Record<VerdictState, number> = { passed: 0, failed: 0, errored: 0, skipped: 0 };\n for (const row of evals) {\n if (row.verdict === \"unknown\")\n continue;\n counts[row.verdict] += 1;\n }\n return counts;\n}\nfunction missingEvalIdsOf(sample: Sample, experimentId: ExperimentId): readonly string[] {\n const ids = new Set<string>();\n for (const slot of experimentSlots(sample, experimentId)) {\n if (slot.state === \"not-recorded\")\n ids.add((slot as NotRecordedSlot).evalId);\n if (slot.state === \"core-invalid\")\n ids.add(slot.evalId);\n }\n return Object.freeze([...ids].sort(compareText));\n}\n/** sample 选择问题 + 实验缺口 → notices;Analysis issues → diagnostics。 */\nfunction noticesOf(sample: Sample, experimentId: ExperimentId, evidence: AttemptEvidenceDomainView): readonly CalloutGroup[] {\n const groups: CalloutGroup[] = [];\n for (const problem of sample.snapshot.selection.problems) {\n groups.push({\n title: \"Sample selection\",\n items: [{ level: \"warning\", message: `${problem.code}: ${problem.runId}` }],\n });\n }\n const missing = missingEvalIdsOf(sample, experimentId);\n if (missing.length > 0) {\n groups.push({\n title: \"Coverage gaps\",\n items: [{ level: \"warning\", message: `${missing.length} eval(s) without an Attempt in this experiment.` }],\n });\n }\n const experimentLocators = new Set(experimentSlots(sample, experimentId)\n .filter((slot): slot is IncludedSlot => slot.state === \"included\")\n .map((slot) => slot.attempt.locator));\n for (const entry of evidence.entries) {\n if (entry.state === \"available\" || !experimentLocators.has(entry.attempt.locator))\n continue;\n groups.push({\n title: \"Closed assertion evidence\",\n items: [{ level: \"warning\", message: `${entry.attempt.locator}: entry state ${entry.state}.` }],\n });\n }\n return groups;\n}\nfunction diagnosticsOf(metrics: readonly ExperimentMetricRow[], evidence: AttemptEvidenceDomainView, experimentId: ExperimentId): readonly CalloutGroup[] {\n const groups: CalloutGroup[] = [];\n const row = metrics.find((entry) => entry.experiment === experimentId);\n const metricIssues = row === undefined\n ? []\n : Object.values(row).flatMap((value) => typeof value === \"object\" && value !== null &&\n \"issues\" in value && Array.isArray((value as {\n issues: unknown;\n }).issues)\n ? (value as {\n issues: readonly {\n code: string;\n message: string;\n }[];\n }).issues\n : []);\n const issues = [...metricIssues, ...evidence.issues];\n if (issues.length === 0)\n return groups;\n groups.push({\n title: \"Analysis issues\",\n items: issues.map((issue) => ({ level: \"warning\" as const, message: `${issue.code}: ${issue.message}` })),\n });\n return groups;\n}\n/**\n * 收窄目标必须恰好属于当前固定 Sample:不在 sample 里按完整用户反馈报错,不静默取第一个\n * experiment——把调用方的收窄 bug 藏成错数据。\n */\nexport async function experimentDetailsData(sample: Sample, experimentId: ExperimentId, pricing: PricingProfile | null = null): Promise<ExperimentDetailsData> {\n const present = sample.snapshot.slots.some((slot) => slot.state !== \"excluded\" && slot.experimentId === experimentId);\n if (!present) {\n throw new Error(`ExperimentDetails received experiment \"${experimentId}\" which is not a member of the fixed Sample. ` +\n \"Pass an experimentId that belongs to the current Sample.\");\n }\n const [metrics, evidence] = await Promise.all([\n loadExperimentMetrics(sample, pricing),\n query(sample, { kind: \"domain-view\", view: attemptEvidenceView }),\n ]);\n const row = metrics.find((entry) => entry.experiment === experimentId);\n const included = experimentSlots(sample, experimentId).filter((slot): slot is IncludedSlot => slot.state === \"included\");\n const evalsView = evalsViewOf(sample, experimentId, evidence);\n const evidenceById = new Map<string, EvidenceEntry>();\n for (const entry of evidence.entries)\n evidenceById.set(entry.attempt.locator, entry);\n const kindByEval = new Map<string, \"pass\" | \"points\">();\n for (const evalEntry of evalsView) {\n for (const attempt of evalEntry.attempts) {\n const entry = evidenceById.get(attempt.locator);\n if (entry?.state === \"available\") {\n kindByEval.set(evalEntry.evalId, evaluationKindOf(sealedEntriesOf(entry)));\n break;\n }\n }\n }\n const evaluationKind = experimentListEvaluationKindComposition(evalsView.map((entry) => ({ evaluationKind: kindByEval.get(entry.evalId) ?? \"pass\", attempts: entry.attempts.length })));\n const scored = evalsView.flatMap((entry) => entry.attempts)\n .map((attempt) => evidenceById.get(attempt.locator))\n .reduce((sum, entry) => sum + earnedTotalOf(sealedEntriesOf(entry)), 0);\n const hasPoints = evalsView.some((entry) => kindByEval.get(entry.evalId) === \"points\");\n const experiment: ExperimentDetailsView = {\n identity: identityOf(sample, experimentId),\n evaluationKind,\n lastRunAt: lastRunAtOf(sample, experimentId),\n evals: evalsView.length,\n attempts: included.length,\n evalVerdicts: evalVerdictsOf(evalsView),\n metrics: {\n ...(row === undefined || evaluationKind === \"points\" ? {} : { passRate: row.passRate }),\n ...(row === undefined ? {} : {\n ...(pricing === null ? {} : { costUSD: (row as unknown as {\n readonly totalCostUSD: CostMetricValue;\n }).totalCostUSD }),\n tokens: row.tokens,\n durationMs: row.durationMs,\n }),\n ...(hasPoints ? { totalScore: scored } : {}),\n },\n evalsView,\n missingEvalIds: missingEvalIdsOf(sample, experimentId),\n };\n return {\n experiment,\n catchUpCommand: experiment.missingEvalIds.length > 0 ? `niceeval exp ${experimentId}` : null,\n notices: noticesOf(sample, experimentId, evidence),\n diagnostics: diagnosticsOf(metrics, evidence, experimentId),\n };\n}\nfunction compareText(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0;\n}\n"]}
1
+ {"version":3,"file":"compute.js","sourceRoot":"","sources":["compute.ts"],"names":[],"mappings":";;AAkOA,sDA0DC;AA5RD,0DAA0D;AAC1D,+EAA+E;AAC/E,wDAAwD;AACxD,uDAAuD;AACvD,yDAAsP;AAGtP,2DAAsD;AACtD,uDAAoF;AACpF,qDAAgF;AAGhF,6DAAoG;AAsDpG,SAAS,qBAAqB,CAAC,MAAc,EAAE,OAA8B;IACzE,OAAO,IAAA,oBAAS,EAAC,MAAM,EAAE;QACrB,EAAE,EAAE,EAAE,UAAU,EAAV,yBAAU,EAAE;QAClB,MAAM,EAAE,OAAO,KAAK,IAAI;YACpB,CAAC,CAAC,EAAE,QAAQ,EAAR,qBAAQ,EAAE,UAAU,EAAV,uBAAU,EAAE,MAAM,EAAN,mBAAM,EAAE;YAClC,CAAC,CAAC,EAAE,QAAQ,EAAR,qBAAQ,EAAE,UAAU,EAAV,uBAAU,EAAE,MAAM,EAAN,mBAAM,EAAE,YAAY,EAAE,IAAA,yBAAY,EAAC,OAAO,CAAC,EAAE;KAC9E,CAAC,CAAC;AACP,CAAC;AACD,+CAA+C;AAC/C,SAAS,eAAe,CAAC,KAAgC;IACrD,IAAI,KAAK,EAAE,KAAK,KAAK,WAAW;QAC5B,OAAO,EAAE,CAAC;IACd,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iCAAoB,CAAC,CAAC;AAC1D,CAAC;AACD,iEAAiE;AACjE,SAAS,gBAAgB,CAAC,OAA4C;IAClE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;AAC3G,CAAC;AACD,0CAA0C;AAC1C,SAAS,aAAa,CAAC,OAA4C;IAC/D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC1C,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YACtD,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AACD,SAAS,eAAe,CAAC,QAAmC,EAAE,OAAuB;IACjF,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;AAC/E,CAAC;AACD,SAAS,SAAS,CAAC,KAAgC;IAC/C,OAAO,KAAK,EAAE,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC;AACD,SAAS,eAAe,CAAC,MAAc,EAAE,YAA0B;IAC/D,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC;AACnH,CAAC;AACD,SAAS,cAAc,CAAC,MAAc,EAAE,YAA0B;IAC9D,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC;AACnF,CAAC;AACD,SAAS,UAAU,CAAC,MAAc,EAAE,YAA0B;IAC1D,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;IAChG,MAAM,OAAO,GAAG,cAAc,EAAE,OAAO,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC;IACvC,MAAM,eAAe,GAAG,OAAO,EAAE,SAAS,CAAC,eAAe,CAAC;IAC3D,OAAO;QACH,YAAY;QACZ,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,SAAS;QAC9C,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QAC3D,GAAG,CAAC,eAAe,KAAK,IAAI,IAAI,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;QACzF,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;KAC3F,CAAC;AACN,CAAC;AACD,SAAS,WAAW,CAAC,MAAc,EAAE,YAA0B;IAC3D,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QACjB,OAAO,IAAI,CAAC;IAChB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,WAAW,CAAC,CAAC;AACrH,CAAC;AACD,SAAS,WAAW,CAAC,MAAc,EAAE,YAA0B,EAAE,QAAmC;IAChG,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,KAAK,UAAU;YACzB,SAAS;QACb,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,IAAI,GAAyB,EAAE,CAAC;IACtC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;QACxG,iEAAiE;QACjE,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC3G,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,OAAO,EAAE,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SACtE,CAAC,CAAC,CAAC;QACJ,MAAM,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,SAAS,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AACD,SAAS,cAAc,CAAC,KAAoC;IACxD,MAAM,MAAM,GAAiC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC9F,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS;YACzB,SAAS;QACb,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AACD,SAAS,gBAAgB,CAAC,MAAc,EAAE,YAA0B;IAChE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC;QACvD,IAAI,IAAI,CAAC,KAAK,KAAK,cAAc;YAC7B,GAAG,CAAC,GAAG,CAAE,IAAwB,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,KAAK,KAAK,cAAc;YAC7B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;AACrD,CAAC;AACD,kEAAkE;AAClE,SAAS,SAAS,CAAC,MAAc,EAAE,YAA0B,EAAE,QAAmC;IAC9F,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC;YACR,KAAK,EAAE,kBAAkB;YACzB,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAC9E,CAAC,CAAC;IACP,CAAC;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC;YACR,KAAK,EAAE,eAAe;YACtB,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,iDAAiD,EAAE,CAAC;SAC7G,CAAC,CAAC;IACP,CAAC;IACD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC;SACnE,MAAM,CAAC,CAAC,IAAI,EAAwB,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC;SACjE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAC7E,SAAS;QACb,MAAM,CAAC,IAAI,CAAC;YACR,KAAK,EAAE,2BAA2B;YAClC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,iBAAiB,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;SAClG,CAAC,CAAC;IACP,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AACD,SAAS,aAAa,CAAC,OAAuC,EAAE,QAAmC,EAAE,YAA0B;IAC3H,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC;IACvE,MAAM,YAAY,GAAG,GAAG,KAAK,SAAS;QAClC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAC/E,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,CAAE,KAEtC,CAAC,MAAM,CAAC;YACN,CAAC,CAAE,KAKD,CAAC,MAAM;YACT,CAAC,CAAC,EAAE,CAAC,CAAC;IACd,MAAM,MAAM,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QACnB,OAAO,MAAM,CAAC;IAClB,MAAM,CAAC,IAAI,CAAC;QACR,KAAK,EAAE,iBAAiB;QACxB,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,SAAkB,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;KAC5G,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAClB,CAAC;AACD;;;GAGG;AACI,KAAK,UAAU,qBAAqB,CAAC,MAAc,EAAE,YAA0B,EAAE,UAAiC,IAAI;IACzH,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC;IACtH,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,0CAA0C,YAAY,+CAA+C;YACjH,0DAA0D,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1C,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC;QACtC,IAAA,gBAAK,EAAC,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,8BAAmB,EAAE,CAAC;KACpE,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAwB,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC;IACzH,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,IAAI,GAAG,EAAyB,CAAC;IACtD,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO;QAChC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,GAAG,EAA6B,CAAC;IACxD,KAAK,MAAM,SAAS,IAAI,SAAS,EAAE,CAAC;QAChC,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAChD,IAAI,KAAK,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;gBAC/B,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,gBAAgB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3E,MAAM;YACV,CAAC;QACL,CAAC;IACL,CAAC;IACD,MAAM,cAAc,GAAG,IAAA,mDAAuC,EAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACxL,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;SACtD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SACnD,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5E,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC;IACvF,MAAM,UAAU,GAA0B;QACtC,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC;QAC1C,cAAc;QACd,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC;QAC5C,KAAK,EAAE,SAAS,CAAC,MAAM;QACvB,QAAQ,EAAE,QAAQ,CAAC,MAAM;QACzB,YAAY,EAAE,cAAc,CAAC,SAAS,CAAC;QACvC,OAAO,EAAE;YACL,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;YACvF,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzB,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAG,GAElC,CAAC,YAAY,EAAE,CAAC;gBACtB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,UAAU,EAAE,GAAG,CAAC,UAAU;aAC7B,CAAC;YACF,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/C;QACD,SAAS;QACT,cAAc,EAAE,gBAAgB,CAAC,MAAM,EAAE,YAAY,CAAC;KACzD,CAAC;IACF,OAAO;QACH,UAAU;QACV,cAAc,EAAE,UAAU,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI;QAC5F,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC;QAClD,WAAW,EAAE,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC;KAC9D,CAAC;AACN,CAAC;AACD,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa;IAC5C,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC","sourcesContent":["// Experiment 详情组合件的计算函数(docs/feature/reports/library.md)。\n// `experimentDetailsData(sample, experimentId)` 把固定 Sample 上属于该 experiment 的闭合\n// rows / DomainView 折成六区块共享的一份普通值;六区块只投影这份结果,不各自取数。组件源码\n// 取不到 Record reader、path、AttemptHandle 或 Effect Scope。\nimport { aggregate, attemptEvidenceView, query, type AttemptEvidenceDomainView, type CostMetricValue, type ExperimentId, type JsonValue, type MetricValue, type PricingProfile, type Sample, type SampleSnapshot, } from \"../../../analysis/index.ts\";\nimport type { VerdictState } from \"../../../eval/record/verdict.ts\";\nimport type { AttemptLocator } from \"../../../attempt-locator.ts\";\nimport { experiment } from \"../../model/aggregate.ts\";\nimport { durationMs, passRate, tokens, totalCostUSD } from \"../../model/metrics.ts\";\nimport { experimentListEvaluationKindComposition } from \"../../model/format.ts\";\nimport type { CalloutGroup } from \"../../definition/primitives/callouts-logic.ts\";\nimport type { VerdictCounts } from \"../../definition/cell.ts\";\nimport { assertionEntryViewOf, type SealedAssertionEntryView, } from \"../attempt-detail/compute.ts\";\nexport interface ExperimentIdentityView {\n readonly experimentId: ExperimentId;\n readonly agent: string;\n readonly model?: string;\n readonly reasoningEffort?: string;\n readonly flags?: Readonly<Record<string, JsonValue>>;\n}\n/** 读数摘要:全部是 Analysis 已关闭的 MetricValue,或闭合证据派生的展示值。 */\nexport interface ExperimentMetricsView {\n readonly passRate?: MetricValue;\n /** 计分制合计挣分(闭合断言 entries 的 earned 求和);通过制省略。 */\n readonly totalScore?: number;\n readonly costUSD?: CostMetricValue;\n readonly tokens?: MetricValue;\n readonly durationMs?: MetricValue;\n}\nexport interface ExperimentAttemptView {\n readonly locator: AttemptLocator;\n readonly attemptOrdinal: number;\n readonly verdict: VerdictState | \"unknown\";\n}\nexport interface ExperimentEvalView {\n readonly evalId: string;\n readonly verdict: VerdictState | \"unknown\";\n readonly attempts: readonly ExperimentAttemptView[];\n}\nexport interface ExperimentDetailsView {\n readonly identity: ExperimentIdentityView;\n readonly evaluationKind: \"pass\" | \"points\" | \"mixed\";\n /** 该 experiment 最近一次 selected run 的完成时间(epoch ms);没有 run 时为 null。 */\n readonly lastRunAt: number | null;\n readonly evals: number;\n readonly attempts: number;\n readonly evalVerdicts: VerdictCounts;\n readonly metrics: ExperimentMetricsView;\n /** Eval → Attempt 层级清单,供题目清单表格。 */\n readonly evalsView: readonly ExperimentEvalView[];\n readonly missingEvalIds: readonly string[];\n}\nexport interface ExperimentDetailsData {\n readonly experiment: ExperimentDetailsView;\n readonly catchUpCommand: string | null;\n readonly notices: readonly CalloutGroup[];\n readonly diagnostics: readonly CalloutGroup[];\n}\nexport type ExperimentMetricRow = Awaited<ReturnType<typeof loadExperimentMetrics>>[number];\ntype IncludedSlot = Extract<SampleSnapshot[\"slots\"][number], {\n readonly state: \"included\";\n}>;\ntype NotRecordedSlot = Extract<SampleSnapshot[\"slots\"][number], {\n readonly state: \"not-recorded\";\n}>;\ntype EvidenceEntry = AttemptEvidenceDomainView[\"entries\"][number];\nfunction loadExperimentMetrics(sample: Sample, pricing: PricingProfile | null) {\n return aggregate(sample, {\n by: { experiment },\n values: pricing === null\n ? { passRate, durationMs, tokens }\n : { passRate, durationMs, tokens, totalCostUSD: totalCostUSD(pricing) },\n });\n}\n/** 一份闭合 evidence entry 的 typed sealed 断言清单。 */\nfunction sealedEntriesOf(entry: EvidenceEntry | undefined): readonly SealedAssertionEntryView[] {\n if (entry?.state !== \"available\")\n return [];\n return entry.detail.entries.map(assertionEntryViewOf);\n}\n/** sealed score 状态 → 题型:任一 entry 有非 not-scored 的 score 就是计分制。 */\nfunction evaluationKindOf(entries: readonly SealedAssertionEntryView[]): \"pass\" | \"points\" {\n return entries.some((entry) => entry.decision.contribution.state !== \"not-scored\") ? \"points\" : \"pass\";\n}\n/** 闭合断言 entries 的本轮挣分合计(纯闭合值求和,无分母语义)。 */\nfunction earnedTotalOf(entries: readonly SealedAssertionEntryView[]): number {\n let total = 0;\n for (const entry of entries) {\n const score = entry.decision.contribution;\n if (score.state === \"earned\" && score.earned !== undefined)\n total += score.earned;\n }\n return total;\n}\nfunction evidenceEntryOf(evidence: AttemptEvidenceDomainView, locator: AttemptLocator): EvidenceEntry | undefined {\n return evidence.entries.find((entry) => entry.attempt.locator === locator);\n}\nfunction verdictOf(entry: EvidenceEntry | undefined): VerdictState | \"unknown\" {\n return entry?.state === \"available\" ? entry.detail.verdict : \"unknown\";\n}\nfunction experimentSlots(sample: Sample, experimentId: ExperimentId) {\n return sample.snapshot.slots.filter((slot) => slot.state !== \"excluded\" && slot.experimentId === experimentId);\n}\nfunction experimentRuns(sample: Sample, experimentId: ExperimentId) {\n return sample.snapshot.runs.filter((run) => run.experimentId === experimentId);\n}\nfunction identityOf(sample: Sample, experimentId: ExperimentId): ExperimentIdentityView {\n const runWithContext = experimentRuns(sample, experimentId).find((run) => run.context !== null);\n const context = runWithContext?.context;\n const model = context?.execution.model;\n const reasoningEffort = context?.execution.reasoningEffort;\n return {\n experimentId,\n agent: context?.execution.agentId ?? \"unknown\",\n ...(model === null || model === undefined ? {} : { model }),\n ...(reasoningEffort === null || reasoningEffort === undefined ? {} : { reasoningEffort }),\n ...(context === undefined || context === null ? {} : { flags: context.execution.flags }),\n };\n}\nfunction lastRunAtOf(sample: Sample, experimentId: ExperimentId): number | null {\n const runs = experimentRuns(sample, experimentId);\n if (runs.length === 0)\n return null;\n return runs.reduce((latest, run) => (run.completedAt > latest ? run.completedAt : latest), runs[0]!.completedAt);\n}\nfunction evalsViewOf(sample: Sample, experimentId: ExperimentId, evidence: AttemptEvidenceDomainView): ExperimentEvalView[] {\n const slots = experimentSlots(sample, experimentId);\n const byEval = new Map<string, IncludedSlot[]>();\n for (const slot of slots) {\n if (slot.state !== \"included\")\n continue;\n const list = byEval.get(slot.evalId) ?? [];\n list.push(slot);\n byEval.set(slot.evalId, list);\n }\n const rows: ExperimentEvalView[] = [];\n for (const [evalId, members] of [...byEval.entries()].sort(([left], [right]) => compareText(left, right))) {\n // 每个 eval 的判定取最高 attempt 序号的那条 included attempt(closed verdict 是\n // terminal fact,不重跑 fold)。\n const attempts = [...members].sort((left, right) => left.attemptOrdinal - right.attemptOrdinal).map((slot) => ({\n locator: slot.attempt.locator,\n attemptOrdinal: slot.attemptOrdinal,\n verdict: verdictOf(evidenceEntryOf(evidence, slot.attempt.locator)),\n }));\n const evalVerdict = attempts.at(-1)?.verdict ?? \"unknown\";\n rows.push({ evalId, verdict: evalVerdict, attempts });\n }\n return rows;\n}\nfunction evalVerdictsOf(evals: readonly ExperimentEvalView[]): VerdictCounts {\n const counts: Record<VerdictState, number> = { passed: 0, failed: 0, errored: 0, skipped: 0 };\n for (const row of evals) {\n if (row.verdict === \"unknown\")\n continue;\n counts[row.verdict] += 1;\n }\n return counts;\n}\nfunction missingEvalIdsOf(sample: Sample, experimentId: ExperimentId): readonly string[] {\n const ids = new Set<string>();\n for (const slot of experimentSlots(sample, experimentId)) {\n if (slot.state === \"not-recorded\")\n ids.add((slot as NotRecordedSlot).evalId);\n if (slot.state === \"core-invalid\")\n ids.add(slot.evalId);\n }\n return Object.freeze([...ids].sort(compareText));\n}\n/** sample 选择问题 + 实验缺口 → notices;Analysis issues → diagnostics。 */\nfunction noticesOf(sample: Sample, experimentId: ExperimentId, evidence: AttemptEvidenceDomainView): readonly CalloutGroup[] {\n const groups: CalloutGroup[] = [];\n for (const problem of sample.snapshot.selection.problems) {\n groups.push({\n title: \"Sample selection\",\n items: [{ level: \"warning\", message: `${problem.code}: ${problem.runId}` }],\n });\n }\n const missing = missingEvalIdsOf(sample, experimentId);\n if (missing.length > 0) {\n groups.push({\n title: \"Coverage gaps\",\n items: [{ level: \"warning\", message: `${missing.length} eval(s) without an Attempt in this experiment.` }],\n });\n }\n const experimentLocators = new Set(experimentSlots(sample, experimentId)\n .filter((slot): slot is IncludedSlot => slot.state === \"included\")\n .map((slot) => slot.attempt.locator));\n for (const entry of evidence.entries) {\n if (entry.state === \"available\" || !experimentLocators.has(entry.attempt.locator))\n continue;\n groups.push({\n title: \"Closed assertion evidence\",\n items: [{ level: \"warning\", message: `${entry.attempt.locator}: entry state ${entry.state}.` }],\n });\n }\n return groups;\n}\nfunction diagnosticsOf(metrics: readonly ExperimentMetricRow[], evidence: AttemptEvidenceDomainView, experimentId: ExperimentId): readonly CalloutGroup[] {\n const groups: CalloutGroup[] = [];\n const row = metrics.find((entry) => entry.experiment === experimentId);\n const metricIssues = row === undefined\n ? []\n : Object.values(row).flatMap((value) => typeof value === \"object\" && value !== null &&\n \"issues\" in value && Array.isArray((value as {\n issues: unknown;\n }).issues)\n ? (value as {\n issues: readonly {\n code: string;\n message: string;\n }[];\n }).issues\n : []);\n const issues = [...metricIssues, ...evidence.issues];\n if (issues.length === 0)\n return groups;\n groups.push({\n title: \"Analysis issues\",\n items: issues.map((issue) => ({ level: \"warning\" as const, message: `${issue.code}: ${issue.message}` })),\n });\n return groups;\n}\n/**\n * 收窄目标必须恰好属于当前固定 Sample:不在 sample 里按完整用户反馈报错,不静默取第一个\n * experiment——把调用方的收窄 bug 藏成错数据。\n */\nexport async function experimentDetailsData(sample: Sample, experimentId: ExperimentId, pricing: PricingProfile | null = null): Promise<ExperimentDetailsData> {\n const present = sample.snapshot.slots.some((slot) => slot.state !== \"excluded\" && slot.experimentId === experimentId);\n if (!present) {\n throw new Error(`ExperimentDetails received experiment \"${experimentId}\" which is not a member of the fixed Sample. ` +\n \"Pass an experimentId that belongs to the current Sample.\");\n }\n const [metrics, evidence] = await Promise.all([\n loadExperimentMetrics(sample, pricing),\n query(sample, { kind: \"domain-view\", view: attemptEvidenceView }),\n ]);\n const row = metrics.find((entry) => entry.experiment === experimentId);\n const included = experimentSlots(sample, experimentId).filter((slot): slot is IncludedSlot => slot.state === \"included\");\n const evalsView = evalsViewOf(sample, experimentId, evidence);\n const evidenceById = new Map<string, EvidenceEntry>();\n for (const entry of evidence.entries)\n evidenceById.set(entry.attempt.locator, entry);\n const kindByEval = new Map<string, \"pass\" | \"points\">();\n for (const evalEntry of evalsView) {\n for (const attempt of evalEntry.attempts) {\n const entry = evidenceById.get(attempt.locator);\n if (entry?.state === \"available\") {\n kindByEval.set(evalEntry.evalId, evaluationKindOf(sealedEntriesOf(entry)));\n break;\n }\n }\n }\n const evaluationKind = experimentListEvaluationKindComposition(evalsView.map((entry) => ({ evaluationKind: kindByEval.get(entry.evalId) ?? \"pass\", attempts: entry.attempts.length })));\n const scored = evalsView.flatMap((entry) => entry.attempts)\n .map((attempt) => evidenceById.get(attempt.locator))\n .reduce((sum, entry) => sum + earnedTotalOf(sealedEntriesOf(entry)), 0);\n const hasPoints = evalsView.some((entry) => kindByEval.get(entry.evalId) === \"points\");\n const experiment: ExperimentDetailsView = {\n identity: identityOf(sample, experimentId),\n evaluationKind,\n lastRunAt: lastRunAtOf(sample, experimentId),\n evals: evalsView.length,\n attempts: included.length,\n evalVerdicts: evalVerdictsOf(evalsView),\n metrics: {\n ...(row === undefined || evaluationKind === \"points\" ? {} : { passRate: row.passRate }),\n ...(row === undefined ? {} : {\n ...(pricing === null ? {} : { costUSD: (row as unknown as {\n readonly totalCostUSD: CostMetricValue;\n }).totalCostUSD }),\n tokens: row.tokens,\n durationMs: row.durationMs,\n }),\n ...(hasPoints ? { totalScore: scored } : {}),\n },\n evalsView,\n missingEvalIds: missingEvalIdsOf(sample, experimentId),\n };\n return {\n experiment,\n catchUpCommand: experiment.missingEvalIds.length > 0 ? `niceeval exp ${experimentId}` : null,\n notices: noticesOf(sample, experimentId, evidence),\n diagnostics: diagnosticsOf(metrics, evidence, experimentId),\n };\n}\nfunction compareText(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0;\n}\n"]}
@@ -10,6 +10,11 @@ function formatCellText(cell, locale) {
10
10
  if (cell == null)
11
11
  return "—";
12
12
  switch (cell.kind) {
13
+ case "stack":
14
+ return cell.cells
15
+ .map((entry) => formatCellText(entry, locale))
16
+ .filter((entry) => entry !== "—")
17
+ .join(" · ") || "—";
13
18
  case "notApplicable":
14
19
  return "—";
15
20
  case "missing": {
@@ -55,7 +60,8 @@ function formatCellText(cell, locale) {
55
60
  if (cell.showCoverage === false) {
56
61
  return (0, format_ts_1.formatMetricScalar)(cell.metric.value, cell.metric.unit, cell.metric.format, locale ?? locale_ts_1.DEFAULT_REPORT_LOCALE);
57
62
  }
58
- return (0, format_ts_1.formatMetricValue)(cell.metric, locale ?? locale_ts_1.DEFAULT_REPORT_LOCALE);
63
+ const display = (0, format_ts_1.formatMetricScalar)(cell.metric.value, cell.metric.unit, cell.metric.format, locale ?? locale_ts_1.DEFAULT_REPORT_LOCALE);
64
+ return `${display} · ${cell.metric.state}`;
59
65
  }
60
66
  default: {
61
67
  const _exhaustive = cell;
@@ -72,22 +78,23 @@ function flattenTableContentForText(content, locale) {
72
78
  align: (c.better ? "right" : "left"),
73
79
  }));
74
80
  const rows = [];
75
- const walk = (row, depth) => {
81
+ const walk = (row, depth, ancestorLast, isLast) => {
76
82
  const cells = {};
77
83
  for (const col of content.columns) {
78
84
  const cell = row.cells[col.key];
79
85
  let text = formatCellText(cell, locale);
80
86
  if (depth > 0 && col === content.columns[0] && text !== "—") {
81
- text = `${" ".repeat(depth)}${text}`;
87
+ const rails = ancestorLast.map((last) => last ? " " : "│ ").join("");
88
+ text = `${rails}${isLast ? "└─ " : "├─ "}${text}`;
82
89
  }
83
90
  cells[col.key] = text;
84
91
  }
85
92
  rows.push({ key: row.key, cells, variant: row.variant, depth });
86
- for (const child of row.subRows ?? [])
87
- walk(child, depth + 1);
93
+ const children = row.subRows ?? [];
94
+ const childAncestors = depth === 0 ? ancestorLast : [...ancestorLast, isLast];
95
+ children.forEach((child, index) => walk(child, depth + 1, childAncestors, index === children.length - 1));
88
96
  };
89
- for (const row of content.rows)
90
- walk(row, 0);
97
+ content.rows.forEach((row, index) => walk(row, 0, [], index === content.rows.length - 1));
91
98
  return { columns, rows };
92
99
  }
93
100
  //# sourceMappingURL=cell.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cell.js","sourceRoot":"","sources":["cell.tsx"],"names":[],"mappings":"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","sourcesContent":["// 官方表格数据协议的单元格类型(docs/feature/reports/library.md「单元格类型」)。\n// Table / Grid / Stat 共用这份判别联合;自定义 Source 要交给这些原语必须适配成这个形状。\nimport type { AttemptLocator } from \"../../attempt-locator.ts\";\nimport type { LocalizedText } from \"../../shared/types.ts\";\nimport type { Verdict } from \"../../shared/types.ts\";\nimport type { MetricValue } from \"../../analysis/index.ts\";\nimport { formatMetricScalar, formatMetricValue, missingText, verdictMark } from \"../model/format.ts\";\nimport { formatCostProjectionCellText, isCostMetricValue } from \"../model/pricing.ts\";\nimport { DEFAULT_REPORT_LOCALE, localeText, resolveLocalizedText, type ReportLocale, } from \"../model/locale.ts\";\n/** 判定计票:passed / failed / errored / skipped。 */\nexport interface VerdictCounts {\n readonly passed: number;\n readonly failed: number;\n readonly errored: number;\n readonly skipped: number;\n}\n/**\n * 官方表格一格。三条不变量:\n * - metric 格永远带证据(不得压成 text);\n * - notApplicable 与 missing 不合并;\n * - summary 的文本已在上游折好。\n */\nexport type Cell = {\n readonly kind: \"metric\";\n readonly metric: MetricValue;\n /** Hide the compact samples/total suffix only when an adjacent region presents coverage. */\n readonly showCoverage?: boolean;\n} | {\n readonly kind: \"verdict\";\n readonly verdict?: Verdict | \"skipped\";\n readonly counts?: VerdictCounts;\n /** 计票覆盖的 attempt 引用(有证据可下钻的计票格才携带,如稳定性矩阵)。 */\n readonly refs?: readonly AttemptLocator[];\n // 两种形态:counts = 判定构成计票(experiment / Eval 行);verdict = 单判定(attempt 行)。\n // 格子只带值,计票怎么来的(折叠、分桶)在实体投影侧,渲染面不算数。\n /** 单判定形态省略判定词、只留判定符(如对照矩阵逐格只放得下一个符号的场景)。 */\n readonly bare?: boolean;\n} | {\n readonly kind: \"score\";\n readonly earned: number;\n readonly possible?: number;\n} | {\n readonly kind: \"summary\";\n readonly text: string;\n readonly more?: number;\n} | {\n readonly kind: \"locator\";\n readonly locator: AttemptLocator;\n /** 有判定的 attempt 行:判定长在 locator 上(判定符 + 语义色),没有判定就省略。 */\n readonly verdict?: Verdict | \"skipped\";\n} | {\n readonly kind: \"text\";\n readonly text: string;\n readonly detail?: string;\n} | {\n readonly kind: \"notApplicable\";\n} | {\n readonly kind: \"missing\";\n readonly code: string;\n /** 补上这一格的命令,可直接复制(如 `niceeval exp <experimentId>`)。 */\n readonly detail?: string;\n};\nexport interface ColumnSpec {\n readonly key: string;\n readonly unit?: string;\n readonly better?: \"higher\" | \"lower\";\n /**\n * 列表头。text / web 两面按当前 locale 解析同一份;省略时按 key 原样显示\n * (维度值列——条件名、实验 id 这类列名即数据的列——用这一支)。\n * Table 原语自己不携带列名词表,表头只来自这里\n * (docs/feature/reports/library.md「Content 协议」)。\n */\n readonly header?: LocalizedText;\n}\n/**\n * 表行 Content。与布局原语 `Row` 组件不同名。\n * placeholder 行照常渲染,但不进任何列的聚合读数。\n * group 行的读数由自己的 subRows 聚合而来,不是一条独立事实。\n */\nexport interface TableContentRow {\n readonly key: string;\n readonly cells: Readonly<Record<string, Cell>>;\n readonly subRows?: readonly TableContentRow[];\n /** group 行的读数由自己的 subRows 聚合而来,不是一条独立事实。 */\n readonly variant?: \"normal\" | \"placeholder\" | \"group\";\n}\nexport interface TableContent {\n readonly columns: readonly ColumnSpec[];\n readonly rows: readonly TableContentRow[];\n}\n/** 把 Cell 折成 text 面可见字符串(缺数据 / 不适用统一不补成 0)。 */\nexport function formatCellText(cell: Cell | null | undefined, locale?: ReportLocale): string {\n if (cell == null)\n return \"—\";\n switch (cell.kind) {\n case \"notApplicable\":\n return \"—\";\n case \"missing\": {\n const loc = locale ?? DEFAULT_REPORT_LOCALE;\n const reason = missingText(cell.code, loc);\n return cell.detail ? `${reason} · ${cell.detail}` : reason;\n }\n case \"text\":\n return cell.detail ? `${cell.text}\\n ${cell.detail}` : cell.text;\n case \"locator\": {\n const mark = cell.verdict !== undefined ? `${verdictMark(cell.verdict === \"skipped\" ? \"skipped\" : cell.verdict)} ` : \"\";\n return `${mark}${cell.locator}`;\n }\n case \"summary\": {\n const more = cell.more && cell.more > 0 ? ` +${cell.more} more` : \"\";\n return `${cell.text}${more}`;\n }\n case \"score\":\n return cell.possible !== undefined ? `${cell.earned} / ${cell.possible}` : String(cell.earned);\n case \"verdict\": {\n const loc = locale ?? DEFAULT_REPORT_LOCALE;\n if (cell.counts) {\n const parts = ([\"passed\", \"failed\", \"errored\", \"skipped\"] as const)\n .filter((k) => cell.counts![k] > 0)\n .map((k) => `${cell.counts![k]} ${localeText(loc, `verdict.${k === \"skipped\" ? \"skipped\" : k}`)}`);\n return parts.join(\" · \") || \"—\";\n }\n if (cell.verdict !== undefined) {\n const v = cell.verdict === \"skipped\" ? \"skipped\" : cell.verdict;\n // 判定符与判定词同场,与 locator 格、web 面同一条纪律:单色打印下照样读得出。\n // bare 省略判定词,只留判定符,供逐格空间紧张的场景(如对照矩阵)使用。\n if (cell.bare)\n return verdictMark(v);\n return `${verdictMark(v)} ${localeText(loc, `verdict.${v}`)}`;\n }\n return \"—\";\n }\n case \"metric\": {\n if (isCostMetricValue(cell.metric)) {\n const closed = formatCostProjectionCellText(cell.metric, locale ?? DEFAULT_REPORT_LOCALE);\n return closed.detail ? `${closed.text}\\n ${closed.detail}` : closed.text;\n }\n if (cell.showCoverage === false) {\n return formatMetricScalar(cell.metric.value, cell.metric.unit, cell.metric.format, locale ?? DEFAULT_REPORT_LOCALE);\n }\n return formatMetricValue(cell.metric, locale ?? DEFAULT_REPORT_LOCALE);\n }\n default: {\n const _exhaustive: never = cell;\n return _exhaustive;\n }\n }\n}\n/** 把 TableContent 展平为 text 排版器用的预格式化行(含 subRows 缩进前缀)。 */\nexport function flattenTableContentForText(content: TableContent, locale?: string): {\n columns: Array<{\n key: string;\n header: string;\n align?: \"left\" | \"right\";\n }>;\n /** depth 是行树里的层数(顶层 0);text 面按它画组边界横线,不认识具体实体。 */\n rows: Array<{\n key: string;\n cells: Record<string, string | null>;\n variant?: string;\n depth: number;\n }>;\n} {\n // 表头与 web 面同源:走列声明的 header,缺省才回落 key。\n const columns = content.columns.map((c) => ({\n key: c.key,\n header: c.header !== undefined ? resolveLocalizedText(c.header, locale ?? DEFAULT_REPORT_LOCALE) : c.key,\n align: (c.better ? \"right\" : \"left\") as \"left\" | \"right\",\n }));\n const rows: Array<{\n key: string;\n cells: Record<string, string | null>;\n variant?: string;\n depth: number;\n }> = [];\n const walk = (row: TableContentRow, depth: number): void => {\n const cells: Record<string, string | null> = {};\n for (const col of content.columns) {\n const cell = row.cells[col.key];\n let text = formatCellText(cell, locale);\n if (depth > 0 && col === content.columns[0] && text !== \"—\") {\n text = `${\" \".repeat(depth)}${text}`;\n }\n cells[col.key] = text;\n }\n rows.push({ key: row.key, cells, variant: row.variant, depth });\n for (const child of row.subRows ?? [])\n walk(child, depth + 1);\n };\n for (const row of content.rows)\n walk(row, 0);\n return { columns, rows };\n}\n"]}
1
+ {"version":3,"file":"cell.js","sourceRoot":"","sources":["cell.tsx"],"names":[],"mappings":";;AAkGA,wCA8DC;AAED,gEA4CC;AAxMD,kDAAkF;AAClF,oDAAsF;AACtF,kDAAiH;AAyFjH,+CAA+C;AAC/C,SAAgB,cAAc,CAAC,IAA6B,EAAE,MAAqB;IAC/E,IAAI,IAAI,IAAI,IAAI;QACZ,OAAO,GAAG,CAAC;IACf,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,OAAO;YACR,OAAO,IAAI,CAAC,KAAK;iBACZ,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;iBAC7C,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC;iBAChC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC;QAC5B,KAAK,eAAe;YAChB,OAAO,GAAG,CAAC;QACf,KAAK,SAAS,CAAC,CAAC,CAAC;YACb,MAAM,GAAG,GAAG,MAAM,IAAI,iCAAqB,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAA,uBAAW,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/D,CAAC;QACD,KAAK,MAAM;YACP,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACtE,KAAK,SAAS,CAAC,CAAC,CAAC;YACb,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAA,uBAAW,EAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACxH,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACb,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;QACjC,CAAC;QACD,KAAK,OAAO;YACR,OAAO,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnG,KAAK,SAAS,CAAC,CAAC,CAAC;YACb,MAAM,GAAG,GAAG,MAAM,IAAI,iCAAqB,CAAC;YAC5C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACd,MAAM,KAAK,GAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAW;qBAC9D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;qBAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,MAAO,CAAC,CAAC,CAAC,IAAI,IAAA,sBAAU,EAAC,GAAG,EAAE,WAAW,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBACvG,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC;YACpC,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;gBAChE,+CAA+C;gBAC/C,wCAAwC;gBACxC,IAAI,IAAI,CAAC,IAAI;oBACT,OAAO,IAAA,uBAAW,EAAC,CAAC,CAAC,CAAC;gBAC1B,OAAO,GAAG,IAAA,uBAAW,EAAC,CAAC,CAAC,IAAI,IAAA,sBAAU,EAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;YAClE,CAAC;YACD,OAAO,GAAG,CAAC;QACf,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACZ,IAAI,IAAA,8BAAiB,EAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACjC,MAAM,MAAM,GAAG,IAAA,yCAA4B,EAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,iCAAqB,CAAC,CAAC;gBAC1F,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;YAC9E,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;gBAC9B,OAAO,IAAA,8BAAkB,EAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,iCAAqB,CAAC,CAAC;YACxH,CAAC;YACD,MAAM,OAAO,GAAG,IAAA,8BAAkB,EAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,iCAAqB,CAAC,CAAC;YAC7H,OAAO,GAAG,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACN,MAAM,WAAW,GAAU,IAAI,CAAC;YAChC,OAAO,WAAW,CAAC;QACvB,CAAC;IACL,CAAC;AACL,CAAC;AACD,0DAA0D;AAC1D,SAAgB,0BAA0B,CAAC,OAAqB,EAAE,MAAe;IAc7E,sCAAsC;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxC,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,MAAM,EAAE,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAA,gCAAoB,EAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,iCAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QACxG,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAqB;KAC3D,CAAC,CAAC,CAAC;IACJ,MAAM,IAAI,GAKL,EAAE,CAAC;IACR,MAAM,IAAI,GAAG,CAAC,GAAoB,EAAE,KAAa,EAAE,YAAgC,EAAE,MAAe,EAAQ,EAAE;QAC1G,MAAM,KAAK,GAAkC,EAAE,CAAC;QAChD,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBAC1D,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACxE,IAAI,GAAG,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC;YACtD,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;QACnC,MAAM,cAAc,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,EAAE,MAAM,CAAC,CAAC;QAC9E,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,cAAc,EAAE,KAAK,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9G,CAAC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["// 官方表格数据协议的单元格类型(docs/feature/reports/library.md「单元格类型」)。\n// Table / Grid / Stat 共用这份判别联合;自定义 Source 要交给这些原语必须适配成这个形状。\nimport type { AttemptLocator } from \"../../attempt-locator.ts\";\nimport type { LocalizedText } from \"../../shared/types.ts\";\nimport type { Verdict } from \"../../shared/types.ts\";\nimport type { MetricValue } from \"../../analysis/index.ts\";\nimport { formatMetricScalar, missingText, verdictMark } from \"../model/format.ts\";\nimport { formatCostProjectionCellText, isCostMetricValue } from \"../model/pricing.ts\";\nimport { DEFAULT_REPORT_LOCALE, localeText, resolveLocalizedText, type ReportLocale, } from \"../model/locale.ts\";\n/** 判定计票:passed / failed / errored / skipped。 */\nexport interface VerdictCounts {\n readonly passed: number;\n readonly failed: number;\n readonly errored: number;\n readonly skipped: number;\n}\n/**\n * 官方表格一格。三条不变量:\n * - metric 格永远带证据(不得压成 text);\n * - notApplicable 与 missing 不合并;\n * - summary 的文本已在上游折好。\n */\nexport type Cell = {\n /** 同一格内按顺序组合多个中立 Cell;不得嵌套 stack。 */\n readonly kind: \"stack\";\n readonly cells: readonly [\n Cell,\n ...Cell[]\n ];\n} | {\n readonly kind: \"metric\";\n readonly metric: MetricValue;\n /** Hide the compact samples/total suffix only when an adjacent region presents coverage. */\n readonly showCoverage?: boolean;\n} | {\n readonly kind: \"verdict\";\n readonly verdict?: Verdict | \"skipped\";\n readonly counts?: VerdictCounts;\n /** 计票覆盖的 attempt 引用(有证据可下钻的计票格才携带,如稳定性矩阵)。 */\n readonly refs?: readonly AttemptLocator[];\n // 两种形态:counts = 判定构成计票(experiment / Eval 行);verdict = 单判定(attempt 行)。\n // 格子只带值,计票怎么来的(折叠、分桶)在实体投影侧,渲染面不算数。\n /** 单判定形态省略判定词、只留判定符(如对照矩阵逐格只放得下一个符号的场景)。 */\n readonly bare?: boolean;\n} | {\n readonly kind: \"score\";\n readonly earned: number;\n readonly possible?: number;\n} | {\n readonly kind: \"summary\";\n readonly text: string;\n readonly more?: number;\n} | {\n readonly kind: \"locator\";\n readonly locator: AttemptLocator;\n /** 有判定的 attempt 行:判定长在 locator 上(判定符 + 语义色),没有判定就省略。 */\n readonly verdict?: Verdict | \"skipped\";\n} | {\n readonly kind: \"text\";\n readonly text: string;\n readonly detail?: string;\n} | {\n readonly kind: \"notApplicable\";\n} | {\n readonly kind: \"missing\";\n readonly code: string;\n /** 补上这一格的命令,可直接复制(如 `niceeval exp <experimentId>`)。 */\n readonly detail?: string;\n};\nexport interface ColumnSpec {\n readonly key: string;\n readonly unit?: string;\n readonly better?: \"higher\" | \"lower\";\n /**\n * 列表头。text / web 两面按当前 locale 解析同一份;省略时按 key 原样显示\n * (维度值列——条件名、实验 id 这类列名即数据的列——用这一支)。\n * Table 原语自己不携带列名词表,表头只来自这里\n * (docs/feature/reports/library.md「Content 协议」)。\n */\n readonly header?: LocalizedText;\n}\n/**\n * 表行 Content。与布局原语 `Row` 组件不同名。\n * placeholder 行照常渲染,但不进任何列的聚合读数。\n * group 行的读数由自己的 subRows 聚合而来,不是一条独立事实。\n */\nexport interface TableContentRow {\n readonly key: string;\n readonly cells: Readonly<Record<string, Cell>>;\n readonly subRows?: readonly TableContentRow[];\n /** group 行的读数由自己的 subRows 聚合而来,不是一条独立事实。 */\n readonly variant?: \"normal\" | \"placeholder\" | \"group\";\n}\nexport interface TableContent {\n readonly columns: readonly ColumnSpec[];\n readonly rows: readonly TableContentRow[];\n}\n/** 把 Cell 折成 text 面可见字符串(缺数据 / 不适用统一不补成 0)。 */\nexport function formatCellText(cell: Cell | null | undefined, locale?: ReportLocale): string {\n if (cell == null)\n return \"—\";\n switch (cell.kind) {\n case \"stack\":\n return cell.cells\n .map((entry) => formatCellText(entry, locale))\n .filter((entry) => entry !== \"—\")\n .join(\" · \") || \"—\";\n case \"notApplicable\":\n return \"—\";\n case \"missing\": {\n const loc = locale ?? DEFAULT_REPORT_LOCALE;\n const reason = missingText(cell.code, loc);\n return cell.detail ? `${reason} · ${cell.detail}` : reason;\n }\n case \"text\":\n return cell.detail ? `${cell.text}\\n ${cell.detail}` : cell.text;\n case \"locator\": {\n const mark = cell.verdict !== undefined ? `${verdictMark(cell.verdict === \"skipped\" ? \"skipped\" : cell.verdict)} ` : \"\";\n return `${mark}${cell.locator}`;\n }\n case \"summary\": {\n const more = cell.more && cell.more > 0 ? ` +${cell.more} more` : \"\";\n return `${cell.text}${more}`;\n }\n case \"score\":\n return cell.possible !== undefined ? `${cell.earned} / ${cell.possible}` : String(cell.earned);\n case \"verdict\": {\n const loc = locale ?? DEFAULT_REPORT_LOCALE;\n if (cell.counts) {\n const parts = ([\"passed\", \"failed\", \"errored\", \"skipped\"] as const)\n .filter((k) => cell.counts![k] > 0)\n .map((k) => `${cell.counts![k]} ${localeText(loc, `verdict.${k === \"skipped\" ? \"skipped\" : k}`)}`);\n return parts.join(\" · \") || \"—\";\n }\n if (cell.verdict !== undefined) {\n const v = cell.verdict === \"skipped\" ? \"skipped\" : cell.verdict;\n // 判定符与判定词同场,与 locator 格、web 面同一条纪律:单色打印下照样读得出。\n // bare 省略判定词,只留判定符,供逐格空间紧张的场景(如对照矩阵)使用。\n if (cell.bare)\n return verdictMark(v);\n return `${verdictMark(v)} ${localeText(loc, `verdict.${v}`)}`;\n }\n return \"—\";\n }\n case \"metric\": {\n if (isCostMetricValue(cell.metric)) {\n const closed = formatCostProjectionCellText(cell.metric, locale ?? DEFAULT_REPORT_LOCALE);\n return closed.detail ? `${closed.text}\\n ${closed.detail}` : closed.text;\n }\n if (cell.showCoverage === false) {\n return formatMetricScalar(cell.metric.value, cell.metric.unit, cell.metric.format, locale ?? DEFAULT_REPORT_LOCALE);\n }\n const display = formatMetricScalar(cell.metric.value, cell.metric.unit, cell.metric.format, locale ?? DEFAULT_REPORT_LOCALE);\n return `${display} · ${cell.metric.state}`;\n }\n default: {\n const _exhaustive: never = cell;\n return _exhaustive;\n }\n }\n}\n/** 把 TableContent 展平为 text 排版器用的预格式化行(含 subRows 缩进前缀)。 */\nexport function flattenTableContentForText(content: TableContent, locale?: string): {\n columns: Array<{\n key: string;\n header: string;\n align?: \"left\" | \"right\";\n }>;\n /** depth 是行树里的层数(顶层 0);text 面按它画组边界横线,不认识具体实体。 */\n rows: Array<{\n key: string;\n cells: Record<string, string | null>;\n variant?: string;\n depth: number;\n }>;\n} {\n // 表头与 web 面同源:走列声明的 header,缺省才回落 key。\n const columns = content.columns.map((c) => ({\n key: c.key,\n header: c.header !== undefined ? resolveLocalizedText(c.header, locale ?? DEFAULT_REPORT_LOCALE) : c.key,\n align: (c.better ? \"right\" : \"left\") as \"left\" | \"right\",\n }));\n const rows: Array<{\n key: string;\n cells: Record<string, string | null>;\n variant?: string;\n depth: number;\n }> = [];\n const walk = (row: TableContentRow, depth: number, ancestorLast: readonly boolean[], isLast: boolean): void => {\n const cells: Record<string, string | null> = {};\n for (const col of content.columns) {\n const cell = row.cells[col.key];\n let text = formatCellText(cell, locale);\n if (depth > 0 && col === content.columns[0] && text !== \"—\") {\n const rails = ancestorLast.map((last) => last ? \" \" : \"│ \").join(\"\");\n text = `${rails}${isLast ? \"└─ \" : \"├─ \"}${text}`;\n }\n cells[col.key] = text;\n }\n rows.push({ key: row.key, cells, variant: row.variant, depth });\n const children = row.subRows ?? [];\n const childAncestors = depth === 0 ? ancestorLast : [...ancestorLast, isLast];\n children.forEach((child, index) => walk(child, depth + 1, childAncestors, index === children.length - 1));\n };\n content.rows.forEach((row, index) => walk(row, 0, [], index === content.rows.length - 1));\n return { columns, rows };\n}\n"]}
@@ -17,6 +17,10 @@ export interface VerdictCounts {
17
17
  * - summary 的文本已在上游折好。
18
18
  */
19
19
  export type Cell = {
20
+ /** 同一格内按顺序组合多个中立 Cell;不得嵌套 stack。 */
21
+ readonly kind: "stack";
22
+ readonly cells: readonly [Cell, ...Cell[]];
23
+ } | {
20
24
  readonly kind: "metric";
21
25
  readonly metric: MetricValue;
22
26
  /** Hide the compact samples/total suffix only when an adjacent region presents coverage. */
@@ -17,6 +17,10 @@ export interface VerdictCounts {
17
17
  * - summary 的文本已在上游折好。
18
18
  */
19
19
  export type Cell = {
20
+ /** 同一格内按顺序组合多个中立 Cell;不得嵌套 stack。 */
21
+ readonly kind: "stack";
22
+ readonly cells: readonly [Cell, ...Cell[]];
23
+ } | {
20
24
  readonly kind: "metric";
21
25
  readonly metric: MetricValue;
22
26
  /** Hide the compact samples/total suffix only when an adjacent region presents coverage. */
@@ -17,6 +17,10 @@ export interface VerdictCounts {
17
17
  * - summary 的文本已在上游折好。
18
18
  */
19
19
  export type Cell = {
20
+ /** 同一格内按顺序组合多个中立 Cell;不得嵌套 stack。 */
21
+ readonly kind: "stack";
22
+ readonly cells: readonly [Cell, ...Cell[]];
23
+ } | {
20
24
  readonly kind: "metric";
21
25
  readonly metric: MetricValue;
22
26
  /** Hide the compact samples/total suffix only when an adjacent region presents coverage. */
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssertionEvidence = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const tree_ts_1 = require("../tree.cjs");
6
+ const INLINE_STRING_CHARACTER_LIMIT = 240;
7
+ const STRING_PREVIEW_CHARACTER_LIMIT = 120;
8
+ function label(locale, english, chinese) {
9
+ return locale === "zh-CN" ? chinese : english;
10
+ }
11
+ function scalarText(value) {
12
+ return typeof value === "string" ? JSON.stringify(value) : String(value);
13
+ }
14
+ function characters(value) {
15
+ return Array.from(value);
16
+ }
17
+ function compactString(value) {
18
+ const content = characters(value);
19
+ if (content.length <= INLINE_STRING_CHARACTER_LIMIT)
20
+ return value;
21
+ return `${content.slice(0, STRING_PREVIEW_CHARACTER_LIMIT).join("")}… (${content.length} characters)`;
22
+ }
23
+ function compactScalarText(value) {
24
+ const content = characters(value);
25
+ if (content.length <= INLINE_STRING_CHARACTER_LIMIT)
26
+ return JSON.stringify(value);
27
+ const preview = content.slice(0, STRING_PREVIEW_CHARACTER_LIMIT).join("");
28
+ return `${JSON.stringify(preview)}… (${content.length} characters)`;
29
+ }
30
+ function stringSummary(value, locale) {
31
+ const content = characters(value);
32
+ const preview = content.slice(0, STRING_PREVIEW_CHARACTER_LIMIT).join("");
33
+ const unit = label(locale, content.length === 1 ? "character" : "characters", "字符");
34
+ return `${content.length} ${unit} · ${JSON.stringify(preview)}…`;
35
+ }
36
+ function valueText(value) {
37
+ switch (value.kind) {
38
+ case "text":
39
+ return compactString(value.text);
40
+ case "value":
41
+ return typeof value.value === "string"
42
+ ? compactScalarText(value.value)
43
+ : scalarText(value.value);
44
+ case "unavailable":
45
+ return value.reason;
46
+ case "fields":
47
+ return value.fields.map((field) => `${field.label}: ${valueText(field.value)}`).join("; ");
48
+ case "list":
49
+ return value.items.map(valueText).join("; ");
50
+ }
51
+ }
52
+ function LongString({ value, locale, quoted }) {
53
+ return ((0, jsx_runtime_1.jsxs)("details", { className: "niceeval-assertion-evidence-long-value", children: [(0, jsx_runtime_1.jsx)("summary", { children: stringSummary(value, locale) }), (0, jsx_runtime_1.jsx)("pre", { className: "niceeval-assertion-evidence-code", children: quoted ? JSON.stringify(value) : value })] }));
54
+ }
55
+ function Value({ value, locale }) {
56
+ switch (value.kind) {
57
+ case "text":
58
+ return characters(value.text).length > INLINE_STRING_CHARACTER_LIMIT
59
+ ? (0, jsx_runtime_1.jsx)(LongString, { value: value.text, locale: locale, quoted: false })
60
+ : (0, jsx_runtime_1.jsx)("p", { children: value.text });
61
+ case "value":
62
+ if (typeof value.value === "string" && characters(value.value).length > INLINE_STRING_CHARACTER_LIMIT) {
63
+ return (0, jsx_runtime_1.jsx)(LongString, { value: value.value, locale: locale, quoted: true });
64
+ }
65
+ return (0, jsx_runtime_1.jsx)("pre", { className: "niceeval-assertion-evidence-code", children: scalarText(value.value) });
66
+ case "unavailable":
67
+ return ((0, jsx_runtime_1.jsxs)("p", { className: "niceeval-assertion-evidence-state", children: [(0, jsx_runtime_1.jsx)("code", { children: "unavailable" }), (0, jsx_runtime_1.jsx)("span", { children: value.reason })] }));
68
+ case "fields":
69
+ return ((0, jsx_runtime_1.jsx)("dl", { className: "niceeval-assertion-evidence-fields", children: value.fields.map((field, index) => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("dt", { children: field.label }), (0, jsx_runtime_1.jsx)("dd", { children: (0, jsx_runtime_1.jsx)(Value, { value: field.value, locale: locale }) })] }, `${field.label}:${index}`))) }));
70
+ case "list":
71
+ return ((0, jsx_runtime_1.jsx)("ul", { className: "niceeval-assertion-evidence-list", children: value.items.map((item, index) => (0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsx)(Value, { value: item, locale: locale }) }, index)) }));
72
+ }
73
+ }
74
+ function Section({ heading, value, locale }) {
75
+ return ((0, jsx_runtime_1.jsxs)("section", { className: "niceeval-assertion-evidence-section", children: [(0, jsx_runtime_1.jsx)("h5", { children: heading }), (0, jsx_runtime_1.jsx)(Value, { value: value, locale: locale })] }));
76
+ }
77
+ function web(content, locale) {
78
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "niceeval-assertion-evidence", children: [(0, jsx_runtime_1.jsx)(Section, { heading: label(locale, "Source", "来源"), value: content.source, locale: locale }), (0, jsx_runtime_1.jsx)(Section, { heading: label(locale, "Check", "检查条件"), value: content.check, locale: locale }), (0, jsx_runtime_1.jsx)(Section, { heading: label(locale, "Observed", "实际结果"), value: content.observed, locale: locale }), (0, jsx_runtime_1.jsx)(Section, { heading: label(locale, "Expected", "预期结果"), value: content.expected, locale: locale }), (0, jsx_runtime_1.jsx)(Section, { heading: label(locale, "Explanation", "解释"), value: content.explanation, locale: locale })] }));
79
+ }
80
+ exports.AssertionEvidence = (0, tree_ts_1.defineComponent)({
81
+ dimensions: () => ({}),
82
+ text({ content }) {
83
+ return [
84
+ `Source: ${valueText(content.source)}`,
85
+ `Check: ${valueText(content.check)}`,
86
+ `Observed: ${valueText(content.observed)}`,
87
+ `Expected: ${valueText(content.expected)}`,
88
+ `Explanation: ${valueText(content.explanation)}`,
89
+ ].join("\n");
90
+ },
91
+ web({ content }, ctx) {
92
+ return web(content, ctx.locale);
93
+ },
94
+ });
95
+ exports.AssertionEvidence.displayName = "AssertionEvidence";
96
+ //# sourceMappingURL=assertion-evidence.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-evidence.js","sourceRoot":"","sources":["assertion-evidence.tsx"],"names":[],"mappings":"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","sourcesContent":["// AssertionEvidence: neutral structured projection of one sealed assertion.\nimport type { ReactElement } from \"react\";\nimport type { ClosedAssertionFactValue } from \"../../../analysis/index.ts\";\nimport { defineComponent } from \"../tree.ts\";\nexport interface AssertionEvidenceContent {\n readonly source: ClosedAssertionFactValue;\n readonly check: ClosedAssertionFactValue;\n readonly observed: ClosedAssertionFactValue;\n readonly expected: ClosedAssertionFactValue;\n readonly explanation: ClosedAssertionFactValue;\n}\nconst INLINE_STRING_CHARACTER_LIMIT = 240;\nconst STRING_PREVIEW_CHARACTER_LIMIT = 120;\nfunction label(locale: string, english: string, chinese: string): string {\n return locale === \"zh-CN\" ? chinese : english;\n}\nfunction scalarText(value: null | boolean | number | string): string {\n return typeof value === \"string\" ? JSON.stringify(value) : String(value);\n}\nfunction characters(value: string): readonly string[] {\n return Array.from(value);\n}\nfunction compactString(value: string): string {\n const content = characters(value);\n if (content.length <= INLINE_STRING_CHARACTER_LIMIT)\n return value;\n return `${content.slice(0, STRING_PREVIEW_CHARACTER_LIMIT).join(\"\")}… (${content.length} characters)`;\n}\nfunction compactScalarText(value: string): string {\n const content = characters(value);\n if (content.length <= INLINE_STRING_CHARACTER_LIMIT)\n return JSON.stringify(value);\n const preview = content.slice(0, STRING_PREVIEW_CHARACTER_LIMIT).join(\"\");\n return `${JSON.stringify(preview)}… (${content.length} characters)`;\n}\nfunction stringSummary(value: string, locale: string): string {\n const content = characters(value);\n const preview = content.slice(0, STRING_PREVIEW_CHARACTER_LIMIT).join(\"\");\n const unit = label(locale, content.length === 1 ? \"character\" : \"characters\", \"字符\");\n return `${content.length} ${unit} · ${JSON.stringify(preview)}…`;\n}\nfunction valueText(value: ClosedAssertionFactValue): string {\n switch (value.kind) {\n case \"text\":\n return compactString(value.text);\n case \"value\":\n return typeof value.value === \"string\"\n ? compactScalarText(value.value)\n : scalarText(value.value);\n case \"unavailable\":\n return value.reason;\n case \"fields\":\n return value.fields.map((field) => `${field.label}: ${valueText(field.value)}`).join(\"; \");\n case \"list\":\n return value.items.map(valueText).join(\"; \");\n }\n}\nfunction LongString({ value, locale, quoted }: {\n readonly value: string;\n readonly locale: string;\n readonly quoted: boolean;\n}): ReactElement {\n return (<details className=\"niceeval-assertion-evidence-long-value\">\n <summary>{stringSummary(value, locale)}</summary>\n <pre className=\"niceeval-assertion-evidence-code\">{quoted ? JSON.stringify(value) : value}</pre>\n </details>);\n}\nfunction Value({ value, locale }: {\n readonly value: ClosedAssertionFactValue;\n readonly locale: string;\n}): ReactElement {\n switch (value.kind) {\n case \"text\":\n return characters(value.text).length > INLINE_STRING_CHARACTER_LIMIT\n ? <LongString value={value.text} locale={locale} quoted={false}/>\n : <p>{value.text}</p>;\n case \"value\":\n if (typeof value.value === \"string\" && characters(value.value).length > INLINE_STRING_CHARACTER_LIMIT) {\n return <LongString value={value.value} locale={locale} quoted/>;\n }\n return <pre className=\"niceeval-assertion-evidence-code\">{scalarText(value.value)}</pre>;\n case \"unavailable\":\n return (<p className=\"niceeval-assertion-evidence-state\">\n <code>unavailable</code>\n <span>{value.reason}</span>\n </p>);\n case \"fields\":\n return (<dl className=\"niceeval-assertion-evidence-fields\">\n {value.fields.map((field, index) => (<div key={`${field.label}:${index}`}>\n <dt>{field.label}</dt>\n <dd><Value value={field.value} locale={locale}/></dd>\n </div>))}\n </dl>);\n case \"list\":\n return (<ul className=\"niceeval-assertion-evidence-list\">\n {value.items.map((item, index) => <li key={index}><Value value={item} locale={locale}/></li>)}\n </ul>);\n }\n}\nfunction Section({ heading, value, locale }: {\n readonly heading: string;\n readonly value: ClosedAssertionFactValue;\n readonly locale: string;\n}): ReactElement {\n return (<section className=\"niceeval-assertion-evidence-section\">\n <h5>{heading}</h5>\n <Value value={value} locale={locale}/>\n </section>);\n}\nfunction web(content: AssertionEvidenceContent, locale: string): ReactElement {\n return (<div className=\"niceeval-assertion-evidence\">\n <Section heading={label(locale, \"Source\", \"来源\")} value={content.source} locale={locale}/>\n <Section heading={label(locale, \"Check\", \"检查条件\")} value={content.check} locale={locale}/>\n <Section heading={label(locale, \"Observed\", \"实际结果\")} value={content.observed} locale={locale}/>\n <Section heading={label(locale, \"Expected\", \"预期结果\")} value={content.expected} locale={locale}/>\n <Section heading={label(locale, \"Explanation\", \"解释\")} value={content.explanation} locale={locale}/>\n </div>);\n}\nexport const AssertionEvidence = defineComponent<{\n readonly content: AssertionEvidenceContent;\n}>({\n dimensions: () => ({}),\n text({ content }) {\n return [\n `Source: ${valueText(content.source)}`,\n `Check: ${valueText(content.check)}`,\n `Observed: ${valueText(content.observed)}`,\n `Expected: ${valueText(content.expected)}`,\n `Explanation: ${valueText(content.explanation)}`,\n ].join(\"\\n\");\n },\n web({ content }, ctx) {\n return web(content, ctx.locale);\n },\n});\nAssertionEvidence.displayName = \"AssertionEvidence\";\n"]}
@@ -0,0 +1,11 @@
1
+ import type { ClosedAssertionFactValue } from "../../../analysis/index.cjs";
2
+ export interface AssertionEvidenceContent {
3
+ readonly source: ClosedAssertionFactValue;
4
+ readonly check: ClosedAssertionFactValue;
5
+ readonly observed: ClosedAssertionFactValue;
6
+ readonly expected: ClosedAssertionFactValue;
7
+ readonly explanation: ClosedAssertionFactValue;
8
+ }
9
+ export declare const AssertionEvidence: import("../tree.cjs").ReportComponent<{
10
+ readonly content: AssertionEvidenceContent;
11
+ }>;
@@ -0,0 +1,11 @@
1
+ import type { ClosedAssertionFactValue } from "../../../analysis/index.mjs";
2
+ export interface AssertionEvidenceContent {
3
+ readonly source: ClosedAssertionFactValue;
4
+ readonly check: ClosedAssertionFactValue;
5
+ readonly observed: ClosedAssertionFactValue;
6
+ readonly expected: ClosedAssertionFactValue;
7
+ readonly explanation: ClosedAssertionFactValue;
8
+ }
9
+ export declare const AssertionEvidence: import("../tree.mjs").ReportComponent<{
10
+ readonly content: AssertionEvidenceContent;
11
+ }>;
@@ -0,0 +1,11 @@
1
+ import type { ClosedAssertionFactValue } from "../../../analysis/index.js";
2
+ export interface AssertionEvidenceContent {
3
+ readonly source: ClosedAssertionFactValue;
4
+ readonly check: ClosedAssertionFactValue;
5
+ readonly observed: ClosedAssertionFactValue;
6
+ readonly expected: ClosedAssertionFactValue;
7
+ readonly explanation: ClosedAssertionFactValue;
8
+ }
9
+ export declare const AssertionEvidence: import("../tree.js").ReportComponent<{
10
+ readonly content: AssertionEvidenceContent;
11
+ }>;
@@ -0,0 +1,6 @@
1
+ import { createRequire as __niceevalCreateRequire } from "node:module";
2
+ const __niceevalRequire = __niceevalCreateRequire(import.meta.url);
3
+ const __niceevalCanonical = __niceevalRequire("./assertion-evidence.cjs");
4
+ const __niceevalExport0 = __niceevalCanonical["AssertionEvidence"];
5
+ export { __niceevalExport0 as AssertionEvidence };
6
+ //# sourceMappingURL=assertion-evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-evidence.js","sources":[],"names":[],"mappings":""}
@@ -618,6 +618,8 @@ function renderCellWeb(cell, ctx) {
618
618
  if (!cell)
619
619
  return (0, jsx_runtime_1.jsx)("span", { className: "niceeval-missing", children: MISSING_MARK });
620
620
  switch (cell.kind) {
621
+ case "stack":
622
+ return ((0, jsx_runtime_1.jsx)("span", { className: "niceeval-cell-stack", children: cell.cells.map((entry, index) => ((0, jsx_runtime_1.jsx)("span", { className: "niceeval-cell-stack-item", children: renderCellWeb(entry, ctx) }, index))) }));
621
623
  case "notApplicable":
622
624
  return (0, jsx_runtime_1.jsx)("span", { className: "niceeval-missing", children: MISSING_MARK });
623
625
  case "missing": {
@@ -657,6 +659,8 @@ function renderCellWeb(cell, ctx) {
657
659
  function cellSortValue(cell) {
658
660
  if (!cell)
659
661
  return "";
662
+ if (cell.kind === "stack")
663
+ return cellSortValue(cell.cells[0]);
660
664
  if (cell.kind === "metric")
661
665
  return cell.metric.value ?? "";
662
666
  if (cell.kind === "score")
@@ -721,7 +725,16 @@ const TableImplementation = (0, tree_ts_1.defineComponent)({
721
725
  const locale = props.locale ?? ctx.locale;
722
726
  const { columns, content } = tableContentOf(props, locale);
723
727
  const flat = (0, cell_tsx_1.flattenTableContentForText)(content, locale);
724
- return (0, table_text_ts_1.renderTableText)({ columns, rows: flat.rows.map((row) => ({ key: row.key, cells: row.cells, depth: row.depth })), locale }, ctx);
728
+ return (0, table_text_ts_1.renderTableText)({
729
+ columns,
730
+ rows: flat.rows.map((row) => ({
731
+ key: row.key,
732
+ cells: row.cells,
733
+ depth: row.depth,
734
+ ruleBefore: row.variant === "group",
735
+ })),
736
+ locale,
737
+ }, ctx);
725
738
  },
726
739
  });
727
740
  exports.Table = TableImplementation;