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
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
// ExperimentComparison:裸 niceeval show / view 首页渲染的内置默认报告,同时是可整体引用的
|
|
2
|
-
// 官方组合件(docs/feature/reports/library.md「ExperimentComparison」)。
|
|
3
|
-
//
|
|
4
|
-
// 名字描述整份报告回答的问题,不绑定其中某一张图。它是组合件而非新的数据源——每组的
|
|
5
|
-
// GroupSummary、成本 × 端到端成功率散点、固定列 ExperimentList 都消费各自公开 .data() 的结果。
|
|
6
|
-
// 两种用法共享同一份口径:
|
|
7
|
-
// · 默认报告:宿主把它当普通 ReportDefinition(build 面),没有 renderer 私有通道;
|
|
8
|
-
// · 报告组件:`<ExperimentComparison data={await ExperimentComparison.data(selection)} />`,
|
|
9
|
-
// 在自定义报告或用户自己的 React 页面里整体引用。
|
|
10
|
-
|
|
11
|
-
import { Col, Section, Table } from "../primitives.tsx";
|
|
12
|
-
import { ExperimentList, GroupSummary, MetricScatter } from "../components.tsx";
|
|
13
|
-
import { costUSD, endToEndPassRate } from "../metrics.ts";
|
|
14
|
-
import { defineReport, type ReportDefinition } from "../report.ts";
|
|
15
|
-
import { defineComponent, type ReportComponent, type TextContext } from "../tree.ts";
|
|
16
|
-
import { localeText, type ReportLocale } from "../locale.ts";
|
|
17
|
-
import type { ExperimentListItem, GroupSummaryData, ScatterData } from "../types.ts";
|
|
18
|
-
import type { ScatterDataOptions } from "../compute.ts";
|
|
19
|
-
import { resolveInput, type SnapshotsInput } from "../aggregate.ts";
|
|
20
|
-
import { ExperimentComparisonView } from "../react/ExperimentComparison.tsx";
|
|
21
|
-
import { wrapDisplay } from "../text/layout.ts";
|
|
22
|
-
import { formatUSD } from "../format.ts";
|
|
23
|
-
|
|
24
|
-
// 每组散点的唯一口径:默认 definition 与公开 `.data()` 共用,不各写一份。
|
|
25
|
-
const SCATTER_OPTIONS: ScatterDataOptions = {
|
|
26
|
-
points: "experiment",
|
|
27
|
-
series: "agent",
|
|
28
|
-
x: costUSD,
|
|
29
|
-
y: endToEndPassRate,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 一个可比组的数据。三个子块都只消费本组快照,不能含其它父目录的引用。
|
|
34
|
-
*/
|
|
35
|
-
export interface ExperimentComparisonGroupData {
|
|
36
|
-
/** experiment id 的完整父路径;根目录 experiment 使用自己的完整 id。 */
|
|
37
|
-
key: string;
|
|
38
|
-
summary: GroupSummaryData;
|
|
39
|
-
/** 成本 × 端到端成功率散点(`MetricScatter.data` 的口径:points=experiment、series=agent)。 */
|
|
40
|
-
scatter: ScatterData;
|
|
41
|
-
/** 固定列 experiment 比较表(`ExperimentList.data` 的口径,已按端到端成功率排序)。 */
|
|
42
|
-
experiments: ExperimentListItem[];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** `ExperimentComparison.data(selection)` 的穷尽产物:按 key 排序的独立可比组。 */
|
|
46
|
-
export interface ExperimentComparisonData {
|
|
47
|
-
groups: ExperimentComparisonGroupData[];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** 完整父路径是组键;没有父路径的 experiment 不能互相比,自己形成单例组。 */
|
|
51
|
-
export function experimentComparisonGroupKey(experimentId: string): string {
|
|
52
|
-
const slash = experimentId.lastIndexOf("/");
|
|
53
|
-
return slash === -1 ? experimentId : experimentId.slice(0, slash);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** 组合件的数据计算:先分区,再让三个官方子块在各组内并行计算。 */
|
|
57
|
-
async function experimentComparisonData(input: SnapshotsInput): Promise<ExperimentComparisonData> {
|
|
58
|
-
const { snapshots } = resolveInput(input);
|
|
59
|
-
const snapshotsByGroup = new Map<string, typeof snapshots>();
|
|
60
|
-
for (const snapshot of snapshots) {
|
|
61
|
-
const key = experimentComparisonGroupKey(snapshot.experimentId);
|
|
62
|
-
const group = snapshotsByGroup.get(key);
|
|
63
|
-
if (group) group.push(snapshot);
|
|
64
|
-
else snapshotsByGroup.set(key, [snapshot]);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const groups = await Promise.all(
|
|
68
|
-
[...snapshotsByGroup.entries()]
|
|
69
|
-
.sort(([a], [b]) => a.localeCompare(b))
|
|
70
|
-
.map(async ([key, groupSnapshots]): Promise<ExperimentComparisonGroupData> => {
|
|
71
|
-
const [summary, scatter, experiments] = await Promise.all([
|
|
72
|
-
GroupSummary.data(groupSnapshots),
|
|
73
|
-
MetricScatter.data(groupSnapshots, SCATTER_OPTIONS),
|
|
74
|
-
ExperimentList.data(groupSnapshots),
|
|
75
|
-
]);
|
|
76
|
-
return { key, summary, scatter, experiments };
|
|
77
|
-
}),
|
|
78
|
-
);
|
|
79
|
-
return { groups };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface ExperimentComparisonProps {
|
|
83
|
-
data: ExperimentComparisonData;
|
|
84
|
-
/** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
|
|
85
|
-
locale?: ReportLocale;
|
|
86
|
-
className?: string;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** 单组详情:散点与实验列表全部来自同一个预分区结果。 */
|
|
90
|
-
function groupComposition(group: ExperimentComparisonGroupData, locale?: ReportLocale, className?: string) {
|
|
91
|
-
return (
|
|
92
|
-
<Col className={className}>
|
|
93
|
-
<MetricScatter data={group.scatter} locale={locale} />
|
|
94
|
-
<ExperimentList items={group.experiments} filter locale={locale} relativeTo={group.key} />
|
|
95
|
-
</Col>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function shellQuote(value: string): string {
|
|
100
|
-
return /^[A-Za-z0-9._/-]+$/.test(value) ? value : `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function verdictsText(group: ExperimentComparisonGroupData, locale: ReportLocale): string {
|
|
104
|
-
const parts: string[] = [];
|
|
105
|
-
for (const verdict of ["passed", "failed", "errored", "skipped"] as const) {
|
|
106
|
-
const count = group.summary.verdicts[verdict];
|
|
107
|
-
if (count > 0) parts.push(`${count} ${localeText(locale, `verdict.${verdict}`)}`);
|
|
108
|
-
}
|
|
109
|
-
return parts.length > 0 ? parts.join(" / ") : "—";
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function textFace(data: ExperimentComparisonData, className: string | undefined, ctx: TextContext): string {
|
|
113
|
-
if (data.groups.length === 0) return localeText(ctx.locale, "experimentComparison.empty");
|
|
114
|
-
if (data.groups.length === 1) {
|
|
115
|
-
const group = data.groups[0]!;
|
|
116
|
-
return ctx.render(
|
|
117
|
-
<Section title={group.key} className={className}>
|
|
118
|
-
{groupComposition(group)}
|
|
119
|
-
</Section>,
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const table = ctx.render(
|
|
124
|
-
<Table
|
|
125
|
-
columns={[
|
|
126
|
-
{ key: "group", header: localeText(ctx.locale, "experimentComparison.group") },
|
|
127
|
-
{ key: "experiments", header: localeText(ctx.locale, "groupSummary.experiments"), align: "right" },
|
|
128
|
-
{ key: "evals", header: localeText(ctx.locale, "overview.evals"), align: "right" },
|
|
129
|
-
{ key: "passRate", header: localeText(ctx.locale, "overview.passRate"), align: "right" },
|
|
130
|
-
{ key: "results", header: localeText(ctx.locale, "experimentComparison.results") },
|
|
131
|
-
{ key: "cost", header: localeText(ctx.locale, "overview.totalCost"), align: "right" },
|
|
132
|
-
{ key: "lastRun", header: localeText(ctx.locale, "experimentComparison.lastRun") },
|
|
133
|
-
]}
|
|
134
|
-
rows={data.groups.map((group) => ({
|
|
135
|
-
key: group.key,
|
|
136
|
-
cells: {
|
|
137
|
-
group: group.key,
|
|
138
|
-
experiments: String(group.summary.experiments),
|
|
139
|
-
evals: String(group.summary.evals),
|
|
140
|
-
passRate: group.summary.passRate.display,
|
|
141
|
-
results: verdictsText(group, ctx.locale),
|
|
142
|
-
cost: group.summary.totalCostUSD === null ? null : formatUSD(group.summary.totalCostUSD),
|
|
143
|
-
lastRun: group.summary.lastRunAt ?? null,
|
|
144
|
-
},
|
|
145
|
-
}))}
|
|
146
|
-
/>,
|
|
147
|
-
);
|
|
148
|
-
const commands = data.groups
|
|
149
|
-
.map((group) => {
|
|
150
|
-
const command = `niceeval show --experiment ${shellQuote(group.key)}`;
|
|
151
|
-
return wrapDisplay(localeText(ctx.locale, "experimentComparison.command", { command }), ctx.width).join("\n");
|
|
152
|
-
})
|
|
153
|
-
.join("\n");
|
|
154
|
-
return `${localeText(ctx.locale, "experimentComparison.groups")}\n\n${table}\n\n${commands}`;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* 内置默认报告兼官方组合件:作为组件时收 `data`(`.data()` 的产物),两个渲染面直接摆
|
|
159
|
-
* 数据形态的子组件;作为默认报告时经 build 面走与用户 `--report` 完全相同的管线。
|
|
160
|
-
*/
|
|
161
|
-
export const ExperimentComparison: ReportComponent<ExperimentComparisonProps> &
|
|
162
|
-
ReportDefinition & { data: typeof experimentComparisonData } = Object.assign(
|
|
163
|
-
defineComponent<ExperimentComparisonProps>({
|
|
164
|
-
web: (props, ctx) => (
|
|
165
|
-
<ExperimentComparisonView
|
|
166
|
-
data={props.data}
|
|
167
|
-
locale={props.locale ?? ctx.locale}
|
|
168
|
-
className={props.className}
|
|
169
|
-
/>
|
|
170
|
-
),
|
|
171
|
-
text: ({ data, className }, ctx) => textFace(data, className, ctx),
|
|
172
|
-
}),
|
|
173
|
-
defineReport(async ({ selection }) => {
|
|
174
|
-
const data = await experimentComparisonData(selection);
|
|
175
|
-
return <ExperimentComparison data={data} />;
|
|
176
|
-
}),
|
|
177
|
-
{ data: experimentComparisonData },
|
|
178
|
-
);
|
|
179
|
-
ExperimentComparison.displayName = "ExperimentComparison";
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
// 内置报告目录:一个文件一个按展示内容命名的组合件(组件兼默认报告),显式导出值,不建字符串 registry。
|
|
2
|
-
export { ExperimentComparison } from "./experiment-comparison.tsx";
|
|
3
|
-
export type {
|
|
4
|
-
ExperimentComparisonData,
|
|
5
|
-
ExperimentComparisonGroupData,
|
|
6
|
-
ExperimentComparisonProps,
|
|
7
|
-
} from "./experiment-comparison.tsx";
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// GroupSummary:一组 experiment(如自定义报告里同一 <Section> 内的全部 experiment)的
|
|
2
|
-
// 紧凑摘要块——恢复旧 GroupSelector 卡片的信息密度(通过率、experiment/eval 数、failed、
|
|
3
|
-
// errored、总成本、最后运行时间),但只渲染 GroupSummaryData 算好的 MetricCell / 计数,
|
|
4
|
-
// 不现场重算比例(docs/feature/reports/library.md「GroupSummary」)。errored 为 0 时省略该片段(旧卡片同一姿态),
|
|
5
|
-
// 但这只是渲染取舍——数据侧 verdicts.errored 字段本身永不省略。
|
|
6
|
-
|
|
7
|
-
import type { ReactElement } from "react";
|
|
8
|
-
import type { GroupSummaryData } from "../types.ts";
|
|
9
|
-
import { DEFAULT_REPORT_LOCALE, localeText, type ReportLocale } from "../locale.ts";
|
|
10
|
-
import { MetricCellView } from "./cell.tsx";
|
|
11
|
-
import { cx, formatUSD } from "./format.ts";
|
|
12
|
-
|
|
13
|
-
export function GroupSummary({
|
|
14
|
-
data,
|
|
15
|
-
className,
|
|
16
|
-
locale = DEFAULT_REPORT_LOCALE,
|
|
17
|
-
}: {
|
|
18
|
-
data: GroupSummaryData;
|
|
19
|
-
className?: string;
|
|
20
|
-
locale?: ReportLocale;
|
|
21
|
-
}): ReactElement {
|
|
22
|
-
const missing = <span className="nre-missing">{localeText(locale, "cell.missing")}</span>;
|
|
23
|
-
return (
|
|
24
|
-
<div className={cx("nre", "nre-group-summary", className)}>
|
|
25
|
-
<dl className="nre-group-kpis">
|
|
26
|
-
<div className="nre-group-kpi nre-group-kpi-rate">
|
|
27
|
-
<dt>{localeText(locale, "overview.passRate")}</dt>
|
|
28
|
-
<dd>
|
|
29
|
-
<MetricCellView cell={data.passRate} locale={locale} />
|
|
30
|
-
</dd>
|
|
31
|
-
</div>
|
|
32
|
-
<div className="nre-group-kpi">
|
|
33
|
-
<dt>{localeText(locale, "groupSummary.experiments")}</dt>
|
|
34
|
-
<dd>{data.experiments}</dd>
|
|
35
|
-
</div>
|
|
36
|
-
<div className="nre-group-kpi">
|
|
37
|
-
<dt>{localeText(locale, "overview.evals")}</dt>
|
|
38
|
-
<dd>{data.evals}</dd>
|
|
39
|
-
</div>
|
|
40
|
-
<div className="nre-group-kpi">
|
|
41
|
-
<dt>{localeText(locale, "overview.attempts")}</dt>
|
|
42
|
-
<dd>{data.attempts}</dd>
|
|
43
|
-
</div>
|
|
44
|
-
<div className="nre-group-kpi">
|
|
45
|
-
<dt>{localeText(locale, "verdict.failed")}</dt>
|
|
46
|
-
<dd className="nre-verdict-failed">{data.verdicts.failed}</dd>
|
|
47
|
-
</div>
|
|
48
|
-
{/* errored 为 0 省略这一片段(旧 GroupSelector 卡片同一姿态);数据字段本身不受影响 */}
|
|
49
|
-
{data.verdicts.errored > 0 && (
|
|
50
|
-
<div className="nre-group-kpi">
|
|
51
|
-
<dt>{localeText(locale, "verdict.errored")}</dt>
|
|
52
|
-
<dd className="nre-verdict-errored">{data.verdicts.errored}</dd>
|
|
53
|
-
</div>
|
|
54
|
-
)}
|
|
55
|
-
<div className="nre-group-kpi">
|
|
56
|
-
<dt>{localeText(locale, "overview.totalCost")}</dt>
|
|
57
|
-
{/* totalCostUSD 全缺 = null:显示缺数据,不编 $0 */}
|
|
58
|
-
<dd>{data.totalCostUSD === null ? missing : formatUSD(data.totalCostUSD)}</dd>
|
|
59
|
-
</div>
|
|
60
|
-
</dl>
|
|
61
|
-
{data.lastRunAt && (
|
|
62
|
-
<p className="nre-group-summary-time">{localeText(locale, "latestRun", { run: data.lastRunAt })}</p>
|
|
63
|
-
)}
|
|
64
|
-
</div>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
// RunOverview:页头 KPI 条——「这批数据是什么」。
|
|
2
|
-
// 数字下面标注数据来源(几个快照、何时跑的);warnings 有内容时直接显示在条内,
|
|
3
|
-
// 诚实不靠使用者记得渲染(docs/feature/reports/library.md「RunOverview」行为清单)。
|
|
4
|
-
|
|
5
|
-
import type { ReactElement } from "react";
|
|
6
|
-
import type { OverviewData } from "../types.ts";
|
|
7
|
-
import { DEFAULT_REPORT_LOCALE, localeText, type ReportLocale } from "../locale.ts";
|
|
8
|
-
import { cx, formatDurationMs, formatUSD } from "./format.ts";
|
|
9
|
-
|
|
10
|
-
export function RunOverview({
|
|
11
|
-
data,
|
|
12
|
-
className,
|
|
13
|
-
locale = DEFAULT_REPORT_LOCALE,
|
|
14
|
-
}: {
|
|
15
|
-
data: OverviewData;
|
|
16
|
-
className?: string;
|
|
17
|
-
locale?: ReportLocale;
|
|
18
|
-
}): ReactElement {
|
|
19
|
-
const { totals } = data;
|
|
20
|
-
const missing = <span className="nre-missing">{localeText(locale, "cell.missing")}</span>;
|
|
21
|
-
// 通过率只渲染 computeCell 算好的 MetricCell,不现场重算——覆盖率角标复用
|
|
22
|
-
// MetricCellView 的缺数据/coverage 语义(缺数据 = 显式文案,绝不画 0%)
|
|
23
|
-
const { passRate } = totals;
|
|
24
|
-
const passRateNode =
|
|
25
|
-
passRate.value === null ? (
|
|
26
|
-
missing
|
|
27
|
-
) : (
|
|
28
|
-
<>
|
|
29
|
-
{passRate.display}
|
|
30
|
-
{passRate.samples < passRate.total && (
|
|
31
|
-
<sup
|
|
32
|
-
className="nre-coverage"
|
|
33
|
-
title={localeText(locale, "cell.coverageTitle", { samples: passRate.samples, total: passRate.total })}
|
|
34
|
-
>
|
|
35
|
-
{passRate.samples}/{passRate.total}
|
|
36
|
-
</sup>
|
|
37
|
-
)}
|
|
38
|
-
</>
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
return (
|
|
42
|
-
<header className={cx("nre", "nre-overview", className)}>
|
|
43
|
-
<dl className="nre-kpis">
|
|
44
|
-
<div className="nre-kpi">
|
|
45
|
-
<dt>{localeText(locale, "overview.snapshots")}</dt>
|
|
46
|
-
<dd>{data.snapshots.length}</dd>
|
|
47
|
-
</div>
|
|
48
|
-
<div className="nre-kpi">
|
|
49
|
-
<dt>{localeText(locale, "overview.evals")}</dt>
|
|
50
|
-
<dd>{totals.evals}</dd>
|
|
51
|
-
</div>
|
|
52
|
-
<div className="nre-kpi">
|
|
53
|
-
<dt>{localeText(locale, "overview.attempts")}</dt>
|
|
54
|
-
<dd>{totals.attempts}</dd>
|
|
55
|
-
</div>
|
|
56
|
-
<div className="nre-kpi">
|
|
57
|
-
<dt>{localeText(locale, "overview.passRate")}</dt>
|
|
58
|
-
<dd>{passRateNode}</dd>
|
|
59
|
-
</div>
|
|
60
|
-
<div className="nre-kpi">
|
|
61
|
-
<dt>{localeText(locale, "overview.totalCost")}</dt>
|
|
62
|
-
{/* costUSD 全缺 = null:显示缺数据,不编 $0 */}
|
|
63
|
-
<dd>{totals.costUSD === null ? missing : formatUSD(totals.costUSD)}</dd>
|
|
64
|
-
</div>
|
|
65
|
-
<div className="nre-kpi">
|
|
66
|
-
<dt>{localeText(locale, "overview.totalDuration")}</dt>
|
|
67
|
-
<dd>{formatDurationMs(totals.durationMs)}</dd>
|
|
68
|
-
</div>
|
|
69
|
-
</dl>
|
|
70
|
-
|
|
71
|
-
<p className="nre-verdicts">
|
|
72
|
-
<span className="nre-verdict nre-verdict-passed">
|
|
73
|
-
{localeText(locale, "verdict.passed")} {totals.passed}
|
|
74
|
-
</span>
|
|
75
|
-
<span className="nre-verdict nre-verdict-failed">
|
|
76
|
-
{localeText(locale, "verdict.failed")} {totals.failed}
|
|
77
|
-
</span>
|
|
78
|
-
<span className="nre-verdict nre-verdict-errored">
|
|
79
|
-
{localeText(locale, "verdict.errored")} {totals.errored}
|
|
80
|
-
</span>
|
|
81
|
-
<span className="nre-verdict nre-verdict-skipped">
|
|
82
|
-
{localeText(locale, "verdict.skipped")} {totals.skipped}
|
|
83
|
-
</span>
|
|
84
|
-
</p>
|
|
85
|
-
|
|
86
|
-
{/* 数据来源:哪些快照、何时跑的——报告的数字都从这里来 */}
|
|
87
|
-
<p className="nre-source">
|
|
88
|
-
{localeText(locale, "overview.source", { n: data.snapshots.length })}
|
|
89
|
-
{data.snapshots.map((s) => (
|
|
90
|
-
<span key={`${s.experimentId}@${s.startedAt}`} className="nre-source-snapshot">
|
|
91
|
-
{s.experimentId}({s.agent}
|
|
92
|
-
{s.model ? ` · ${s.model}` : ""})@ {s.startedAt}
|
|
93
|
-
</span>
|
|
94
|
-
))}
|
|
95
|
-
</p>
|
|
96
|
-
|
|
97
|
-
{/* Selection 的警告(残缺快照等)直接渲染在条内,不静默;结构化字段供程序判断,这里打 message */}
|
|
98
|
-
{data.warnings.length > 0 && (
|
|
99
|
-
<ul className="nre-warnings">
|
|
100
|
-
{data.warnings.map((w, i) => (
|
|
101
|
-
<li key={i} className="nre-warning" data-kind={w.kind}>
|
|
102
|
-
{w.message}
|
|
103
|
-
</li>
|
|
104
|
-
))}
|
|
105
|
-
</ul>
|
|
106
|
-
)}
|
|
107
|
-
</header>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|