niceeval 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INDEX.md +23 -23
- package/README.zh.md +6 -6
- package/dist/agents/types.d.ts +69 -7
- package/dist/context/types.d.ts +32 -12
- package/dist/i18n/en.d.ts +54 -0
- package/dist/i18n/zh-CN.d.ts +57 -3
- package/dist/o11y/types.d.ts +16 -2
- package/dist/report/aggregate.d.ts +32 -24
- package/dist/report/aggregate.js +158 -50
- package/dist/report/built-in/index.d.ts +2 -0
- package/dist/report/built-in/index.js +8 -0
- package/dist/report/components.d.ts +93 -160
- package/dist/report/components.js +377 -114
- package/dist/report/compute.d.ts +87 -81
- package/dist/report/compute.js +597 -417
- package/dist/report/flag.d.ts +32 -6
- package/dist/report/flag.js +92 -4
- package/dist/report/format.d.ts +19 -11
- package/dist/report/format.js +30 -13
- package/dist/report/index.d.ts +16 -16
- package/dist/report/index.js +20 -21
- package/dist/report/load.js +3 -2
- package/dist/report/locale.d.ts +57 -33
- package/dist/report/locale.js +122 -56
- package/dist/report/metrics.d.ts +23 -4
- package/dist/report/metrics.js +110 -25
- package/dist/report/primitives.d.ts +48 -15
- package/dist/report/primitives.js +135 -26
- package/dist/report/react/AttemptList.d.ts +9 -7
- package/dist/report/react/AttemptList.js +17 -10
- package/dist/report/react/DeltaTable.js +19 -18
- package/dist/report/react/EvalList.d.ts +4 -4
- package/dist/report/react/EvalList.js +0 -0
- package/dist/report/react/ExperimentComparison.d.ts +10 -0
- package/dist/report/react/ExperimentComparison.js +12 -0
- package/dist/report/react/ExperimentList.d.ts +4 -3
- package/dist/report/react/ExperimentList.js +17 -18
- package/dist/report/react/MetricBars.js +5 -4
- package/dist/report/react/MetricLine.js +12 -5
- package/dist/report/react/MetricMatrix.js +1 -1
- package/dist/report/react/MetricScatter.js +59 -28
- package/dist/report/react/MetricTable.js +2 -12
- package/dist/report/react/ScopeSummary.d.ts +10 -0
- package/dist/report/react/ScopeSummary.js +17 -0
- package/dist/report/react/Scoreboard.js +6 -6
- package/dist/report/react/cell.js +2 -2
- package/dist/report/react/chart-math.d.ts +23 -6
- package/dist/report/react/chart-math.js +71 -19
- package/dist/report/react/fixtures.d.ts +5 -9
- package/dist/report/react/fixtures.js +110 -147
- package/dist/report/react/index.d.ts +15 -5
- package/dist/report/react/index.js +18 -7
- package/dist/report/report.d.ts +137 -16
- package/dist/report/report.js +259 -28
- package/dist/report/text/faces.d.ts +17 -19
- package/dist/report/text/faces.js +253 -184
- package/dist/report/text/plot.js +1 -1
- package/dist/report/text/table.js +38 -7
- package/dist/report/tree.d.ts +90 -40
- package/dist/report/tree.js +252 -94
- package/dist/report/types.d.ts +247 -284
- package/dist/report/types.js +4 -3
- package/dist/report/web.d.ts +21 -5
- package/dist/report/web.js +42 -16
- package/dist/results/select.d.ts +38 -16
- package/dist/results/select.js +73 -25
- package/dist/results/types.d.ts +49 -14
- package/dist/runner/feedback/sink.d.ts +110 -0
- package/dist/runner/types.d.ts +513 -22
- package/dist/sandbox/docker.d.ts +23 -2
- package/dist/sandbox/e2b.d.ts +15 -1
- package/dist/sandbox/errors.d.ts +30 -3
- package/dist/sandbox/io-retry.d.ts +17 -0
- package/dist/sandbox/registry.d.ts +2 -0
- package/dist/sandbox/resolve.d.ts +18 -5
- package/dist/sandbox/retry.d.ts +11 -1
- package/dist/sandbox/types.d.ts +39 -5
- package/dist/sandbox/vercel.d.ts +7 -1
- package/dist/scoring/coverage.d.ts +30 -0
- package/dist/scoring/display.d.ts +21 -0
- package/dist/scoring/display.js +120 -0
- package/dist/scoring/types.d.ts +103 -20
- package/dist/shared/aggregate.d.ts +4 -2
- package/dist/shared/aggregate.js +8 -7
- package/dist/shared/types.d.ts +28 -0
- package/dist/tty-line.d.ts +0 -4
- package/dist/util.d.ts +23 -0
- package/docs-site/zh/README.md +44 -0
- package/docs-site/zh/examples/ai-agent-application.mdx +63 -0
- package/docs-site/zh/examples/coding-agent-extensions.mdx +57 -0
- package/docs-site/zh/examples/index.mdx +50 -0
- package/docs-site/zh/{concepts → explanation}/adapter.mdx +31 -13
- package/docs-site/zh/{concepts → explanation}/assert.mdx +7 -7
- package/docs-site/zh/{concepts → explanation}/drive.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/evals.mdx +4 -4
- package/docs-site/zh/{concepts → explanation}/experiment.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/hitl.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/judge.mdx +5 -5
- package/docs-site/zh/{concepts → explanation}/overview.mdx +11 -11
- package/docs-site/zh/{guides → explanation}/runner.mdx +18 -8
- package/docs-site/zh/{concepts → explanation}/tier.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/agent-feedback-loop.mdx +35 -33
- package/docs-site/zh/{guides → how-to}/authoring.mdx +35 -2
- package/docs-site/zh/{guides → how-to}/ci-integration.mdx +23 -12
- package/docs-site/zh/{guides → how-to}/connect-otel.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/connect-your-agent.mdx +47 -21
- package/docs-site/zh/{guides → how-to}/custom-reports.mdx +34 -39
- package/docs-site/zh/{guides → how-to}/dataset-fanout.mdx +25 -3
- package/docs-site/zh/{guides → how-to}/experiments.mdx +12 -5
- package/docs-site/zh/how-to/publish-report.mdx +105 -0
- package/docs-site/zh/{guides → how-to}/reporters.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/sandbox-agent.mdx +56 -7
- package/docs-site/zh/how-to/sandbox-providers.mdx +350 -0
- package/docs-site/zh/{guides → how-to}/scoring-guide.mdx +4 -4
- package/docs-site/zh/{guides → how-to}/viewing-results.mdx +82 -39
- package/docs-site/zh/{guides → how-to}/write-experiment.mdx +6 -4
- package/docs-site/zh/{guides → how-to}/write-send.mdx +30 -14
- package/docs-site/zh/index.mdx +24 -26
- package/docs-site/zh/introduction.mdx +8 -8
- package/docs-site/zh/reference/builtin-agents.mdx +32 -5
- package/docs-site/zh/reference/capabilities.mdx +8 -8
- package/docs-site/zh/reference/cli.mdx +40 -12
- package/docs-site/zh/reference/define-agent.mdx +58 -5
- package/docs-site/zh/reference/define-config.mdx +1 -1
- package/docs-site/zh/reference/define-eval.mdx +42 -9
- package/docs-site/zh/reference/events.mdx +3 -3
- package/docs-site/zh/reference/expect.mdx +26 -1
- package/docs-site/zh/{guides → reference}/official-adapters.mdx +32 -8
- package/docs-site/zh/{guides → reference}/report-components.mdx +45 -33
- package/docs-site/zh/{guides → reference}/results-data.mdx +21 -13
- package/docs-site/zh/troubleshooting/debug-sandbox.mdx +57 -0
- package/docs-site/zh/troubleshooting/debugging.mdx +212 -0
- package/docs-site/zh/{quickstart.mdx → tutorials/quickstart.mdx} +5 -17
- package/package.json +10 -2
- package/src/agents/ai-sdk-otel.test.ts +1 -0
- package/src/agents/ai-sdk.test.ts +3 -0
- package/src/agents/ai-sdk.ts +3 -0
- package/src/agents/bub-install-spec.test.ts +34 -0
- package/src/agents/bub-install-spec.ts +32 -0
- package/src/agents/bub.ts +31 -32
- package/src/agents/claude-code.test.ts +130 -9
- package/src/agents/claude-code.ts +76 -4
- package/src/agents/codex.test.ts +189 -40
- package/src/agents/codex.ts +155 -14
- package/src/agents/coding-cli-versions.test.ts +15 -0
- package/src/agents/coding-cli-versions.ts +3 -0
- package/src/agents/index.ts +13 -2
- package/src/agents/langgraph.test.ts +204 -0
- package/src/agents/langgraph.ts +495 -0
- package/src/agents/marketplace.ts +85 -0
- package/src/agents/native-config.test.ts +179 -0
- package/src/agents/native-config.ts +267 -0
- package/src/agents/openai-compat.test.ts +1 -0
- package/src/agents/openai-compat.ts +1 -1
- package/src/agents/openclaw.test.ts +31 -0
- package/src/agents/openclaw.ts +171 -0
- package/src/agents/plugin-config.test.ts +1 -0
- package/src/agents/sdk-streams.test.ts +79 -0
- package/src/agents/sdk-streams.ts +55 -10
- package/src/agents/skills.test.ts +1 -0
- package/src/agents/streaming.test.ts +3 -9
- package/src/agents/streaming.ts +2 -2
- package/src/agents/types.ts +71 -8
- package/src/agents/ui-message-stream.test.ts +3 -0
- package/src/cli.ts +446 -124
- package/src/context/context.test.ts +51 -12
- package/src/context/context.ts +162 -30
- package/src/context/session.test.ts +2 -1
- package/src/context/session.ts +115 -7
- package/src/context/types.ts +30 -12
- package/src/define.test.ts +13 -8
- package/src/define.ts +25 -4
- package/src/expect/index.ts +53 -23
- package/src/i18n/en.ts +81 -17
- package/src/i18n/zh-CN.ts +80 -17
- package/src/o11y/cost.test.ts +1 -0
- package/src/o11y/execution-tree.test.ts +1 -20
- package/src/o11y/otlp/mappers/claude-code.test.ts +1 -0
- package/src/o11y/otlp/parse.test.ts +1 -0
- package/src/o11y/otlp/turn-otel.test.ts +1 -0
- package/src/o11y/parsers/bub.test.ts +1 -0
- package/src/o11y/parsers/claude-code.test.ts +1 -34
- package/src/o11y/parsers/openclaw.test.ts +154 -0
- package/src/o11y/parsers/openclaw.ts +310 -0
- package/src/o11y/prices.json +746 -311
- package/src/o11y/tool-names.test.ts +1 -0
- package/src/o11y/types.ts +16 -2
- package/src/report/aggregate.ts +178 -61
- package/src/report/built-in/index.tsx +9 -0
- package/src/report/components.tsx +625 -279
- package/src/report/compute.ts +723 -491
- package/src/report/dual-render.test.tsx +741 -1024
- package/src/report/flag.ts +104 -12
- package/src/report/format.ts +32 -12
- package/src/report/index.ts +119 -46
- package/src/report/load.ts +3 -2
- package/src/report/locale.ts +136 -65
- package/src/report/metrics.ts +108 -25
- package/src/report/primitives.tsx +196 -45
- package/src/report/react/AttemptList.tsx +30 -43
- package/src/report/react/DeltaTable.tsx +63 -45
- package/src/report/react/EvalList.tsx +0 -0
- package/src/report/react/ExperimentComparison.tsx +73 -0
- package/src/report/react/ExperimentList.tsx +50 -32
- package/src/report/react/MetricBars.tsx +5 -4
- package/src/report/react/MetricLine.tsx +13 -8
- package/src/report/react/MetricMatrix.tsx +2 -2
- package/src/report/react/MetricScatter.tsx +86 -34
- package/src/report/react/MetricTable.tsx +4 -76
- package/src/report/react/ScopeSummary.tsx +86 -0
- package/src/report/react/Scoreboard.tsx +28 -10
- package/src/report/react/cell.tsx +2 -2
- package/src/report/react/chart-math.test.ts +85 -0
- package/src/report/react/chart-math.ts +101 -22
- package/src/report/react/enhance.js +89 -5
- package/src/report/react/fixtures.ts +114 -154
- package/src/report/react/index.tsx +24 -39
- package/src/report/react/render.test.tsx +138 -158
- package/src/report/react/styles.css +243 -82
- package/src/report/report.test.ts +779 -841
- package/src/report/report.ts +423 -41
- package/src/report/text/faces.ts +290 -193
- package/src/report/text/plot.ts +1 -1
- package/src/report/text/table.ts +44 -7
- package/src/report/tree.ts +362 -104
- package/src/report/types.ts +261 -271
- package/src/report/web.ts +63 -20
- package/src/results/annotated-source.test.ts +62 -9
- package/src/results/annotated-source.ts +64 -6
- package/src/results/attempt-evidence.test.ts +13 -11
- package/src/results/attempt-evidence.ts +20 -13
- package/src/results/attempt-source.ts +6 -3
- package/src/results/copy.ts +150 -60
- package/src/results/host-equivalence.test.ts +34 -20
- package/src/results/index.ts +12 -4
- package/src/results/locator.test.ts +1 -22
- package/src/results/open.ts +15 -5
- package/src/results/publish.ts +149 -0
- package/src/results/results.test.ts +89 -54
- package/src/results/select.ts +104 -34
- package/src/results/truncate.ts +90 -0
- package/src/results/types.ts +43 -14
- package/src/results/writer.ts +31 -13
- package/src/runner/attempt.test.ts +138 -7
- package/src/runner/attempt.ts +603 -104
- package/src/runner/discover.test.ts +47 -0
- package/src/runner/discover.ts +36 -2
- package/src/runner/eval-source.test.ts +1 -27
- package/src/runner/feedback/agent.test.ts +504 -0
- package/src/runner/feedback/agent.ts +409 -0
- package/src/runner/feedback/ci.test.ts +562 -0
- package/src/runner/feedback/ci.ts +401 -0
- package/src/runner/feedback/coordinator.test.ts +317 -0
- package/src/runner/feedback/coordinator.ts +397 -0
- package/src/runner/feedback/failure.ts +40 -0
- package/src/runner/feedback/human.test.ts +616 -0
- package/src/runner/feedback/human.ts +535 -0
- package/src/runner/feedback/index.ts +66 -0
- package/src/runner/feedback/io.ts +78 -0
- package/src/runner/feedback/profile.test.ts +50 -0
- package/src/runner/feedback/profile.ts +58 -0
- package/src/runner/feedback/reducer.test.ts +395 -0
- package/src/runner/feedback/reducer.ts +260 -0
- package/src/runner/feedback/renderer.ts +82 -0
- package/src/runner/feedback/sink.ts +203 -0
- package/src/runner/feedback/testing.ts +106 -0
- package/src/runner/ledger.test.ts +230 -0
- package/src/runner/ledger.ts +329 -0
- package/src/runner/report.test.ts +128 -3
- package/src/runner/report.ts +33 -9
- package/src/runner/reporters/artifacts.ts +8 -2
- package/src/runner/reporters/braintrust.test.ts +8 -7
- package/src/runner/reporters/braintrust.ts +9 -2
- package/src/runner/reporters/index.ts +2 -2
- package/src/runner/reporters/json.test.ts +162 -0
- package/src/runner/reporters/json.ts +35 -8
- package/src/runner/reporters/shared.ts +1 -5
- package/src/runner/run.test.ts +760 -3
- package/src/runner/run.ts +243 -37
- package/src/runner/sandbox-prep.ts +3 -42
- package/src/runner/timing.ts +158 -0
- package/src/runner/types.ts +518 -22
- package/src/sandbox/checkpoint.test.ts +55 -0
- package/src/sandbox/checkpoint.ts +29 -8
- package/src/sandbox/cli-commands.ts +407 -0
- package/src/sandbox/docker.ts +115 -16
- package/src/sandbox/e2b-agent-template.test.ts +56 -0
- package/src/sandbox/e2b-agent-template.ts +94 -0
- package/src/sandbox/e2b.ts +74 -9
- package/src/sandbox/errors.ts +111 -4
- package/src/sandbox/index.ts +2 -0
- package/src/sandbox/io-retry.test.ts +58 -0
- package/src/sandbox/io-retry.ts +45 -0
- package/src/sandbox/keep-registry.test.ts +86 -0
- package/src/sandbox/keep-registry.ts +142 -0
- package/src/sandbox/keep.ts +178 -0
- package/src/sandbox/paths.test.ts +1 -0
- package/src/sandbox/paths.ts +19 -8
- package/src/sandbox/registry.ts +20 -3
- package/src/sandbox/resolve.ts +76 -11
- package/src/sandbox/retry.test.ts +70 -0
- package/src/sandbox/retry.ts +46 -4
- package/src/sandbox/types.ts +44 -6
- package/src/sandbox/vercel.ts +43 -20
- package/src/scoring/collector.ts +60 -17
- package/src/scoring/coverage.ts +95 -0
- package/src/scoring/diff.ts +81 -0
- package/src/scoring/display.test.ts +121 -0
- package/src/scoring/display.ts +133 -0
- package/src/scoring/evidence.test.ts +189 -0
- package/src/scoring/judge.test.ts +142 -0
- package/src/scoring/judge.ts +15 -18
- package/src/scoring/scoped.ts +217 -50
- package/src/scoring/types.ts +117 -20
- package/src/scoring/verdict.ts +16 -4
- package/src/shared/aggregate.ts +8 -6
- package/src/shared/types.ts +31 -0
- package/src/show/compose.ts +50 -67
- package/src/show/index.ts +127 -56
- package/src/show/render.ts +662 -131
- package/src/show/report-host.test.ts +188 -0
- package/src/show/report-host.ts +375 -0
- package/src/show/show.test.ts +320 -54
- package/src/tty-line.ts +8 -26
- package/src/util.test.ts +1 -0
- package/src/util.ts +41 -0
- package/src/view/app/App.test.tsx +69 -0
- package/src/view/app/App.tsx +144 -48
- package/src/view/app/components/AttemptModal.tsx +423 -11
- package/src/view/app/components/CodeView.tsx +41 -14
- package/src/view/app/components/CopyControls.tsx +2 -2
- package/src/view/app/i18n.ts +37 -17
- package/src/view/app/lib/attempt-route.test.ts +1 -0
- package/src/view/app/lib/verdict.ts +7 -9
- package/src/view/app/main.tsx +13 -8
- package/src/view/app/pages/{RunsPage.tsx → AttemptsPage.tsx} +6 -6
- package/src/view/app/types.ts +4 -1
- package/src/view/artifact-serving.test.ts +2 -1
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +17 -17
- package/src/view/data.test.ts +10 -3
- package/src/view/data.ts +155 -49
- package/src/view/index.ts +56 -41
- package/src/view/server.ts +37 -15
- package/src/view/shared/types.ts +34 -5
- package/src/view/styles.css +227 -0
- package/src/view/view-report.test.ts +167 -62
- package/dist/report/built-ins/experiment-comparison.d.ts +0 -1
- package/dist/report/built-ins/experiment-comparison.js +0 -13
- package/dist/report/built-ins/index.d.ts +0 -1
- package/dist/report/built-ins/index.js +0 -2
- package/dist/report/react/GroupSummary.d.ts +0 -8
- package/dist/report/react/GroupSummary.js +0 -8
- package/dist/report/react/RunOverview.d.ts +0 -8
- package/dist/report/react/RunOverview.js +0 -12
- package/docs-site/zh/example/ai-agent-application.mdx +0 -152
- package/docs-site/zh/example/claude-code-codex-plugin.mdx +0 -167
- package/docs-site/zh/example/claude-code-codex-skill.mdx +0 -152
- package/docs-site/zh/example/showcase.mdx +0 -39
- package/docs-site/zh/guides/publish-report.mdx +0 -91
- package/docs-site/zh/guides/sandbox-providers.mdx +0 -102
- package/src/report/built-in-user-parity.test.tsx +0 -640
- package/src/report/built-ins/experiment-comparison.tsx +0 -19
- package/src/report/built-ins/index.ts +0 -2
- package/src/report/react/GroupSummary.tsx +0 -66
- package/src/report/react/RunOverview.tsx +0 -109
- package/src/runner/reporters/console.ts +0 -70
- package/src/runner/reporters/live.test.ts +0 -56
- package/src/runner/reporters/live.ts +0 -247
- package/src/runner/reporters/quiet.test.ts +0 -66
- package/src/runner/reporters/quiet.ts +0 -49
- package/src/runner/reporters/table.ts +0 -277
- /package/docs-site/zh/{example/tier1-ai-sdk-v7.mdx → examples/integrations/ai-sdk-v7.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-claude-sdk.mdx → examples/integrations/claude-sdk.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-codex-sdk.mdx → examples/integrations/codex-sdk.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-langgraph.mdx → examples/integrations/langgraph.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-pi-sdk.mdx → examples/integrations/pi-sdk.mdx} +0 -0
- /package/docs-site/zh/{guides → how-to}/fixtures.mdx +0 -0
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// (ExperimentList / EvalList / AttemptList)没有这个覆盖口子——它们的 locator 徽标恒经
|
|
9
|
-
// ctx.attemptHref / ctx.attemptCommand,不接受 attemptHref/attemptCommand prop(docs/feature/reports/library.md
|
|
10
|
-
// 「嵌入自己的 React 页面」的函数签名没有这个参数),证据室深链在这三个组件上不是可选行为。
|
|
11
|
-
import { defineComponent, isHostWebContextActive } from "./tree.js";
|
|
12
|
-
import { attemptListData, deltaData, evalListData, experimentListData, groupSummaryData, lineData, matrixData, overviewData, scatterData, scoreboardData, tableData, } from "./compute.js";
|
|
13
|
-
import { attemptListText, barsText, deltaText, evalListText, experimentListText, groupSummaryText, lineText, matrixText, overviewText, scatterText, scoreboardText, tableText, } from "./text/faces.js";
|
|
14
|
-
import { RunOverview as RunOverviewWeb } from "./react/RunOverview.js";
|
|
15
|
-
import { GroupSummary as GroupSummaryWeb } from "./react/GroupSummary.js";
|
|
2
|
+
import { defineComponent, isHostWebContextActive, memoFetchOf, } from "./tree.js";
|
|
3
|
+
import { attemptListData, deltaTableData, evalListData, experimentComparisonData, experimentListData, metricLineData, metricMatrixData, metricScatterData, metricTableData, scopeSummaryData, scoreboardData, } from "./compute.js";
|
|
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";
|
|
6
|
+
import { ScopeSummary as ScopeSummaryWeb } from "./react/ScopeSummary.js";
|
|
7
|
+
import { ExperimentComparisonView } from "./react/ExperimentComparison.js";
|
|
16
8
|
import { ExperimentList as ExperimentListWeb } from "./react/ExperimentList.js";
|
|
17
9
|
import { EvalList as EvalListWeb } from "./react/EvalList.js";
|
|
18
10
|
import { AttemptList as AttemptListWeb } from "./react/AttemptList.js";
|
|
@@ -23,110 +15,381 @@ import { Scoreboard as ScoreboardWeb } from "./react/Scoreboard.js";
|
|
|
23
15
|
import { MetricScatter as MetricScatterWeb } from "./react/MetricScatter.js";
|
|
24
16
|
import { MetricLine as MetricLineWeb } from "./react/MetricLine.js";
|
|
25
17
|
import { DeltaTable as DeltaTableWeb } from "./react/DeltaTable.js";
|
|
26
|
-
// ─────────────────────────
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"or precompute with `await MetricScatter.data(selection, options)` and pass the result as `data`.";
|
|
30
|
-
/** 渲染面(web / text)只吃已解析的数据形态;selection 形态漏解析时直说,而不是画一张空组件。 */
|
|
31
|
-
function requireScatterData(props) {
|
|
32
|
-
if (props.data === undefined)
|
|
33
|
-
throw new Error(SCATTER_UNRESOLVED_MESSAGE);
|
|
34
|
-
return props.data;
|
|
18
|
+
// ───────────────────────── data 结构校验(版本漂移防线)─────────────────────────
|
|
19
|
+
function isObject(value) {
|
|
20
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35
21
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
22
|
+
function isCell(value) {
|
|
23
|
+
return (isObject(value) &&
|
|
24
|
+
"value" in value &&
|
|
25
|
+
"display" in value &&
|
|
26
|
+
typeof value.samples === "number" &&
|
|
27
|
+
typeof value.total === "number" &&
|
|
28
|
+
Array.isArray(value.refs));
|
|
29
|
+
}
|
|
30
|
+
function isTally(value) {
|
|
31
|
+
return (isObject(value) &&
|
|
32
|
+
typeof value.passed === "number" &&
|
|
33
|
+
typeof value.failed === "number" &&
|
|
34
|
+
typeof value.errored === "number" &&
|
|
35
|
+
typeof value.skipped === "number");
|
|
36
|
+
}
|
|
37
|
+
function dataShapeError(component, dataFnName, shape, problem) {
|
|
38
|
+
return new Error(`<${component}> received data that does not match the current ${shape} shape: ${problem}. ` +
|
|
39
|
+
`It may have been computed by a different niceeval version (component data carries no schemaVersion; the support window is same-version write and read). ` +
|
|
40
|
+
`Recompute it with ${dataFnName}() from this niceeval version, then re-render.`);
|
|
41
|
+
}
|
|
42
|
+
const validateTableData = (data) => {
|
|
43
|
+
if (!isObject(data))
|
|
44
|
+
return "expected an object";
|
|
45
|
+
if (typeof data.rowDimension !== "string")
|
|
46
|
+
return 'missing "rowDimension" (string)';
|
|
47
|
+
if (!Array.isArray(data.columns))
|
|
48
|
+
return 'missing "columns" (array)';
|
|
49
|
+
if (!Array.isArray(data.rows))
|
|
50
|
+
return 'missing "rows" (array)';
|
|
51
|
+
for (const row of data.rows) {
|
|
52
|
+
if (!isObject(row) || typeof row.key !== "string" || !isObject(row.cells)) {
|
|
53
|
+
return 'each row needs { key, cells }';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
};
|
|
58
|
+
const validateMatrixData = (data) => {
|
|
59
|
+
if (!isObject(data))
|
|
60
|
+
return "expected an object";
|
|
61
|
+
if (typeof data.rowDimension !== "string" || typeof data.columnDimension !== "string") {
|
|
62
|
+
return 'missing "rowDimension" / "columnDimension" (string)';
|
|
63
|
+
}
|
|
64
|
+
if (!isObject(data.metric))
|
|
65
|
+
return 'missing "metric" (MetricColumn)';
|
|
66
|
+
if (!Array.isArray(data.cells))
|
|
67
|
+
return 'missing "cells" (array)';
|
|
68
|
+
return null;
|
|
69
|
+
};
|
|
70
|
+
const validateScatterData = (data) => {
|
|
71
|
+
if (!isObject(data))
|
|
72
|
+
return "expected an object";
|
|
73
|
+
if (typeof data.pointDimension !== "string")
|
|
74
|
+
return 'missing "pointDimension" (string)';
|
|
75
|
+
if (!isObject(data.x) || !isObject(data.y))
|
|
76
|
+
return 'missing "x" / "y" (MetricColumn)';
|
|
77
|
+
if (!Array.isArray(data.rows))
|
|
78
|
+
return 'missing "rows" (array)';
|
|
79
|
+
for (const row of data.rows) {
|
|
80
|
+
if (!isObject(row) || typeof row.key !== "string" || !isCell(row.x) || !isCell(row.y)) {
|
|
81
|
+
return "each row needs { key, x: MetricCell, y: MetricCell }";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
};
|
|
86
|
+
const validateLineData = (data) => {
|
|
87
|
+
if (!isObject(data))
|
|
88
|
+
return "expected an object";
|
|
89
|
+
if (!isObject(data.x) || typeof data.x.key !== "string")
|
|
90
|
+
return 'missing "x" axis descriptor';
|
|
91
|
+
if (!isObject(data.y))
|
|
92
|
+
return 'missing "y" (MetricColumn)';
|
|
93
|
+
if (!Array.isArray(data.rows))
|
|
94
|
+
return 'missing "rows" (array)';
|
|
95
|
+
return null;
|
|
96
|
+
};
|
|
97
|
+
const validateScoreboardData = (data) => {
|
|
98
|
+
if (!isObject(data))
|
|
99
|
+
return "expected an object";
|
|
100
|
+
if (typeof data.rowDimension !== "string")
|
|
101
|
+
return 'missing "rowDimension" (string)';
|
|
102
|
+
if (!Array.isArray(data.questions))
|
|
103
|
+
return 'missing "questions" (array)';
|
|
104
|
+
if (typeof data.fullMarks !== "number")
|
|
105
|
+
return 'missing "fullMarks" (number)';
|
|
106
|
+
if (typeof data.ignoredEvals !== "number")
|
|
107
|
+
return 'missing "ignoredEvals" (number)';
|
|
108
|
+
if (!Array.isArray(data.rows))
|
|
109
|
+
return 'missing "rows" (array)';
|
|
110
|
+
for (const row of data.rows) {
|
|
111
|
+
if (!isObject(row) || !isObject(row.total) || typeof row.total.notRun !== "number") {
|
|
112
|
+
return 'each row needs { key, total: { value, display, notRun, unscorable, refs }, subjects }';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
};
|
|
117
|
+
const validateDeltaData = (data) => {
|
|
118
|
+
if (!isObject(data))
|
|
119
|
+
return "expected an object";
|
|
120
|
+
if (typeof data.byDimension !== "string")
|
|
121
|
+
return 'missing "byDimension" (string)';
|
|
122
|
+
if (!Array.isArray(data.columns) || !Array.isArray(data.rows))
|
|
123
|
+
return 'missing "columns" / "rows" (array)';
|
|
124
|
+
for (const row of data.rows) {
|
|
125
|
+
if (!isObject(row) || row.label === undefined || !isObject(row.a) || !isObject(row.b)) {
|
|
126
|
+
return "each row needs { key, label, a, b, cells }";
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
};
|
|
131
|
+
const validateScopeSummaryData = (data) => {
|
|
132
|
+
if (!isObject(data))
|
|
133
|
+
return "expected an object";
|
|
134
|
+
if (!isObject(data.range))
|
|
135
|
+
return 'missing "range" ({ earliestStartedAt, latestStartedAt })';
|
|
136
|
+
if (!isTally(data.evalVerdicts) || !isTally(data.attemptVerdicts)) {
|
|
137
|
+
return 'missing "evalVerdicts" / "attemptVerdicts" tallies';
|
|
138
|
+
}
|
|
139
|
+
if (!isCell(data.endToEndPassRate) || !isCell(data.totalCostUSD)) {
|
|
140
|
+
return 'missing "endToEndPassRate" / "totalCostUSD" (MetricCell)';
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
};
|
|
144
|
+
const validateComparisonData = (data) => {
|
|
145
|
+
if (!isObject(data))
|
|
146
|
+
return "expected an object";
|
|
147
|
+
if (!Array.isArray(data.groups))
|
|
148
|
+
return 'missing "groups" (array)';
|
|
149
|
+
for (const group of data.groups) {
|
|
150
|
+
if (!isObject(group) || typeof group.key !== "string" || validateScopeSummaryData(group.summary) !== null) {
|
|
151
|
+
return "each group needs { key, summary, scatter, experiments }";
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
};
|
|
156
|
+
const validateExperimentListData = (data) => {
|
|
157
|
+
if (!Array.isArray(data))
|
|
158
|
+
return "expected an array of ExperimentListItem";
|
|
159
|
+
for (const item of data) {
|
|
160
|
+
if (!isObject(item) || typeof item.experimentId !== "string" || !isTally(item.evalVerdicts) || !isCell(item.endToEndPassRate)) {
|
|
161
|
+
return "each item needs { experimentId, evalVerdicts, endToEndPassRate, costUSD, durationMs, tokens, evalRows, … }";
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
};
|
|
166
|
+
const validateEvalListData = (data) => {
|
|
167
|
+
if (!Array.isArray(data))
|
|
168
|
+
return "expected an array of EvalListItem";
|
|
169
|
+
for (const item of data) {
|
|
170
|
+
if (!isObject(item) || typeof item.evalId !== "string" || !isCell(item.examScore) || !Array.isArray(item.attempts)) {
|
|
171
|
+
return "each item needs { experimentId, evalId, verdict, examScore, durationMs, costUSD, attempts }";
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
};
|
|
176
|
+
const validateAttemptListData = (data) => {
|
|
177
|
+
if (!Array.isArray(data))
|
|
178
|
+
return "expected an array of AttemptListItem";
|
|
179
|
+
for (const item of data) {
|
|
180
|
+
if (!isObject(item) || typeof item.evalId !== "string" || !("failureSummary" in item) || !("costUSD" in item)) {
|
|
181
|
+
return "each item needs { experimentId, evalId, verdict, failureSummary, moreFailures, examScore, durationMs, costUSD, locator }";
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
};
|
|
186
|
+
function makeDataComponent(def) {
|
|
187
|
+
const assertData = (data) => {
|
|
188
|
+
const problem = def.validate(data);
|
|
189
|
+
if (problem !== null)
|
|
190
|
+
throw dataShapeError(def.name, def.dataFnName, def.shapeName, problem);
|
|
191
|
+
return data;
|
|
192
|
+
};
|
|
193
|
+
const resolve = async (props, ctx) => {
|
|
194
|
+
const givenSpec = def.specKeys.filter((key) => props[key] !== undefined);
|
|
195
|
+
if (props.data !== undefined) {
|
|
196
|
+
if (givenSpec.length > 0 || props.input !== undefined) {
|
|
197
|
+
const extras = [...givenSpec, ...(props.input !== undefined ? ["input"] : [])];
|
|
198
|
+
throw new Error(`<${def.name}> got both \`data\` and spec field${extras.length > 1 ? "s" : ""} (${extras.join(", ")}) — the two data sources are exclusive and niceeval will not silently pick one. ` +
|
|
199
|
+
`Keep \`data\` (precomputed with ${def.dataFnName}()) and drop the spec fields, or drop \`data\` and let the pipeline compute from the spec.`);
|
|
200
|
+
}
|
|
201
|
+
assertData(props.data);
|
|
202
|
+
return props;
|
|
203
|
+
}
|
|
204
|
+
const options = {};
|
|
205
|
+
for (const key of givenSpec)
|
|
206
|
+
options[key] = props[key];
|
|
207
|
+
const input = props.input ?? ctx.input;
|
|
208
|
+
const data = await memoFetchOf(ctx)(def.dataFn, input, options, () => def.dataFn(input, options));
|
|
209
|
+
const rest = { ...props };
|
|
210
|
+
delete rest.input;
|
|
211
|
+
for (const key of def.specKeys)
|
|
212
|
+
delete rest[key];
|
|
213
|
+
return { ...rest, data };
|
|
214
|
+
};
|
|
215
|
+
const component = defineComponent({
|
|
216
|
+
resolve,
|
|
217
|
+
web: (props, ctx) => {
|
|
218
|
+
assertData(props.data);
|
|
219
|
+
return def.web(props, ctx);
|
|
220
|
+
},
|
|
221
|
+
text: (props, ctx) => {
|
|
222
|
+
assertData(props.data);
|
|
223
|
+
return def.text(props, ctx);
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
component.displayName = def.name;
|
|
227
|
+
return component;
|
|
228
|
+
}
|
|
229
|
+
/** 宿主内缺省接证据室,显式 prop 覆盖;宿主外不传 attemptHref 就是纯展示。 */
|
|
230
|
+
function hrefOf(props, ctx) {
|
|
231
|
+
return props.attemptHref ?? (isHostWebContextActive() ? ctx.attemptHref : undefined);
|
|
232
|
+
}
|
|
233
|
+
/** 范围摘要卡:时间窗、数量、两级计票、端到端成功率与总成本。 */
|
|
234
|
+
export const ScopeSummary = makeDataComponent({
|
|
235
|
+
name: "ScopeSummary",
|
|
236
|
+
dataFnName: "scopeSummaryData",
|
|
237
|
+
shapeName: "ScopeSummaryData",
|
|
238
|
+
dataFn: (input) => scopeSummaryData(input),
|
|
239
|
+
specKeys: [],
|
|
240
|
+
validate: validateScopeSummaryData,
|
|
241
|
+
web: (props, ctx) => _jsx(ScopeSummaryWeb, { ...props, locale: props.locale ?? ctx.locale }),
|
|
242
|
+
text: (props, ctx) => scopeSummaryText(props.data, props.votes ?? "eval", ctx),
|
|
243
|
+
});
|
|
63
244
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
245
|
+
* 内建报告的默认组合件:先把 input 按可比组分区,再为每组分别计算 ScopeSummary、
|
|
246
|
+
* 成本 × 端到端成功率散点和 ExperimentList。web 面持有完整组索引并一次聚焦一组;
|
|
247
|
+
* text 面命中多个组时只显示组索引与可执行的单组查看命令,命中单组时才输出完整散点与列表。
|
|
66
248
|
*/
|
|
67
|
-
export const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
249
|
+
export const ExperimentComparison = makeDataComponent({
|
|
250
|
+
name: "ExperimentComparison",
|
|
251
|
+
dataFnName: "experimentComparisonData",
|
|
252
|
+
shapeName: "ExperimentComparisonData",
|
|
253
|
+
dataFn: (input) => experimentComparisonData(input),
|
|
254
|
+
specKeys: [],
|
|
255
|
+
validate: validateComparisonData,
|
|
256
|
+
web: (props, ctx) => (_jsx(ExperimentComparisonView, { data: props.data, locale: props.locale ?? ctx.locale, className: props.className, attemptHref: isHostWebContextActive() ? ctx.attemptHref : undefined })),
|
|
257
|
+
text: (props, ctx) => experimentComparisonText(props.data, props.className, ctx),
|
|
258
|
+
});
|
|
259
|
+
/** 实验列表:每项一个 experiment,固定八列比较表 + 展开到 Eval / Attempt。 */
|
|
260
|
+
export const ExperimentList = makeDataComponent({
|
|
261
|
+
name: "ExperimentList",
|
|
262
|
+
dataFnName: "experimentListData",
|
|
263
|
+
shapeName: "ExperimentListItem[]",
|
|
264
|
+
dataFn: (input, options) => experimentListData(input, options),
|
|
265
|
+
specKeys: ["redact"],
|
|
266
|
+
validate: validateExperimentListData,
|
|
267
|
+
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
|
+
text: (props, ctx) => experimentListText(props.data, ctx, props.relativeTo),
|
|
269
|
+
});
|
|
270
|
+
/** Eval 列表:每项一个 experimentId + evalId,展开到这道题的 Attempt。 */
|
|
271
|
+
export const EvalList = makeDataComponent({
|
|
272
|
+
name: "EvalList",
|
|
273
|
+
dataFnName: "evalListData",
|
|
274
|
+
shapeName: "EvalListItem[]",
|
|
275
|
+
dataFn: (input, options) => evalListData(input, options),
|
|
276
|
+
specKeys: ["redact"],
|
|
277
|
+
validate: validateEvalListData,
|
|
278
|
+
web: (props, ctx) => (_jsx(EvalListWeb, { data: props.data, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx) ?? ctx.attemptHref, className: props.className })),
|
|
279
|
+
text: (props, ctx) => evalListText(props.data, ctx),
|
|
280
|
+
});
|
|
281
|
+
/** Attempt 列表:实体列表的叶子层,每项一次 attempt 的判定、单行摘要与 locator。 */
|
|
282
|
+
export const AttemptList = makeDataComponent({
|
|
283
|
+
name: "AttemptList",
|
|
284
|
+
dataFnName: "attemptListData",
|
|
285
|
+
shapeName: "AttemptListItem[]",
|
|
286
|
+
dataFn: (input, options) => attemptListData(input, options),
|
|
287
|
+
specKeys: ["redact"],
|
|
288
|
+
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 })),
|
|
290
|
+
text: (props, ctx) => attemptListText(props.data, props.total, ctx),
|
|
291
|
+
});
|
|
72
292
|
/**
|
|
73
|
-
*
|
|
74
|
-
* (
|
|
75
|
-
*
|
|
293
|
+
* 「现在有哪些失败要处理」的成品组合件:内部就是 attemptListData → 过滤 → AttemptList
|
|
294
|
+
* data 形态,与手写组合严格等价、没有私有能力(docs/feature/reports/library/entity-lists.md)。
|
|
295
|
+
* verdict ∈ failed / errored,按 attempt 开始时间降序(同刻按 locator 字典序),
|
|
296
|
+
* 截断到 limit(默认 20),total 报告截断前总数。
|
|
76
297
|
*/
|
|
77
|
-
export const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
298
|
+
export const FailureList = defineComponent(async (props, ctx) => {
|
|
299
|
+
const input = props.input ?? ctx.scope;
|
|
300
|
+
const all = await attemptListData(input, props.redact !== undefined ? { redact: props.redact } : undefined);
|
|
301
|
+
// attempt 开始时间不在列表条目里(它不是列表展示字段);从同一 input 的读取面按 locator 对回。
|
|
302
|
+
const startedAtByLocator = new Map();
|
|
303
|
+
for (const item of collectItems(resolveInput(input).snapshots)) {
|
|
304
|
+
startedAtByLocator.set(locatorOf(item), item.attempt.result.startedAt ?? "");
|
|
305
|
+
}
|
|
306
|
+
const failures = all
|
|
307
|
+
.filter((item) => item.verdict === "failed" || item.verdict === "errored")
|
|
308
|
+
.sort((a, b) => {
|
|
309
|
+
const ta = startedAtByLocator.get(a.locator) ?? "";
|
|
310
|
+
const tb = startedAtByLocator.get(b.locator) ?? "";
|
|
311
|
+
if (ta !== tb)
|
|
312
|
+
return ta < tb ? 1 : -1; // 最近的失败在前
|
|
313
|
+
return a.locator < b.locator ? -1 : a.locator > b.locator ? 1 : 0;
|
|
314
|
+
});
|
|
315
|
+
const limit = props.limit ?? 20;
|
|
316
|
+
return (_jsx(AttemptList, { data: failures.slice(0, limit), total: failures.length, attemptHref: props.attemptHref, locale: props.locale, className: props.className }));
|
|
317
|
+
});
|
|
318
|
+
FailureList.displayName = "FailureList";
|
|
82
319
|
/** 榜单:一行一个维度值、一列一个指标,回答「谁整体更好」。 */
|
|
83
|
-
export const MetricTable =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
320
|
+
export const MetricTable = makeDataComponent({
|
|
321
|
+
name: "MetricTable",
|
|
322
|
+
dataFnName: "metricTableData",
|
|
323
|
+
shapeName: "TableData",
|
|
324
|
+
dataFn: metricTableData,
|
|
325
|
+
specKeys: ["rows", "columns", "sort", "evals"],
|
|
326
|
+
validate: validateTableData,
|
|
327
|
+
web: (props, ctx) => (_jsx(MetricTableWeb, { data: props.data, filter: props.filter, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx), className: props.className })),
|
|
328
|
+
text: (props, ctx) => tableText(props.data, ctx),
|
|
329
|
+
});
|
|
88
330
|
/** 逐题格子:行 × 列两个维度、格子里一个指标,回答「哪道题谁挂了」。 */
|
|
89
|
-
export const MetricMatrix =
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
web: (props, ctx) => (_jsx(
|
|
97
|
-
text: (
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
export const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
web: (props, ctx) => _jsx(
|
|
130
|
-
text: (
|
|
131
|
-
})
|
|
132
|
-
|
|
331
|
+
export const MetricMatrix = makeDataComponent({
|
|
332
|
+
name: "MetricMatrix",
|
|
333
|
+
dataFnName: "metricMatrixData",
|
|
334
|
+
shapeName: "MatrixData",
|
|
335
|
+
dataFn: metricMatrixData,
|
|
336
|
+
specKeys: ["rows", "columns", "cell", "evals"],
|
|
337
|
+
validate: validateMatrixData,
|
|
338
|
+
web: (props, ctx) => (_jsx(MetricMatrixWeb, { data: props.data, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx), className: props.className })),
|
|
339
|
+
text: (props, ctx) => matrixText(props.data, ctx),
|
|
340
|
+
});
|
|
341
|
+
/** 分组条形:同一份矩阵数据的另一种摆法;与 MetricMatrix 写同一份 spec 时只计算一次。 */
|
|
342
|
+
export const MetricBars = makeDataComponent({
|
|
343
|
+
name: "MetricBars",
|
|
344
|
+
dataFnName: "metricMatrixData",
|
|
345
|
+
shapeName: "MatrixData",
|
|
346
|
+
dataFn: metricMatrixData,
|
|
347
|
+
specKeys: ["rows", "columns", "cell", "evals"],
|
|
348
|
+
validate: validateMatrixData,
|
|
349
|
+
web: (props, ctx) => (_jsx(MetricBarsWeb, { data: props.data, locale: props.locale ?? ctx.locale, attemptHref: hrefOf(props, ctx), className: props.className })),
|
|
350
|
+
text: (props, ctx) => barsText(props.data, ctx),
|
|
351
|
+
});
|
|
352
|
+
/** 考试成绩单:总分 + 分科小计,固定分母、notRun / unscorable 分开如实报。 */
|
|
353
|
+
export const Scoreboard = makeDataComponent({
|
|
354
|
+
name: "Scoreboard",
|
|
355
|
+
dataFnName: "scoreboardData",
|
|
356
|
+
shapeName: "ScoreboardData",
|
|
357
|
+
dataFn: scoreboardData,
|
|
358
|
+
specKeys: ["rows", "questions", "subject", "weights", "fullMarks", "score"],
|
|
359
|
+
validate: validateScoreboardData,
|
|
360
|
+
web: (props, ctx) => _jsx(ScoreboardWeb, { data: props.data, locale: props.locale ?? ctx.locale, className: props.className }),
|
|
361
|
+
text: (props, ctx) => scoreboardText(props.data, ctx),
|
|
362
|
+
});
|
|
363
|
+
/** 两个指标之间的取舍:每个点一个维度值,x / y 各一个指标,series 只决定颜色和分组。 */
|
|
364
|
+
export const MetricScatter = makeDataComponent({
|
|
365
|
+
name: "MetricScatter",
|
|
366
|
+
dataFnName: "metricScatterData",
|
|
367
|
+
shapeName: "ScatterData",
|
|
368
|
+
dataFn: metricScatterData,
|
|
369
|
+
specKeys: ["points", "series", "x", "y", "evals"],
|
|
370
|
+
validate: validateScatterData,
|
|
371
|
+
web: (props, ctx) => (_jsx(MetricScatterWeb, { data: props.data, pointHref: props.pointHref, locale: props.locale ?? ctx.locale, className: props.className })),
|
|
372
|
+
text: (props, ctx) => scatterText(props.data, ctx),
|
|
373
|
+
});
|
|
374
|
+
/** 趋势线:x 是 NumericAxis(参数轴),点身份 = (series, x)。 */
|
|
375
|
+
export const MetricLine = makeDataComponent({
|
|
376
|
+
name: "MetricLine",
|
|
377
|
+
dataFnName: "metricLineData",
|
|
378
|
+
shapeName: "LineData",
|
|
379
|
+
dataFn: metricLineData,
|
|
380
|
+
specKeys: ["x", "series", "y", "evals"],
|
|
381
|
+
validate: validateLineData,
|
|
382
|
+
web: (props, ctx) => (_jsx(MetricLineWeb, { data: props.data, pointHref: props.pointHref, locale: props.locale ?? ctx.locale, className: props.className })),
|
|
383
|
+
text: (props, ctx) => lineText(props.data, ctx),
|
|
384
|
+
});
|
|
385
|
+
/** 成对对比:每行一对(字面声明或 pairsByFlag 派生),格子里 A、B、Δ 三个值。 */
|
|
386
|
+
export const DeltaTable = makeDataComponent({
|
|
387
|
+
name: "DeltaTable",
|
|
388
|
+
dataFnName: "deltaTableData",
|
|
389
|
+
shapeName: "DeltaData",
|
|
390
|
+
dataFn: deltaTableData,
|
|
391
|
+
specKeys: ["by", "pairs", "metrics", "evals"],
|
|
392
|
+
validate: validateDeltaData,
|
|
393
|
+
web: (props, ctx) => _jsx(DeltaTableWeb, { data: props.data, locale: props.locale ?? ctx.locale, className: props.className }),
|
|
394
|
+
text: (props, ctx) => deltaText(props.data, ctx),
|
|
395
|
+
});
|