niceeval 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/INDEX.md +55 -0
  2. package/dist/agents/types.d.ts +317 -0
  3. package/dist/context/types.d.ts +335 -0
  4. package/dist/i18n/core.d.ts +11 -0
  5. package/dist/i18n/en.d.ts +181 -0
  6. package/dist/i18n/index.d.ts +5 -0
  7. package/dist/i18n/zh-CN.d.ts +183 -0
  8. package/dist/o11y/execution-tree.d.ts +103 -0
  9. package/dist/o11y/otlp/parse.d.ts +3 -0
  10. package/dist/o11y/otlp/receiver.d.ts +21 -0
  11. package/dist/o11y/otlp/select.d.ts +22 -0
  12. package/dist/o11y/otlp/turn-otel.d.ts +43 -0
  13. package/dist/o11y/types.d.ts +190 -0
  14. package/dist/report/aggregate.d.ts +57 -0
  15. package/dist/report/aggregate.js +212 -0
  16. package/dist/report/built-ins/cost-pass-rate-comparison.d.ts +1 -0
  17. package/dist/report/built-ins/cost-pass-rate-comparison.js +17 -0
  18. package/dist/report/built-ins/index.d.ts +1 -0
  19. package/dist/report/built-ins/index.js +2 -0
  20. package/dist/report/components.d.ts +178 -0
  21. package/dist/report/components.js +132 -0
  22. package/dist/report/compute.d.ts +106 -0
  23. package/dist/report/compute.js +618 -0
  24. package/dist/report/flag.d.ts +6 -0
  25. package/dist/report/flag.js +8 -0
  26. package/dist/report/format.d.ts +32 -0
  27. package/dist/report/format.js +126 -0
  28. package/dist/report/index.d.ts +19 -0
  29. package/dist/report/index.js +30 -0
  30. package/dist/report/load.d.ts +12 -0
  31. package/dist/report/load.js +56 -0
  32. package/dist/report/locale.d.ts +83 -0
  33. package/dist/report/locale.js +160 -0
  34. package/dist/report/metrics.d.ts +21 -0
  35. package/dist/report/metrics.js +115 -0
  36. package/dist/report/primitives.d.ts +64 -0
  37. package/dist/report/primitives.js +113 -0
  38. package/dist/report/react/AttemptList.d.ts +23 -0
  39. package/dist/report/react/AttemptList.js +20 -0
  40. package/dist/report/react/DeltaTable.d.ts +8 -0
  41. package/dist/report/react/DeltaTable.js +24 -0
  42. package/dist/report/react/EvalList.d.ts +10 -0
  43. package/dist/report/react/EvalList.js +0 -0
  44. package/dist/report/react/ExperimentList.d.ts +10 -0
  45. package/dist/report/react/ExperimentList.js +15 -0
  46. package/dist/report/react/GroupSummary.d.ts +8 -0
  47. package/dist/report/react/GroupSummary.js +8 -0
  48. package/dist/report/react/MetricBars.d.ts +10 -0
  49. package/dist/report/react/MetricBars.js +48 -0
  50. package/dist/report/react/MetricLine.d.ts +9 -0
  51. package/dist/report/react/MetricLine.js +68 -0
  52. package/dist/report/react/MetricMatrix.d.ts +10 -0
  53. package/dist/report/react/MetricMatrix.js +23 -0
  54. package/dist/report/react/MetricScatter.d.ts +9 -0
  55. package/dist/report/react/MetricScatter.js +100 -0
  56. package/dist/report/react/MetricTable.d.ts +11 -0
  57. package/dist/report/react/MetricTable.js +26 -0
  58. package/dist/report/react/RunOverview.d.ts +8 -0
  59. package/dist/report/react/RunOverview.js +12 -0
  60. package/dist/report/react/Scoreboard.d.ts +8 -0
  61. package/dist/report/react/Scoreboard.js +26 -0
  62. package/dist/report/react/cell.d.ts +9 -0
  63. package/dist/report/react/cell.js +9 -0
  64. package/dist/report/react/chart-math.d.ts +14 -0
  65. package/dist/report/react/chart-math.js +68 -0
  66. package/dist/report/react/colors.d.ts +14 -0
  67. package/dist/report/react/colors.js +45 -0
  68. package/dist/report/react/fixtures.d.ts +19 -0
  69. package/dist/report/react/fixtures.js +393 -0
  70. package/dist/report/react/format.d.ts +3 -0
  71. package/dist/report/react/format.js +7 -0
  72. package/dist/report/react/index.d.ts +6 -0
  73. package/dist/report/react/index.js +14 -0
  74. package/dist/report/report.d.ts +24 -0
  75. package/dist/report/report.js +49 -0
  76. package/dist/report/text/faces.d.ts +29 -0
  77. package/dist/report/text/faces.js +503 -0
  78. package/dist/report/text/layout.d.ts +75 -0
  79. package/dist/report/text/layout.js +173 -0
  80. package/dist/report/text/plot.d.ts +37 -0
  81. package/dist/report/text/plot.js +81 -0
  82. package/dist/report/text/table.d.ts +8 -0
  83. package/dist/report/text/table.js +86 -0
  84. package/dist/report/tree.d.ts +99 -0
  85. package/dist/report/tree.js +228 -0
  86. package/dist/report/types.d.ts +420 -0
  87. package/dist/report/types.js +4 -0
  88. package/dist/report/web.d.ts +15 -0
  89. package/dist/report/web.js +37 -0
  90. package/dist/results/annotated-source.d.ts +61 -0
  91. package/dist/results/attempt-evidence.d.ts +69 -0
  92. package/dist/results/attempt-source.d.ts +15 -0
  93. package/dist/results/locator.d.ts +75 -0
  94. package/dist/results/locator.js +0 -0
  95. package/dist/results/select.d.ts +45 -0
  96. package/dist/results/select.js +230 -0
  97. package/dist/results/source-hash.d.ts +9 -0
  98. package/dist/results/types.d.ts +204 -0
  99. package/dist/runner/eval-source.d.ts +22 -0
  100. package/dist/runner/fingerprint.d.ts +23 -0
  101. package/dist/runner/types.d.ts +332 -0
  102. package/dist/sandbox/docker-stream.d.ts +24 -0
  103. package/dist/sandbox/docker.d.ts +84 -0
  104. package/dist/sandbox/e2b.d.ts +31 -0
  105. package/dist/sandbox/errors.d.ts +4 -0
  106. package/dist/sandbox/local-files.d.ts +6 -0
  107. package/dist/sandbox/paths.d.ts +4 -0
  108. package/dist/sandbox/registry.d.ts +13 -0
  109. package/dist/sandbox/resolve.d.ts +40 -0
  110. package/dist/sandbox/retry.d.ts +10 -0
  111. package/dist/sandbox/shell.d.ts +11 -0
  112. package/dist/sandbox/source-files.d.ts +13 -0
  113. package/dist/sandbox/types.d.ts +203 -0
  114. package/dist/sandbox/vercel.d.ts +37 -0
  115. package/dist/scoring/types.d.ts +70 -0
  116. package/dist/shared/aggregate.d.ts +29 -0
  117. package/dist/shared/aggregate.js +55 -0
  118. package/dist/shared/types.d.ts +27 -0
  119. package/dist/shared/verdict.d.ts +27 -0
  120. package/dist/shared/verdict.js +34 -0
  121. package/dist/tty-line.d.ts +6 -0
  122. package/dist/types.d.ts +7 -0
  123. package/dist/util.d.ts +22 -0
  124. package/docs-site/zh/concepts/adapter.mdx +9 -4
  125. package/docs-site/zh/concepts/assert.mdx +8 -8
  126. package/docs-site/zh/concepts/evals.mdx +5 -5
  127. package/docs-site/zh/concepts/experiment.mdx +3 -1
  128. package/docs-site/zh/concepts/judge.mdx +9 -9
  129. package/docs-site/zh/concepts/overview.mdx +2 -2
  130. package/docs-site/zh/concepts/tier.mdx +6 -6
  131. package/docs-site/zh/example/claude-code-codex-plugin.mdx +9 -5
  132. package/docs-site/zh/example/claude-code-codex-skill.mdx +12 -7
  133. package/docs-site/zh/guides/agent-feedback-loop.mdx +235 -78
  134. package/docs-site/zh/guides/connect-otel.mdx +3 -3
  135. package/docs-site/zh/guides/connect-your-agent.mdx +2 -2
  136. package/docs-site/zh/guides/custom-reports.mdx +196 -36
  137. package/docs-site/zh/guides/experiments.mdx +7 -0
  138. package/docs-site/zh/guides/fixtures.mdx +1 -1
  139. package/docs-site/zh/guides/official-adapters.mdx +31 -9
  140. package/docs-site/zh/guides/publish-report.mdx +4 -4
  141. package/docs-site/zh/guides/report-components.mdx +194 -55
  142. package/docs-site/zh/guides/reporters.mdx +2 -2
  143. package/docs-site/zh/guides/results-data.mdx +35 -34
  144. package/docs-site/zh/guides/runner.mdx +2 -2
  145. package/docs-site/zh/guides/sandbox-agent.mdx +10 -5
  146. package/docs-site/zh/guides/sandbox-providers.mdx +102 -0
  147. package/docs-site/zh/guides/viewing-results.mdx +199 -79
  148. package/docs-site/zh/guides/write-experiment.mdx +23 -1
  149. package/docs-site/zh/guides/write-send.mdx +2 -2
  150. package/docs-site/zh/index.mdx +4 -3
  151. package/docs-site/zh/introduction.mdx +2 -1
  152. package/docs-site/zh/quickstart.mdx +5 -3
  153. package/docs-site/zh/reference/builtin-agents.mdx +38 -13
  154. package/docs-site/zh/reference/capabilities.mdx +1 -1
  155. package/docs-site/zh/reference/cli.mdx +36 -13
  156. package/docs-site/zh/reference/define-agent.mdx +24 -12
  157. package/docs-site/zh/reference/define-config.mdx +1 -1
  158. package/docs-site/zh/reference/define-eval.mdx +3 -3
  159. package/docs-site/zh/reference/events.mdx +7 -1
  160. package/docs-site/zh/reference/expect.mdx +3 -3
  161. package/package.json +10 -6
  162. package/src/agents/bub.ts +134 -43
  163. package/src/agents/claude-code.test.ts +152 -0
  164. package/src/agents/claude-code.ts +127 -13
  165. package/src/agents/codex.test.ts +192 -0
  166. package/src/agents/codex.ts +151 -12
  167. package/src/agents/index.ts +11 -3
  168. package/src/agents/manifest.ts +41 -0
  169. package/src/agents/plugin-config.test.ts +94 -0
  170. package/src/agents/shared.ts +33 -2
  171. package/src/agents/skills.test.ts +214 -0
  172. package/src/agents/skills.ts +304 -0
  173. package/src/agents/streaming.ts +5 -5
  174. package/src/agents/types.ts +62 -2
  175. package/src/cli.ts +74 -47
  176. package/src/context/context.test.ts +20 -2
  177. package/src/context/context.ts +3 -0
  178. package/src/context/control-flow.ts +1 -1
  179. package/src/context/session.test.ts +92 -1
  180. package/src/context/session.ts +26 -1
  181. package/src/context/types.ts +4 -4
  182. package/src/define.test.ts +82 -0
  183. package/src/define.ts +72 -11
  184. package/src/expect/index.ts +5 -5
  185. package/src/i18n/en.ts +36 -15
  186. package/src/i18n/zh-CN.ts +39 -21
  187. package/src/index.ts +1 -1
  188. package/src/o11y/execution-tree.test.ts +452 -0
  189. package/src/o11y/execution-tree.ts +367 -0
  190. package/src/o11y/otlp/receiver.ts +1 -1
  191. package/src/o11y/otlp/select.ts +7 -3
  192. package/src/o11y/parsers/claude-code.test.ts +175 -0
  193. package/src/o11y/parsers/claude-code.ts +32 -0
  194. package/src/o11y/types.ts +6 -1
  195. package/src/report/aggregate.ts +26 -20
  196. package/src/report/built-in-user-parity.test.tsx +643 -0
  197. package/src/report/built-ins/cost-pass-rate-comparison.tsx +23 -0
  198. package/src/report/built-ins/index.ts +2 -0
  199. package/src/report/components.tsx +223 -50
  200. package/src/report/compute.ts +358 -53
  201. package/src/report/dual-render.test.tsx +1125 -0
  202. package/src/report/flag.ts +1 -1
  203. package/src/report/format.ts +50 -2
  204. package/src/report/index.ts +48 -14
  205. package/src/report/load.ts +1 -1
  206. package/src/report/locale.ts +206 -0
  207. package/src/report/metrics.ts +39 -15
  208. package/src/report/primitives.tsx +100 -2
  209. package/src/report/react/AttemptList.tsx +115 -0
  210. package/src/report/react/DeltaTable.tsx +9 -6
  211. package/src/report/react/EvalList.tsx +0 -0
  212. package/src/report/react/ExperimentList.tsx +108 -0
  213. package/src/report/react/GroupSummary.tsx +66 -0
  214. package/src/report/react/MetricBars.tsx +24 -13
  215. package/src/report/react/MetricLine.tsx +21 -21
  216. package/src/report/react/MetricMatrix.tsx +8 -4
  217. package/src/report/react/MetricScatter.tsx +136 -96
  218. package/src/report/react/MetricTable.tsx +115 -15
  219. package/src/report/react/RunOverview.tsx +48 -26
  220. package/src/report/react/Scoreboard.tsx +15 -7
  221. package/src/report/react/cell.tsx +18 -9
  222. package/src/{view/app/lib/chart.ts → report/react/chart-math.ts} +2 -6
  223. package/src/report/react/colors.ts +24 -15
  224. package/src/report/react/enhance.js +129 -0
  225. package/src/report/react/fixtures.ts +163 -34
  226. package/src/report/react/format.ts +1 -1
  227. package/src/report/react/index.tsx +22 -6
  228. package/src/report/react/render.test.tsx +164 -31
  229. package/src/report/react/styles.css +405 -213
  230. package/src/report/report.test.ts +403 -94
  231. package/src/report/report.ts +29 -11
  232. package/src/report/text/faces.ts +303 -95
  233. package/src/report/text/layout.ts +76 -11
  234. package/src/report/text/table.ts +98 -0
  235. package/src/report/tree.ts +103 -20
  236. package/src/report/types.ts +196 -25
  237. package/src/report/web.ts +46 -19
  238. package/src/results/annotated-source.test.ts +146 -0
  239. package/src/results/annotated-source.ts +128 -0
  240. package/src/results/attempt-evidence.test.ts +158 -0
  241. package/src/results/attempt-evidence.ts +158 -0
  242. package/src/results/attempt-source.ts +48 -0
  243. package/src/results/copy.ts +154 -139
  244. package/src/results/format.ts +54 -47
  245. package/src/results/host-equivalence.test.ts +527 -0
  246. package/src/results/index.ts +56 -14
  247. package/src/results/locator.test.ts +198 -0
  248. package/src/results/locator.ts +0 -0
  249. package/src/results/open.ts +392 -175
  250. package/src/results/results.test.ts +943 -494
  251. package/src/results/select.ts +129 -23
  252. package/src/results/skipped-notice.ts +0 -0
  253. package/src/results/source-hash.ts +28 -0
  254. package/src/results/types.ts +98 -62
  255. package/src/results/writer.ts +304 -176
  256. package/src/runner/attempt.test.ts +170 -0
  257. package/src/runner/attempt.ts +97 -15
  258. package/src/runner/discover.test.ts +65 -0
  259. package/src/runner/discover.ts +6 -2
  260. package/src/runner/eval-source.test.ts +121 -0
  261. package/src/runner/eval-source.ts +45 -0
  262. package/src/runner/fingerprint.ts +54 -1
  263. package/src/runner/remote-sandbox.ts +1 -1
  264. package/src/runner/report.test.ts +6 -8
  265. package/src/runner/report.ts +5 -4
  266. package/src/runner/reporters/artifacts.ts +27 -41
  267. package/src/runner/reporters/braintrust.test.ts +3 -3
  268. package/src/runner/reporters/braintrust.ts +1 -1
  269. package/src/runner/reporters/console.ts +6 -6
  270. package/src/runner/reporters/json.ts +4 -4
  271. package/src/runner/reporters/live.test.ts +56 -0
  272. package/src/runner/reporters/live.ts +36 -10
  273. package/src/runner/reporters/quiet.test.ts +66 -0
  274. package/src/runner/reporters/quiet.ts +49 -0
  275. package/src/runner/reporters/shared.ts +5 -5
  276. package/src/runner/reporters/table.ts +17 -17
  277. package/src/runner/run.ts +61 -102
  278. package/src/runner/types.ts +43 -32
  279. package/src/sandbox/checkpoint.ts +1 -1
  280. package/src/sandbox/docker.ts +15 -2
  281. package/src/sandbox/e2b.ts +11 -5
  282. package/src/sandbox/errors.ts +13 -0
  283. package/src/sandbox/index.ts +3 -3
  284. package/src/sandbox/local-files.ts +1 -1
  285. package/src/sandbox/registry.ts +6 -5
  286. package/src/sandbox/resolve.ts +38 -23
  287. package/src/sandbox/retry.test.ts +68 -0
  288. package/src/sandbox/retry.ts +44 -0
  289. package/src/sandbox/types.ts +69 -28
  290. package/src/sandbox/vercel.ts +17 -3
  291. package/src/scoring/collector.ts +3 -3
  292. package/src/scoring/judge.ts +2 -2
  293. package/src/scoring/scoped.ts +13 -1
  294. package/src/scoring/types.ts +7 -7
  295. package/src/scoring/verdict.ts +4 -4
  296. package/src/shared/aggregate.ts +23 -3
  297. package/src/shared/types.ts +2 -2
  298. package/src/shared/{outcome.ts → verdict.ts} +15 -15
  299. package/src/show/compose.ts +12 -132
  300. package/src/show/index.ts +125 -94
  301. package/src/show/render.ts +660 -160
  302. package/src/show/show.test.ts +472 -253
  303. package/src/source-loc.ts +1 -1
  304. package/src/tty-line.ts +32 -0
  305. package/src/types.ts +2 -2
  306. package/src/util.test.ts +21 -1
  307. package/src/util.ts +5 -1
  308. package/src/view/app/App.tsx +33 -198
  309. package/src/view/app/components/AttemptModal.tsx +6 -6
  310. package/src/view/app/components/CodeView.tsx +2 -2
  311. package/src/view/app/components/CopyControls.tsx +32 -36
  312. package/src/view/app/components/SkippedRunsBanner.tsx +140 -0
  313. package/src/view/app/components/ui/badge.tsx +1 -1
  314. package/src/view/app/components/ui/dialog.tsx +2 -2
  315. package/src/view/app/i18n.ts +40 -31
  316. package/src/view/app/lib/artifact-url.ts +1 -1
  317. package/src/view/app/lib/attempt-route.test.ts +37 -47
  318. package/src/view/app/lib/attempt-route.ts +26 -26
  319. package/src/view/app/lib/rows.ts +9 -112
  320. package/src/view/app/lib/verdict.ts +25 -0
  321. package/src/view/app/main.tsx +9 -12
  322. package/src/view/app/pages/RunsPage.tsx +4 -4
  323. package/src/view/app/pages/TracesPage.tsx +3 -3
  324. package/src/view/app/shared.ts +0 -1
  325. package/src/view/app/types.ts +6 -51
  326. package/src/view/artifact-serving.test.ts +136 -0
  327. package/src/view/client-dist/app.css +1 -1
  328. package/src/view/client-dist/app.js +21 -21
  329. package/src/view/data.test.ts +214 -143
  330. package/src/view/data.ts +166 -120
  331. package/src/view/index.ts +23 -11
  332. package/src/view/server.ts +52 -17
  333. package/src/view/shared/types.ts +22 -31
  334. package/src/view/styles.css +117 -327
  335. package/src/view/view-report.test.ts +146 -98
  336. package/docs-site/zh/guides/sandbox-backends.mdx +0 -75
  337. package/src/report/default-report.tsx +0 -222
  338. package/src/report/dual-face.test.tsx +0 -527
  339. package/src/report/react/CaseList.tsx +0 -70
  340. package/src/view/app/components/CostScoreChart.tsx +0 -147
  341. package/src/view/app/components/ExperimentTable.tsx +0 -284
  342. package/src/view/app/components/GroupSelector.tsx +0 -61
  343. package/src/view/app/components/primitives.tsx +0 -43
  344. package/src/view/app/lib/outcome.ts +0 -82
@@ -0,0 +1,183 @@
1
+ export declare const zhCN: {
2
+ readonly "agent.installFailed": "安装失败:{{key}}\n{{tail}}";
3
+ readonly "agent.unknown": "未知 agent \"{{name}}\"。已注册:{{known}}。";
4
+ readonly "agent.diagnose.exitCode": "agent 运行退出码 {{code}}";
5
+ readonly "agent.diagnose.lastError": "最后错误:{{message}}";
6
+ readonly "agent.diagnose.noTranscript": "transcript 未生成";
7
+ readonly "agent.diagnose.outputTail": "输出末尾:{{tail}}";
8
+ readonly "agent.diagnose.zeroEvents": "transcript 存在但 0 事件";
9
+ readonly "bub.homeDetectFailed": "无法探测沙箱 $HOME(printf $HOME 输出为空)。不兜底到 provider 专属固定路径,请检查沙箱 provider。";
10
+ readonly "bub.checkpointCaptureFailed": "bub checkpoint 缓存回填失败(本沙箱不受影响,后续沙箱会重新安装):{{error}}";
11
+ readonly "bub.checkpointRestoreFailed": "bub checkpoint 还原失败,回退到全量安装:{{error}}";
12
+ readonly "bub.installFailed": "bub 安装失败(重试 {{attempts}} 次):\n{{tail}}";
13
+ readonly "bub.setupNotRun": "bub adapter 的 setup() 尚未在该沙箱运行(缺 home/workspace 信息);运行器应先调 setup 再 send。";
14
+ readonly "checkpoint.emptyTar": "checkpoint: tar 为空(paths: {{paths}})";
15
+ readonly "skill.localMissing": "本地 skill 路径不存在:\"{{path}}\"(解析到 {{resolved}})。path 相对跑 niceeval 的项目根解析。";
16
+ readonly "skill.localDirNoSkillFile": "本地 skill 目录 \"{{path}}\" 里没有 SKILL.md。目录形态的 skill 必须在根下带一个 SKILL.md。";
17
+ readonly "skill.localUnsupportedShape": "本地 skill 路径 \"{{path}}\" 形态不支持。只接受:含 SKILL.md 的目录,或单个 .md 文件。";
18
+ readonly "skill.repoCloneFailed": "repo skill 拉取失败:{{source}}(ref: {{ref}})\n{{tail}}";
19
+ readonly "skill.repoNoSkills": "repo skill {{source}} 里没找到任何 SKILL.md。";
20
+ readonly "skill.repoAmbiguous": "repo skill {{source}} 里有多个 skill,必须用 `skills: [...]` 明确选择要启用哪些。可选:{{available}}。";
21
+ readonly "skill.repoUnknownSkill": "repo skill {{source}}(ref: {{ref}})里没有名为 \"{{skill}}\" 的 skill。可选:{{available}}。";
22
+ readonly "skill.copyFailed": "skill \"{{name}}\" 装进 {{dest}} 失败:\n{{tail}}";
23
+ readonly "plugin.marketplaceFailed": "{{agent}} marketplace \"{{name}}\" 连接失败(source: {{source}}, ref: {{ref}}):\n{{tail}}";
24
+ readonly "plugin.installFailed": "{{agent}} plugin \"{{name}}\"(marketplace: {{marketplace}})安装失败:\n{{tail}}";
25
+ readonly "cli.all": "(全部)";
26
+ readonly "cli.browserOpenFailed": "无法自动打开浏览器,请手动访问:{{url}}\n";
27
+ readonly "cli.clean.done": "已删除 .niceeval/ 历史运行 artifact。\n";
28
+ readonly "cli.config.missing": string;
29
+ readonly "cli.config.noDefault": "niceeval.config.ts 需要 default export(defineConfig(...))。";
30
+ readonly "cli.dry.header": "\n[dry] {{evals}} 个 eval × {{configs}} 个运行配置:\n";
31
+ readonly "cli.dry.noMatches": "(无匹配)";
32
+ readonly "cli.dry.row": " {{who}}{{experiment}}: {{evals}} ×{{runs}}\n";
33
+ readonly "cli.error": "niceeval 出错:{{error}}\n";
34
+ readonly "cli.flag.invalidNumber": "标志 --{{flag}} 需要数字,收到 \"{{value}}\"。\n";
35
+ readonly "runner.budgetUnenforceable": "{{budgetKey}} 的 budget:连续多个 attempt 完成后都拿不到成本数据(agent 不上报用量且模型不在价格表)——该 agent 的 budget 无法执行,取消护栏继续跑。\n";
36
+ readonly "judge.modelMissing": string;
37
+ readonly "loaders.yamlMissing": "loadYaml(\"{{path}}\") 需要 YAML 解析器:请先 `pnpm add yaml`(或改用 loadJson + JSON 数据集)。";
38
+ readonly "cli.flag.parseError": "{{message}}\n运行 `niceeval --help` 查看用法。\n";
39
+ readonly "cli.envInvalidNumber": "环境变量 {{name}} 不是数字:\"{{value}}\"。\n";
40
+ readonly "cli.help": string;
41
+ readonly "cli.show.noResults": "{{root}} 下没有结果。先 `niceeval exp` 跑一轮,再 `niceeval show`。\n";
42
+ readonly "cli.show.runDirMissing": "Results directory not found: {{dir}}\n";
43
+ readonly "cli.show.noEvalMatch": "No results matched: {{patterns}}. Evals with results: {{evals}}\n";
44
+ readonly "cli.show.noExperimentMatch": "No experiment matched --experiment {{arg}}. Experiments with results: {{experiments}}\n";
45
+ readonly "cli.show.historyReportConflict": "`--history` and `--report` are mutually exclusive: --history is the built-in trend view. For a custom trend, compose exp.snapshots inside your report file instead.\n";
46
+ readonly "cli.show.evidenceNeedsEval": "--eval / --execution / --diff show one attempt's evidence, but the selection matched {{matched}} evals. Pick an attempt locator from the index below:\n{{index}}\n";
47
+ readonly "cli.show.locatorMalformed": "{{message}}\n";
48
+ readonly "cli.show.locatorNotFound": "{{message}}\n";
49
+ readonly "cli.eval.noMatch": "没有匹配的 eval:{{patterns}}。\n";
50
+ readonly "cli.eval.noMatchHintExperiment": "提示:\"{{pattern}}\" 是实验{{kind}},你大概想跑:niceeval exp {{pattern}}\n";
51
+ readonly "cli.eval.noMatchKnown": "已发现 {{count}} 个 eval:{{evals}}\n";
52
+ readonly "cli.exp.agentModelFlagUnsupported": "`--agent` / `--model` 不能覆盖 experiment。请在 experiments/ 里新增或复制一个配置文件。\n";
53
+ readonly "cli.experiment.noMatch": "没有匹配的实验:{{arg}}。已发现:{{experiments}}\n";
54
+ readonly "cli.experimentGroup": "组";
55
+ readonly "cli.fallbackCleanupTimeout": "\ngraceful 清理超时,强制清理沙箱…\n";
56
+ readonly "cli.forceCleanupExit": "\n强制清理沙箱并退出…\n";
57
+ readonly "cli.init.done": "已就绪:evals/、niceeval.config.ts,以及 AGENTS.md 里的 niceeval agent 指引区块(指向 node_modules/niceeval/docs-site/zh)。\n";
58
+ readonly "cli.interruptCleanup": "\n收到中断,正在清理沙箱容器…(再按一次强制清理并退出)\n";
59
+ readonly "cli.list.header": "发现 {{count}} 个 eval:\n";
60
+ readonly "cli.noAgent": "未指定 agent(用 --agent <name>)。\n";
61
+ readonly "cli.none": "(无)";
62
+ readonly "cli.pressCtrlC": "按 Ctrl+C 退出。\n";
63
+ readonly "cli.resultsPath": "结构化结果:{{path}}(snapshot.json + 每 attempt 的 result.json / events.json / trace.json / diff.json)\n";
64
+ readonly "cli.run.experimentRequired": string;
65
+ readonly "cli.run.experimentRequiredHint": "提示:\"{{pattern}}\" 是实验{{kind}},你大概想跑:niceeval exp {{pattern}}\n";
66
+ readonly "cli.run.experimentRequiredKnown": "已发现实验:{{experiments}}\n";
67
+ readonly "cli.unimplemented": "命令 \"{{command}}\" 暂未实现(MVP)。\n";
68
+ readonly "cli.view.exportedDir": "已导出静态查看站:{{out}}(整个目录可直接静态托管;本地打开 {{out}}/index.html 需经 http 服务,file:// 下 artifact fetch 不可用)\n";
69
+ readonly "cli.view.incompatible": "{{dir}}: 由 niceeval {{producer}} 写入(schemaVersion {{schemaVersion}}),当前 CLI 只读 schemaVersion {{supported}}。\n运行 `{{command}}` 查看这份报告。\n";
70
+ readonly "cli.view.noResults": "{{root}} 下没有结果。先 `niceeval exp` 跑一轮,再 `niceeval view`。\n";
71
+ readonly "cli.view.incompatibleForeign": "{{dir}}: 由 {{name}} {{version}} 写入(schemaVersion {{schemaVersion}}),当前 CLI 只读 schemaVersion {{supported}}。\n请用写出它的那个工具查看这份报告。\n";
72
+ readonly "cli.view.url": "niceeval view: {{url}}\n";
73
+ readonly "context.capabilityMissing": string;
74
+ readonly "context.skipEmpty": "skip() 需要一个非空理由。";
75
+ readonly "context.turnFailed": "本轮 send 返回 failed(turn status = failed):{{message}}";
76
+ readonly "context.turnFailedDefault": "本轮 send 返回 failed(turn status = failed)";
77
+ readonly "define.agentNameRequired": "defineAgent 需要 name。";
78
+ readonly "define.evalIdRejected": "defineEval 不接受 id —— id 由文件路径推导。";
79
+ readonly "define.evalTestRequired": "defineEval 需要一个 async test(t) 函数。";
80
+ readonly "define.experimentAgentRequired": "defineExperiment 需要 agent。";
81
+ readonly "define.experimentIdRejected": "defineExperiment 不接受 id —— id 由文件路径推导。";
82
+ readonly "define.sandboxAgentNameRequired": "defineSandboxAgent 需要 name。";
83
+ readonly "define.sandboxCreateRequired": "defineSandbox 需要一个 create() 函数。";
84
+ readonly "define.sandboxNameRequired": "defineSandbox 需要 name。";
85
+ readonly "docker.commandTimeout": "Command timed out after {{timeoutMs}}ms";
86
+ readonly "docker.containerNotInitialized": "Container not initialized";
87
+ readonly "docker.imagePullDone": "Docker image ready: {{image}}";
88
+ readonly "docker.imagePullStart": "Pulling Docker image: {{image}}...";
89
+ readonly "docker.readFileFailed": "Failed to read file {{path}}: {{stderr}}";
90
+ readonly "docker.unsupportedRuntime": "Unsupported runtime: {{runtime}}";
91
+ readonly "hitl.answerNeedsOptionOrText": "t.respond 的对象形式需要 optionId 或 text 二选一(两者都没给)。";
92
+ readonly "hitl.invalidOption": "回答 \"{{optionId}}\" 不是请求 {{requestId}} 的可选项({{options}})。";
93
+ readonly "hitl.noOptions": "该请求没有可选项";
94
+ readonly "hitl.requestMissingId": "该 input.requested 请求没有稳定的 id,无法生成 responses——adapter 侧要给每条待回答请求一个稳定 id。";
95
+ readonly "hitl.respondAllEmpty": "没有待回答的 input.requested 请求,respond() / respondAll() 无法工作;先用 t.parked() 确认停轮,再用 t.requireInputRequest() 或 t.respond() 回答。";
96
+ readonly "hitl.respondEmpty": "t.respond(...) 至少需要一个回答。";
97
+ readonly "hitl.stringAmbiguous": "有 {{count}} 条待回答请求,字符串回答无法对位,请用 { request, optionId } 或 { request, text } 对象形式显式指名。";
98
+ readonly "judge.apiKeyMissing": "judge 缺少 API key(CODEX_API_KEY / OPENAI_API_KEY)。";
99
+ readonly "judge.httpError": "judge HTTP {{status}}: {{body}}";
100
+ readonly "judge.probeFailed": "judge 预检失败({{model}}): {{error}}";
101
+ readonly "judge.probeMissingKey": "judge 模型 {{model}} 缺少 API key —— 请配置 {{envHint}}";
102
+ readonly "live.more": "… 其余 {{hidden}} 项({{running}} 运行中 · {{waiting}} 等待 · {{done}} 已完成)";
103
+ readonly "live.running": " 正在运行 {{totalRuns}} 次 ({{evals}} eval × {{configs}} 配置, 并发 {{concurrency}}) {{completed}}/{{total}} 完成";
104
+ readonly "live.runningUnknown": " 正在运行… {{completed}}/{{total}} 完成";
105
+ readonly "live.waiting": "排队等待中…";
106
+ readonly "report.assertionThreshold": " (得分 {{score}} < {{threshold}})";
107
+ readonly "report.error": "错误";
108
+ readonly "report.errored": "错误";
109
+ readonly "report.failed": "失败";
110
+ readonly "report.gate": "gate";
111
+ readonly "report.passed": "通过";
112
+ readonly "report.result": "\n结果:{{parts}} ({{duration}} · {{tokens}}{{cost}})\n\n";
113
+ readonly "report.runStart": "\n本次运行 {{count}} 个 eval{{extra}}(并发 {{concurrency}})\n\n";
114
+ readonly "report.runStartExtra": " × {{configs}} 配置 = {{totalRuns}} 次运行";
115
+ readonly "report.viewHint": "运行 `pnpm exec niceeval view` 以图形化查看结果。\n";
116
+ readonly "report.skipped": "跳过";
117
+ readonly "report.soft": "soft";
118
+ readonly "report.summary.errored": "{{count}} 错误";
119
+ readonly "report.summary.failed": "{{count}} 失败";
120
+ readonly "report.summary.passed": "{{count}} 通过";
121
+ readonly "report.summary.skipped": "{{count}} 跳过";
122
+ readonly "report.table.agent": "Agent";
123
+ readonly "report.table.avgDuration": "平均耗时";
124
+ readonly "report.table.cost": "预估成本";
125
+ readonly "report.table.default": "默认";
126
+ readonly "report.table.duration": "耗时";
127
+ readonly "report.table.eval": "Eval";
128
+ readonly "report.table.evalTitle": "各 Eval:";
129
+ readonly "report.table.experiment": "实验";
130
+ readonly "report.table.experimentsTitle": "实验";
131
+ readonly "report.table.model": "模型";
132
+ readonly "report.table.reason": "原因";
133
+ readonly "report.table.result": "结果";
134
+ readonly "report.table.runs": "轮次";
135
+ readonly "report.table.status": "状态";
136
+ readonly "report.table.successRate": "成功率";
137
+ readonly "report.table.tokens": "Tokens";
138
+ readonly "otel.noSpans": "otel:本轮 0 span —— 端点没接上?(env 没注入 / 服务没重启 / 没 flush)";
139
+ readonly "otel.portInUse": "OTLP 接收端口 {{port}} 已被占用(另一个进程占着这个端口)。在 defineConfig({ telemetry: { port } }) 里换一个空闲端口,或者停掉占用 {{port}} 的进程后重试。";
140
+ readonly "otel.windowAttribution": "otel:span 未带本轮 traceparent,按时间窗口归属(该 agent 的轮次已串行;应用支持 W3C 传播后自动并发)";
141
+ readonly "runner.diffProgress": "采 diff:{{changed}} 改 / {{deleted}} 删";
142
+ readonly "runner.driveAgent": "驱动 agent…";
143
+ readonly "runner.evalSetup": "eval setup(装依赖)…";
144
+ readonly "runner.interrupted": " · 已中断:沙箱容器已清理,输出本次已完成的部分结果。\n";
145
+ readonly "runner.judgePrecheck": " · 预检 judge 配置…\n";
146
+ readonly "runner.otlpInSandbox": "OTLP in-sandbox collector → {{endpoint}}{{proto}}";
147
+ readonly "runner.otlpOverride": "OTLP 接收器(覆盖 host) → {{endpoint}}";
148
+ readonly "runner.otlpReceiver": "OTLP 接收器 → {{endpoint}}{{proto}}";
149
+ readonly "runner.otlpShared": "OTLP 共享接收器(run 级) → {{endpoint}}";
150
+ readonly "runner.remoteSandboxUnavailable": "remote agent 没有 sandbox.{{method}};请改用 sandbox agent 或移除 workspace 断言。";
151
+ readonly "runner.reporterDiagnostic": " · [diagnostic] {{stage}} 失败(已忽略):{{message}}\n";
152
+ readonly "runner.scoreJudge": "评分 / judge…";
153
+ readonly "runner.skip": "skip:{{reason}}";
154
+ readonly "runner.startAgentSetup": "agent setup(装 CLI / 写配置)…";
155
+ readonly "runner.startAgentTracing": "agent tracing(写 otel 导出配置)…";
156
+ readonly "runner.startSandbox": "起沙箱…";
157
+ readonly "runner.startSandboxSetup": "sandbox setup(环境预置钩子)…";
158
+ readonly "runner.startSandboxTeardown": "sandbox teardown(环境预置钩子)…";
159
+ readonly "runner.timeout": "attempt 超时({{timeoutMs}}ms)\n最近进度:\n{{recentLogs}}";
160
+ readonly "runner.traceSelected": " → 留 {{count}}(按语义)";
161
+ readonly "runner.resumeCarry": " · 复用上次 {{carried}} 个已判定的结果,重跑 {{retry}} 个 eval\n";
162
+ readonly "runner.resumeCarryDetail": " 复用 [{{experiment}}] {{evals}}\n";
163
+ readonly "runner.useRemoteAgent": "使用 remote agent(不创建沙箱)…";
164
+ readonly "sandbox.providerNotImplemented": "{{provider}} sandbox provider not implemented; use docker, vercel, or e2b";
165
+ readonly "sandbox.missingSpec": string;
166
+ readonly "sandbox.dependencyMissing.docker": "Docker sandbox requires 'dockerode'. Install it with: pnpm add dockerode @types/dockerode";
167
+ readonly "sandbox.dependencyMissing.e2b": "E2B sandbox requires 'e2b'. Install it with: pnpm add e2b";
168
+ readonly "sandbox.dependencyMissing.vercel": "Vercel sandbox requires '@vercel/sandbox'. Install it with: pnpm add @vercel/sandbox";
169
+ readonly "sandbox.forceCleanup": " · [sandbox] 强制清理 {{count}} 个沙箱…\n";
170
+ readonly "sandbox.stopFailed": " · [sandbox] 停沙箱 {{id}} 失败(已忽略,靠 provider 过期兜底):{{message}}\n";
171
+ readonly "sandbox.stopTimeout": "stop 超时({{timeoutMs}}ms)";
172
+ readonly "scoring.evalError": "评估出错: {{error}}";
173
+ readonly "session.fileFallback": "[file]";
174
+ readonly "session.tools": "{{count}} 工具";
175
+ readonly "session.turn.primary": "第{{turn}}轮";
176
+ readonly "session.turn.secondary": "会话{{session}}·第{{turn}}轮";
177
+ readonly "util.requiredEnv": "缺少必需的环境变量 {{name}}(请在 .env 里配置)。";
178
+ readonly "vercel.fileNotFound": "File not found: {{path}}";
179
+ readonly "vercel.rotateFailed": "[VercelSandbox] session rotate failed ({{seconds}}s): {{error}}";
180
+ readonly "vercel.rotated": "[VercelSandbox] session rotated after {{seconds}}s → {{sessionId}}";
181
+ };
182
+ export type MessageKey = keyof typeof zhCN;
183
+ export type Messages = Record<MessageKey, string>;
@@ -0,0 +1,103 @@
1
+ import type { InputRequest, JsonValue, StreamEvent, ToolName, TraceSpan } from "../types.ts";
2
+ interface ExecutionNodeBase {
3
+ /** 本函数内确定性生成,同一份 (events, spans) 输入永远产出同一批 id(不是全局稳定 id,
4
+ * 不跨调用持久化——目前没有下游需要跨次运行比对同一个节点)。 */
5
+ id: string;
6
+ /** 唯一关联上的 OTel span(供下钻;渲染层用 endMs - startMs 算耗时)。action 节点的
7
+ * span.attributes 额外补了 io.tool/io.input/io.output/io.status(见 withIoAttributes);
8
+ * 其余节点原样保留。缺失 = timing unavailable——要么这次运行没有 OTel 接入,要么有 span
9
+ * 但没能唯一关联到这个节点上;两种情况都不是「假装有耗时」,统一表现为字段不存在。 */
10
+ span?: TraceSpan;
11
+ }
12
+ export interface ExecutionMessageNode extends ExecutionNodeBase {
13
+ kind: "message";
14
+ role: "assistant" | "user";
15
+ text: string;
16
+ }
17
+ export interface ExecutionThinkingNode extends ExecutionNodeBase {
18
+ kind: "thinking";
19
+ text: string;
20
+ }
21
+ /** Skill 加载节点——一等,直接来自 StreamEvent 的 "skill.loaded",不靠工具名/文本猜。 */
22
+ export interface ExecutionSkillNode extends ExecutionNodeBase {
23
+ kind: "skill.loaded";
24
+ skill: string;
25
+ /**
26
+ * 仅当原生协议把 Skill 加载表达成可关联的工具调用时才有,和 StreamEvent 同名字段同一含义。
27
+ * 存在时参与和 action/subagent 节点同一套 callId 关联(见主函数 nodeByCallId):Claude Code
28
+ * 的 Skill 调用本身就是一次 tool_use,OTel mapper 同样会把它的 tool_use_id 复制成
29
+ * span.attributes.call_id,唯一命中时这个节点也应该拿到 timing,不因为节点 kind 是
30
+ * skill.loaded 就被排除在 enrichment 之外。
31
+ */
32
+ callId?: string;
33
+ }
34
+ /**
35
+ * action.called + action.result 按 callId 合并成一个节点。`status` 多了 "pending"
36
+ * (StreamEvent 的 action.result.status 没有这一档)——这是 ExecutionTree 独有的中间态,
37
+ * 表示这次运行结束时结果始终没有回来(如超时截断的 transcript),诚实地区分「还没完成」
38
+ * 和「跑完但失败/被拒绝」。
39
+ */
40
+ export interface ExecutionActionNode extends ExecutionNodeBase {
41
+ kind: "action";
42
+ callId: string;
43
+ /** 原始工具名(未归一化),对齐 StreamEvent.action.called.name。 */
44
+ name: string;
45
+ /** 归一化后的规范工具名,省略表示 adapter 没能归一(等同 ToolCall.name 缺省为 "unknown")。 */
46
+ tool?: ToolName;
47
+ input: JsonValue;
48
+ output?: JsonValue;
49
+ status: "pending" | "completed" | "failed" | "rejected";
50
+ }
51
+ /** subagent.called + subagent.completed 按 callId 合并;pending 语义同 ExecutionActionNode。 */
52
+ export interface ExecutionSubagentNode extends ExecutionNodeBase {
53
+ kind: "subagent";
54
+ callId: string;
55
+ name: string;
56
+ remoteUrl?: string;
57
+ output?: JsonValue;
58
+ status: "pending" | "completed" | "failed";
59
+ }
60
+ export interface ExecutionInputRequestedNode extends ExecutionNodeBase {
61
+ kind: "input.requested";
62
+ request: InputRequest;
63
+ }
64
+ export interface ExecutionCompactionNode extends ExecutionNodeBase {
65
+ kind: "compaction";
66
+ reason?: string;
67
+ }
68
+ export interface ExecutionErrorNode extends ExecutionNodeBase {
69
+ kind: "error";
70
+ message: string;
71
+ }
72
+ /**
73
+ * span 存在、有意义,但唯一关联不到任何骨架节点——原样保留成独立节点,清楚标注「只有遥测、
74
+ * 没有对应事件」,不悄悄猜着并进某个骨架节点。`span` 是必填字段:这类节点的全部内容就是
75
+ * 这一条 span 本身,没有骨架事件可以叠加。
76
+ */
77
+ export interface ExecutionTelemetryNode {
78
+ kind: "telemetry";
79
+ id: string;
80
+ span: TraceSpan;
81
+ }
82
+ export type ExecutionNode = ExecutionMessageNode | ExecutionThinkingNode | ExecutionSkillNode | ExecutionActionNode | ExecutionSubagentNode | ExecutionInputRequestedNode | ExecutionCompactionNode | ExecutionErrorNode | ExecutionTelemetryNode;
83
+ export interface ExecutionTree {
84
+ /**
85
+ * 骨架节点在前,顺序 = 事件出现顺序;telemetry-only 节点(未能唯一关联的 span)
86
+ * 按 span.startMs 追加在骨架之后——它们不属于骨架,不改变骨架的节点/顺序/内容,
87
+ * 只是叠加在末尾的额外证据。
88
+ */
89
+ nodes: ExecutionNode[];
90
+ /**
91
+ * 这次运行是否提供过任何 span——不代表关联成功,只代表「OTel 接入过」。供渲染层区分
92
+ * 两种不同的诚实提示:整体没有 OTel 接入(该字段为 false,所有节点自然都没有 span),
93
+ * 和 OTel 接入了但这一个节点恰好关联不上(该字段为 true,该节点的 span 仍缺失)。
94
+ */
95
+ timingAvailable: boolean;
96
+ }
97
+ /**
98
+ * 纯函数:把标准事件流(骨架)与一批已挑选好的 OTel span(可选 enrichment)合成一棵
99
+ * ExecutionTree。events 决定节点的存在、顺序与内容;spans 只能给已存在的节点补时间,
100
+ * 从不新增、删除或重排骨架节点。
101
+ */
102
+ export declare function buildExecutionTree(events: readonly StreamEvent[], spans: readonly TraceSpan[]): ExecutionTree;
103
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { TraceSpan } from "../../types.ts";
2
+ /** 按 Content-Type 选编码,失败一律回空数组(导出端不该因我们解析挂而报错)。 */
3
+ export declare function parseOtlpTraces(body: Buffer, contentType: string): TraceSpan[];
@@ -0,0 +1,21 @@
1
+ import { Effect } from "effect";
2
+ import type { TraceSpan } from "../../types.ts";
3
+ export interface TraceReceiver {
4
+ /** agent 应导出到的完整端点(host 由 provider 定:docker → host.docker.internal)。 */
5
+ endpoint(host: string): string;
6
+ /** 目前为止收到并解析出的全部 span(副本)。 */
7
+ collect(): TraceSpan[];
8
+ /** 给在途的最后一批导出留点落地时间(无新 span 持续 quietMs 即返回,至多 maxMs)。 */
9
+ settle(quietMs: number, maxMs: number): Promise<void>;
10
+ close(): Promise<void>;
11
+ }
12
+ /**
13
+ * 创建 OTLP 接收器,并把 close() 注册为 Scope 回收动作(免端口泄漏)。
14
+ * 在 Effect.scoped / Effect.gen 里 yield* 即可。
15
+ */
16
+ export declare function createTraceReceiver(): Effect.Effect<TraceReceiver, never, import("effect/Scope").Scope>;
17
+ /**
18
+ * 直接创建接收器(非 Effect 场景:run 级共享池自己管生命周期)。
19
+ * port=0 挑临时端口;固定端口模式(config telemetry.port / NICEEVAL_OTLP_PORT)传定值。
20
+ */
21
+ export declare function makeTraceReceiver(port?: number): Promise<TraceReceiver>;
@@ -0,0 +1,22 @@
1
+ import type { ToolCall, TraceSpan } from "../../types.ts";
2
+ /**
3
+ * 选出要保留并落盘的 span。
4
+ * 小 trace 原样返回;大 trace 按 canonical kind 过滤(kind ≠ "other" 留);
5
+ * 没 mapper(kind 全 "other")则回落到 firehose 频率过滤;仍过多再按耗时硬截断。
6
+ * 最后一律按起点排序,view 直接当瀑布图渲染。
7
+ */
8
+ export declare function selectTraceSpans(spans: TraceSpan[]): TraceSpan[];
9
+ /**
10
+ * I/O 文本上限:文件内容/命令输出可能很大,截一下别把 trace 撑爆。导出给
11
+ * `execution-tree.ts` 复用——ExecutionTree 的 action 节点给合并上去的 span 补同一份
12
+ * io.* attributes,必须和这里同一个截断预算,不能另立一个数字。
13
+ */
14
+ export declare const IO_MAX = 4000;
15
+ export declare function ioText(v: unknown): string;
16
+ /**
17
+ * 给工具执行 span 补上真实「入参/出参」:codex 等的 OTLP span 只带 tool_name/call_id,
18
+ * 命令文本与输出在 stdout transcript(events)里 —— 按 call_id 把 deriveRunFacts 的
19
+ * ToolCall.input/output join 到对应 span 的 attributes(io.input / io.output / io.tool)。
20
+ * 没匹配上的 span 原样返回。
21
+ */
22
+ export declare function enrichTraceWithIO(spans: TraceSpan[], toolCalls: readonly ToolCall[]): TraceSpan[];
@@ -0,0 +1,43 @@
1
+ import type { TraceSpan } from "../../types.ts";
2
+ import type { TraceReceiver } from "./receiver.ts";
3
+ export interface TurnSpans {
4
+ /** 本轮生成的 traceId(供 attempt 末尾 sweep 迟到 span)。 */
5
+ traceId: string;
6
+ /** 归属到本轮的 span。 */
7
+ spans: TraceSpan[];
8
+ /** 本轮归属用的是 traceparent 还是时间窗口(日志/守卫用)。 */
9
+ attribution: "traceparent" | "window";
10
+ }
11
+ /** 一个 agent(= 一个被测进程)整个 run 的 OTLP 通道:receiver + 归属状态。 */
12
+ export declare class AgentOtelChannel {
13
+ readonly receiver: TraceReceiver;
14
+ /** traceparent 已确认生效(收到过带我们 traceId 的 span)→ 并发守卫解除。 */
15
+ private confirmed;
16
+ /** 串行守卫:未确认 traceparent 时,同 agent 的轮次挨个跑(promise 链当互斥锁)。 */
17
+ private chain;
18
+ /** 已归属过的 span(spanId),共享流里不能重复分给两轮。 */
19
+ private readonly consumed;
20
+ constructor(receiver: TraceReceiver);
21
+ /**
22
+ * 跑一轮:fn 拿到本轮的 W3C trace context headers(spread 进请求头 / 注入子进程 env),
23
+ * 返回后 settle 接收器、归属本轮 span。未确认 traceparent 前整段(含 fn)串行。
24
+ */
25
+ runTurn<T>(fn: (headers: Readonly<Record<string, string>>) => Promise<T>): Promise<{
26
+ result: T;
27
+ } & TurnSpans>;
28
+ /** 是否仍在串行守卫下(日志提示用)。 */
29
+ get serialized(): boolean;
30
+ /** attempt 末尾:按本 attempt 的 traceId 集合捞迟到的 span(Batch 导出等)。 */
31
+ sweep(traceIds: ReadonlySet<string>): Promise<TraceSpan[]>;
32
+ }
33
+ /**
34
+ * run 级共享池:每个 agent 一个通道(懒建)。固定端口模式(defineConfig({ telemetry: { port } }))
35
+ * 下全部 agent 共用一个通道 —— 端口只有一个,归属守卫也必须全局共享。
36
+ */
37
+ export declare class OtelReceiverPool {
38
+ private readonly fixedPort?;
39
+ private readonly channels;
40
+ constructor(fixedPort?: number | undefined);
41
+ channel(agentName: string): Promise<AgentOtelChannel>;
42
+ close(): Promise<void>;
43
+ }
@@ -0,0 +1,190 @@
1
+ import type { JsonValue, SourceLoc } from "../shared/types.ts";
2
+ /** 一次运行的 token 用量(沙箱型从 transcript/OTel span 的 `gen_ai.usage.*` 属性抠,remote 由 send 的 `Turn.usage` 直接返回)。 */
3
+ export interface Usage {
4
+ /** 输入(prompt)token 数,不含缓存命中部分。 */
5
+ inputTokens: number;
6
+ /** 输出(completion)token 数。 */
7
+ outputTokens: number;
8
+ /** 命中 prompt 缓存、按缓存价读取的 token 数(省略表示该 agent 不上报此项)。 */
9
+ cacheReadTokens?: number;
10
+ /** 写入 prompt 缓存的 token 数(省略表示该 agent 不上报此项)。 */
11
+ cacheWriteTokens?: number;
12
+ /** 本次运行触发的模型请求次数(多轮/重试可能大于 1)。 */
13
+ requests?: number;
14
+ /**
15
+ * 网关/adapter 实测的真实美元成本(只能由 `Turn.usage.costUSD` 显式带回,从不从
16
+ * token 用量或 OTel span 反推得到)。存在时优先于按价格表(`defineConfig({ pricing })`)
17
+ * 估算的成本——见 `estimateCost` 的 `usage.costUSD ?? estimateCost(...)` 兜底顺序。
18
+ */
19
+ costUSD?: number;
20
+ }
21
+ /** 跨 agent 归一化后的规范工具名。 */
22
+ export type ToolName = "file_read" | "file_write" | "file_edit" | "shell" | "web_fetch" | "web_search" | "glob" | "grep" | "list_dir" | "agent_task" | "unknown";
23
+ /** HITL 停轮请求的结构化描述,供 `t.requireInputRequest(filter)` / `t.respondAll` 按条件匹配。 */
24
+ export interface InputRequest {
25
+ /** 请求的唯一标识;多个请求并停时,`InputResponse.requestId` 靠它对位。 */
26
+ readonly id?: string;
27
+ /** 模型提出的原始问题/文本(用于 `stringMatches` 过滤)。 */
28
+ readonly prompt?: string;
29
+ /** adapter 自定义的人类可读展示文案,与 `prompt` 二选一或并存,用于 UI/日志展示及过滤匹配。 */
30
+ readonly display?: string;
31
+ /** 请求关联的动作类型(如某个待批准的工具调用名),供过滤用。 */
32
+ readonly action?: string;
33
+ /** 请求携带的结构化输入(如待批准命令的参数)。 */
34
+ readonly input?: JsonValue;
35
+ /** 若请求提供了预设选项(如批准/拒绝),逐项列出;`id` 对应 `InputResponse.optionId`。 */
36
+ readonly options?: readonly {
37
+ id: string;
38
+ label?: string;
39
+ }[];
40
+ }
41
+ /**
42
+ * 标准事件流的词汇(对标 docs/feature/adapters/architecture/events.md)。adapter 唯一的硬活就是把
43
+ * 各 agent 五花八门的原始 transcript 映射成 StreamEvent[];映射完,整套断言免费。
44
+ */
45
+ export type StreamEvent =
46
+ /** 一条文本消息(assistant 回复或 user 输入);`loc` 是可选的源码位置,用于把消息叠回 eval 源码。 */
47
+ {
48
+ type: "message";
49
+ role: "assistant" | "user";
50
+ text: string;
51
+ loc?: SourceLoc;
52
+ }
53
+ /** 发起一次工具/动作调用;`tool` 是归一化后的规范工具名,原始名保留在 DerivedFacts.ToolCall.originalName。 */
54
+ | {
55
+ type: "action.called";
56
+ callId: string;
57
+ name: string;
58
+ input: JsonValue;
59
+ tool?: ToolName;
60
+ }
61
+ /** 一次工具/动作调用的结果,按 `callId` 与对应的 `action.called` 对位。 */
62
+ | {
63
+ type: "action.result";
64
+ callId: string;
65
+ output?: JsonValue;
66
+ status: "completed" | "failed" | "rejected";
67
+ }
68
+ /**
69
+ * 一次 Skill 加载:一等事件,由 adapter 从原生协议里识别出「这是加载 Skill」并直接产出,
70
+ * 不靠 renderer 按工具名/文本猜。`callId` 仅当原生协议把 Skill 加载表达成可关联的工具调用时才有。
71
+ */
72
+ | {
73
+ type: "skill.loaded";
74
+ skill: string;
75
+ callId?: string;
76
+ }
77
+ /** 发起一次子 agent 调用(如 Task 工具、远程 sub-agent);`remoteUrl` 仅远程子 agent 有。 */
78
+ | {
79
+ type: "subagent.called";
80
+ callId: string;
81
+ name: string;
82
+ remoteUrl?: string;
83
+ }
84
+ /** 一次子 agent 调用的结果,按 `callId` 与对应的 `subagent.called` 对位。 */
85
+ | {
86
+ type: "subagent.completed";
87
+ callId: string;
88
+ output?: JsonValue;
89
+ status: "completed" | "failed";
90
+ }
91
+ /** 模型停下来向人请求输入(HITL);具体请求内容见 InputRequest。 */
92
+ | {
93
+ type: "input.requested";
94
+ request: InputRequest;
95
+ }
96
+ /** 模型的思考/推理文本(非最终回复)。 */
97
+ | {
98
+ type: "thinking";
99
+ text: string;
100
+ }
101
+ /** 上下文被压缩/摘要(如超长会话截断历史);`reason` 是可选的压缩原因说明。 */
102
+ | {
103
+ type: "compaction";
104
+ reason?: string;
105
+ }
106
+ /** 运行中出现的错误。 */
107
+ | {
108
+ type: "error";
109
+ message: string;
110
+ };
111
+ /** core 从事件流折叠出的结构化事实(deriveRunFacts)。 */
112
+ export interface ToolCall {
113
+ callId: string;
114
+ name: ToolName;
115
+ originalName?: string;
116
+ input: JsonValue;
117
+ output?: JsonValue;
118
+ status: "completed" | "failed" | "rejected";
119
+ }
120
+ export interface SubagentCall {
121
+ callId: string;
122
+ name: string;
123
+ remoteUrl?: string;
124
+ output?: JsonValue;
125
+ status: "completed" | "failed";
126
+ }
127
+ export interface DerivedFacts {
128
+ readonly toolCalls: readonly ToolCall[];
129
+ readonly subagentCalls: readonly SubagentCall[];
130
+ readonly inputRequests: readonly InputRequest[];
131
+ readonly parked: boolean;
132
+ readonly messageCount: number;
133
+ readonly compactions: number;
134
+ }
135
+ /**
136
+ * span 的【语义角色】,从 OTel GenAI 语义约定的 gen_ai.operation.name 归一而来
137
+ * (见 o11y/otlp/canonical.ts)。view 据此着色 / 分组 / 跨 agent 对比,**只认这个,
138
+ * 不读原生 span 名**。未识别的 span 落 "other",view 折叠。
139
+ */
140
+ export type SpanKind = "turn" | "model" | "tool" | "agent" | "other";
141
+ /**
142
+ * 一条分布式追踪的 span(从 agent 经 OpenTelemetry 导出的 OTLP traces 归一而来)。
143
+ * 与 StreamEvent 不同:它带【时间】(起止 epoch 毫秒)与【父子】(parentSpanId),
144
+ * 所以 view 能画成瀑布图。事件流回答「做了什么」,trace 回答「各花了多久、谁套谁」。
145
+ *
146
+ * 两层归一:线格式层(OTLP/JSON|protobuf → 本结构,见 otlp/parse.ts,通用);
147
+ * 语义层(原生 span 名/属性 → canonical GenAI semconv,见 otlp/mappers/<agent>.ts,每 agent 一个薄 mapper)。
148
+ */
149
+ export interface TraceSpan {
150
+ traceId: string;
151
+ spanId: string;
152
+ parentSpanId?: string;
153
+ name: string;
154
+ /** span 起点 / 终点(epoch 毫秒)。 */
155
+ startMs: number;
156
+ endMs: number;
157
+ status?: "ok" | "error" | "unset";
158
+ /**
159
+ * 归一后的语义角色(每-agent mapper 据 canonical GenAI semconv 定;view/select 只认它)。
160
+ * 未经 mapper 或未识别时为 undefined / "other"。
161
+ */
162
+ kind?: SpanKind;
163
+ /** OTLP span 属性(gen_ai.* / tool 名 / token 等),按 key 摊平。raw 属性始终保留供下钻。 */
164
+ attributes?: Record<string, JsonValue>;
165
+ }
166
+ /** 给人 / 给 EVAL.ts 看的 o11y 摘要(注入沙箱 __niceeval__/results.json)。 */
167
+ export interface O11ySummary {
168
+ totalTurns: number;
169
+ /** 只有跑之前调用过的 canonical 工具名才有 key,不是全量出现;省略的 ToolName 视为 0。 */
170
+ toolCalls: Partial<Record<ToolName, number>>;
171
+ totalToolCalls: number;
172
+ filesRead: string[];
173
+ filesModified: string[];
174
+ shellCommands: {
175
+ command: string;
176
+ exitCode?: number;
177
+ success?: boolean;
178
+ }[];
179
+ webFetches: {
180
+ url: string;
181
+ status?: number;
182
+ success?: boolean;
183
+ }[];
184
+ errors: string[];
185
+ thinkingBlocks: number;
186
+ compactions: number;
187
+ durationMs: number;
188
+ usage: Usage;
189
+ estimatedCostUSD?: number;
190
+ }
@@ -0,0 +1,57 @@
1
+ import type { AttemptHandle, Selection, SelectionWarning, Snapshot } from "../results/types.ts";
2
+ import { type AttemptLocator } from "../results/locator.ts";
3
+ import type { Aggregator, DimensionInput, Metric, MetricCell, MetricColumn, FlagRef } from "./types.ts";
4
+ import { evalPrefixPredicate } from "../shared/aggregate.ts";
5
+ /** flag 未声明时的组名:不猜,如实归一组。 */
6
+ export declare const FLAG_UNSET = "(unset)";
7
+ /** 计算函数的第一参:Selection(warnings 随行)或手工挑的快照数组(没有挑选过程,自然无警告)。 */
8
+ export type SnapshotsInput = Selection | Snapshot[];
9
+ export declare function resolveInput(input: SnapshotsInput): {
10
+ snapshots: Snapshot[];
11
+ warnings: SelectionWarning[];
12
+ };
13
+ /** 展平后的一条样本:attempt + 它所属的快照(维度解析与题级折叠都需要快照身份)。 */
14
+ export interface Item {
15
+ snapshot: Snapshot;
16
+ attempt: AttemptHandle;
17
+ }
18
+ export declare function experimentIdOf(item: Item): string;
19
+ export declare function evalIdOf(item: Item): string;
20
+ /** 快照键:与 view Compare 同口径的 "<experimentId> @ <startedAt>"。 */
21
+ export declare function snapshotKeyOf(snapshot: Snapshot): string;
22
+ /**
23
+ * 一条 Item 的 AttemptLocator:真实读取路径(openResults() 产出的 handle)恒有
24
+ * `attempt.locator`;手工构造的测试 fixture 若省略它,按当前身份元组兜底算一份
25
+ * (与 `loadAttemptEvidence`、`open.ts` 的回填同一口径)——只服务这类场景,不改变真实
26
+ * 读取路径的行为。
27
+ */
28
+ export declare function locatorOf(item: Item): AttemptLocator;
29
+ /**
30
+ * 展平 + 聚合前去重(niceeval/results 的 dedupeAttempts,身份键
31
+ * (experimentId, evalId, attempt, startedAt))。missing-startedAt 的警告不透出:
32
+ * 官方产出永不缺 startedAt,缺失只可能来自 legacy 落盘,「不去重、如实保留重复」即终稿。
33
+ */
34
+ export declare function collectItems(snapshots: Snapshot[]): Item[];
35
+ export { evalPrefixPredicate };
36
+ export declare function filterItems(items: Item[], evals?: string | string[]): Item[];
37
+ export declare function dimensionName(dimension: DimensionInput): string;
38
+ /** eval id 的第一段:"algebra/quadratic" → "algebra";没有 "/" 时就是 id 本身。 */
39
+ export declare function evalGroupOf(id: string): string;
40
+ /** flag 声明值 → 组标签:label 函数优先,其余 String();未声明 → FLAG_UNSET。 */
41
+ export declare function flagGroupKey(ref: FlagRef, item: Item): string;
42
+ /** flag 作轴:要求数值;未声明或非数值 → null(点不画,注脚报数)。 */
43
+ export declare function flagAxisValue(ref: FlagRef, item: Item): number | null;
44
+ export declare function dimensionKey(dimension: DimensionInput, item: Item): string;
45
+ /** 按维度分组,保持首次出现顺序(无 sort 时表格行序即此序)。 */
46
+ export declare function groupItems(items: Item[], dimension: DimensionInput): Map<string, Item[]>;
47
+ export declare function applyAggregator(aggregator: Aggregator, values: number[]): number;
48
+ /** where 不满足 → null,语义等价于 value 开头 return null。 */
49
+ export declare function evaluateMetric(metric: Metric, attempt: AttemptHandle): Promise<number | null>;
50
+ export declare function displayValue(metric: Metric, value: number | null): string;
51
+ /**
52
+ * 一个格子:组内 attempt → 两级聚合 → 终值。
53
+ * null 值不进聚合但计入 total(覆盖率经 samples/total 如实暴露);全 null → value null。
54
+ */
55
+ export declare function computeCell(metric: Metric, items: Item[]): Promise<MetricCell>;
56
+ export declare function toColumn(metric: Metric): MetricColumn;
57
+ export declare function assertUniqueMetricNames(metrics: readonly Metric[], where: string): void;