niceeval 0.6.1 → 0.7.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.
- package/INDEX.md +23 -23
- package/README.zh.md +6 -6
- package/dist/agents/types.d.ts +69 -7
- package/dist/context/types.d.ts +32 -12
- package/dist/i18n/en.d.ts +54 -0
- package/dist/i18n/zh-CN.d.ts +57 -3
- package/dist/o11y/types.d.ts +16 -2
- package/dist/report/aggregate.d.ts +32 -24
- package/dist/report/aggregate.js +158 -50
- package/dist/report/built-in/index.d.ts +2 -0
- package/dist/report/built-in/index.js +8 -0
- package/dist/report/components.d.ts +93 -160
- package/dist/report/components.js +377 -114
- package/dist/report/compute.d.ts +87 -81
- package/dist/report/compute.js +597 -417
- package/dist/report/flag.d.ts +32 -6
- package/dist/report/flag.js +92 -4
- package/dist/report/format.d.ts +19 -11
- package/dist/report/format.js +30 -13
- package/dist/report/index.d.ts +16 -16
- package/dist/report/index.js +20 -21
- package/dist/report/load.js +3 -2
- package/dist/report/locale.d.ts +57 -33
- package/dist/report/locale.js +122 -56
- package/dist/report/metrics.d.ts +23 -4
- package/dist/report/metrics.js +110 -25
- package/dist/report/primitives.d.ts +48 -15
- package/dist/report/primitives.js +135 -26
- package/dist/report/react/AttemptList.d.ts +9 -7
- package/dist/report/react/AttemptList.js +17 -10
- package/dist/report/react/DeltaTable.js +19 -18
- package/dist/report/react/EvalList.d.ts +4 -4
- package/dist/report/react/EvalList.js +0 -0
- package/dist/report/react/ExperimentComparison.d.ts +10 -0
- package/dist/report/react/ExperimentComparison.js +12 -0
- package/dist/report/react/ExperimentList.d.ts +4 -3
- package/dist/report/react/ExperimentList.js +17 -18
- package/dist/report/react/MetricBars.js +5 -4
- package/dist/report/react/MetricLine.js +12 -5
- package/dist/report/react/MetricMatrix.js +1 -1
- package/dist/report/react/MetricScatter.js +59 -28
- package/dist/report/react/MetricTable.js +2 -12
- package/dist/report/react/ScopeSummary.d.ts +10 -0
- package/dist/report/react/ScopeSummary.js +17 -0
- package/dist/report/react/Scoreboard.js +6 -6
- package/dist/report/react/cell.js +2 -2
- package/dist/report/react/chart-math.d.ts +23 -6
- package/dist/report/react/chart-math.js +71 -19
- package/dist/report/react/fixtures.d.ts +5 -9
- package/dist/report/react/fixtures.js +110 -147
- package/dist/report/react/index.d.ts +15 -5
- package/dist/report/react/index.js +18 -7
- package/dist/report/report.d.ts +137 -16
- package/dist/report/report.js +259 -28
- package/dist/report/text/faces.d.ts +17 -19
- package/dist/report/text/faces.js +253 -184
- package/dist/report/text/plot.js +1 -1
- package/dist/report/text/table.js +38 -7
- package/dist/report/tree.d.ts +90 -40
- package/dist/report/tree.js +252 -94
- package/dist/report/types.d.ts +247 -284
- package/dist/report/types.js +4 -3
- package/dist/report/web.d.ts +21 -5
- package/dist/report/web.js +42 -16
- package/dist/results/select.d.ts +38 -16
- package/dist/results/select.js +73 -25
- package/dist/results/types.d.ts +49 -14
- package/dist/runner/feedback/sink.d.ts +110 -0
- package/dist/runner/types.d.ts +513 -22
- package/dist/sandbox/docker.d.ts +23 -2
- package/dist/sandbox/e2b.d.ts +15 -1
- package/dist/sandbox/errors.d.ts +30 -3
- package/dist/sandbox/io-retry.d.ts +17 -0
- package/dist/sandbox/registry.d.ts +2 -0
- package/dist/sandbox/resolve.d.ts +18 -5
- package/dist/sandbox/retry.d.ts +11 -1
- package/dist/sandbox/types.d.ts +39 -5
- package/dist/sandbox/vercel.d.ts +7 -1
- package/dist/scoring/coverage.d.ts +30 -0
- package/dist/scoring/display.d.ts +21 -0
- package/dist/scoring/display.js +120 -0
- package/dist/scoring/types.d.ts +103 -20
- package/dist/shared/aggregate.d.ts +4 -2
- package/dist/shared/aggregate.js +8 -7
- package/dist/shared/types.d.ts +28 -0
- package/dist/tty-line.d.ts +0 -4
- package/dist/util.d.ts +23 -0
- package/docs-site/zh/README.md +44 -0
- package/docs-site/zh/examples/ai-agent-application.mdx +63 -0
- package/docs-site/zh/examples/coding-agent-extensions.mdx +57 -0
- package/docs-site/zh/examples/index.mdx +50 -0
- package/docs-site/zh/{concepts → explanation}/adapter.mdx +31 -13
- package/docs-site/zh/{concepts → explanation}/assert.mdx +7 -7
- package/docs-site/zh/{concepts → explanation}/drive.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/evals.mdx +4 -4
- package/docs-site/zh/{concepts → explanation}/experiment.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/hitl.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/judge.mdx +5 -5
- package/docs-site/zh/{concepts → explanation}/overview.mdx +11 -11
- package/docs-site/zh/{guides → explanation}/runner.mdx +18 -8
- package/docs-site/zh/{concepts → explanation}/tier.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/agent-feedback-loop.mdx +35 -33
- package/docs-site/zh/{guides → how-to}/authoring.mdx +35 -2
- package/docs-site/zh/{guides → how-to}/ci-integration.mdx +23 -12
- package/docs-site/zh/{guides → how-to}/connect-otel.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/connect-your-agent.mdx +47 -21
- package/docs-site/zh/{guides → how-to}/custom-reports.mdx +34 -39
- package/docs-site/zh/{guides → how-to}/dataset-fanout.mdx +25 -3
- package/docs-site/zh/{guides → how-to}/experiments.mdx +12 -5
- package/docs-site/zh/how-to/publish-report.mdx +105 -0
- package/docs-site/zh/{guides → how-to}/reporters.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/sandbox-agent.mdx +56 -7
- package/docs-site/zh/how-to/sandbox-providers.mdx +350 -0
- package/docs-site/zh/{guides → how-to}/scoring-guide.mdx +4 -4
- package/docs-site/zh/{guides → how-to}/viewing-results.mdx +82 -39
- package/docs-site/zh/{guides → how-to}/write-experiment.mdx +6 -4
- package/docs-site/zh/{guides → how-to}/write-send.mdx +30 -14
- package/docs-site/zh/index.mdx +24 -26
- package/docs-site/zh/introduction.mdx +8 -8
- package/docs-site/zh/reference/builtin-agents.mdx +32 -5
- package/docs-site/zh/reference/capabilities.mdx +8 -8
- package/docs-site/zh/reference/cli.mdx +40 -12
- package/docs-site/zh/reference/define-agent.mdx +58 -5
- package/docs-site/zh/reference/define-config.mdx +1 -1
- package/docs-site/zh/reference/define-eval.mdx +42 -9
- package/docs-site/zh/reference/events.mdx +3 -3
- package/docs-site/zh/reference/expect.mdx +26 -1
- package/docs-site/zh/{guides → reference}/official-adapters.mdx +32 -8
- package/docs-site/zh/{guides → reference}/report-components.mdx +45 -33
- package/docs-site/zh/{guides → reference}/results-data.mdx +21 -13
- package/docs-site/zh/troubleshooting/debug-sandbox.mdx +57 -0
- package/docs-site/zh/troubleshooting/debugging.mdx +212 -0
- package/docs-site/zh/{quickstart.mdx → tutorials/quickstart.mdx} +5 -17
- package/package.json +10 -2
- package/src/agents/ai-sdk-otel.test.ts +1 -0
- package/src/agents/ai-sdk.test.ts +3 -0
- package/src/agents/ai-sdk.ts +3 -0
- package/src/agents/bub-install-spec.test.ts +34 -0
- package/src/agents/bub-install-spec.ts +32 -0
- package/src/agents/bub.ts +31 -32
- package/src/agents/claude-code.test.ts +130 -9
- package/src/agents/claude-code.ts +76 -4
- package/src/agents/codex.test.ts +189 -40
- package/src/agents/codex.ts +155 -14
- package/src/agents/coding-cli-versions.test.ts +15 -0
- package/src/agents/coding-cli-versions.ts +3 -0
- package/src/agents/index.ts +13 -2
- package/src/agents/langgraph.test.ts +204 -0
- package/src/agents/langgraph.ts +495 -0
- package/src/agents/marketplace.ts +85 -0
- package/src/agents/native-config.test.ts +179 -0
- package/src/agents/native-config.ts +267 -0
- package/src/agents/openai-compat.test.ts +1 -0
- package/src/agents/openai-compat.ts +1 -1
- package/src/agents/openclaw.test.ts +31 -0
- package/src/agents/openclaw.ts +171 -0
- package/src/agents/plugin-config.test.ts +1 -0
- package/src/agents/sdk-streams.test.ts +79 -0
- package/src/agents/sdk-streams.ts +55 -10
- package/src/agents/skills.test.ts +1 -0
- package/src/agents/streaming.test.ts +3 -9
- package/src/agents/streaming.ts +2 -2
- package/src/agents/types.ts +71 -8
- package/src/agents/ui-message-stream.test.ts +3 -0
- package/src/cli.ts +446 -124
- package/src/context/context.test.ts +51 -12
- package/src/context/context.ts +162 -30
- package/src/context/session.test.ts +2 -1
- package/src/context/session.ts +115 -7
- package/src/context/types.ts +30 -12
- package/src/define.test.ts +13 -8
- package/src/define.ts +25 -4
- package/src/expect/index.ts +53 -23
- package/src/i18n/en.ts +81 -17
- package/src/i18n/zh-CN.ts +80 -17
- package/src/o11y/cost.test.ts +1 -0
- package/src/o11y/execution-tree.test.ts +1 -20
- package/src/o11y/otlp/mappers/claude-code.test.ts +1 -0
- package/src/o11y/otlp/parse.test.ts +1 -0
- package/src/o11y/otlp/turn-otel.test.ts +1 -0
- package/src/o11y/parsers/bub.test.ts +1 -0
- package/src/o11y/parsers/claude-code.test.ts +1 -34
- package/src/o11y/parsers/openclaw.test.ts +154 -0
- package/src/o11y/parsers/openclaw.ts +310 -0
- package/src/o11y/prices.json +746 -311
- package/src/o11y/tool-names.test.ts +1 -0
- package/src/o11y/types.ts +16 -2
- package/src/report/aggregate.ts +178 -61
- package/src/report/built-in/index.tsx +9 -0
- package/src/report/components.tsx +625 -279
- package/src/report/compute.ts +723 -491
- package/src/report/dual-render.test.tsx +741 -1024
- package/src/report/flag.ts +104 -12
- package/src/report/format.ts +32 -12
- package/src/report/index.ts +119 -46
- package/src/report/load.ts +3 -2
- package/src/report/locale.ts +136 -65
- package/src/report/metrics.ts +108 -25
- package/src/report/primitives.tsx +196 -45
- package/src/report/react/AttemptList.tsx +30 -43
- package/src/report/react/DeltaTable.tsx +63 -45
- package/src/report/react/EvalList.tsx +0 -0
- package/src/report/react/ExperimentComparison.tsx +73 -0
- package/src/report/react/ExperimentList.tsx +50 -32
- package/src/report/react/MetricBars.tsx +5 -4
- package/src/report/react/MetricLine.tsx +13 -8
- package/src/report/react/MetricMatrix.tsx +2 -2
- package/src/report/react/MetricScatter.tsx +86 -34
- package/src/report/react/MetricTable.tsx +4 -76
- package/src/report/react/ScopeSummary.tsx +86 -0
- package/src/report/react/Scoreboard.tsx +28 -10
- package/src/report/react/cell.tsx +2 -2
- package/src/report/react/chart-math.test.ts +85 -0
- package/src/report/react/chart-math.ts +101 -22
- package/src/report/react/enhance.js +89 -5
- package/src/report/react/fixtures.ts +114 -154
- package/src/report/react/index.tsx +24 -39
- package/src/report/react/render.test.tsx +138 -158
- package/src/report/react/styles.css +243 -82
- package/src/report/report.test.ts +779 -841
- package/src/report/report.ts +423 -41
- package/src/report/text/faces.ts +290 -193
- package/src/report/text/plot.ts +1 -1
- package/src/report/text/table.ts +44 -7
- package/src/report/tree.ts +362 -104
- package/src/report/types.ts +261 -271
- package/src/report/web.ts +63 -20
- package/src/results/annotated-source.test.ts +62 -9
- package/src/results/annotated-source.ts +64 -6
- package/src/results/attempt-evidence.test.ts +13 -11
- package/src/results/attempt-evidence.ts +20 -13
- package/src/results/attempt-source.ts +6 -3
- package/src/results/copy.ts +150 -60
- package/src/results/host-equivalence.test.ts +34 -20
- package/src/results/index.ts +12 -4
- package/src/results/locator.test.ts +1 -22
- package/src/results/open.ts +15 -5
- package/src/results/publish.ts +149 -0
- package/src/results/results.test.ts +89 -54
- package/src/results/select.ts +104 -34
- package/src/results/truncate.ts +90 -0
- package/src/results/types.ts +43 -14
- package/src/results/writer.ts +31 -13
- package/src/runner/attempt.test.ts +138 -7
- package/src/runner/attempt.ts +603 -104
- package/src/runner/discover.test.ts +47 -0
- package/src/runner/discover.ts +36 -2
- package/src/runner/eval-source.test.ts +1 -27
- package/src/runner/feedback/agent.test.ts +504 -0
- package/src/runner/feedback/agent.ts +409 -0
- package/src/runner/feedback/ci.test.ts +562 -0
- package/src/runner/feedback/ci.ts +401 -0
- package/src/runner/feedback/coordinator.test.ts +317 -0
- package/src/runner/feedback/coordinator.ts +397 -0
- package/src/runner/feedback/failure.ts +40 -0
- package/src/runner/feedback/human.test.ts +616 -0
- package/src/runner/feedback/human.ts +535 -0
- package/src/runner/feedback/index.ts +66 -0
- package/src/runner/feedback/io.ts +78 -0
- package/src/runner/feedback/profile.test.ts +50 -0
- package/src/runner/feedback/profile.ts +58 -0
- package/src/runner/feedback/reducer.test.ts +395 -0
- package/src/runner/feedback/reducer.ts +260 -0
- package/src/runner/feedback/renderer.ts +82 -0
- package/src/runner/feedback/sink.ts +203 -0
- package/src/runner/feedback/testing.ts +106 -0
- package/src/runner/ledger.test.ts +230 -0
- package/src/runner/ledger.ts +329 -0
- package/src/runner/report.test.ts +128 -3
- package/src/runner/report.ts +33 -9
- package/src/runner/reporters/artifacts.ts +8 -2
- package/src/runner/reporters/braintrust.test.ts +8 -7
- package/src/runner/reporters/braintrust.ts +9 -2
- package/src/runner/reporters/index.ts +2 -2
- package/src/runner/reporters/json.test.ts +162 -0
- package/src/runner/reporters/json.ts +35 -8
- package/src/runner/reporters/shared.ts +1 -5
- package/src/runner/run.test.ts +760 -3
- package/src/runner/run.ts +243 -37
- package/src/runner/sandbox-prep.ts +3 -42
- package/src/runner/timing.ts +158 -0
- package/src/runner/types.ts +518 -22
- package/src/sandbox/checkpoint.test.ts +55 -0
- package/src/sandbox/checkpoint.ts +29 -8
- package/src/sandbox/cli-commands.ts +407 -0
- package/src/sandbox/docker.ts +115 -16
- package/src/sandbox/e2b-agent-template.test.ts +56 -0
- package/src/sandbox/e2b-agent-template.ts +94 -0
- package/src/sandbox/e2b.ts +74 -9
- package/src/sandbox/errors.ts +111 -4
- package/src/sandbox/index.ts +2 -0
- package/src/sandbox/io-retry.test.ts +58 -0
- package/src/sandbox/io-retry.ts +45 -0
- package/src/sandbox/keep-registry.test.ts +86 -0
- package/src/sandbox/keep-registry.ts +142 -0
- package/src/sandbox/keep.ts +178 -0
- package/src/sandbox/paths.test.ts +1 -0
- package/src/sandbox/paths.ts +19 -8
- package/src/sandbox/registry.ts +20 -3
- package/src/sandbox/resolve.ts +76 -11
- package/src/sandbox/retry.test.ts +70 -0
- package/src/sandbox/retry.ts +46 -4
- package/src/sandbox/types.ts +44 -6
- package/src/sandbox/vercel.ts +43 -20
- package/src/scoring/collector.ts +60 -17
- package/src/scoring/coverage.ts +95 -0
- package/src/scoring/diff.ts +81 -0
- package/src/scoring/display.test.ts +121 -0
- package/src/scoring/display.ts +133 -0
- package/src/scoring/evidence.test.ts +189 -0
- package/src/scoring/judge.test.ts +142 -0
- package/src/scoring/judge.ts +15 -18
- package/src/scoring/scoped.ts +217 -50
- package/src/scoring/types.ts +117 -20
- package/src/scoring/verdict.ts +16 -4
- package/src/shared/aggregate.ts +8 -6
- package/src/shared/types.ts +31 -0
- package/src/show/compose.ts +50 -67
- package/src/show/index.ts +127 -56
- package/src/show/render.ts +662 -131
- package/src/show/report-host.test.ts +188 -0
- package/src/show/report-host.ts +375 -0
- package/src/show/show.test.ts +320 -54
- package/src/tty-line.ts +8 -26
- package/src/util.test.ts +1 -0
- package/src/util.ts +41 -0
- package/src/view/app/App.test.tsx +69 -0
- package/src/view/app/App.tsx +144 -48
- package/src/view/app/components/AttemptModal.tsx +423 -11
- package/src/view/app/components/CodeView.tsx +41 -14
- package/src/view/app/components/CopyControls.tsx +2 -2
- package/src/view/app/i18n.ts +37 -17
- package/src/view/app/lib/attempt-route.test.ts +1 -0
- package/src/view/app/lib/verdict.ts +7 -9
- package/src/view/app/main.tsx +13 -8
- package/src/view/app/pages/{RunsPage.tsx → AttemptsPage.tsx} +6 -6
- package/src/view/app/types.ts +4 -1
- package/src/view/artifact-serving.test.ts +2 -1
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +17 -17
- package/src/view/data.test.ts +10 -3
- package/src/view/data.ts +155 -49
- package/src/view/index.ts +56 -41
- package/src/view/server.ts +37 -15
- package/src/view/shared/types.ts +34 -5
- package/src/view/styles.css +227 -0
- package/src/view/view-report.test.ts +167 -62
- package/dist/report/built-ins/experiment-comparison.d.ts +0 -1
- package/dist/report/built-ins/experiment-comparison.js +0 -13
- package/dist/report/built-ins/index.d.ts +0 -1
- package/dist/report/built-ins/index.js +0 -2
- package/dist/report/react/GroupSummary.d.ts +0 -8
- package/dist/report/react/GroupSummary.js +0 -8
- package/dist/report/react/RunOverview.d.ts +0 -8
- package/dist/report/react/RunOverview.js +0 -12
- package/docs-site/zh/example/ai-agent-application.mdx +0 -152
- package/docs-site/zh/example/claude-code-codex-plugin.mdx +0 -167
- package/docs-site/zh/example/claude-code-codex-skill.mdx +0 -152
- package/docs-site/zh/example/showcase.mdx +0 -39
- package/docs-site/zh/guides/publish-report.mdx +0 -91
- package/docs-site/zh/guides/sandbox-providers.mdx +0 -102
- package/src/report/built-in-user-parity.test.tsx +0 -640
- package/src/report/built-ins/experiment-comparison.tsx +0 -19
- package/src/report/built-ins/index.ts +0 -2
- package/src/report/react/GroupSummary.tsx +0 -66
- package/src/report/react/RunOverview.tsx +0 -109
- package/src/runner/reporters/console.ts +0 -70
- package/src/runner/reporters/live.test.ts +0 -56
- package/src/runner/reporters/live.ts +0 -247
- package/src/runner/reporters/quiet.test.ts +0 -66
- package/src/runner/reporters/quiet.ts +0 -49
- package/src/runner/reporters/table.ts +0 -277
- /package/docs-site/zh/{example/tier1-ai-sdk-v7.mdx → examples/integrations/ai-sdk-v7.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-claude-sdk.mdx → examples/integrations/claude-sdk.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-codex-sdk.mdx → examples/integrations/codex-sdk.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-langgraph.mdx → examples/integrations/langgraph.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-pi-sdk.mdx → examples/integrations/pi-sdk.mdx} +0 -0
- /package/docs-site/zh/{guides → how-to}/fixtures.mdx +0 -0
package/src/report/locale.ts
CHANGED
|
@@ -1,14 +1,51 @@
|
|
|
1
|
-
// 官方组件 chrome 文案的 locale
|
|
1
|
+
// 官方组件 chrome 文案的 locale 字典与 LocalizedText 解析。
|
|
2
|
+
// ReportLocale 是开放的 BCP 47 标签(数据协议不封语言上限);官方内置文案与
|
|
3
|
+
// MetricCell.display 生成面当前覆盖 en / zh-CN,其它 locale 走 LocalizedText 回退规则。
|
|
2
4
|
// 只覆盖组件自带的固定文案(verdict 词、缺数据、覆盖率角标、注脚、占位符等);
|
|
3
|
-
//
|
|
4
|
-
// 刻意不 import src/i18n/(CLI 专用字典,locale 来源与 key 面完全不同)
|
|
5
|
-
// zh-CN 译法与 src/view/app/i18n.ts 现有词保持一致(成功率/平均耗时/预估成本…)。
|
|
5
|
+
// 维度键、warnings 的 message 不经这里。
|
|
6
|
+
// 刻意不 import src/i18n/(CLI 专用字典,locale 来源与 key 面完全不同)。
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
import type { LocalizedText } from "../types.ts";
|
|
9
|
+
|
|
10
|
+
export type { LocalizedText };
|
|
11
|
+
|
|
12
|
+
/** 报告渲染的 locale(BCP 47 标签,开放);默认 "en"(`niceeval show` 缺省输出不变)。 */
|
|
13
|
+
export type ReportLocale = string;
|
|
9
14
|
|
|
10
15
|
export const DEFAULT_REPORT_LOCALE: ReportLocale = "en";
|
|
11
16
|
|
|
17
|
+
/** MetricCell.display 生成面覆盖的 locale 全集;其它 locale 按 LocalizedText 回退取 en。 */
|
|
18
|
+
export const DISPLAY_LOCALES: readonly ReportLocale[] = ["en", "zh-CN"];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* LocalizedText 的确定回退:取当前 locale;缺失时取 en;仍缺失时取按 locale 键字典序的
|
|
22
|
+
* 第一个非空值。对象没有任何非空值时报错,不渲染空文案
|
|
23
|
+
* (docs/feature/reports/library/shell.md「行为约束」)。
|
|
24
|
+
*/
|
|
25
|
+
export function resolveLocalizedText(text: LocalizedText, locale: ReportLocale): string {
|
|
26
|
+
if (typeof text === "string") return text;
|
|
27
|
+
const direct = text[locale];
|
|
28
|
+
if (direct !== undefined && direct !== "") return direct;
|
|
29
|
+
const en = text.en;
|
|
30
|
+
if (en !== undefined && en !== "") return en;
|
|
31
|
+
for (const key of Object.keys(text).sort()) {
|
|
32
|
+
const value = text[key];
|
|
33
|
+
if (value !== undefined && value !== "") return value;
|
|
34
|
+
}
|
|
35
|
+
throw new Error(
|
|
36
|
+
"LocalizedText object has no non-empty value. Provide at least one locale entry, e.g. { en: \"…\" }.",
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** LocalizedText 按字段值深相等(键顺序无关;标题回退链的「唯一且相同」判定用)。 */
|
|
41
|
+
export function localizedTextEquals(a: LocalizedText, b: LocalizedText): boolean {
|
|
42
|
+
if (typeof a === "string" || typeof b === "string") return a === b;
|
|
43
|
+
const keysA = Object.keys(a).sort();
|
|
44
|
+
const keysB = Object.keys(b).sort();
|
|
45
|
+
if (keysA.length !== keysB.length) return false;
|
|
46
|
+
return keysA.every((key, i) => key === keysB[i] && a[key] === b[key]);
|
|
47
|
+
}
|
|
48
|
+
|
|
12
49
|
const en = {
|
|
13
50
|
"verdict.passed": "passed",
|
|
14
51
|
"verdict.failed": "failed",
|
|
@@ -20,6 +57,7 @@ const en = {
|
|
|
20
57
|
"cell.measuredTitle": "{samples}/{total} attempts measured",
|
|
21
58
|
"cell.noneMeasurableTitle": "0/{total} attempts measurable",
|
|
22
59
|
"cell.coverageTitle": "coverage {samples}/{total}: this metric is null for the remaining attempts",
|
|
60
|
+
"cell.missingValue": "(missing)",
|
|
23
61
|
|
|
24
62
|
"table.higherBetter": "higher is better",
|
|
25
63
|
"table.lowerBetter": "lower is better",
|
|
@@ -34,43 +72,50 @@ const en = {
|
|
|
34
72
|
"table.attempt": "attempt",
|
|
35
73
|
"experimentList.experiment": "Experiment",
|
|
36
74
|
"experimentList.avgDuration": "Avg duration",
|
|
37
|
-
"experimentList.passRate": "
|
|
75
|
+
"experimentList.passRate": "End-to-end pass rate",
|
|
38
76
|
"experimentList.tokens": "Tokens",
|
|
39
|
-
"experimentList.
|
|
77
|
+
"experimentList.cost": "Cost",
|
|
40
78
|
"experimentList.result": "Result",
|
|
41
79
|
"experimentList.status": "Status",
|
|
42
80
|
"experimentList.evalAttempt": "Eval / Attempt",
|
|
43
81
|
"experimentList.duration": "Duration",
|
|
44
|
-
"experimentList.cost": "Cost",
|
|
45
82
|
"experimentList.filterPlaceholder": "Filter experiments…",
|
|
46
83
|
"experimentList.defaultModel": "default",
|
|
47
84
|
"experimentList.flags": "Flags",
|
|
85
|
+
"entityList.average": "{value} avg",
|
|
86
|
+
"entityList.moreFailures.one": "+{n} more failure",
|
|
87
|
+
"entityList.moreFailures.other": "+{n} more failures",
|
|
48
88
|
/** <Table> 压到下限仍放不下时,从右侧丢列并如实报数。 */
|
|
49
89
|
"table.columnsHidden.one": "({n} more column not shown)",
|
|
50
90
|
"table.columnsHidden.other": "({n} more columns not shown)",
|
|
51
91
|
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
92
|
+
/** ScopeSummary 的 KPI 标签。 */
|
|
93
|
+
"scopeSummary.experiments": "Experiments",
|
|
94
|
+
"scopeSummary.evals": "Evals",
|
|
95
|
+
"scopeSummary.attempts": "attempts",
|
|
96
|
+
"scopeSummary.passRate": "End-to-end pass rate",
|
|
97
|
+
"scopeSummary.totalCost": "Total cost",
|
|
98
|
+
"scopeSummary.range": "{from} – {to}",
|
|
99
|
+
"scopeSummary.votesEval": "eval verdicts",
|
|
100
|
+
"scopeSummary.votesAttempt": "attempt verdicts",
|
|
59
101
|
"overview.experiments.one": "{n} experiment",
|
|
60
102
|
"overview.experiments.other": "{n} experiments",
|
|
61
103
|
"overview.evalsCount": "{n} evals",
|
|
62
104
|
"overview.attemptsCount": "{n} attempts",
|
|
105
|
+
"overview.evals": "Evals",
|
|
106
|
+
"overview.passRate": "End-to-end pass rate",
|
|
107
|
+
"overview.totalCost": "Cost",
|
|
63
108
|
|
|
64
|
-
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
109
|
+
"experimentComparison.groups": "Experiment groups",
|
|
110
|
+
"experimentComparison.group": "Experiment group",
|
|
111
|
+
"experimentComparison.results": "Eval results",
|
|
112
|
+
"experimentComparison.lastRun": "Last run",
|
|
113
|
+
"experimentComparison.selectGroup": "Select experiment group {group}",
|
|
114
|
+
"experimentComparison.commandsHead": "Group details:",
|
|
115
|
+
"experimentComparison.empty": "No experiment groups",
|
|
70
116
|
|
|
71
|
-
|
|
117
|
+
/** 方向提示唯一文案:轴向已随 better 反正,「更好」恒指向右上(两轴都声明 better 时才显示)。 */
|
|
72
118
|
"scatter.betterUpperRight": "better → upper right",
|
|
73
|
-
"scatter.axisReversed": "(axis reversed: right = better)",
|
|
74
119
|
/** 0 个可画点:x/y 指标没有可用数据。 */
|
|
75
120
|
"scatter.noData": "No data to plot {x} × {y}",
|
|
76
121
|
"pointsMissing.one": "{n} point missing data",
|
|
@@ -80,22 +125,28 @@ const en = {
|
|
|
80
125
|
"attemptList.truncated": "and {n} more not shown",
|
|
81
126
|
"attemptList.truncatedText": "({n} more not shown)",
|
|
82
127
|
"attemptList.score": "score {score}",
|
|
128
|
+
"attemptList.unavailable": "unavailable",
|
|
83
129
|
"attemptList.details": "details",
|
|
84
130
|
|
|
85
131
|
"scoreboard.total": "Total",
|
|
86
132
|
"scoreboard.totalText": "total",
|
|
87
|
-
"scoreboard.
|
|
88
|
-
"scoreboard.
|
|
89
|
-
"scoreboard.
|
|
133
|
+
"scoreboard.notRun.one": "{n} eval not run, scored 0",
|
|
134
|
+
"scoreboard.notRun.other": "{n} evals not run, scored 0",
|
|
135
|
+
"scoreboard.unscorable.one": "{n} eval unscorable, scored 0",
|
|
136
|
+
"scoreboard.unscorable.other": "{n} evals unscorable, scored 0",
|
|
137
|
+
"scoreboard.notRunText": "({n} not run)",
|
|
138
|
+
"scoreboard.unscorableText": "({n} unscorable)",
|
|
139
|
+
"scoreboard.ignored.one": "{n} eval outside the question set ignored",
|
|
140
|
+
"scoreboard.ignored.other": "{n} evals outside the question set ignored",
|
|
90
141
|
"scoreboard.weights": "weights:",
|
|
91
142
|
"scoreboard.allWeights": "all evals ×1",
|
|
92
143
|
"scoreboard.othersWeight": "others ×1",
|
|
93
|
-
"scoreboard.subjectTitle": "{
|
|
144
|
+
"scoreboard.subjectTitle": "{questions} evals, weighted {earned} of {possible}",
|
|
94
145
|
|
|
95
146
|
"delta.pairHeader": "pair (A → B)",
|
|
147
|
+
"delta.empty": "{experiments} experiments, 0 comparable pairs",
|
|
96
148
|
|
|
97
|
-
"
|
|
98
|
-
"board.failing": "Failing:",
|
|
149
|
+
"tabs.tab": "Tab",
|
|
99
150
|
} as const;
|
|
100
151
|
|
|
101
152
|
export type ReportMessageKey = keyof typeof en;
|
|
@@ -110,6 +161,7 @@ const zhCN: Record<ReportMessageKey, string> = {
|
|
|
110
161
|
"cell.measuredTitle": "{samples}/{total} 次 attempt 测得",
|
|
111
162
|
"cell.noneMeasurableTitle": "0/{total} 次 attempt 可测",
|
|
112
163
|
"cell.coverageTitle": "覆盖率 {samples}/{total}:其余 attempt 测不了这个指标",
|
|
164
|
+
"cell.missingValue": "(missing)",
|
|
113
165
|
|
|
114
166
|
"table.higherBetter": "越高越好",
|
|
115
167
|
"table.lowerBetter": "越低越好",
|
|
@@ -123,41 +175,47 @@ const zhCN: Record<ReportMessageKey, string> = {
|
|
|
123
175
|
"table.attempt": "Attempt",
|
|
124
176
|
"experimentList.experiment": "实验",
|
|
125
177
|
"experimentList.avgDuration": "平均耗时",
|
|
126
|
-
"experimentList.passRate": "
|
|
178
|
+
"experimentList.passRate": "端到端成功率",
|
|
127
179
|
"experimentList.tokens": "Tokens",
|
|
128
|
-
"experimentList.
|
|
180
|
+
"experimentList.cost": "成本",
|
|
129
181
|
"experimentList.result": "结果",
|
|
130
182
|
"experimentList.status": "状态",
|
|
131
183
|
"experimentList.evalAttempt": "题目 / Attempt",
|
|
132
184
|
"experimentList.duration": "耗时",
|
|
133
|
-
"experimentList.cost": "成本",
|
|
134
185
|
"experimentList.filterPlaceholder": "筛选实验…",
|
|
135
186
|
"experimentList.defaultModel": "默认",
|
|
136
187
|
"experimentList.flags": "Flags",
|
|
188
|
+
"entityList.average": "平均 {value}",
|
|
189
|
+
"entityList.moreFailures.one": "+{n} 条其它失败",
|
|
190
|
+
"entityList.moreFailures.other": "+{n} 条其它失败",
|
|
137
191
|
"table.columnsHidden.one": "(还有 {n} 列未列出)",
|
|
138
192
|
"table.columnsHidden.other": "(还有 {n} 列未列出)",
|
|
139
193
|
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"
|
|
194
|
+
"scopeSummary.experiments": "实验数",
|
|
195
|
+
"scopeSummary.evals": "题目",
|
|
196
|
+
"scopeSummary.attempts": "次 attempt",
|
|
197
|
+
"scopeSummary.passRate": "端到端成功率",
|
|
198
|
+
"scopeSummary.totalCost": "总成本",
|
|
199
|
+
"scopeSummary.range": "{from} – {to}",
|
|
200
|
+
"scopeSummary.votesEval": "Eval 计票",
|
|
201
|
+
"scopeSummary.votesAttempt": "Attempt 计票",
|
|
147
202
|
"overview.experiments.one": "{n} 个实验",
|
|
148
203
|
"overview.experiments.other": "{n} 个实验",
|
|
149
204
|
"overview.evalsCount": "{n} 道题",
|
|
150
205
|
"overview.attemptsCount": "{n} 次 attempt",
|
|
206
|
+
"overview.evals": "Eval",
|
|
207
|
+
"overview.passRate": "端到端成功率",
|
|
208
|
+
"overview.totalCost": "成本",
|
|
151
209
|
|
|
152
|
-
"
|
|
210
|
+
"experimentComparison.groups": "实验组",
|
|
211
|
+
"experimentComparison.group": "实验组",
|
|
212
|
+
"experimentComparison.results": "Eval 结果",
|
|
213
|
+
"experimentComparison.lastRun": "最后运行",
|
|
214
|
+
"experimentComparison.selectGroup": "选择实验组 {group}",
|
|
215
|
+
"experimentComparison.commandsHead": "查看组内详情:",
|
|
216
|
+
"experimentComparison.empty": "没有实验组",
|
|
153
217
|
|
|
154
|
-
"
|
|
155
|
-
"composedFrom.other": "合成自 {n} 个 run",
|
|
156
|
-
"latestRun": "最新 {run}",
|
|
157
|
-
|
|
158
|
-
"scatter.betterHint": "更好 ↗",
|
|
159
|
-
"scatter.betterUpperRight": "更好 → 右上",
|
|
160
|
-
"scatter.axisReversed": "(轴反向:右 = 更好)",
|
|
218
|
+
"scatter.betterUpperRight": "越靠右上越好",
|
|
161
219
|
"scatter.noData": "{x} × {y} 没有可绘制的数据",
|
|
162
220
|
"pointsMissing.one": "{n} 个点缺数据",
|
|
163
221
|
"pointsMissing.other": "{n} 个点缺数据",
|
|
@@ -166,30 +224,36 @@ const zhCN: Record<ReportMessageKey, string> = {
|
|
|
166
224
|
"attemptList.truncated": "还有 {n} 条未列出",
|
|
167
225
|
"attemptList.truncatedText": "(还有 {n} 条未列出)",
|
|
168
226
|
"attemptList.score": "得分 {score}",
|
|
227
|
+
"attemptList.unavailable": "评不了",
|
|
169
228
|
"attemptList.details": "详情",
|
|
170
229
|
|
|
171
230
|
"scoreboard.total": "总分",
|
|
172
231
|
"scoreboard.totalText": "总分",
|
|
173
|
-
"scoreboard.
|
|
174
|
-
"scoreboard.
|
|
175
|
-
"scoreboard.
|
|
232
|
+
"scoreboard.notRun.one": "{n} 道题没跑,按 0 计",
|
|
233
|
+
"scoreboard.notRun.other": "{n} 道题没跑,按 0 计",
|
|
234
|
+
"scoreboard.unscorable.one": "{n} 道题测不了,按 0 计",
|
|
235
|
+
"scoreboard.unscorable.other": "{n} 道题测不了,按 0 计",
|
|
236
|
+
"scoreboard.notRunText": "(没跑 {n} 题)",
|
|
237
|
+
"scoreboard.unscorableText": "(测不了 {n} 题)",
|
|
238
|
+
"scoreboard.ignored.one": "题集之外的 {n} 道题已忽略",
|
|
239
|
+
"scoreboard.ignored.other": "题集之外的 {n} 道题已忽略",
|
|
176
240
|
"scoreboard.weights": "权重:",
|
|
177
241
|
"scoreboard.allWeights": "全部题 ×1",
|
|
178
242
|
"scoreboard.othersWeight": "其余 ×1",
|
|
179
|
-
"scoreboard.subjectTitle": "{
|
|
243
|
+
"scoreboard.subjectTitle": "{questions} 道题,加权得分 {earned}/{possible}",
|
|
180
244
|
|
|
181
245
|
"delta.pairHeader": "对比 (A → B)",
|
|
246
|
+
"delta.empty": "{experiments} 个实验、0 个可配对",
|
|
182
247
|
|
|
183
|
-
"
|
|
184
|
-
"board.failing": "失败清单:",
|
|
248
|
+
"tabs.tab": "Tab",
|
|
185
249
|
};
|
|
186
250
|
|
|
187
|
-
const dictionaries: Record<
|
|
251
|
+
const dictionaries: Record<string, Record<ReportMessageKey, string>> = {
|
|
188
252
|
en,
|
|
189
253
|
"zh-CN": zhCN,
|
|
190
254
|
};
|
|
191
255
|
|
|
192
|
-
/** 查字典 + 简单插值({name} 占位符)
|
|
256
|
+
/** 查字典 + 简单插值({name} 占位符)。内置词典未覆盖的 locale 回退 en。 */
|
|
193
257
|
export function localeText(
|
|
194
258
|
locale: ReportLocale,
|
|
195
259
|
key: ReportMessageKey,
|
|
@@ -205,25 +269,32 @@ export function localeText(
|
|
|
205
269
|
/** 带单复数的计数文案:n === 1 用 `<base>.one`,其余 `<base>.other`(zh-CN 两键同值)。 */
|
|
206
270
|
export function countText(
|
|
207
271
|
locale: ReportLocale,
|
|
208
|
-
base:
|
|
272
|
+
base:
|
|
273
|
+
| "overview.experiments"
|
|
274
|
+
| "pointsMissing"
|
|
275
|
+
| "scoreboard.notRun"
|
|
276
|
+
| "scoreboard.unscorable"
|
|
277
|
+
| "scoreboard.ignored"
|
|
278
|
+
| "entityList.moreFailures"
|
|
279
|
+
| "table.columnsHidden",
|
|
209
280
|
n: number,
|
|
210
281
|
): string {
|
|
211
282
|
return localeText(locale, `${base}.${n === 1 ? "one" : "other"}` as ReportMessageKey, { n });
|
|
212
283
|
}
|
|
213
284
|
|
|
214
|
-
/** 指标 label 的可本地化形态:字符串,或按 locale 给的字典(缺项回退 en,再回退任一非空值)。 */
|
|
215
|
-
export type LocalizedLabel = string | Partial<Record<ReportLocale, string>>;
|
|
216
|
-
|
|
217
285
|
/**
|
|
218
|
-
* 按 locale 解析指标 label
|
|
219
|
-
*
|
|
286
|
+
* 按 locale 解析指标 / 列 label:字符串原样;字典按 LocalizedText 回退规则取值;
|
|
287
|
+
* undefined 回退 fallback(= metric.name)。渲染面(web / text)共用。
|
|
220
288
|
*/
|
|
221
289
|
export function resolveMetricLabel(
|
|
222
|
-
label:
|
|
290
|
+
label: LocalizedText | undefined,
|
|
223
291
|
locale: ReportLocale,
|
|
224
292
|
fallback: string,
|
|
225
293
|
): string {
|
|
226
294
|
if (label === undefined) return fallback;
|
|
227
|
-
|
|
228
|
-
|
|
295
|
+
try {
|
|
296
|
+
return resolveLocalizedText(label, locale);
|
|
297
|
+
} catch {
|
|
298
|
+
return fallback;
|
|
299
|
+
}
|
|
229
300
|
}
|
package/src/report/metrics.ts
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
// defineMetric 与内置指标。
|
|
2
2
|
//
|
|
3
3
|
// null ≠ 0:null = 此 attempt 测不了这个指标(不进聚合);0 = 测了,结果是零(照常进)。
|
|
4
|
-
// 哪个 verdict 落哪边必须显式表态,内置指标按 docs/feature/reports/library.md
|
|
4
|
+
// 哪个 verdict 落哪边必须显式表态,内置指标按 docs/feature/reports/library.md「内置指标」的表格。
|
|
5
|
+
// 三个通过率指标把「Agent 答错」与「基建没跑起来」拆开,不互相伪装:
|
|
5
6
|
//
|
|
6
|
-
// 指标(name)
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
7
|
+
// 指标(name) skipped errored failed passed better
|
|
8
|
+
// taskPassRate(task-pass-rate) null null 0 1 higher
|
|
9
|
+
// executionReliability(execution-reliability) null 0 1 1 higher
|
|
10
|
+
// endToEndPassRate(end-to-end-pass-rate) null 0 0 1 higher
|
|
11
|
+
// examScore(exam-score) null 0 0 soft 均分 higher
|
|
12
|
+
// durationMs(duration) null 实测 实测 实测 lower
|
|
13
|
+
// tokens(tokens) null 实测;无 usage→null 同左 同左 lower
|
|
14
|
+
// costUSD(cost) null 同上 同左 同左 lower
|
|
15
|
+
// assistantTurns(assistant-turns) null 实测;o11y 缺失→null 同左 同左 lower
|
|
16
|
+
// repeatedFailedCommands(repeated-failed-commands) null 实测;o11y 缺失→null 同左 同左 lower
|
|
13
17
|
//
|
|
14
|
-
// 两档指标(docs/feature/reports/library.md「内置指标」):以上除
|
|
15
|
-
// 的瘦身字段——任何 producer、任何
|
|
16
|
-
//
|
|
17
|
-
// o11y
|
|
18
|
+
// 两档指标(docs/feature/reports/library/metrics.md「内置指标」):以上除 assistantTurns 与
|
|
19
|
+
// repeatedFailedCommands 外全部只读 attempt.result 的瘦身字段——任何 producer、任何
|
|
20
|
+
// copySnapshots artifacts 选择都算得出,内置报告 ExperimentComparison 只用这一档。
|
|
21
|
+
// 后两个读 attempt.o11y()(懒加载 artifact),发布时若 o11y 没随行就诚实渲染缺数据「—」,
|
|
22
|
+
// 不算 0——报告作者自己摆时心里要有这根弦,内置报告不用它们。
|
|
18
23
|
|
|
19
24
|
import type { EvalResult } from "../types.ts";
|
|
20
25
|
import type { Metric } from "./types.ts";
|
|
@@ -39,10 +44,58 @@ export function attemptCostUSD(result: EvalResult): number | null {
|
|
|
39
44
|
return result.usage?.costUSD ?? result.estimatedCostUSD ?? null;
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
/**
|
|
48
|
+
* 条件答题质量:passed = 1,failed = 0,errored 记 null 不进分母。
|
|
49
|
+
* 这是「已形成可信判定」条件下的诊断指标,不能简称默认成功率
|
|
50
|
+
* (docs/feature/reports/library.md「内置指标」)。
|
|
51
|
+
*/
|
|
52
|
+
export const taskPassRate = defineMetric({
|
|
53
|
+
name: "task-pass-rate",
|
|
54
|
+
label: { en: "Task pass rate", "zh-CN": "可判定任务通过率" },
|
|
55
|
+
description: "Conditional task quality among attempts that formed a trustworthy verdict: passed = 1, failed = 0; errored is null.",
|
|
56
|
+
better: "higher",
|
|
57
|
+
unit: "%",
|
|
58
|
+
value(a) {
|
|
59
|
+
switch (a.result.verdict) {
|
|
60
|
+
case "passed":
|
|
61
|
+
return 1;
|
|
62
|
+
case "failed":
|
|
63
|
+
return 0;
|
|
64
|
+
default:
|
|
65
|
+
// errored = 没形成可信判定 → null 不进这个条件指标;skipped 同为 null。
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/** 执行可靠性:跑到可判定(passed / failed)= 1,errored = 0;skipped → null。 */
|
|
72
|
+
export const executionReliability = defineMetric({
|
|
73
|
+
name: "execution-reliability",
|
|
74
|
+
label: { en: "Execution reliability", "zh-CN": "执行可靠性" },
|
|
75
|
+
description: "Execution reliability: reached a trustworthy verdict (passed / failed) = 1, errored = 0.",
|
|
76
|
+
better: "higher",
|
|
77
|
+
unit: "%",
|
|
78
|
+
value(a) {
|
|
79
|
+
switch (a.result.verdict) {
|
|
80
|
+
case "passed":
|
|
81
|
+
case "failed":
|
|
82
|
+
return 1;
|
|
83
|
+
case "errored":
|
|
84
|
+
return 0;
|
|
85
|
+
default:
|
|
86
|
+
return null; // skipped
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 端到端合成:passed = 1,failed / errored = 0;哪边拖累用
|
|
93
|
+
* taskPassRate / executionReliability 拆开看。
|
|
94
|
+
*/
|
|
95
|
+
export const endToEndPassRate = defineMetric({
|
|
96
|
+
name: "end-to-end-pass-rate",
|
|
97
|
+
label: { en: "End-to-end pass rate", "zh-CN": "端到端成功率" },
|
|
98
|
+
description: "End-to-end composite: passed = 1, failed / errored = 0. Split blame with taskPassRate and executionReliability.",
|
|
46
99
|
better: "higher",
|
|
47
100
|
unit: "%",
|
|
48
101
|
value: (a) =>
|
|
@@ -62,9 +115,11 @@ export const examScore = defineMetric({
|
|
|
62
115
|
// 字面实现会让条件空真成立、崩溃反而得满分 —— 交白卷是 0 分,不是缺数据,更不是满分。
|
|
63
116
|
// failed 同理得 0:--strict 下被翻成 failed 的哪怕 soft 分不低也是 0(报告不重新判卷)。
|
|
64
117
|
if (verdict !== "passed") return 0;
|
|
65
|
-
|
|
118
|
+
// unavailable 没有分数:不计入均分分母(评不了 ≠ 0 分;非 optional 的 unavailable
|
|
119
|
+
// 早已把 verdict 拖成 errored,走不到这个分支)。
|
|
120
|
+
const soft = assertions.filter((x) => x.severity === "soft" && x.outcome !== "unavailable");
|
|
66
121
|
if (soft.length === 0) return 1;
|
|
67
|
-
return soft.reduce((sum, x) => sum + x.score, 0) / soft.length;
|
|
122
|
+
return soft.reduce((sum, x) => sum + (x.outcome === "unavailable" ? 0 : x.score), 0) / soft.length;
|
|
68
123
|
},
|
|
69
124
|
});
|
|
70
125
|
|
|
@@ -95,7 +150,7 @@ export const tokens = defineMetric({
|
|
|
95
150
|
|
|
96
151
|
export const costUSD = defineMetric({
|
|
97
152
|
name: "cost",
|
|
98
|
-
label: { en: "Cost", "zh-CN": "
|
|
153
|
+
label: { en: "Cost", "zh-CN": "成本" },
|
|
99
154
|
description: "USD cost per attempt (gateway-measured beats estimated).",
|
|
100
155
|
better: "lower",
|
|
101
156
|
unit: "$",
|
|
@@ -103,14 +158,15 @@ export const costUSD = defineMetric({
|
|
|
103
158
|
});
|
|
104
159
|
|
|
105
160
|
/**
|
|
106
|
-
*
|
|
161
|
+
* 读 artifact(o11y,懒加载)的内置指标之一——其余只读瘦身字段。
|
|
107
162
|
* 发布时若该 attempt 没带 o11y(如 copySnapshots 的 artifacts 选项漏了它),
|
|
108
|
-
* value 如实返回 null,渲染成「—」,不冒充 0
|
|
163
|
+
* value 如实返回 null,渲染成「—」,不冒充 0。名字带限定词:o11y 事件流中的 assistant
|
|
164
|
+
* turn 数与 `t.send` 的 `s<session>/t<turn>` 轮次是两个计数。
|
|
109
165
|
*/
|
|
110
|
-
export const
|
|
111
|
-
name: "turns",
|
|
112
|
-
label: { en: "
|
|
113
|
-
description: "
|
|
166
|
+
export const assistantTurns = defineMetric({
|
|
167
|
+
name: "assistant-turns",
|
|
168
|
+
label: { en: "Assistant turns", "zh-CN": "Assistant 轮次" },
|
|
169
|
+
description: "Assistant turns in the o11y event stream per attempt. Reads o11y — “—” if not published alongside this attempt.",
|
|
114
170
|
better: "lower",
|
|
115
171
|
unit: "turns",
|
|
116
172
|
async value(a) {
|
|
@@ -119,3 +175,30 @@ export const turns = defineMetric({
|
|
|
119
175
|
return o11y?.totalTurns ?? null;
|
|
120
176
|
},
|
|
121
177
|
});
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 同一 attempt 内同一条 shell 命令的重复失败数:每条命令失败 n 次(n > 1)记 n − 1,求和。
|
|
181
|
+
* 成功执行与只失败一次的命令不计。回答 agent 是否在反复撞同一个已知失败的命令。
|
|
182
|
+
* 读 o11y.json;skipped 与缺 o11y 返回 null(docs/feature/reports/library/metrics.md「内置指标」)。
|
|
183
|
+
*/
|
|
184
|
+
export const repeatedFailedCommands = defineMetric({
|
|
185
|
+
name: "repeated-failed-commands",
|
|
186
|
+
label: { en: "Repeated failed commands", "zh-CN": "重复失败命令" },
|
|
187
|
+
description: "Per attempt: for each shell command failing n > 1 times, count n − 1, summed. Reads o11y — “—” if not published alongside this attempt.",
|
|
188
|
+
better: "lower",
|
|
189
|
+
unit: "cmds",
|
|
190
|
+
async value(a) {
|
|
191
|
+
if (a.result.verdict === "skipped") return null;
|
|
192
|
+
const o11y = await a.o11y();
|
|
193
|
+
if (!o11y) return null;
|
|
194
|
+
const failures = new Map<string, number>();
|
|
195
|
+
for (const entry of o11y.shellCommands) {
|
|
196
|
+
const failed = entry.success === false || (entry.success === undefined && entry.exitCode !== undefined && entry.exitCode !== 0);
|
|
197
|
+
if (!failed) continue;
|
|
198
|
+
failures.set(entry.command, (failures.get(entry.command) ?? 0) + 1);
|
|
199
|
+
}
|
|
200
|
+
let repeated = 0;
|
|
201
|
+
for (const n of failures.values()) if (n > 1) repeated += n - 1;
|
|
202
|
+
return repeated;
|
|
203
|
+
},
|
|
204
|
+
});
|