niceeval 0.6.2 → 0.7.1
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 +2 -2
- package/dist/i18n/zh-CN.d.ts +3 -3
- package/dist/report/aggregate.d.ts +32 -26
- package/dist/report/aggregate.js +157 -76
- 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 +91 -164
- package/dist/report/components.js +377 -114
- package/dist/report/compute.d.ts +86 -73
- package/dist/report/compute.js +592 -432
- package/dist/report/flag.d.ts +28 -17
- package/dist/report/flag.js +86 -16
- package/dist/report/format.d.ts +11 -11
- package/dist/report/format.js +17 -15
- package/dist/report/index.d.ts +16 -17
- package/dist/report/index.js +20 -22
- package/dist/report/load.js +3 -2
- package/dist/report/locale.d.ts +49 -34
- package/dist/report/locale.js +106 -58
- package/dist/report/metrics.d.ts +10 -3
- package/dist/report/metrics.js +46 -12
- package/dist/report/primitives.d.ts +42 -15
- package/dist/report/primitives.js +135 -26
- package/dist/report/react/AttemptList.d.ts +10 -8
- package/dist/report/react/AttemptList.js +18 -10
- package/dist/report/react/DeltaTable.js +19 -18
- package/dist/report/react/EvalList.d.ts +3 -3
- package/dist/report/react/EvalList.js +0 -0
- package/dist/report/react/ExperimentComparison.d.ts +4 -2
- package/dist/report/react/ExperimentComparison.js +5 -4
- package/dist/report/react/ExperimentList.d.ts +3 -3
- package/dist/report/react/ExperimentList.js +16 -15
- 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 +54 -17
- 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/fixtures.d.ts +5 -9
- package/dist/report/react/fixtures.js +105 -149
- package/dist/report/react/index.d.ts +15 -5
- package/dist/report/react/index.js +18 -7
- package/dist/report/report.d.ts +137 -20
- package/dist/report/report.js +261 -34
- package/dist/report/text/faces.d.ts +17 -19
- package/dist/report/text/faces.js +225 -157
- package/dist/report/text/plot.js +1 -1
- package/dist/report/text/table.js +2 -2
- package/dist/report/tree.d.ts +90 -40
- package/dist/report/tree.js +252 -94
- package/dist/report/types.d.ts +245 -300
- 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 +38 -14
- package/dist/shared/aggregate.d.ts +3 -2
- package/dist/shared/aggregate.js +5 -4
- 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 +11 -11
- 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 +5 -5
- package/docs-site/zh/{guides → explanation}/runner.mdx +1 -1
- package/docs-site/zh/{concepts → explanation}/tier.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/agent-feedback-loop.mdx +7 -7
- package/docs-site/zh/{guides → how-to}/authoring.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/connect-otel.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/connect-your-agent.mdx +18 -18
- package/docs-site/zh/{guides → how-to}/custom-reports.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/experiments.mdx +3 -3
- package/docs-site/zh/{guides → how-to}/publish-report.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/sandbox-agent.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/sandbox-providers.mdx +1 -1
- package/docs-site/zh/{guides → how-to}/viewing-results.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/write-experiment.mdx +3 -3
- package/docs-site/zh/{guides → how-to}/write-send.mdx +13 -13
- package/docs-site/zh/index.mdx +23 -25
- package/docs-site/zh/introduction.mdx +8 -8
- package/docs-site/zh/reference/builtin-agents.mdx +5 -5
- package/docs-site/zh/reference/capabilities.mdx +6 -6
- package/docs-site/zh/reference/cli.mdx +9 -7
- package/docs-site/zh/reference/define-agent.mdx +1 -1
- package/docs-site/zh/reference/events.mdx +3 -3
- package/docs-site/zh/{guides → reference}/official-adapters.mdx +7 -7
- package/docs-site/zh/{guides → reference}/report-components.mdx +5 -5
- package/docs-site/zh/{guides → reference}/results-data.mdx +5 -5
- package/docs-site/zh/{guides → troubleshooting}/debug-sandbox.mdx +2 -2
- package/docs-site/zh/{guides → troubleshooting}/debugging.mdx +4 -2
- package/docs-site/zh/{quickstart.mdx → tutorials/quickstart.mdx} +5 -17
- package/package.json +6 -2
- package/src/agents/index.ts +2 -2
- package/src/agents/openai-compat.ts +1 -1
- package/src/agents/streaming.ts +2 -2
- package/src/agents/types.ts +3 -3
- package/src/cli.ts +42 -23
- package/src/context/context.ts +1 -1
- package/src/context/session.test.ts +1 -1
- package/src/context/session.ts +1 -1
- package/src/i18n/en.ts +18 -16
- package/src/i18n/zh-CN.ts +16 -15
- package/src/report/aggregate.ts +175 -87
- package/src/report/built-in/index.tsx +9 -0
- package/src/report/components.tsx +625 -285
- package/src/report/compute.ts +717 -515
- package/src/report/dual-render.test.tsx +738 -1148
- package/src/report/flag.ts +97 -33
- package/src/report/format.ts +18 -22
- package/src/report/index.ts +113 -58
- package/src/report/load.ts +3 -2
- package/src/report/locale.ts +120 -69
- package/src/report/metrics.ts +42 -12
- package/src/report/primitives.tsx +190 -45
- package/src/report/react/AttemptList.tsx +32 -20
- package/src/report/react/DeltaTable.tsx +63 -45
- package/src/report/react/EvalList.tsx +0 -0
- package/src/report/react/ExperimentComparison.tsx +12 -7
- package/src/report/react/ExperimentList.tsx +38 -26
- 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 +74 -20
- 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/enhance.js +57 -5
- package/src/report/react/fixtures.ts +109 -156
- package/src/report/react/index.tsx +24 -39
- package/src/report/react/render.test.tsx +139 -104
- package/src/report/react/styles.css +181 -91
- package/src/report/report.test.ts +761 -1031
- package/src/report/report.ts +425 -47
- package/src/report/text/faces.ts +257 -164
- package/src/report/text/plot.ts +1 -1
- package/src/report/text/table.ts +2 -2
- package/src/report/tree.ts +362 -104
- package/src/report/types.ts +257 -287
- package/src/report/web.ts +63 -20
- package/src/results/attempt-evidence.test.ts +4 -4
- package/src/results/attempt-evidence.ts +5 -5
- package/src/results/copy.ts +6 -6
- package/src/results/host-equivalence.test.ts +26 -14
- package/src/results/index.ts +10 -4
- package/src/results/open.ts +8 -4
- package/src/results/results.test.ts +4 -3
- package/src/results/select.ts +104 -34
- package/src/results/types.ts +36 -14
- package/src/runner/feedback/human.test.ts +1 -1
- package/src/runner/run.ts +1 -1
- package/src/sandbox/cli-commands.ts +2 -2
- package/src/scoring/judge.test.ts +1 -1
- package/src/shared/aggregate.ts +5 -4
- package/src/show/compose.ts +50 -67
- package/src/show/index.ts +107 -56
- package/src/show/render.ts +43 -27
- package/src/show/report-host.test.ts +188 -0
- package/src/show/report-host.ts +375 -0
- package/src/show/show.test.ts +86 -36
- package/src/view/app/App.test.tsx +69 -0
- package/src/view/app/App.tsx +144 -48
- package/src/view/app/components/AttemptModal.tsx +324 -63
- package/src/view/app/components/CodeView.tsx +10 -4
- package/src/view/app/i18n.ts +31 -17
- package/src/view/app/lib/artifact-url.ts +14 -3
- 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 +21 -1
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +6 -6
- package/src/view/data.test.ts +9 -3
- package/src/view/data.ts +145 -49
- package/src/view/index.ts +48 -44
- package/src/view/server.ts +35 -15
- package/src/view/shared/types.ts +34 -5
- package/src/view/styles.css +224 -0
- package/src/view/view-report.test.ts +161 -57
- package/dist/report/built-ins/experiment-comparison.d.ts +0 -39
- package/dist/report/built-ins/experiment-comparison.js +0 -119
- package/dist/report/built-ins/index.d.ts +0 -2
- 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/src/report/built-in-user-parity.test.tsx +0 -597
- package/src/report/built-ins/experiment-comparison.tsx +0 -179
- package/src/report/built-ins/index.ts +0 -7
- package/src/report/react/GroupSummary.tsx +0 -66
- package/src/report/react/RunOverview.tsx +0 -109
- /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}/ci-integration.mdx +0 -0
- /package/docs-site/zh/{guides → how-to}/dataset-fanout.mdx +0 -0
- /package/docs-site/zh/{guides → how-to}/fixtures.mdx +0 -0
- /package/docs-site/zh/{guides → how-to}/reporters.mdx +0 -0
- /package/docs-site/zh/{guides → how-to}/scoring-guide.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 译法与默认 Reports 契约保持一致(端到端成功率/平均耗时/预估成本…)。
|
|
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",
|
|
@@ -36,50 +74,48 @@ const en = {
|
|
|
36
74
|
"experimentList.avgDuration": "Avg duration",
|
|
37
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",
|
|
48
85
|
"entityList.average": "{value} avg",
|
|
86
|
+
"entityList.moreFailures.one": "+{n} more failure",
|
|
87
|
+
"entityList.moreFailures.other": "+{n} more failures",
|
|
49
88
|
/** <Table> 压到下限仍放不下时,从右侧丢列并如实报数。 */
|
|
50
89
|
"table.columnsHidden.one": "({n} more column not shown)",
|
|
51
90
|
"table.columnsHidden.other": "({n} more columns not shown)",
|
|
52
91
|
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
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",
|
|
60
101
|
"overview.experiments.one": "{n} experiment",
|
|
61
102
|
"overview.experiments.other": "{n} experiments",
|
|
62
103
|
"overview.evalsCount": "{n} evals",
|
|
63
104
|
"overview.attemptsCount": "{n} attempts",
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"
|
|
105
|
+
"overview.evals": "Evals",
|
|
106
|
+
"overview.passRate": "End-to-end pass rate",
|
|
107
|
+
"overview.totalCost": "Cost",
|
|
67
108
|
|
|
68
109
|
"experimentComparison.groups": "Experiment groups",
|
|
69
110
|
"experimentComparison.group": "Experiment group",
|
|
70
|
-
"experimentComparison.results": "
|
|
111
|
+
"experimentComparison.results": "Eval results",
|
|
71
112
|
"experimentComparison.lastRun": "Last run",
|
|
72
113
|
"experimentComparison.selectGroup": "Select experiment group {group}",
|
|
73
|
-
"experimentComparison.
|
|
114
|
+
"experimentComparison.commandsHead": "Group details:",
|
|
74
115
|
"experimentComparison.empty": "No experiment groups",
|
|
75
116
|
|
|
76
|
-
|
|
77
|
-
"composedFrom.other": "composed from {n} runs",
|
|
78
|
-
"latestRun": "latest {run}",
|
|
79
|
-
|
|
80
|
-
"scatter.betterHint": "better ↗",
|
|
117
|
+
/** 方向提示唯一文案:轴向已随 better 反正,「更好」恒指向右上(两轴都声明 better 时才显示)。 */
|
|
81
118
|
"scatter.betterUpperRight": "better → upper right",
|
|
82
|
-
"scatter.axisReversed": "(axis reversed: right = better)",
|
|
83
119
|
/** 0 个可画点:x/y 指标没有可用数据。 */
|
|
84
120
|
"scatter.noData": "No data to plot {x} × {y}",
|
|
85
121
|
"pointsMissing.one": "{n} point missing data",
|
|
@@ -94,18 +130,23 @@ const en = {
|
|
|
94
130
|
|
|
95
131
|
"scoreboard.total": "Total",
|
|
96
132
|
"scoreboard.totalText": "total",
|
|
97
|
-
"scoreboard.
|
|
98
|
-
"scoreboard.
|
|
99
|
-
"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",
|
|
100
141
|
"scoreboard.weights": "weights:",
|
|
101
142
|
"scoreboard.allWeights": "all evals ×1",
|
|
102
143
|
"scoreboard.othersWeight": "others ×1",
|
|
103
|
-
"scoreboard.subjectTitle": "{
|
|
144
|
+
"scoreboard.subjectTitle": "{questions} evals, weighted {earned} of {possible}",
|
|
104
145
|
|
|
105
146
|
"delta.pairHeader": "pair (A → B)",
|
|
147
|
+
"delta.empty": "{experiments} experiments, 0 comparable pairs",
|
|
106
148
|
|
|
107
|
-
"
|
|
108
|
-
"board.failing": "Failing:",
|
|
149
|
+
"tabs.tab": "Tab",
|
|
109
150
|
} as const;
|
|
110
151
|
|
|
111
152
|
export type ReportMessageKey = keyof typeof en;
|
|
@@ -120,6 +161,7 @@ const zhCN: Record<ReportMessageKey, string> = {
|
|
|
120
161
|
"cell.measuredTitle": "{samples}/{total} 次 attempt 测得",
|
|
121
162
|
"cell.noneMeasurableTitle": "0/{total} 次 attempt 可测",
|
|
122
163
|
"cell.coverageTitle": "覆盖率 {samples}/{total}:其余 attempt 测不了这个指标",
|
|
164
|
+
"cell.missingValue": "(missing)",
|
|
123
165
|
|
|
124
166
|
"table.higherBetter": "越高越好",
|
|
125
167
|
"table.lowerBetter": "越低越好",
|
|
@@ -135,48 +177,45 @@ const zhCN: Record<ReportMessageKey, string> = {
|
|
|
135
177
|
"experimentList.avgDuration": "平均耗时",
|
|
136
178
|
"experimentList.passRate": "端到端成功率",
|
|
137
179
|
"experimentList.tokens": "Tokens",
|
|
138
|
-
"experimentList.
|
|
180
|
+
"experimentList.cost": "成本",
|
|
139
181
|
"experimentList.result": "结果",
|
|
140
182
|
"experimentList.status": "状态",
|
|
141
183
|
"experimentList.evalAttempt": "题目 / Attempt",
|
|
142
184
|
"experimentList.duration": "耗时",
|
|
143
|
-
"experimentList.cost": "成本",
|
|
144
185
|
"experimentList.filterPlaceholder": "筛选实验…",
|
|
145
186
|
"experimentList.defaultModel": "默认",
|
|
146
187
|
"experimentList.flags": "Flags",
|
|
147
188
|
"entityList.average": "平均 {value}",
|
|
189
|
+
"entityList.moreFailures.one": "+{n} 条其它失败",
|
|
190
|
+
"entityList.moreFailures.other": "+{n} 条其它失败",
|
|
148
191
|
"table.columnsHidden.one": "(还有 {n} 列未列出)",
|
|
149
192
|
"table.columnsHidden.other": "(还有 {n} 列未列出)",
|
|
150
193
|
|
|
151
|
-
"
|
|
152
|
-
"
|
|
153
|
-
"
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
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 计票",
|
|
158
202
|
"overview.experiments.one": "{n} 个实验",
|
|
159
203
|
"overview.experiments.other": "{n} 个实验",
|
|
160
204
|
"overview.evalsCount": "{n} 道题",
|
|
161
205
|
"overview.attemptsCount": "{n} 次 attempt",
|
|
162
|
-
|
|
163
|
-
"
|
|
206
|
+
"overview.evals": "Eval",
|
|
207
|
+
"overview.passRate": "端到端成功率",
|
|
208
|
+
"overview.totalCost": "成本",
|
|
164
209
|
|
|
165
210
|
"experimentComparison.groups": "实验组",
|
|
166
211
|
"experimentComparison.group": "实验组",
|
|
167
|
-
"experimentComparison.results": "结果",
|
|
212
|
+
"experimentComparison.results": "Eval 结果",
|
|
168
213
|
"experimentComparison.lastRun": "最后运行",
|
|
169
214
|
"experimentComparison.selectGroup": "选择实验组 {group}",
|
|
170
|
-
"experimentComparison.
|
|
215
|
+
"experimentComparison.commandsHead": "查看组内详情:",
|
|
171
216
|
"experimentComparison.empty": "没有实验组",
|
|
172
217
|
|
|
173
|
-
"
|
|
174
|
-
"composedFrom.other": "合成自 {n} 个 run",
|
|
175
|
-
"latestRun": "最新 {run}",
|
|
176
|
-
|
|
177
|
-
"scatter.betterHint": "更好 ↗",
|
|
178
|
-
"scatter.betterUpperRight": "更好 → 右上",
|
|
179
|
-
"scatter.axisReversed": "(轴反向:右 = 更好)",
|
|
218
|
+
"scatter.betterUpperRight": "越靠右上越好",
|
|
180
219
|
"scatter.noData": "{x} × {y} 没有可绘制的数据",
|
|
181
220
|
"pointsMissing.one": "{n} 个点缺数据",
|
|
182
221
|
"pointsMissing.other": "{n} 个点缺数据",
|
|
@@ -190,26 +229,31 @@ const zhCN: Record<ReportMessageKey, string> = {
|
|
|
190
229
|
|
|
191
230
|
"scoreboard.total": "总分",
|
|
192
231
|
"scoreboard.totalText": "总分",
|
|
193
|
-
"scoreboard.
|
|
194
|
-
"scoreboard.
|
|
195
|
-
"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} 道题已忽略",
|
|
196
240
|
"scoreboard.weights": "权重:",
|
|
197
241
|
"scoreboard.allWeights": "全部题 ×1",
|
|
198
242
|
"scoreboard.othersWeight": "其余 ×1",
|
|
199
|
-
"scoreboard.subjectTitle": "{
|
|
243
|
+
"scoreboard.subjectTitle": "{questions} 道题,加权得分 {earned}/{possible}",
|
|
200
244
|
|
|
201
245
|
"delta.pairHeader": "对比 (A → B)",
|
|
246
|
+
"delta.empty": "{experiments} 个实验、0 个可配对",
|
|
202
247
|
|
|
203
|
-
"
|
|
204
|
-
"board.failing": "失败清单:",
|
|
248
|
+
"tabs.tab": "Tab",
|
|
205
249
|
};
|
|
206
250
|
|
|
207
|
-
const dictionaries: Record<
|
|
251
|
+
const dictionaries: Record<string, Record<ReportMessageKey, string>> = {
|
|
208
252
|
en,
|
|
209
253
|
"zh-CN": zhCN,
|
|
210
254
|
};
|
|
211
255
|
|
|
212
|
-
/** 查字典 + 简单插值({name} 占位符)
|
|
256
|
+
/** 查字典 + 简单插值({name} 占位符)。内置词典未覆盖的 locale 回退 en。 */
|
|
213
257
|
export function localeText(
|
|
214
258
|
locale: ReportLocale,
|
|
215
259
|
key: ReportMessageKey,
|
|
@@ -225,25 +269,32 @@ export function localeText(
|
|
|
225
269
|
/** 带单复数的计数文案:n === 1 用 `<base>.one`,其余 `<base>.other`(zh-CN 两键同值)。 */
|
|
226
270
|
export function countText(
|
|
227
271
|
locale: ReportLocale,
|
|
228
|
-
base:
|
|
272
|
+
base:
|
|
273
|
+
| "overview.experiments"
|
|
274
|
+
| "pointsMissing"
|
|
275
|
+
| "scoreboard.notRun"
|
|
276
|
+
| "scoreboard.unscorable"
|
|
277
|
+
| "scoreboard.ignored"
|
|
278
|
+
| "entityList.moreFailures"
|
|
279
|
+
| "table.columnsHidden",
|
|
229
280
|
n: number,
|
|
230
281
|
): string {
|
|
231
282
|
return localeText(locale, `${base}.${n === 1 ? "one" : "other"}` as ReportMessageKey, { n });
|
|
232
283
|
}
|
|
233
284
|
|
|
234
|
-
/** 指标 label 的可本地化形态:字符串,或按 locale 给的字典(缺项回退 en,再回退任一非空值)。 */
|
|
235
|
-
export type LocalizedLabel = string | Partial<Record<ReportLocale, string>>;
|
|
236
|
-
|
|
237
285
|
/**
|
|
238
|
-
* 按 locale 解析指标 label
|
|
239
|
-
*
|
|
286
|
+
* 按 locale 解析指标 / 列 label:字符串原样;字典按 LocalizedText 回退规则取值;
|
|
287
|
+
* undefined 回退 fallback(= metric.name)。渲染面(web / text)共用。
|
|
240
288
|
*/
|
|
241
289
|
export function resolveMetricLabel(
|
|
242
|
-
label:
|
|
290
|
+
label: LocalizedText | undefined,
|
|
243
291
|
locale: ReportLocale,
|
|
244
292
|
fallback: string,
|
|
245
293
|
): string {
|
|
246
294
|
if (label === undefined) return fallback;
|
|
247
|
-
|
|
248
|
-
|
|
295
|
+
try {
|
|
296
|
+
return resolveLocalizedText(label, locale);
|
|
297
|
+
} catch {
|
|
298
|
+
return fallback;
|
|
299
|
+
}
|
|
249
300
|
}
|
package/src/report/metrics.ts
CHANGED
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
// durationMs(duration) null 实测 实测 实测 lower
|
|
13
13
|
// tokens(tokens) null 实测;无 usage→null 同左 同左 lower
|
|
14
14
|
// costUSD(cost) null 同上 同左 同左 lower
|
|
15
|
-
//
|
|
15
|
+
// assistantTurns(assistant-turns) null 实测;o11y 缺失→null 同左 同左 lower
|
|
16
|
+
// repeatedFailedCommands(repeated-failed-commands) null 实测;o11y 缺失→null 同左 同左 lower
|
|
16
17
|
//
|
|
17
|
-
// 两档指标(docs/feature/reports/library.md「内置指标」):以上除
|
|
18
|
-
// 的瘦身字段——任何 producer、任何
|
|
19
|
-
//
|
|
20
|
-
// 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——报告作者自己摆时心里要有这根弦,内置报告不用它们。
|
|
21
23
|
|
|
22
24
|
import type { EvalResult } from "../types.ts";
|
|
23
25
|
import type { Metric } from "./types.ts";
|
|
@@ -148,7 +150,7 @@ export const tokens = defineMetric({
|
|
|
148
150
|
|
|
149
151
|
export const costUSD = defineMetric({
|
|
150
152
|
name: "cost",
|
|
151
|
-
label: { en: "Cost", "zh-CN": "
|
|
153
|
+
label: { en: "Cost", "zh-CN": "成本" },
|
|
152
154
|
description: "USD cost per attempt (gateway-measured beats estimated).",
|
|
153
155
|
better: "lower",
|
|
154
156
|
unit: "$",
|
|
@@ -156,14 +158,15 @@ export const costUSD = defineMetric({
|
|
|
156
158
|
});
|
|
157
159
|
|
|
158
160
|
/**
|
|
159
|
-
*
|
|
161
|
+
* 读 artifact(o11y,懒加载)的内置指标之一——其余只读瘦身字段。
|
|
160
162
|
* 发布时若该 attempt 没带 o11y(如 copySnapshots 的 artifacts 选项漏了它),
|
|
161
|
-
* value 如实返回 null,渲染成「—」,不冒充 0
|
|
163
|
+
* value 如实返回 null,渲染成「—」,不冒充 0。名字带限定词:o11y 事件流中的 assistant
|
|
164
|
+
* turn 数与 `t.send` 的 `s<session>/t<turn>` 轮次是两个计数。
|
|
162
165
|
*/
|
|
163
|
-
export const
|
|
164
|
-
name: "turns",
|
|
165
|
-
label: { en: "
|
|
166
|
-
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.",
|
|
167
170
|
better: "lower",
|
|
168
171
|
unit: "turns",
|
|
169
172
|
async value(a) {
|
|
@@ -172,3 +175,30 @@ export const turns = defineMetric({
|
|
|
172
175
|
return o11y?.totalTurns ?? null;
|
|
173
176
|
},
|
|
174
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
|
+
});
|