niceeval 0.4.5 → 0.5.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/docs-site/zh/concepts/adapter.mdx +6 -6
- package/docs-site/zh/concepts/experiment.mdx +7 -7
- package/docs-site/zh/concepts/overview.mdx +1 -1
- package/docs-site/zh/concepts/tier.mdx +6 -6
- package/docs-site/zh/guides/agent-feedback-loop.mdx +63 -20
- package/docs-site/zh/guides/connect-your-agent.mdx +7 -7
- package/docs-site/zh/guides/custom-reports.mdx +243 -0
- package/docs-site/zh/guides/experiments.mdx +3 -3
- package/docs-site/zh/guides/report-components.mdx +252 -0
- package/docs-site/zh/guides/reporters.mdx +1 -1
- package/docs-site/zh/guides/results-data.mdx +224 -0
- package/docs-site/zh/guides/runner.mdx +1 -1
- package/docs-site/zh/guides/sandbox-agent.mdx +2 -2
- package/docs-site/zh/guides/viewing-results.mdx +147 -77
- package/docs-site/zh/guides/write-experiment.mdx +9 -9
- package/docs-site/zh/guides/write-send.mdx +6 -6
- package/docs-site/zh/index.mdx +1 -1
- package/docs-site/zh/introduction.mdx +1 -1
- package/docs-site/zh/reference/cli.mdx +10 -2
- package/docs-site/zh/reference/define-agent.mdx +5 -5
- package/docs-site/zh/reference/define-config.mdx +1 -1
- package/docs-site/zh/reference/define-eval.mdx +3 -3
- package/package.json +3 -2
- package/src/agents/ai-sdk.test.ts +1 -1
- package/src/agents/ai-sdk.ts +2 -2
- package/src/agents/bub.ts +14 -4
- package/src/agents/claude-code.ts +1 -1
- package/src/agents/codex.ts +2 -2
- package/src/agents/streaming.test.ts +1 -1
- package/src/agents/types.ts +4 -4
- package/src/agents/ui-message-stream.test.ts +1 -1
- package/src/cli.ts +104 -14
- package/src/context/context.test.ts +1 -1
- package/src/context/context.ts +3 -3
- package/src/context/session.ts +2 -2
- package/src/context/types.ts +2 -2
- package/src/i18n/en.ts +29 -7
- package/src/i18n/zh-CN.ts +24 -2
- package/src/report/aggregate.ts +79 -50
- package/src/report/components.tsx +190 -0
- package/src/report/compute.ts +149 -84
- package/src/report/default-report.tsx +222 -0
- package/src/report/dual-face.test.tsx +527 -0
- package/src/report/format.ts +29 -0
- package/src/report/index.ts +79 -24
- package/src/report/load.ts +67 -0
- package/src/report/metrics.ts +2 -1
- package/src/report/param.ts +18 -0
- package/src/report/primitives.tsx +117 -0
- package/src/report/react/CaseList.tsx +2 -2
- package/src/report/react/DeltaTable.tsx +2 -2
- package/src/report/react/MetricBars.tsx +109 -0
- package/src/report/react/MetricLine.tsx +200 -0
- package/src/report/react/MetricMatrix.tsx +1 -1
- package/src/report/react/MetricScatter.tsx +1 -1
- package/src/report/react/MetricTable.tsx +1 -1
- package/src/report/react/RunOverview.tsx +4 -4
- package/src/report/react/Scoreboard.tsx +3 -3
- package/src/report/react/cell.tsx +1 -1
- package/src/report/react/fixtures.ts +98 -36
- package/src/report/react/format.ts +3 -28
- package/src/report/react/index.tsx +41 -24
- package/src/report/react/render.test.tsx +8 -8
- package/src/report/react/styles.css +77 -0
- package/src/report/report.test.ts +248 -128
- package/src/report/report.ts +69 -0
- package/src/report/text/faces.ts +356 -0
- package/src/report/text/layout.ts +125 -0
- package/src/report/text/plot.ts +127 -0
- package/src/report/tree.ts +220 -0
- package/src/report/types.ts +75 -27
- package/src/report/web.ts +40 -0
- package/src/results/copy.ts +95 -41
- package/src/results/format.ts +12 -11
- package/src/results/index.ts +34 -17
- package/src/results/open.ts +201 -81
- package/src/results/results.test.ts +595 -191
- package/src/results/select.ts +107 -55
- package/src/results/types.ts +137 -45
- package/src/results/writer.ts +258 -0
- package/src/runner/attempt.ts +3 -3
- package/src/runner/fingerprint.ts +1 -1
- package/src/runner/reporters/artifacts.ts +38 -78
- package/src/runner/reporters/braintrust.test.ts +2 -2
- package/src/runner/reporters/braintrust.ts +3 -3
- package/src/runner/run.ts +1 -1
- package/src/runner/types.ts +18 -12
- package/src/show/compose.ts +215 -0
- package/src/show/index.ts +263 -0
- package/src/show/render.ts +456 -0
- package/src/show/show.test.ts +505 -0
- package/src/view/app/App.tsx +85 -24
- package/src/view/app/components/CostScoreChart.tsx +29 -10
- package/src/view/app/components/ExperimentTable.tsx +27 -9
- package/src/view/app/components/GroupSelector.tsx +1 -1
- package/src/view/app/i18n.ts +18 -3
- package/src/view/app/lib/attempt-route.test.ts +9 -9
- package/src/view/app/lib/attempt-route.ts +5 -5
- package/src/view/app/lib/outcome.ts +1 -3
- package/src/view/app/lib/rows.ts +95 -15
- package/src/view/app/main.tsx +18 -6
- package/src/view/app/pages/RunsPage.tsx +4 -7
- package/src/view/app/pages/TracesPage.tsx +3 -8
- package/src/view/app/types.ts +50 -6
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +20 -20
- package/src/view/data.test.ts +254 -0
- package/src/view/data.ts +336 -0
- package/src/view/index.ts +64 -10
- package/src/view/server.ts +31 -9
- package/src/view/shared/types.ts +47 -41
- package/src/view/styles.css +5 -0
- package/src/view/template.html +1 -0
- package/src/view/view-report.test.ts +308 -0
- package/docs-site/.mintignore +0 -13
- package/docs-site/AGENTS.md +0 -46
- package/docs-site/concepts/adapter.mdx +0 -287
- package/docs-site/concepts/assert.mdx +0 -243
- package/docs-site/concepts/drive.mdx +0 -118
- package/docs-site/concepts/evals.mdx +0 -108
- package/docs-site/concepts/experiment.mdx +0 -37
- package/docs-site/concepts/hitl.mdx +0 -83
- package/docs-site/concepts/judge.mdx +0 -129
- package/docs-site/concepts/overview.mdx +0 -98
- package/docs-site/concepts/tier.mdx +0 -42
- package/docs-site/docs-ref/00-index.md +0 -23
- package/docs-site/docs-ref/01-page-types.md +0 -43
- package/docs-site/docs-ref/03-style-rules.md +0 -45
- package/docs-site/docs-ref/04-code-examples.md +0 -37
- package/docs-site/docs-ref/05-dx-failure-paths.md +0 -45
- package/docs-site/docs-ref/06-checklists.md +0 -53
- package/docs-site/docs.json +0 -256
- package/docs-site/example/ai-agent-application.mdx +0 -148
- package/docs-site/example/claude-code-codex-plugin.mdx +0 -162
- package/docs-site/example/claude-code-codex-skill.mdx +0 -147
- package/docs-site/example/showcase.mdx +0 -39
- package/docs-site/example/tier1-ai-sdk-v7.mdx +0 -136
- package/docs-site/example/tier1-claude-sdk.mdx +0 -119
- package/docs-site/example/tier1-codex-sdk.mdx +0 -111
- package/docs-site/example/tier1-langgraph.mdx +0 -119
- package/docs-site/example/tier1-pi-sdk.mdx +0 -119
- package/docs-site/favicon.svg +0 -5
- package/docs-site/github-diff.css +0 -135
- package/docs-site/github-diff.js +0 -11
- package/docs-site/guides/authoring.mdx +0 -129
- package/docs-site/guides/ci-integration.mdx +0 -97
- package/docs-site/guides/connect-otel.mdx +0 -209
- package/docs-site/guides/connect-your-agent.mdx +0 -221
- package/docs-site/guides/dataset-fanout.mdx +0 -98
- package/docs-site/guides/experiments.mdx +0 -71
- package/docs-site/guides/fixtures.mdx +0 -147
- package/docs-site/guides/reporters.mdx +0 -113
- package/docs-site/guides/runner.mdx +0 -79
- package/docs-site/guides/sandbox-agent.mdx +0 -138
- package/docs-site/guides/sandbox-backends.mdx +0 -64
- package/docs-site/guides/scoring-guide.mdx +0 -92
- package/docs-site/guides/viewing-results.mdx +0 -195
- package/docs-site/guides/write-experiment.mdx +0 -81
- package/docs-site/guides/write-send.mdx +0 -347
- package/docs-site/index.mdx +0 -181
- package/docs-site/introduction.mdx +0 -141
- package/docs-site/quickstart.mdx +0 -136
- package/docs-site/reference/builtin-agents.mdx +0 -161
- package/docs-site/reference/capabilities.mdx +0 -76
- package/docs-site/reference/cli.mdx +0 -120
- package/docs-site/reference/define-agent.mdx +0 -168
- package/docs-site/reference/define-config.mdx +0 -41
- package/docs-site/reference/define-eval.mdx +0 -160
- package/docs-site/reference/events.mdx +0 -131
- package/docs-site/reference/expect.mdx +0 -112
- package/docs-site/tracker.js +0 -8
- package/src/report/react/data.ts +0 -17
- package/src/view/aggregate.ts +0 -103
- package/src/view/loader.test.ts +0 -61
- package/src/view/loader.ts +0 -257
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
// 手工 fixture
|
|
2
|
-
//
|
|
1
|
+
// 手工 fixture:模拟计算函数(MetricTable.data / MetricMatrix.data / …)的产物。
|
|
2
|
+
// 仅供渲染测试与 scripts/report-react-demo.tsx 使用,不从入口导出。
|
|
3
3
|
// 数字刻意覆盖诚实细节:coverage 角标(samples<total)、全 null 格子、
|
|
4
4
|
// 稀疏矩阵、缺数据的散点、delta 的 null 不硬算、truncated 计数。
|
|
5
5
|
|
|
6
6
|
import type {
|
|
7
7
|
CaseListData,
|
|
8
8
|
DeltaData,
|
|
9
|
+
LineData,
|
|
9
10
|
MatrixData,
|
|
10
11
|
MetricColumn,
|
|
11
12
|
OverviewData,
|
|
12
13
|
ScatterData,
|
|
13
14
|
ScoreboardData,
|
|
14
15
|
TableData,
|
|
15
|
-
} from "
|
|
16
|
+
} from "../types.ts";
|
|
16
17
|
|
|
17
|
-
export const passRateColumn: MetricColumn = { key: "pass-rate", label: "
|
|
18
|
-
export const codeLinesColumn: MetricColumn = { key: "code-lines", label: "
|
|
19
|
-
export const costColumn: MetricColumn = { key: "cost", label: "
|
|
18
|
+
export const passRateColumn: MetricColumn = { key: "pass-rate", label: "pass rate", unit: "%", better: "higher" };
|
|
19
|
+
export const codeLinesColumn: MetricColumn = { key: "code-lines", label: "code lines", unit: "lines", better: "lower" };
|
|
20
|
+
export const costColumn: MetricColumn = { key: "cost", label: "cost", unit: "$", better: "lower" };
|
|
20
21
|
|
|
21
22
|
export const overviewData: OverviewData = {
|
|
22
23
|
snapshots: [
|
|
@@ -33,7 +34,15 @@ export const overviewData: OverviewData = {
|
|
|
33
34
|
costUSD: null, // 全部 attempt 都没报成本:null,组件必须显示缺数据而不是 $0
|
|
34
35
|
durationMs: 261_000,
|
|
35
36
|
},
|
|
36
|
-
warnings: [
|
|
37
|
+
warnings: [
|
|
38
|
+
{
|
|
39
|
+
kind: "partial-coverage",
|
|
40
|
+
experimentId: "compare/bub",
|
|
41
|
+
covered: 9,
|
|
42
|
+
total: 12,
|
|
43
|
+
message: "snapshot covers 9 of 12 evals seen in history; re-run `niceeval exp compare/bub` for a full snapshot",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
37
46
|
};
|
|
38
47
|
|
|
39
48
|
export const overviewWithCost: OverviewData = {
|
|
@@ -42,7 +51,7 @@ export const overviewWithCost: OverviewData = {
|
|
|
42
51
|
warnings: [],
|
|
43
52
|
};
|
|
44
53
|
|
|
45
|
-
export const tableData: TableData = {
|
|
54
|
+
export const tableData: TableData<"pass-rate" | "code-lines"> = {
|
|
46
55
|
dimension: "agent",
|
|
47
56
|
// 行顺序故意不按 passRate 排:组件必须按传入顺序渲染,不重排
|
|
48
57
|
columns: [passRateColumn, codeLinesColumn],
|
|
@@ -50,9 +59,9 @@ export const tableData: TableData = {
|
|
|
50
59
|
{
|
|
51
60
|
key: "codex",
|
|
52
61
|
cells: {
|
|
53
|
-
"pass-rate": { value: 0.5, display: "50%", samples: 6, total: 6 },
|
|
62
|
+
"pass-rate": { value: 0.5, display: "50%", samples: 6, total: 6, refs: [] },
|
|
54
63
|
// 全 null:一个有效样本都没有 → 缺数据文案,绝不画 0
|
|
55
|
-
"code-lines": { value: null, display: "", samples: 0, total: 6 },
|
|
64
|
+
"code-lines": { value: null, display: "—", samples: 0, total: 6, refs: [] },
|
|
56
65
|
},
|
|
57
66
|
},
|
|
58
67
|
{
|
|
@@ -66,7 +75,7 @@ export const tableData: TableData = {
|
|
|
66
75
|
refs: [{ run: "run-a", result: 0 }],
|
|
67
76
|
},
|
|
68
77
|
// samples < total:有 attempt 测不了 → 覆盖率角标 5/6
|
|
69
|
-
"code-lines": { value: 120, display: "120 lines", samples: 5, total: 6 },
|
|
78
|
+
"code-lines": { value: 120, display: "120 lines", samples: 5, total: 6, refs: [] },
|
|
70
79
|
},
|
|
71
80
|
},
|
|
72
81
|
],
|
|
@@ -81,23 +90,32 @@ export const matrixData: MatrixData = {
|
|
|
81
90
|
{
|
|
82
91
|
row: "algebra/quadratic",
|
|
83
92
|
column: "bub",
|
|
84
|
-
cell: {
|
|
93
|
+
cell: {
|
|
94
|
+
value: 1,
|
|
95
|
+
display: "100%",
|
|
96
|
+
samples: 2,
|
|
97
|
+
total: 2,
|
|
98
|
+
refs: [
|
|
99
|
+
{ run: "run-b", result: 3 },
|
|
100
|
+
{ run: "run-b", result: 7 },
|
|
101
|
+
],
|
|
102
|
+
},
|
|
85
103
|
},
|
|
86
104
|
{
|
|
87
105
|
row: "algebra/quadratic",
|
|
88
106
|
column: "codex",
|
|
89
|
-
cell: { value: 0, display: "0%", samples: 3, total: 3 },
|
|
107
|
+
cell: { value: 0, display: "0%", samples: 3, total: 3, refs: [] },
|
|
90
108
|
},
|
|
91
109
|
{
|
|
92
110
|
row: "geometry/angles",
|
|
93
111
|
column: "bub",
|
|
94
|
-
cell: { value: 0.5, display: "50%", samples: 2, total: 2 },
|
|
112
|
+
cell: { value: 0.5, display: "50%", samples: 2, total: 2, refs: [] },
|
|
95
113
|
},
|
|
96
114
|
],
|
|
97
115
|
};
|
|
98
116
|
|
|
99
117
|
export const scoreboardData: ScoreboardData = {
|
|
100
|
-
|
|
118
|
+
dimension: "agent",
|
|
101
119
|
fullMarks: 100,
|
|
102
120
|
weights: [{ prefix: "algebra/", weight: 2 }],
|
|
103
121
|
rows: [
|
|
@@ -130,32 +148,76 @@ export const scatterData: ScatterData = {
|
|
|
130
148
|
{
|
|
131
149
|
key: "compare/bub-low",
|
|
132
150
|
series: "bub",
|
|
133
|
-
x: { value: 5, display: "$5.00", samples: 6, total: 6 },
|
|
134
|
-
y: { value: 0.5, display: "50%", samples: 6, total: 6 },
|
|
151
|
+
x: { value: 5, display: "$5.00", samples: 6, total: 6, refs: [] },
|
|
152
|
+
y: { value: 0.5, display: "50%", samples: 6, total: 6, refs: [] },
|
|
135
153
|
},
|
|
136
154
|
{
|
|
137
155
|
key: "compare/bub-high",
|
|
138
156
|
series: "bub",
|
|
139
|
-
x: { value: 10, display: "$10.00", samples: 6, total: 6 },
|
|
140
|
-
y: { value: 0.9, display: "90%", samples: 6, total: 6 },
|
|
157
|
+
x: { value: 10, display: "$10.00", samples: 6, total: 6, refs: [] },
|
|
158
|
+
y: { value: 0.9, display: "90%", samples: 6, total: 6, refs: [] },
|
|
141
159
|
},
|
|
142
160
|
{
|
|
143
161
|
key: "compare/codex-mid",
|
|
144
162
|
series: "codex",
|
|
145
|
-
x: { value: 7, display: "$7.00", samples: 6, total: 6 },
|
|
146
|
-
y: { value: 0.6, display: "60%", samples: 6, total: 6 },
|
|
163
|
+
x: { value: 7, display: "$7.00", samples: 6, total: 6, refs: [] },
|
|
164
|
+
y: { value: 0.6, display: "60%", samples: 6, total: 6, refs: [] },
|
|
147
165
|
},
|
|
148
166
|
{
|
|
149
167
|
// x 缺数据:这个点不画,注脚报 1 个点缺数据
|
|
150
168
|
key: "compare/codex-broken",
|
|
151
169
|
series: "codex",
|
|
152
|
-
x: { value: null, display: "", samples: 0, total: 6 },
|
|
153
|
-
y: { value: 0.7, display: "70%", samples: 6, total: 6 },
|
|
170
|
+
x: { value: null, display: "—", samples: 0, total: 6, refs: [] },
|
|
171
|
+
y: { value: 0.7, display: "70%", samples: 6, total: 6, refs: [] },
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export const lineData: LineData = {
|
|
177
|
+
x: { key: "latencyMs", label: "Simulated latency", unit: "ms" },
|
|
178
|
+
series: "agents",
|
|
179
|
+
y: passRateColumn,
|
|
180
|
+
rows: [
|
|
181
|
+
{
|
|
182
|
+
key: "ultra/agents-1-lat-100",
|
|
183
|
+
series: "1 agents",
|
|
184
|
+
x: 100,
|
|
185
|
+
xDisplay: "100ms",
|
|
186
|
+
y: { value: 0.4, display: "40%", samples: 6, total: 6, refs: [] },
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
key: "ultra/agents-1-lat-300",
|
|
190
|
+
series: "1 agents",
|
|
191
|
+
x: 300,
|
|
192
|
+
xDisplay: "300ms",
|
|
193
|
+
y: { value: 0.3, display: "30%", samples: 6, total: 6, refs: [] },
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
key: "ultra/agents-16-lat-100",
|
|
197
|
+
series: "16 agents",
|
|
198
|
+
x: 100,
|
|
199
|
+
xDisplay: "100ms",
|
|
200
|
+
y: { value: 0.8, display: "80%", samples: 6, total: 6, refs: [] },
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
key: "ultra/agents-16-lat-300",
|
|
204
|
+
series: "16 agents",
|
|
205
|
+
x: 300,
|
|
206
|
+
xDisplay: "300ms",
|
|
207
|
+
y: { value: 0.7, display: "70%", samples: 6, total: 6, refs: [] },
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
// 未声明 param 的 experiment:作轴不画点,注脚报数
|
|
211
|
+
key: "ultra/legacy",
|
|
212
|
+
series: "1 agents",
|
|
213
|
+
x: null,
|
|
214
|
+
xDisplay: "",
|
|
215
|
+
y: { value: 0.5, display: "50%", samples: 6, total: 6, refs: [] },
|
|
154
216
|
},
|
|
155
217
|
],
|
|
156
218
|
};
|
|
157
219
|
|
|
158
|
-
export const deltaData: DeltaData = {
|
|
220
|
+
export const deltaData: DeltaData<"pass-rate" | "cost"> = {
|
|
159
221
|
columns: [passRateColumn, costColumn],
|
|
160
222
|
rows: [
|
|
161
223
|
{
|
|
@@ -165,15 +227,15 @@ export const deltaData: DeltaData = {
|
|
|
165
227
|
cells: {
|
|
166
228
|
// 通过率 +12pp:better higher → 好(绿)
|
|
167
229
|
"pass-rate": {
|
|
168
|
-
a: { value: 0.5, display: "50%", samples: 6, total: 6 },
|
|
169
|
-
b: { value: 0.62, display: "62%", samples: 6, total: 6 },
|
|
230
|
+
a: { value: 0.5, display: "50%", samples: 6, total: 6, refs: [] },
|
|
231
|
+
b: { value: 0.62, display: "62%", samples: 6, total: 6, refs: [] },
|
|
170
232
|
delta: 0.12,
|
|
171
233
|
display: "+12pp",
|
|
172
234
|
},
|
|
173
235
|
// 成本 +$0.15:better lower → 坏(红)
|
|
174
236
|
cost: {
|
|
175
|
-
a: { value: 0.2, display: "$0.20", samples: 6, total: 6 },
|
|
176
|
-
b: { value: 0.35, display: "$0.35", samples: 6, total: 6 },
|
|
237
|
+
a: { value: 0.2, display: "$0.20", samples: 6, total: 6, refs: [] },
|
|
238
|
+
b: { value: 0.35, display: "$0.35", samples: 6, total: 6, refs: [] },
|
|
177
239
|
delta: 0.15,
|
|
178
240
|
display: "+$0.15",
|
|
179
241
|
},
|
|
@@ -185,17 +247,17 @@ export const deltaData: DeltaData = {
|
|
|
185
247
|
b: { experimentId: "compare/codex--agents-md" },
|
|
186
248
|
cells: {
|
|
187
249
|
"pass-rate": {
|
|
188
|
-
a: { value: 0.4, display: "40%", samples: 6, total: 6 },
|
|
189
|
-
b: { value: 0.4, display: "40%", samples: 6, total: 6 },
|
|
250
|
+
a: { value: 0.4, display: "40%", samples: 6, total: 6, refs: [] },
|
|
251
|
+
b: { value: 0.4, display: "40%", samples: 6, total: 6, refs: [] },
|
|
190
252
|
delta: 0,
|
|
191
|
-
display: "±
|
|
253
|
+
display: "±0",
|
|
192
254
|
},
|
|
193
255
|
// A 侧缺数据 → delta null:显示缺,不硬算
|
|
194
256
|
cost: {
|
|
195
|
-
a: { value: null, display: "", samples: 0, total: 6 },
|
|
196
|
-
b: { value: 0.3, display: "$0.30", samples: 6, total: 6 },
|
|
257
|
+
a: { value: null, display: "—", samples: 0, total: 6, refs: [] },
|
|
258
|
+
b: { value: 0.3, display: "$0.30", samples: 6, total: 6, refs: [] },
|
|
197
259
|
delta: null,
|
|
198
|
-
display: "",
|
|
260
|
+
display: "—",
|
|
199
261
|
},
|
|
200
262
|
},
|
|
201
263
|
},
|
|
@@ -213,8 +275,8 @@ export const caseListData: CaseListData = {
|
|
|
213
275
|
{
|
|
214
276
|
name: "roots-correct",
|
|
215
277
|
score: 0,
|
|
216
|
-
detail: "
|
|
217
|
-
evidence: "judge:
|
|
278
|
+
detail: "expected x=2, got x=3",
|
|
279
|
+
evidence: "judge: sign flipped when substituting into the quadratic formula",
|
|
218
280
|
},
|
|
219
281
|
],
|
|
220
282
|
durationMs: 32_000,
|
|
@@ -1,34 +1,9 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// 以及 class 名拼接。缺数据的统一文案也钉在这里,保证各组件同词。
|
|
1
|
+
// web 面的小工具:展示格式化统一住在计算侧的 ../format.ts(两个渲染面同一份),
|
|
2
|
+
// 这里 re-export 并补 class 名拼接。MetricCell 一律自带 display,组件不重算。
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
export const MISSING_TEXT = "no data";
|
|
4
|
+
export { MISSING_TEXT, formatDurationMs, formatPercent, formatUSD } from "../format.ts";
|
|
7
5
|
|
|
8
6
|
/** 拼 class 名:过滤空值,末尾接使用者透传的 className。 */
|
|
9
7
|
export function cx(...parts: (string | undefined | false)[]): string {
|
|
10
8
|
return parts.filter(Boolean).join(" ");
|
|
11
9
|
}
|
|
12
|
-
|
|
13
|
-
/** 毫秒 → 人读耗时("850ms" / "1.2s" / "4m 20s" / "1h 4m")。 */
|
|
14
|
-
export function formatDurationMs(ms: number): string {
|
|
15
|
-
if (ms < 1000) return `${Math.round(ms)}ms`;
|
|
16
|
-
const s = ms / 1000;
|
|
17
|
-
if (s < 60) return `${s.toFixed(1)}s`;
|
|
18
|
-
const m = Math.floor(s / 60);
|
|
19
|
-
if (m < 60) return `${m}m ${Math.round(s % 60)}s`;
|
|
20
|
-
const h = Math.floor(m / 60);
|
|
21
|
-
return `${h}h ${m % 60}m`;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** 美元金额;小额保留更多位数,不四舍五入成 $0.00 的假零。 */
|
|
25
|
-
export function formatUSD(usd: number): string {
|
|
26
|
-
if (usd === 0) return "$0";
|
|
27
|
-
const digits = Math.abs(usd) >= 0.01 ? 2 : 4;
|
|
28
|
-
return `$${usd.toFixed(digits)}`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** 0..1 的比率 → 整数百分比。 */
|
|
32
|
-
export function formatPercent(ratio: number): string {
|
|
33
|
-
return `${Math.round(ratio * 100)}%`;
|
|
34
|
-
}
|
|
@@ -1,34 +1,51 @@
|
|
|
1
|
-
// niceeval/report/react ——
|
|
1
|
+
// niceeval/report/react —— 零件复用的导出点:把某一块指标表嵌进已有内部面板时从这里
|
|
2
|
+
// import。导出的组件与 niceeval/report 是同一批双面组件(web 面即 React 渲染,零 IO、
|
|
3
|
+
// 可进 "use client",不 hydrate 也完整),都带自己的 data 计算函数;那是零件的复用,
|
|
4
|
+
// 不是另一套报告系统 —— 报告的家在官方宿主(--report)。
|
|
2
5
|
//
|
|
3
6
|
// 契约:
|
|
4
|
-
// - 组件只认「算好的可序列化数据」:零
|
|
5
|
-
// - 不 hydrate 也完整:renderToStaticMarkup 的产物即成品——排序在数据侧预排,
|
|
6
|
-
// hover 退化为 title,下钻是普通 <a>,展开折叠是 <details>;
|
|
7
|
+
// - 组件只认「算好的可序列化数据」:零 hooks、零数据操作;
|
|
7
8
|
// - 样式随包发布:配套 ./styles.css(nre-* 稳定类名),使用者在其后加载覆盖即可;
|
|
8
9
|
// - 跨块配色一致:维度键 → 稳定散列 → 固定调色板下标(colors.ts)。
|
|
9
|
-
//
|
|
10
|
-
// 数据从哪来:niceeval/report 的计算函数(table()/matrix()/scoreboard()/scatter()/
|
|
11
|
-
// overview()/delta()/cases())。计算层在并行实验中实现;类型暂由 ./data.ts 声明,
|
|
12
|
-
// 合并时切换为从计算层 re-export。
|
|
13
10
|
|
|
14
|
-
export {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
export {
|
|
12
|
+
CaseList,
|
|
13
|
+
DeltaTable,
|
|
14
|
+
MetricBars,
|
|
15
|
+
MetricLine,
|
|
16
|
+
MetricMatrix,
|
|
17
|
+
MetricScatter,
|
|
18
|
+
MetricTable,
|
|
19
|
+
RunOverview,
|
|
20
|
+
Scoreboard,
|
|
21
|
+
} from "../components.tsx";
|
|
22
|
+
export type {
|
|
23
|
+
CaseListProps,
|
|
24
|
+
DeltaTableProps,
|
|
25
|
+
MetricLineProps,
|
|
26
|
+
MetricMatrixProps,
|
|
27
|
+
MetricScatterProps,
|
|
28
|
+
MetricTableProps,
|
|
29
|
+
RunOverviewProps,
|
|
30
|
+
ScoreboardProps,
|
|
31
|
+
} from "../components.tsx";
|
|
21
32
|
|
|
22
|
-
// 数据契约类型(
|
|
33
|
+
// 数据契约类型(家在 ../types.ts,「算」与「画」两侧共用同一份)
|
|
23
34
|
export type {
|
|
24
35
|
AttemptRef,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
36
|
+
CaseListData,
|
|
37
|
+
DeltaData,
|
|
38
|
+
LineAxis,
|
|
39
|
+
LineData,
|
|
28
40
|
MatrixData,
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
MetricCell,
|
|
42
|
+
MetricColumn,
|
|
31
43
|
OverviewData,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
ScatterData,
|
|
45
|
+
ScoreboardData,
|
|
46
|
+
SelectionWarning,
|
|
47
|
+
TableData,
|
|
48
|
+
} from "../types.ts";
|
|
49
|
+
|
|
50
|
+
// 稳定配色(自定义组件想与官方组件同键同色时用)
|
|
51
|
+
export { NRE_PALETTE, colorClassForKey, colorHexForKey, colorIndexForKey } from "./colors.ts";
|
|
@@ -54,7 +54,7 @@ describe("RunOverview", () => {
|
|
|
54
54
|
expect(html).toContain("2 snapshots");
|
|
55
55
|
expect(html).toContain("compare/bub");
|
|
56
56
|
expect(html).toContain("2026-07-01T10:00:00Z");
|
|
57
|
-
expect(html).toContain("
|
|
57
|
+
expect(html).toContain("snapshot covers 9 of 12 evals seen in history");
|
|
58
58
|
expect(html).toContain("nre-warnings");
|
|
59
59
|
});
|
|
60
60
|
});
|
|
@@ -69,9 +69,9 @@ describe("MetricTable", () => {
|
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
it("列头带 label、unit 与 better 方向", () => {
|
|
72
|
-
expect(html).toContain("
|
|
72
|
+
expect(html).toContain("pass rate");
|
|
73
73
|
expect(html).toContain("(%)");
|
|
74
|
-
expect(html).toContain("
|
|
74
|
+
expect(html).toContain("code lines");
|
|
75
75
|
expect(html).toContain("↑");
|
|
76
76
|
expect(html).toContain("↓");
|
|
77
77
|
});
|
|
@@ -96,7 +96,7 @@ describe("MetricMatrix", () => {
|
|
|
96
96
|
const html = renderToStaticMarkup(<MetricMatrix data={matrixData} attemptHref={attemptHref} />);
|
|
97
97
|
|
|
98
98
|
it("caption 标出指标与行列维度", () => {
|
|
99
|
-
expect(html).toContain("
|
|
99
|
+
expect(html).toContain("pass rate");
|
|
100
100
|
expect(html).toContain("eval × agent");
|
|
101
101
|
});
|
|
102
102
|
|
|
@@ -158,8 +158,8 @@ describe("MetricScatter", () => {
|
|
|
158
158
|
|
|
159
159
|
it("内联 SVG + 轴标签", () => {
|
|
160
160
|
expect(html).toContain("<svg");
|
|
161
|
-
expect(html).toContain("
|
|
162
|
-
expect(html).toContain("
|
|
161
|
+
expect(html).toContain("cost($)");
|
|
162
|
+
expect(html).toContain("pass rate(%)");
|
|
163
163
|
});
|
|
164
164
|
|
|
165
165
|
it("better:lower 的 x 轴反向:便宜($5)在贵($10)右边,好的角落恒在右上", () => {
|
|
@@ -239,8 +239,8 @@ describe("CaseList", () => {
|
|
|
239
239
|
it("逐条失败断言:name、score、detail、evidence", () => {
|
|
240
240
|
expect(html).toContain("roots-correct");
|
|
241
241
|
expect(html).toContain("score 0");
|
|
242
|
-
expect(html).toContain("
|
|
243
|
-
expect(html).toContain("judge:
|
|
242
|
+
expect(html).toContain("expected x=2, got x=3");
|
|
243
|
+
expect(html).toContain("judge: sign flipped when substituting into the quadratic formula");
|
|
244
244
|
});
|
|
245
245
|
|
|
246
246
|
it("errored 的 error 摘要", () => {
|
|
@@ -300,3 +300,80 @@ table.nre,
|
|
|
300
300
|
.nre-case-list .nre-case-empty {
|
|
301
301
|
color: #737373;
|
|
302
302
|
}
|
|
303
|
+
|
|
304
|
+
/* ---- MetricBars ---- */
|
|
305
|
+
.nre-metric-bars {
|
|
306
|
+
margin: 1rem 0;
|
|
307
|
+
}
|
|
308
|
+
.nre-metric-bars .nre-bars-svg {
|
|
309
|
+
max-width: 640px;
|
|
310
|
+
width: 100%;
|
|
311
|
+
height: auto;
|
|
312
|
+
display: block;
|
|
313
|
+
}
|
|
314
|
+
.nre-metric-bars .nre-bars-legend {
|
|
315
|
+
color: #737373;
|
|
316
|
+
font-size: 0.85em;
|
|
317
|
+
margin-top: 0.25rem;
|
|
318
|
+
}
|
|
319
|
+
.nre-metric-bars .nre-bars-metric {
|
|
320
|
+
margin-right: 1em;
|
|
321
|
+
font-weight: 600;
|
|
322
|
+
color: #171717;
|
|
323
|
+
}
|
|
324
|
+
.nre-metric-bars .nre-legend-key {
|
|
325
|
+
margin-right: 0.75em;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/* ---- MetricLine ---- */
|
|
329
|
+
.nre-metric-line {
|
|
330
|
+
margin: 1rem 0;
|
|
331
|
+
}
|
|
332
|
+
.nre-metric-line .nre-line-svg {
|
|
333
|
+
max-width: 640px;
|
|
334
|
+
width: 100%;
|
|
335
|
+
height: auto;
|
|
336
|
+
display: block;
|
|
337
|
+
}
|
|
338
|
+
.nre-metric-line .nre-line-missing {
|
|
339
|
+
color: #b45309;
|
|
340
|
+
font-size: 0.85em;
|
|
341
|
+
margin: 0.25rem 0 0;
|
|
342
|
+
}
|
|
343
|
+
.nre-metric-line .nre-line-point-link circle:hover {
|
|
344
|
+
stroke: #171717;
|
|
345
|
+
stroke-width: 1.5;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/* ---- 排版原语 Row / Col / Section / Text ---- */
|
|
349
|
+
.nre-col {
|
|
350
|
+
display: flex;
|
|
351
|
+
flex-direction: column;
|
|
352
|
+
gap: 1rem;
|
|
353
|
+
}
|
|
354
|
+
.nre-row {
|
|
355
|
+
display: flex;
|
|
356
|
+
flex-wrap: wrap;
|
|
357
|
+
gap: 1.5rem;
|
|
358
|
+
align-items: flex-start;
|
|
359
|
+
}
|
|
360
|
+
.nre-row > * {
|
|
361
|
+
flex: 1 1 20rem;
|
|
362
|
+
min-width: 0;
|
|
363
|
+
}
|
|
364
|
+
.nre-section .nre-section-title {
|
|
365
|
+
font-size: 1.1em;
|
|
366
|
+
font-weight: 700;
|
|
367
|
+
margin: 0 0 0.5rem;
|
|
368
|
+
}
|
|
369
|
+
.nre-text {
|
|
370
|
+
color: #525252;
|
|
371
|
+
margin: 0.25rem 0;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* ---- DefaultReport(官方水位整块)---- */
|
|
375
|
+
.nre-default-report {
|
|
376
|
+
display: flex;
|
|
377
|
+
flex-direction: column;
|
|
378
|
+
gap: 1rem;
|
|
379
|
+
}
|