niceeval 0.8.0 → 0.9.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 +77 -45
- package/dist/agents/types.d.ts +28 -6
- package/dist/i18n/en.d.ts +2 -0
- package/dist/i18n/zh-CN.d.ts +2 -0
- package/dist/report/built-in/index.d.ts +3 -2
- package/dist/report/built-in/index.js +7 -8
- package/dist/report/built-in/standard.d.ts +1 -0
- package/dist/report/built-in/standard.js +30 -0
- package/dist/report/components.d.ts +72 -6
- package/dist/report/components.js +159 -10
- package/dist/report/compute.d.ts +31 -4
- package/dist/report/compute.js +131 -12
- package/dist/report/index.d.ts +4 -4
- package/dist/report/index.js +3 -2
- package/dist/report/locale.d.ts +39 -1
- package/dist/report/locale.js +69 -0
- package/dist/report/react/AttemptList.d.ts +3 -1
- package/dist/report/react/AttemptList.js +3 -3
- package/dist/report/react/CopyFixPrompt.d.ts +12 -0
- package/dist/report/react/CopyFixPrompt.js +12 -0
- package/dist/report/react/HeroCard.d.ts +13 -0
- package/dist/report/react/HeroCard.js +35 -0
- package/dist/report/react/PoweredBy.d.ts +5 -0
- package/dist/report/react/PoweredBy.js +7 -0
- package/dist/report/react/ScopeWarnings.d.ts +12 -0
- package/dist/report/react/ScopeWarnings.js +18 -0
- package/dist/report/react/TraceWaterfall.d.ts +14 -0
- package/dist/report/react/TraceWaterfall.js +22 -0
- package/dist/report/react/index.d.ts +6 -1
- package/dist/report/react/index.js +6 -0
- package/dist/report/report.d.ts +22 -6
- package/dist/report/report.js +66 -53
- package/dist/report/scope-warnings.d.ts +28 -0
- package/dist/report/scope-warnings.js +101 -0
- package/dist/report/text/faces.d.ts +19 -1
- package/dist/report/text/faces.js +61 -0
- package/dist/report/tree.js +6 -1
- package/dist/report/types.d.ts +45 -10
- package/dist/report/web.d.ts +5 -4
- package/dist/report/web.js +7 -22
- package/dist/results/select.d.ts +15 -2
- package/dist/results/select.js +75 -10
- package/dist/results/types.d.ts +26 -11
- package/dist/runner/fingerprint.d.ts +3 -3
- package/dist/runner/sandbox-selection.d.ts +12 -0
- package/dist/runner/types.d.ts +18 -6
- package/dist/sandbox/types.d.ts +12 -0
- package/docs-site/zh/explanation/evals.mdx +2 -1
- package/docs-site/zh/explanation/experiment.mdx +2 -0
- package/docs-site/zh/how-to/custom-reports.mdx +22 -6
- package/docs-site/zh/how-to/publish-report.mdx +6 -8
- package/docs-site/zh/how-to/viewing-results.mdx +3 -3
- package/docs-site/zh/how-to/write-experiment.mdx +40 -1
- package/docs-site/zh/reference/builtin-agents.mdx +40 -3
- package/docs-site/zh/reference/cli.mdx +1 -2
- package/docs-site/zh/reference/define-eval.mdx +8 -0
- package/docs-site/zh/reference/official-adapters.mdx +10 -5
- package/docs-site/zh/reference/report-components.mdx +2 -2
- package/docs-site/zh/reference/results-data.mdx +2 -4
- package/package.json +2 -1
- package/src/agents/bub.ts +13 -1
- package/src/agents/claude-code.test.ts +43 -1
- package/src/agents/claude-code.ts +32 -14
- package/src/agents/codex.test.ts +168 -1
- package/src/agents/codex.ts +51 -15
- package/src/agents/mcp.ts +31 -0
- package/src/agents/post-setup.ts +33 -0
- package/src/agents/types.ts +28 -7
- package/src/cli.ts +9 -11
- package/src/context/context.ts +11 -5
- package/src/define.ts +3 -0
- package/src/i18n/en.ts +5 -2
- package/src/i18n/zh-CN.ts +5 -1
- package/src/index.ts +1 -0
- package/src/report/built-in/index.tsx +8 -7
- package/src/report/built-in/standard.tsx +59 -0
- package/src/report/components.tsx +231 -17
- package/src/report/compute.ts +146 -21
- package/src/report/dual-render.test.tsx +139 -12
- package/src/report/index.ts +20 -1
- package/src/report/locale.ts +83 -1
- package/src/report/react/AttemptList.tsx +13 -1
- package/src/report/react/CopyFixPrompt.tsx +37 -0
- package/src/report/react/HeroCard.tsx +59 -0
- package/src/report/react/PoweredBy.tsx +20 -0
- package/src/report/react/ScopeWarnings.tsx +74 -0
- package/src/report/react/TraceWaterfall.tsx +78 -0
- package/src/report/react/enhance.js +14 -0
- package/src/report/react/index.tsx +11 -0
- package/src/report/react/styles.css +187 -7
- package/src/report/report.test.ts +2 -20
- package/src/report/report.ts +97 -62
- package/src/report/scope-warnings.ts +155 -0
- package/src/report/site-components.test.tsx +526 -0
- package/src/report/text/faces.ts +66 -0
- package/src/report/tree.ts +8 -1
- package/src/report/types.ts +51 -11
- package/src/report/web.ts +7 -40
- package/src/results/copy.ts +15 -78
- package/src/results/host-equivalence.test.ts +5 -1
- package/src/results/open.ts +5 -4
- package/src/results/publish.ts +4 -146
- package/src/results/results.test.ts +86 -9
- package/src/results/select.ts +78 -10
- package/src/results/types.ts +27 -7
- package/src/runner/attempt.ts +10 -9
- package/src/runner/discover.test.ts +9 -1
- package/src/runner/discover.ts +3 -3
- package/src/runner/fingerprint.ts +9 -4
- package/src/runner/ledger.test.ts +30 -1
- package/src/runner/ledger.ts +26 -4
- package/src/runner/run.ts +5 -1
- package/src/runner/sandbox-selection.test.ts +131 -0
- package/src/runner/sandbox-selection.ts +110 -0
- package/src/runner/types.ts +19 -2
- package/src/sandbox/types.ts +6 -0
- package/src/show/index.ts +17 -10
- package/src/show/render.ts +11 -11
- package/src/show/report-host.test.ts +32 -15
- package/src/show/report-host.ts +5 -4
- package/src/show/show.test.ts +140 -3
- package/src/view/app/App.test.tsx +78 -17
- package/src/view/app/App.tsx +17 -78
- package/src/view/app/components/CopyControls.tsx +4 -42
- package/src/view/app/i18n.ts +5 -227
- package/src/view/app/lib/rows.ts +3 -21
- package/src/view/app/shared.ts +1 -3
- package/src/view/app/types.ts +2 -2
- package/src/view/artifact-serving.test.ts +1 -1
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +20 -20
- package/src/view/data.ts +2 -13
- package/src/view/index.ts +1 -12
- package/src/view/server.ts +0 -2
- package/src/view/shared/types.ts +11 -6
- package/src/view/site-parity.test.ts +1 -1
- package/src/view/site.ts +1 -1
- package/src/view/styles.css +6 -266
- package/src/view/view-report.test.ts +64 -27
- package/src/view/app/components/LazyArtifact.tsx +0 -51
- package/src/view/app/components/SkippedRunsBanner.tsx +0 -140
- package/src/view/app/pages/AttemptsPage.tsx +0 -80
- package/src/view/app/pages/TracesPage.tsx +0 -35
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { defineComponent, isHostWebContextActive, memoFetchOf, } from "./tree.js";
|
|
3
|
-
import { attemptListData, deltaTableData, evalListData, experimentComparisonData, experimentListData, metricLineData, metricMatrixData, metricScatterData, metricTableData, scopeSummaryData, scoreboardData, } from "./compute.js";
|
|
3
|
+
import { attemptListData, copyFixPromptData, deltaTableData, evalListData, experimentComparisonData, experimentListData, heroData, metricLineData, metricMatrixData, metricScatterData, metricTableData, scopeSummaryData, scopeWarningsData, scoreboardData, traceWaterfallData, } from "./compute.js";
|
|
4
4
|
import { collectItems, locatorOf, resolveInput } from "./aggregate.js";
|
|
5
|
-
import { attemptListText, deltaText, evalListText, experimentComparisonText, experimentListText, barsText, lineText, matrixText, scatterText, scoreboardText, scopeSummaryText, tableText, } from "./text/faces.js";
|
|
5
|
+
import { attemptListText, deltaText, evalListText, experimentComparisonText, experimentListText, barsText, heroCardText, lineText, matrixText, scatterText, scopeWarningsText, scoreboardText, scopeSummaryText, tableText, traceWaterfallText, } from "./text/faces.js";
|
|
6
6
|
import { ScopeSummary as ScopeSummaryWeb } from "./react/ScopeSummary.js";
|
|
7
7
|
import { ExperimentComparisonView } from "./react/ExperimentComparison.js";
|
|
8
8
|
import { ExperimentList as ExperimentListWeb } from "./react/ExperimentList.js";
|
|
9
9
|
import { EvalList as EvalListWeb } from "./react/EvalList.js";
|
|
10
10
|
import { AttemptList as AttemptListWeb } from "./react/AttemptList.js";
|
|
11
|
+
import { HeroCard as HeroCardWeb } from "./react/HeroCard.js";
|
|
12
|
+
import { PoweredBy as PoweredByWeb } from "./react/PoweredBy.js";
|
|
13
|
+
import { ScopeWarnings as ScopeWarningsWeb } from "./react/ScopeWarnings.js";
|
|
14
|
+
import { CopyFixPrompt as CopyFixPromptWeb } from "./react/CopyFixPrompt.js";
|
|
15
|
+
import { TraceWaterfall as TraceWaterfallWeb } from "./react/TraceWaterfall.js";
|
|
11
16
|
import { MetricTable as MetricTableWeb } from "./react/MetricTable.js";
|
|
12
17
|
import { MetricMatrix as MetricMatrixWeb } from "./react/MetricMatrix.js";
|
|
13
18
|
import { MetricBars as MetricBarsWeb } from "./react/MetricBars.js";
|
|
@@ -183,6 +188,56 @@ const validateAttemptListData = (data) => {
|
|
|
183
188
|
}
|
|
184
189
|
return null;
|
|
185
190
|
};
|
|
191
|
+
const validateHeroData = (data) => {
|
|
192
|
+
if (!isObject(data))
|
|
193
|
+
return "expected an object";
|
|
194
|
+
if (!("latestStartedAt" in data) || (data.latestStartedAt !== null && typeof data.latestStartedAt !== "string")) {
|
|
195
|
+
return 'missing "latestStartedAt" (string | null)';
|
|
196
|
+
}
|
|
197
|
+
if (typeof data.snapshots !== "number")
|
|
198
|
+
return 'missing "snapshots" (number)';
|
|
199
|
+
return null;
|
|
200
|
+
};
|
|
201
|
+
const validateScopeWarningsData = (data) => {
|
|
202
|
+
if (!Array.isArray(data))
|
|
203
|
+
return "expected an array of ScopeWarning";
|
|
204
|
+
for (const item of data) {
|
|
205
|
+
if (!isObject(item) || typeof item.kind !== "string" || typeof item.message !== "string") {
|
|
206
|
+
return "each warning needs { kind, message, … }";
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return null;
|
|
210
|
+
};
|
|
211
|
+
const validateCopyFixPromptData = (data) => {
|
|
212
|
+
if (!isObject(data))
|
|
213
|
+
return "expected an object";
|
|
214
|
+
if (typeof data.prompt !== "string")
|
|
215
|
+
return 'missing "prompt" (string)';
|
|
216
|
+
if (typeof data.failures !== "number")
|
|
217
|
+
return 'missing "failures" (number)';
|
|
218
|
+
return null;
|
|
219
|
+
};
|
|
220
|
+
const validateTraceWaterfallData = (data) => {
|
|
221
|
+
if (!Array.isArray(data))
|
|
222
|
+
return "expected an array of TraceWaterfallRow";
|
|
223
|
+
for (const row of data) {
|
|
224
|
+
if (!isObject(row) ||
|
|
225
|
+
typeof row.experimentId !== "string" ||
|
|
226
|
+
typeof row.evalId !== "string" ||
|
|
227
|
+
typeof row.locator !== "string" ||
|
|
228
|
+
!("durationMs" in row) ||
|
|
229
|
+
(row.durationMs !== null && typeof row.durationMs !== "number") ||
|
|
230
|
+
!Array.isArray(row.spans)) {
|
|
231
|
+
return "each row needs { experimentId, evalId, locator, durationMs: number | null, spans }";
|
|
232
|
+
}
|
|
233
|
+
for (const span of row.spans) {
|
|
234
|
+
if (!isObject(span) || typeof span.name !== "string" || typeof span.startOffsetMs !== "number") {
|
|
235
|
+
return "each span needs { name, kind, startOffsetMs, durationMs, failed }";
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
};
|
|
186
241
|
function makeDataComponent(def) {
|
|
187
242
|
const assertData = (data) => {
|
|
188
243
|
const problem = def.validate(data);
|
|
@@ -261,8 +316,8 @@ export const ExperimentList = makeDataComponent({
|
|
|
261
316
|
name: "ExperimentList",
|
|
262
317
|
dataFnName: "experimentListData",
|
|
263
318
|
shapeName: "ExperimentListItem[]",
|
|
264
|
-
dataFn: (input
|
|
265
|
-
specKeys: [
|
|
319
|
+
dataFn: (input) => experimentListData(input),
|
|
320
|
+
specKeys: [],
|
|
266
321
|
validate: validateExperimentListData,
|
|
267
322
|
web: (props, ctx) => (_jsx(ExperimentListWeb, { data: props.data, filter: props.filter, relativeTo: props.relativeTo, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx) ?? ctx.attemptHref, className: props.className })),
|
|
268
323
|
text: (props, ctx) => experimentListText(props.data, ctx, props.relativeTo),
|
|
@@ -272,8 +327,8 @@ export const EvalList = makeDataComponent({
|
|
|
272
327
|
name: "EvalList",
|
|
273
328
|
dataFnName: "evalListData",
|
|
274
329
|
shapeName: "EvalListItem[]",
|
|
275
|
-
dataFn: (input
|
|
276
|
-
specKeys: [
|
|
330
|
+
dataFn: (input) => evalListData(input),
|
|
331
|
+
specKeys: [],
|
|
277
332
|
validate: validateEvalListData,
|
|
278
333
|
web: (props, ctx) => (_jsx(EvalListWeb, { data: props.data, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx) ?? ctx.attemptHref, className: props.className })),
|
|
279
334
|
text: (props, ctx) => evalListText(props.data, ctx),
|
|
@@ -283,10 +338,10 @@ export const AttemptList = makeDataComponent({
|
|
|
283
338
|
name: "AttemptList",
|
|
284
339
|
dataFnName: "attemptListData",
|
|
285
340
|
shapeName: "AttemptListItem[]",
|
|
286
|
-
dataFn: (input
|
|
287
|
-
specKeys: [
|
|
341
|
+
dataFn: (input) => attemptListData(input),
|
|
342
|
+
specKeys: [],
|
|
288
343
|
validate: validateAttemptListData,
|
|
289
|
-
web: (props, ctx) => (_jsx(AttemptListWeb, { data: props.data, total: props.total, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx) ?? ctx.attemptHref, className: props.className })),
|
|
344
|
+
web: (props, ctx) => (_jsx(AttemptListWeb, { data: props.data, total: props.total, filter: props.filter, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx) ?? ctx.attemptHref, className: props.className })),
|
|
290
345
|
text: (props, ctx) => attemptListText(props.data, props.total, ctx),
|
|
291
346
|
});
|
|
292
347
|
/**
|
|
@@ -297,7 +352,7 @@ export const AttemptList = makeDataComponent({
|
|
|
297
352
|
*/
|
|
298
353
|
export const FailureList = defineComponent(async (props, ctx) => {
|
|
299
354
|
const input = props.input ?? ctx.scope;
|
|
300
|
-
const all = await attemptListData(input
|
|
355
|
+
const all = await attemptListData(input);
|
|
301
356
|
// attempt 开始时间不在列表条目里(它不是列表展示字段);从同一 input 的读取面按 locator 对回。
|
|
302
357
|
const startedAtByLocator = new Map();
|
|
303
358
|
for (const item of collectItems(resolveInput(input).snapshots)) {
|
|
@@ -316,6 +371,100 @@ export const FailureList = defineComponent(async (props, ctx) => {
|
|
|
316
371
|
return (_jsx(AttemptList, { data: failures.slice(0, limit), total: failures.length, attemptHref: props.attemptHref, locale: props.locale, className: props.className }));
|
|
317
372
|
});
|
|
318
373
|
FailureList.displayName = "FailureList";
|
|
374
|
+
/** HeroCard 的 data 校验入口(它不经 makeDataComponent,数据形态是唯一形态)。 */
|
|
375
|
+
const assertHeroData = (data) => {
|
|
376
|
+
const problem = validateHeroData(data);
|
|
377
|
+
if (problem !== null)
|
|
378
|
+
throw dataShapeError("HeroCard", "heroData", "HeroData", problem);
|
|
379
|
+
return data;
|
|
380
|
+
};
|
|
381
|
+
/**
|
|
382
|
+
* `HeroCard`:Hero 的渲染件,双面组件,只收 data 形态——标题输入是站点声明与 Scope 的
|
|
383
|
+
* 合成物,没有单独的 spec 等价形。web 面渲染 hero 标题(h1)、按渲染 locale 格式化的运行
|
|
384
|
+
* meta(latestStartedAt 为 null 时内置「暂无运行」文案)与品牌行(等同 PoweredBy,恒含、
|
|
385
|
+
* 无拆除 prop);text 面输出标题行与 meta 行,不含品牌行
|
|
386
|
+
* (docs/feature/reports/library/site-components.md「HeroCard」)。
|
|
387
|
+
*/
|
|
388
|
+
export const HeroCard = defineComponent({
|
|
389
|
+
web: (props, ctx) => {
|
|
390
|
+
assertHeroData(props.data);
|
|
391
|
+
return _jsx(HeroCardWeb, { title: props.title, data: props.data, className: props.className, locale: ctx.locale });
|
|
392
|
+
},
|
|
393
|
+
text: (props, ctx) => {
|
|
394
|
+
assertHeroData(props.data);
|
|
395
|
+
return heroCardText(props.title, props.data, ctx);
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
HeroCard.displayName = "HeroCard";
|
|
399
|
+
/**
|
|
400
|
+
* `Hero`:页首的站点标题区——标题、最后运行时间、快照合成来源,恒含品牌行。官方组合组件,
|
|
401
|
+
* 与手写 `<HeroCard title={title ?? ctx.report.title} data={await heroData(ctx.scope)} />`
|
|
402
|
+
* 严格等价、没有私有能力;读 `ctx.report` 意味着输出跟随站点,要站点无关的标题区直接用
|
|
403
|
+
* `HeroCard` 显式传值(docs/feature/reports/library/site-components.md「Hero」)。
|
|
404
|
+
*/
|
|
405
|
+
export const Hero = defineComponent(async ({ title, className }, ctx) => (_jsx(HeroCard, { title: title ?? ctx.report.title, data: await heroData(ctx.scope), className: className })));
|
|
406
|
+
Hero.displayName = "Hero";
|
|
407
|
+
/**
|
|
408
|
+
* `PoweredBy`:唯一的品牌件,无 props 双面组件。web 面渲染指向 niceeval 官网的一行品牌色
|
|
409
|
+
* 小字(`utm_source=report&utm_medium=powered-by`,`rel` 仅 `noopener` 以保留 Referer);
|
|
410
|
+
* text 面零输出。没有任何配置——品牌契约是「提供一个组件,不给开关」:不想要品牌就不用
|
|
411
|
+
* 这些组件、自己写替代组件(docs/feature/reports/library/site-components.md「PoweredBy」)。
|
|
412
|
+
*/
|
|
413
|
+
export const PoweredBy = defineComponent({
|
|
414
|
+
web: () => _jsx(PoweredByWeb, {}),
|
|
415
|
+
text: () => "",
|
|
416
|
+
});
|
|
417
|
+
PoweredBy.displayName = "PoweredBy";
|
|
418
|
+
/**
|
|
419
|
+
* `ScopeWarnings`:选择警告区,警告的唯一呈现组件。把 Scope 携带的 `ScopeWarning[]`
|
|
420
|
+
* 按「下一步动作」聚合渲染(带 experimentId 的按实验聚合、非实验作用域按 kind 聚合;
|
|
421
|
+
* integrity 组在前);web 面组头带去重后的可复制命令、明细收原生 `<details>`(总条数 ≤ 3
|
|
422
|
+
* 默认展开),text 面同构但不折叠。空警告集与裸 `Snapshot[]` 输入两面零输出
|
|
423
|
+
* (docs/feature/reports/library/site-components.md「ScopeWarnings」)。
|
|
424
|
+
*/
|
|
425
|
+
export const ScopeWarnings = makeDataComponent({
|
|
426
|
+
name: "ScopeWarnings",
|
|
427
|
+
dataFnName: "scopeWarningsData",
|
|
428
|
+
shapeName: "ScopeWarning[]",
|
|
429
|
+
dataFn: (input) => scopeWarningsData(input),
|
|
430
|
+
specKeys: [],
|
|
431
|
+
validate: validateScopeWarningsData,
|
|
432
|
+
web: (props, ctx) => props.data.length === 0 ? null : (_jsx(ScopeWarningsWeb, { data: props.data, locale: props.locale ?? ctx.locale, className: props.className })),
|
|
433
|
+
text: (props, ctx) => scopeWarningsText(props.data, ctx),
|
|
434
|
+
});
|
|
435
|
+
/**
|
|
436
|
+
* `CopyFixPrompt`:把当前范围的全部失败整理成一段可交给 coding agent 的修复 prompt。
|
|
437
|
+
* prompt 在 resolve 阶段算好、烘进静态 HTML,无 JS 时在折叠块里完整可读,「复制」是增强层
|
|
438
|
+
* 行为;`failures` 为 0 时两面零输出;text 面恒零输出——终端里的等价能力是 `show` 的
|
|
439
|
+
* attempt 下钻命令本身(docs/feature/reports/library/site-components.md「CopyFixPrompt」)。
|
|
440
|
+
*/
|
|
441
|
+
export const CopyFixPrompt = makeDataComponent({
|
|
442
|
+
name: "CopyFixPrompt",
|
|
443
|
+
dataFnName: "copyFixPromptData",
|
|
444
|
+
shapeName: "CopyFixPromptData",
|
|
445
|
+
dataFn: (input) => copyFixPromptData(input),
|
|
446
|
+
specKeys: [],
|
|
447
|
+
validate: validateCopyFixPromptData,
|
|
448
|
+
web: (props, ctx) => props.data.failures === 0 ? null : (_jsx(CopyFixPromptWeb, { data: props.data, locale: props.locale ?? ctx.locale, className: props.className })),
|
|
449
|
+
text: () => "",
|
|
450
|
+
});
|
|
451
|
+
/**
|
|
452
|
+
* `TraceWaterfall`:每个 attempt 一行的执行时间瀑布,用 canonical OTel 字段显示被测 agent
|
|
453
|
+
* 的原始 span(agent / model / tool)。web 面静态渲染顶层 span 分解条(失败 span 带失败
|
|
454
|
+
* 标记),行链接 attempt 详情;text 面每 attempt 一行(locator、总耗时、span 计数与失败
|
|
455
|
+
* 标记)+ 可复制的 `--timing` 下钻命令。trace 缺失的行照常出现并如实显示缺失;runner
|
|
456
|
+
* 生命周期节点不进瀑布(docs/feature/reports/library/site-components.md「TraceWaterfall」)。
|
|
457
|
+
*/
|
|
458
|
+
export const TraceWaterfall = makeDataComponent({
|
|
459
|
+
name: "TraceWaterfall",
|
|
460
|
+
dataFnName: "traceWaterfallData",
|
|
461
|
+
shapeName: "TraceWaterfallRow[]",
|
|
462
|
+
dataFn: (input) => traceWaterfallData(input),
|
|
463
|
+
specKeys: [],
|
|
464
|
+
validate: validateTraceWaterfallData,
|
|
465
|
+
web: (props, ctx) => (_jsx(TraceWaterfallWeb, { data: props.data, attemptHref: hrefOf(props, ctx) ?? ctx.attemptHref, locale: props.locale ?? ctx.locale, className: props.className })),
|
|
466
|
+
text: (props, ctx) => traceWaterfallText(props.data, ctx),
|
|
467
|
+
});
|
|
319
468
|
/** 榜单:一行一个维度值、一列一个指标,回答「谁整体更好」。 */
|
|
320
469
|
export const MetricTable = makeDataComponent({
|
|
321
470
|
name: "MetricTable",
|
package/dist/report/compute.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AttemptListItem, DeltaData, DeltaPair, DimensionInput,
|
|
1
|
+
import type { AttemptListItem, CopyFixPromptData, DeltaData, DeltaPair, DimensionInput, EvalListItem, ExperimentComparisonData, ExperimentListItem, FlagPairs, HeroData, LineData, MatrixData, Metric, NumericAxis, ReportInput, ScatterData, ScopeSummaryData, ScopeWarning, ScoreboardData, TableData, TraceWaterfallRow } from "./types.ts";
|
|
2
2
|
import type { JsonValue } from "../types.ts";
|
|
3
3
|
export interface MetricTableOptions {
|
|
4
4
|
/** 行维度(内置 / 自定义 / flag() / runConfig())。 */
|
|
@@ -23,9 +23,9 @@ export interface MetricMatrixOptions {
|
|
|
23
23
|
}
|
|
24
24
|
export declare function metricMatrixData(input: ReportInput, options: MetricMatrixOptions): Promise<MatrixData>;
|
|
25
25
|
/** `attemptListData(input)`:每个 Attempt 一项,顺序取自 Scope 展平顺序(不重排)。 */
|
|
26
|
-
export declare function attemptListData(input: ReportInput
|
|
26
|
+
export declare function attemptListData(input: ReportInput): Promise<AttemptListItem[]>;
|
|
27
27
|
/** `evalListData(input)`:每个 `experimentId + evalId` 一项,按 evalId 再按 experimentId 升序。 */
|
|
28
|
-
export declare function evalListData(input: ReportInput
|
|
28
|
+
export declare function evalListData(input: ReportInput): Promise<EvalListItem[]>;
|
|
29
29
|
/**
|
|
30
30
|
* `experimentListData(input)`:每个 experiment 一项,展开到每道 Eval;初始按端到端成功率
|
|
31
31
|
* 从高到低(缺数据沉底,同分按 id)。一行只有一套 agent / model / flags 是输入约束:
|
|
@@ -33,7 +33,7 @@ export declare function evalListData(input: ReportInput, options?: EntityListDat
|
|
|
33
33
|
* Snapshot[] 时若同一 experiment 混入不一致的可比性配置,按完整用户反馈失败并指引——
|
|
34
34
|
* 看跨配置演化用 snapshot 维度或 MetricLine,不把两套配置拼成一行冒充单一配置。
|
|
35
35
|
*/
|
|
36
|
-
export declare function experimentListData(input: ReportInput
|
|
36
|
+
export declare function experimentListData(input: ReportInput): Promise<ExperimentListItem[]>;
|
|
37
37
|
/**
|
|
38
38
|
* `scopeSummaryData(input)`:范围摘要——快照时间窗、experiment / eval / attempt 数、
|
|
39
39
|
* 两级判定计票、端到端成功率与总成本(docs/feature/reports/library/summaries.md)。
|
|
@@ -110,3 +110,30 @@ export interface DeltaTableOptions {
|
|
|
110
110
|
evals?: string | readonly string[];
|
|
111
111
|
}
|
|
112
112
|
export declare function deltaTableData(input: ReportInput, options: DeltaTableOptions): Promise<DeltaData>;
|
|
113
|
+
/**
|
|
114
|
+
* `heroData(input)`:站点标题区的运行 meta——`latestStartedAt` 取范围内最新快照的开始时间
|
|
115
|
+
* (空范围为 null,不编造当前时间),`snapshots` 计贡献当前水位的快照数
|
|
116
|
+
* (docs/feature/reports/library/site-components.md「HeroCard」)。
|
|
117
|
+
*/
|
|
118
|
+
export declare function heroData(input: ReportInput): Promise<HeroData>;
|
|
119
|
+
/**
|
|
120
|
+
* `scopeWarningsData(input)`:Scope 携带的挑选警告原样透出;`input` 是裸 `Snapshot[]` 时
|
|
121
|
+
* 没有挑选过程、没有警告,返回空数组,也如实
|
|
122
|
+
* (docs/feature/reports/library/site-components.md「ScopeWarnings」)。
|
|
123
|
+
*/
|
|
124
|
+
export declare function scopeWarningsData(input: ReportInput): Promise<readonly ScopeWarning[]>;
|
|
125
|
+
/**
|
|
126
|
+
* `copyFixPromptData(input)`:把范围内全部失败(verdict 为 failed / errored 的 attempt)
|
|
127
|
+
* 整理成一段可交给 coding agent 的修复 prompt——逐失败含 eval id、主失败摘要与 attempt
|
|
128
|
+
* 下钻命令(`niceeval show @<locator>`)。prompt 面向 agent,固定英文
|
|
129
|
+
* (docs/feature/reports/library/site-components.md「CopyFixPrompt」)。
|
|
130
|
+
*/
|
|
131
|
+
export declare function copyFixPromptData(input: ReportInput): Promise<CopyFixPromptData>;
|
|
132
|
+
/**
|
|
133
|
+
* `traceWaterfallData(input)`:每个 attempt 一行的执行时间瀑布摘要。span 事实只来自
|
|
134
|
+
* trace artifact(经 AttemptHandle 懒加载的 canonical OTel span);runner 生命周期节点
|
|
135
|
+
* (`result.phases`)不进瀑布。行内只汇总顶层 span(parentSpanId 缺失或不在本 trace 内),
|
|
136
|
+
* 按 startOffsetMs 升序;trace 缺失或为空时 `durationMs` 为 null、行照常出现
|
|
137
|
+
* (docs/feature/reports/library/site-components.md「TraceWaterfall」)。
|
|
138
|
+
*/
|
|
139
|
+
export declare function traceWaterfallData(input: ReportInput): Promise<readonly TraceWaterfallRow[]>;
|
package/dist/report/compute.js
CHANGED
|
@@ -117,9 +117,8 @@ function failureSummaryOf(result) {
|
|
|
117
117
|
}
|
|
118
118
|
return { summary: null, more: 0 };
|
|
119
119
|
}
|
|
120
|
-
const identityRedact = (text) => text;
|
|
121
120
|
/** AttemptList / ExperimentList / EvalList 共用的叶子构造:一个 Item → 一个 AttemptListItem。 */
|
|
122
|
-
async function attemptListItemOf(item
|
|
121
|
+
async function attemptListItemOf(item) {
|
|
123
122
|
const result = item.attempt.result;
|
|
124
123
|
const { summary, more } = failureSummaryOf(result);
|
|
125
124
|
return {
|
|
@@ -128,7 +127,7 @@ async function attemptListItemOf(item, redact) {
|
|
|
128
127
|
attempt: result.attempt,
|
|
129
128
|
agent: result.agent,
|
|
130
129
|
verdict: result.verdict,
|
|
131
|
-
failureSummary: summary
|
|
130
|
+
failureSummary: summary,
|
|
132
131
|
moreFailures: more,
|
|
133
132
|
examScore: await computeCell(examScore, [item]),
|
|
134
133
|
durationMs: result.durationMs,
|
|
@@ -137,16 +136,14 @@ async function attemptListItemOf(item, redact) {
|
|
|
137
136
|
};
|
|
138
137
|
}
|
|
139
138
|
/** `attemptListData(input)`:每个 Attempt 一项,顺序取自 Scope 展平顺序(不重排)。 */
|
|
140
|
-
export async function attemptListData(input
|
|
139
|
+
export async function attemptListData(input) {
|
|
141
140
|
const { snapshots } = resolveInput(input);
|
|
142
|
-
const redact = options?.redact ?? identityRedact;
|
|
143
141
|
const items = collectItems(snapshots);
|
|
144
|
-
return Promise.all(items.map((item) => attemptListItemOf(item
|
|
142
|
+
return Promise.all(items.map((item) => attemptListItemOf(item)));
|
|
145
143
|
}
|
|
146
144
|
/** `evalListData(input)`:每个 `experimentId + evalId` 一项,按 evalId 再按 experimentId 升序。 */
|
|
147
|
-
export async function evalListData(input
|
|
145
|
+
export async function evalListData(input) {
|
|
148
146
|
const { snapshots } = resolveInput(input);
|
|
149
|
-
const redact = options?.redact ?? identityRedact;
|
|
150
147
|
const items = collectItems(snapshots);
|
|
151
148
|
const groups = new Map();
|
|
152
149
|
for (const item of items) {
|
|
@@ -161,7 +158,7 @@ export async function evalListData(input, options) {
|
|
|
161
158
|
for (const group of groups.values()) {
|
|
162
159
|
const sorted = [...group].sort((a, b) => a.attempt.result.attempt - b.attempt.result.attempt);
|
|
163
160
|
const verdict = foldEvalVerdict(sorted.map((item) => item.attempt.result));
|
|
164
|
-
const attempts = await Promise.all(sorted.map((item) => attemptListItemOf(item
|
|
161
|
+
const attempts = await Promise.all(sorted.map((item) => attemptListItemOf(item)));
|
|
165
162
|
out.push({
|
|
166
163
|
experimentId: experimentIdOf(sorted[0]),
|
|
167
164
|
evalId: evalIdOf(sorted[0]),
|
|
@@ -182,9 +179,8 @@ export async function evalListData(input, options) {
|
|
|
182
179
|
* Snapshot[] 时若同一 experiment 混入不一致的可比性配置,按完整用户反馈失败并指引——
|
|
183
180
|
* 看跨配置演化用 snapshot 维度或 MetricLine,不把两套配置拼成一行冒充单一配置。
|
|
184
181
|
*/
|
|
185
|
-
export async function experimentListData(input
|
|
182
|
+
export async function experimentListData(input) {
|
|
186
183
|
const { snapshots } = resolveInput(input);
|
|
187
|
-
const redact = options?.redact ?? identityRedact;
|
|
188
184
|
// 可比性配置单义检查:同一 experiment 的输入快照必须共享一套可比性配置。
|
|
189
185
|
const configByExperiment = new Map();
|
|
190
186
|
for (const snapshot of snapshots) {
|
|
@@ -211,7 +207,7 @@ export async function experimentListData(input, options) {
|
|
|
211
207
|
for (const [evalId, evalItems] of evalGroups) {
|
|
212
208
|
const sorted = [...evalItems].sort((a, b) => a.attempt.result.attempt - b.attempt.result.attempt);
|
|
213
209
|
const verdict = foldEvalVerdict(sorted.map((item) => item.attempt.result));
|
|
214
|
-
const attempts = await Promise.all(sorted.map((item) => attemptListItemOf(item
|
|
210
|
+
const attempts = await Promise.all(sorted.map((item) => attemptListItemOf(item)));
|
|
215
211
|
evalRows.push({
|
|
216
212
|
evalId,
|
|
217
213
|
verdict,
|
|
@@ -778,3 +774,126 @@ function deltaOutcome(metric, delta) {
|
|
|
778
774
|
const better = metric.better ?? "higher";
|
|
779
775
|
return (delta > 0) === (better === "higher") ? "improved" : "regressed";
|
|
780
776
|
}
|
|
777
|
+
// ───────────────────────── 站点组件的计算函数(hero / warnings / fix prompt / trace)─────────────────────────
|
|
778
|
+
/**
|
|
779
|
+
* `heroData(input)`:站点标题区的运行 meta——`latestStartedAt` 取范围内最新快照的开始时间
|
|
780
|
+
* (空范围为 null,不编造当前时间),`snapshots` 计贡献当前水位的快照数
|
|
781
|
+
* (docs/feature/reports/library/site-components.md「HeroCard」)。
|
|
782
|
+
*/
|
|
783
|
+
export async function heroData(input) {
|
|
784
|
+
const { snapshots } = resolveInput(input);
|
|
785
|
+
let latest = null;
|
|
786
|
+
for (const snapshot of snapshots) {
|
|
787
|
+
if (latest === null || snapshot.startedAt > latest)
|
|
788
|
+
latest = snapshot.startedAt;
|
|
789
|
+
}
|
|
790
|
+
return { latestStartedAt: latest, snapshots: snapshots.length };
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* `scopeWarningsData(input)`:Scope 携带的挑选警告原样透出;`input` 是裸 `Snapshot[]` 时
|
|
794
|
+
* 没有挑选过程、没有警告,返回空数组,也如实
|
|
795
|
+
* (docs/feature/reports/library/site-components.md「ScopeWarnings」)。
|
|
796
|
+
*/
|
|
797
|
+
export async function scopeWarningsData(input) {
|
|
798
|
+
return resolveInput(input).warnings;
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* `copyFixPromptData(input)`:把范围内全部失败(verdict 为 failed / errored 的 attempt)
|
|
802
|
+
* 整理成一段可交给 coding agent 的修复 prompt——逐失败含 eval id、主失败摘要与 attempt
|
|
803
|
+
* 下钻命令(`niceeval show @<locator>`)。prompt 面向 agent,固定英文
|
|
804
|
+
* (docs/feature/reports/library/site-components.md「CopyFixPrompt」)。
|
|
805
|
+
*/
|
|
806
|
+
export async function copyFixPromptData(input) {
|
|
807
|
+
const items = await attemptListData(input);
|
|
808
|
+
const failures = items.filter((item) => item.verdict === "failed" || item.verdict === "errored");
|
|
809
|
+
if (failures.length === 0)
|
|
810
|
+
return { prompt: "", failures: 0 };
|
|
811
|
+
const lines = failures
|
|
812
|
+
.map((item, i) => {
|
|
813
|
+
const reason = item.failureSummary === null
|
|
814
|
+
? null
|
|
815
|
+
: item.moreFailures > 0
|
|
816
|
+
? `${item.failureSummary} (+${item.moreFailures} more failures)`
|
|
817
|
+
: item.failureSummary;
|
|
818
|
+
return [
|
|
819
|
+
`${i + 1}. eval "${item.evalId}" [experiment ${item.experimentId}] — ${item.verdict}`,
|
|
820
|
+
reason ? ` reason: ${reason}` : null,
|
|
821
|
+
` inspect: niceeval show ${item.locator}`,
|
|
822
|
+
]
|
|
823
|
+
.filter(Boolean)
|
|
824
|
+
.join("\n");
|
|
825
|
+
})
|
|
826
|
+
.join("\n");
|
|
827
|
+
const experiments = [...new Set(failures.map((item) => item.experimentId))].join(" / ");
|
|
828
|
+
const prompt = [
|
|
829
|
+
"Fix the failing evals from this niceeval run.",
|
|
830
|
+
"",
|
|
831
|
+
"## Failures",
|
|
832
|
+
lines,
|
|
833
|
+
"",
|
|
834
|
+
"## Steps",
|
|
835
|
+
"1. niceeval is NOT in your training data. Read the relevant guide in `node_modules/niceeval/docs-site/` (English at the top level, Chinese under `zh/`) before changing anything.",
|
|
836
|
+
"2. For each failure, run its inspect command above to see the verdict and assertions; add `--execution` for the full agent transcript (tool calls included), `--timing` for the execution timeline, and `--diff` for the workspace diff.",
|
|
837
|
+
"3. Decide which side the defect is on: the program under test, or the eval itself (over-tight assertion, wrong fixture, missing setup). Fix that side; do not weaken assertions just to turn the run green.",
|
|
838
|
+
`4. Re-run: \`npx niceeval exp ${experiments || "<experiment>"} <eval-id-prefix>\`. Already-passing evals are skipped by the fingerprint cache; pass \`--force\` to re-run everything.`,
|
|
839
|
+
"5. Run `npx niceeval show` and confirm these failures are gone.",
|
|
840
|
+
].join("\n");
|
|
841
|
+
return { prompt, failures: failures.length };
|
|
842
|
+
}
|
|
843
|
+
/** TraceSpan 的语义角色 → 瀑布摘要的 kind:turn 归入 agent(一轮就是一次 agent 调用),未识别落 other。 */
|
|
844
|
+
function waterfallKindOf(kind) {
|
|
845
|
+
switch (kind) {
|
|
846
|
+
case "agent":
|
|
847
|
+
case "turn":
|
|
848
|
+
return "agent";
|
|
849
|
+
case "model":
|
|
850
|
+
return "model";
|
|
851
|
+
case "tool":
|
|
852
|
+
return "tool";
|
|
853
|
+
default:
|
|
854
|
+
return "other";
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* `traceWaterfallData(input)`:每个 attempt 一行的执行时间瀑布摘要。span 事实只来自
|
|
859
|
+
* trace artifact(经 AttemptHandle 懒加载的 canonical OTel span);runner 生命周期节点
|
|
860
|
+
* (`result.phases`)不进瀑布。行内只汇总顶层 span(parentSpanId 缺失或不在本 trace 内),
|
|
861
|
+
* 按 startOffsetMs 升序;trace 缺失或为空时 `durationMs` 为 null、行照常出现
|
|
862
|
+
* (docs/feature/reports/library/site-components.md「TraceWaterfall」)。
|
|
863
|
+
*/
|
|
864
|
+
export async function traceWaterfallData(input) {
|
|
865
|
+
const { snapshots } = resolveInput(input);
|
|
866
|
+
const items = collectItems(snapshots);
|
|
867
|
+
return Promise.all(items.map(async (item) => {
|
|
868
|
+
const spans = await item.attempt.trace();
|
|
869
|
+
if (spans === null || spans.length === 0) {
|
|
870
|
+
return {
|
|
871
|
+
experimentId: experimentIdOf(item),
|
|
872
|
+
evalId: evalIdOf(item),
|
|
873
|
+
locator: locatorOf(item),
|
|
874
|
+
durationMs: null,
|
|
875
|
+
spans: [],
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
const t0 = Math.min(...spans.map((s) => s.startMs));
|
|
879
|
+
const t1 = Math.max(...spans.map((s) => s.endMs));
|
|
880
|
+
const ids = new Set(spans.map((s) => s.spanId));
|
|
881
|
+
const topLevel = spans.filter((s) => s.parentSpanId === undefined || !ids.has(s.parentSpanId));
|
|
882
|
+
const summaries = topLevel
|
|
883
|
+
.map((s) => ({
|
|
884
|
+
name: s.name,
|
|
885
|
+
kind: waterfallKindOf(s.kind),
|
|
886
|
+
startOffsetMs: s.startMs - t0,
|
|
887
|
+
durationMs: s.endMs - s.startMs,
|
|
888
|
+
failed: s.status === "error",
|
|
889
|
+
}))
|
|
890
|
+
.sort((a, b) => a.startOffsetMs - b.startOffsetMs);
|
|
891
|
+
return {
|
|
892
|
+
experimentId: experimentIdOf(item),
|
|
893
|
+
evalId: evalIdOf(item),
|
|
894
|
+
locator: locatorOf(item),
|
|
895
|
+
durationMs: Math.max(0, t1 - t0),
|
|
896
|
+
spans: summaries,
|
|
897
|
+
};
|
|
898
|
+
}));
|
|
899
|
+
}
|
package/dist/report/index.d.ts
CHANGED
|
@@ -10,10 +10,10 @@ export { stringWidth, padDisplay as padEnd, padStartDisplay as padStart, wrapDis
|
|
|
10
10
|
export type { ColumnAlign } from "./text/layout.ts";
|
|
11
11
|
export { DEFAULT_REPORT_LOCALE, localizedTextEquals, resolveLocalizedText, resolveMetricLabel } from "./locale.ts";
|
|
12
12
|
export type { LocalizedText, ReportLocale } from "./locale.ts";
|
|
13
|
-
export { AttemptList, DeltaTable, EvalList, ExperimentComparison, ExperimentList, FailureList, MetricBars, MetricLine, MetricMatrix, MetricScatter, MetricTable, Scoreboard, ScopeSummary, } from "./components.tsx";
|
|
14
|
-
export type { AttemptListProps, DataProps, DeltaTableProps, EvalListProps, ExperimentComparisonProps, ExperimentListProps, FailureListProps, MetricBarsProps, MetricLineProps, MetricMatrixProps, MetricScatterProps, MetricTableProps, ScoreboardProps, ScopeSummaryProps, } from "./components.tsx";
|
|
15
|
-
export { attemptListData, deltaTableData, evalListData, experimentComparisonData, experimentListData, metricLineData, metricMatrixData, metricScatterData, metricTableData, pairsByFlag, scopeSummaryData, scoreboardData, } from "./compute.ts";
|
|
13
|
+
export { AttemptList, CopyFixPrompt, DeltaTable, EvalList, ExperimentComparison, ExperimentList, FailureList, Hero, HeroCard, MetricBars, MetricLine, MetricMatrix, MetricScatter, MetricTable, PoweredBy, Scoreboard, ScopeSummary, ScopeWarnings, TraceWaterfall, } from "./components.tsx";
|
|
14
|
+
export type { AttemptListProps, CopyFixPromptProps, DataProps, DeltaTableProps, EvalListProps, ExperimentComparisonProps, ExperimentListProps, FailureListProps, HeroCardProps, HeroProps, MetricBarsProps, MetricLineProps, MetricMatrixProps, MetricScatterProps, MetricTableProps, ScoreboardProps, ScopeSummaryProps, ScopeWarningsProps, TraceWaterfallProps, } from "./components.tsx";
|
|
15
|
+
export { attemptListData, copyFixPromptData, deltaTableData, evalListData, experimentComparisonData, experimentListData, heroData, metricLineData, metricMatrixData, metricScatterData, metricTableData, pairsByFlag, scopeSummaryData, scopeWarningsData, scoreboardData, traceWaterfallData, } from "./compute.ts";
|
|
16
16
|
export type { DeltaTableOptions, MetricLineOptions, MetricMatrixOptions, MetricScatterOptions, MetricTableOptions, ScoreboardOptions, } from "./compute.ts";
|
|
17
|
-
export type { Aggregator, AttemptListItem, AttemptLocator, BuiltInDimension, CustomDimension, DeltaData, DeltaPair, DimensionInput, DimensionOptions, DimensionRef,
|
|
17
|
+
export type { Aggregator, AttemptListItem, AttemptLocator, BuiltInDimension, CopyFixPromptData, CustomDimension, DeltaData, DeltaPair, DimensionInput, DimensionOptions, DimensionRef, EvalListItem, ExperimentComparisonData, ExperimentComparisonGroupData, ExperimentListEvalRow, ExperimentListItem, FlagPairs, HeroData, LineData, MatrixData, Metric, MetricAggregate, MetricCell, MetricColumn, NumericAxis, NumericAxisOptions, NumericRunConfigAxisOptions, ReportInput, RunConfigKey, ScatterData, ScopeSummaryData, ScopeWarning, ScoreboardData, TableData, TraceSpanSummary, TraceWaterfallRow, VerdictTally, } from "./types.ts";
|
|
18
18
|
export type { AttemptHandle, Results, Scope, Snapshot } from "../results/types.ts";
|
|
19
19
|
export { experimentGroupOf } from "../shared/aggregate.ts";
|
package/dist/report/index.js
CHANGED
|
@@ -20,10 +20,11 @@ export { stringWidth, padDisplay as padEnd, padStartDisplay as padStart, wrapDis
|
|
|
20
20
|
// locale:官方组件 chrome 文案的语言(内置词典覆盖 en / zh-CN,其它 locale 走回退)
|
|
21
21
|
export { DEFAULT_REPORT_LOCALE, localizedTextEquals, resolveLocalizedText, resolveMetricLabel } from "./locale.js";
|
|
22
22
|
// 官方双面组件(spec / data 双形态;配套 *Data 计算函数在下面成对导出)
|
|
23
|
-
|
|
23
|
+
// 与站点组件(Hero / HeroCard / PoweredBy / ScopeWarnings / CopyFixPrompt / TraceWaterfall)
|
|
24
|
+
export { AttemptList, CopyFixPrompt, DeltaTable, EvalList, ExperimentComparison, ExperimentList, FailureList, Hero, HeroCard, MetricBars, MetricLine, MetricMatrix, MetricScatter, MetricTable, PoweredBy, Scoreboard, ScopeSummary, ScopeWarnings, TraceWaterfall, } from "./components.js";
|
|
24
25
|
// 计算函数(组件解析面的具名形式,与组件成对;spec 形态下由管线代调,data 形态与
|
|
25
26
|
// 嵌入场景下由作者手工调)
|
|
26
|
-
export { attemptListData, deltaTableData, evalListData, experimentComparisonData, experimentListData, metricLineData, metricMatrixData, metricScatterData, metricTableData, pairsByFlag, scopeSummaryData, scoreboardData, } from "./compute.js";
|
|
27
|
+
export { attemptListData, copyFixPromptData, deltaTableData, evalListData, experimentComparisonData, experimentListData, heroData, metricLineData, metricMatrixData, metricScatterData, metricTableData, pairsByFlag, scopeSummaryData, scopeWarningsData, scoreboardData, traceWaterfallData, } from "./compute.js";
|
|
27
28
|
// experiment id 的组键推导(id 的目录前缀,如 `compare/bub-low` 的 `compare`)。
|
|
28
29
|
// 重新导出,让自定义报告能按同一份口径把 experiment 分组,不必自己重写这两行逻辑。
|
|
29
30
|
export { experimentGroupOf } from "../shared/aggregate.js";
|
package/dist/report/locale.d.ts
CHANGED
|
@@ -104,13 +104,51 @@ declare const en: {
|
|
|
104
104
|
readonly "scoreboard.subjectTitle": "{questions} evals, weighted {earned} of {possible}";
|
|
105
105
|
readonly "delta.pairHeader": "pair (A → B)";
|
|
106
106
|
readonly "delta.empty": "{experiments} experiments, 0 comparable pairs";
|
|
107
|
+
/** ScopeWarnings 聚合层的 chrome:汇总行、kind 徽标、组头与明细折叠标签;message 本体不经字典。 */
|
|
108
|
+
readonly "warnings.summary.experiments.one": "{n} experiment flagged";
|
|
109
|
+
readonly "warnings.summary.experiments.other": "{n} experiments flagged";
|
|
110
|
+
readonly "warnings.group.unreadableSnapshot.one": "{n} snapshot skipped";
|
|
111
|
+
readonly "warnings.group.unreadableSnapshot.other": "{n} snapshots skipped";
|
|
112
|
+
readonly "warnings.details.one": "{n} warning";
|
|
113
|
+
readonly "warnings.details.other": "{n} warnings";
|
|
114
|
+
readonly "warnings.badge.partialCoverage": "coverage {covered}/{total}";
|
|
115
|
+
readonly "warnings.badge.staleSnapshot": "{gap} behind";
|
|
116
|
+
readonly "warnings.badge.unfinishedSnapshot": "unfinished";
|
|
117
|
+
readonly "warnings.gap.second.one": "{n} second";
|
|
118
|
+
readonly "warnings.gap.second.other": "{n} seconds";
|
|
119
|
+
readonly "warnings.gap.minute.one": "{n} minute";
|
|
120
|
+
readonly "warnings.gap.minute.other": "{n} minutes";
|
|
121
|
+
readonly "warnings.gap.hour.one": "{n} hour";
|
|
122
|
+
readonly "warnings.gap.hour.other": "{n} hours";
|
|
123
|
+
readonly "warnings.gap.day.one": "{n} day";
|
|
124
|
+
readonly "warnings.gap.day.other": "{n} days";
|
|
125
|
+
/** Hero / HeroCard 的运行 meta(hero.noRuns 是 latestStartedAt 为 null 时的内置文案)。 */
|
|
126
|
+
readonly "hero.lastRun": "Last run {time}";
|
|
127
|
+
readonly "hero.noRuns": "No runs yet";
|
|
128
|
+
/** web 面的合成来源标注(仅 snapshots > 1 时显示)。 */
|
|
129
|
+
readonly "hero.composedRuns": "composed from {n} runs";
|
|
130
|
+
/** text 面的合成来源标注(show 页首 meta 行,仅 snapshots > 1 时显示)。 */
|
|
131
|
+
readonly "hero.composedSnapshots": "composed from {n} snapshots";
|
|
132
|
+
/** CopyFixPrompt 的 web 面 chrome(prompt 本身面向 agent、固定英文,不经词典)。 */
|
|
133
|
+
readonly "copyFixPrompt.summary.one": "Fix prompt · {n} failure";
|
|
134
|
+
readonly "copyFixPrompt.summary.other": "Fix prompt · {n} failures";
|
|
135
|
+
readonly "copyFixPrompt.copy": "Copy fix prompt";
|
|
136
|
+
/** TraceWaterfall 的 chrome。 */
|
|
137
|
+
readonly "traceWaterfall.empty": "No attempts";
|
|
138
|
+
readonly "traceWaterfall.noTrace": "no trace";
|
|
139
|
+
readonly "traceWaterfall.spans.one": "{n} span";
|
|
140
|
+
readonly "traceWaterfall.spans.other": "{n} spans";
|
|
141
|
+
readonly "traceWaterfall.failedSpans.one": "{n} failed";
|
|
142
|
+
readonly "traceWaterfall.failedSpans.other": "{n} failed";
|
|
143
|
+
/** AttemptList 的 web 面过滤框占位符(filter 渐进增强)。 */
|
|
144
|
+
readonly "attemptList.filterPlaceholder": "Filter attempts…";
|
|
107
145
|
readonly "tabs.tab": "Tab";
|
|
108
146
|
};
|
|
109
147
|
export type ReportMessageKey = keyof typeof en;
|
|
110
148
|
/** 查字典 + 简单插值({name} 占位符)。内置词典未覆盖的 locale 回退 en。 */
|
|
111
149
|
export declare function localeText(locale: ReportLocale, key: ReportMessageKey, vars?: Record<string, string | number>): string;
|
|
112
150
|
/** 带单复数的计数文案:n === 1 用 `<base>.one`,其余 `<base>.other`(zh-CN 两键同值)。 */
|
|
113
|
-
export declare function countText(locale: ReportLocale, base: "overview.experiments" | "pointsMissing" | "scoreboard.notRun" | "scoreboard.unscorable" | "scoreboard.ignored" | "entityList.moreFailures" | "table.columnsHidden", n: number): string;
|
|
151
|
+
export declare function countText(locale: ReportLocale, base: "overview.experiments" | "pointsMissing" | "scoreboard.notRun" | "scoreboard.unscorable" | "scoreboard.ignored" | "entityList.moreFailures" | "table.columnsHidden" | "copyFixPrompt.summary" | "traceWaterfall.spans" | "traceWaterfall.failedSpans", n: number): string;
|
|
114
152
|
/**
|
|
115
153
|
* 按 locale 解析指标 / 列 label:字符串原样;字典按 LocalizedText 回退规则取值;
|
|
116
154
|
* undefined 回退 fallback(= metric.name)。渲染面(web / text)共用。
|