niceeval 0.9.0 → 0.10.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 +31 -33
- package/dist/agents/types.d.ts +20 -17
- package/dist/context/types.d.ts +21 -21
- package/dist/i18n/en.d.ts +10 -2
- package/dist/i18n/zh-CN.d.ts +15 -7
- package/dist/o11y/execution-tree.d.ts +103 -0
- package/dist/o11y/otlp/select.d.ts +22 -0
- package/dist/report/{react → assets}/colors.d.ts +8 -0
- package/dist/report/{react → assets}/colors.js +23 -0
- package/dist/report/built-in/index.d.ts +2 -2
- package/dist/report/built-in/index.js +2 -2
- package/dist/report/built-in/standard.d.ts +8 -1
- package/dist/report/built-in/standard.js +17 -7
- package/dist/report/components/attempt-detail/AttemptAssertions.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptAssertions.js +17 -0
- package/dist/report/components/attempt-detail/AttemptConversation.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptConversation.js +34 -0
- package/dist/report/components/attempt-detail/AttemptDiagnostics.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptDiagnostics.js +7 -0
- package/dist/report/components/attempt-detail/AttemptDiff.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptDiff.js +11 -0
- package/dist/report/components/attempt-detail/AttemptError.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptError.js +16 -0
- package/dist/report/components/attempt-detail/AttemptFixPrompt.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptFixPrompt.js +7 -0
- package/dist/report/components/attempt-detail/AttemptSource.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptSource.js +27 -0
- package/dist/report/components/attempt-detail/AttemptSummary.d.ts +8 -0
- package/dist/report/components/attempt-detail/AttemptSummary.js +20 -0
- package/dist/report/components/attempt-detail/AttemptTimeline.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptTimeline.js +28 -0
- package/dist/report/components/attempt-detail/AttemptTrace.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptTrace.js +29 -0
- package/dist/report/components/attempt-detail/AttemptUsage.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptUsage.js +20 -0
- package/dist/report/components/attempt-detail/compute.d.ts +24 -0
- package/dist/report/components/attempt-detail/compute.js +254 -0
- package/dist/report/components/attempt-detail/faces.d.ts +14 -0
- package/dist/report/components/attempt-detail/faces.js +235 -0
- package/dist/report/components/attempt-detail/index.d.ts +38 -0
- package/dist/report/components/attempt-detail/index.js +527 -0
- package/dist/report/{react → components}/cell.d.ts +5 -3
- package/dist/report/{react → components}/cell.js +3 -3
- package/dist/report/{react → components/entity-lists}/AttemptList.d.ts +8 -4
- package/dist/report/{react → components/entity-lists}/AttemptList.js +16 -10
- package/dist/report/{react → components/entity-lists}/EvalList.d.ts +3 -3
- package/dist/report/{react → components/entity-lists}/EvalList.js +0 -0
- package/dist/report/{react → components/entity-lists}/ExperimentList.d.ts +3 -3
- package/dist/report/{react → components/entity-lists}/ExperimentList.js +10 -10
- package/dist/report/components/entity-lists/compute.d.ts +23 -0
- package/dist/report/components/entity-lists/compute.js +171 -0
- package/dist/report/components/entity-lists/faces.d.ts +5 -0
- package/dist/report/components/entity-lists/faces.js +174 -0
- package/dist/report/components/entity-lists/index.d.ts +51 -0
- package/dist/report/components/entity-lists/index.js +165 -0
- package/dist/report/{react → components}/fixtures.d.ts +2 -2
- package/dist/report/{react → components}/fixtures.js +1 -1
- package/dist/report/{react → components/metric-views}/DeltaTable.d.ts +2 -2
- package/dist/report/{react → components/metric-views}/DeltaTable.js +4 -4
- package/dist/report/{react → components/metric-views}/MetricBars.d.ts +3 -3
- package/dist/report/{react → components/metric-views}/MetricBars.js +3 -3
- package/dist/report/{react → components/metric-views}/MetricLine.d.ts +2 -2
- package/dist/report/{react → components/metric-views}/MetricLine.js +8 -5
- package/dist/report/{react → components/metric-views}/MetricMatrix.d.ts +3 -3
- package/dist/report/{react → components/metric-views}/MetricMatrix.js +4 -4
- package/dist/report/components/metric-views/MetricScatter.d.ts +11 -0
- package/dist/report/{react → components/metric-views}/MetricScatter.js +26 -23
- package/dist/report/{react → components/metric-views}/MetricTable.d.ts +3 -3
- package/dist/report/{react → components/metric-views}/MetricTable.js +4 -4
- package/dist/report/{react → components/metric-views}/Scoreboard.d.ts +2 -2
- package/dist/report/{react → components/metric-views}/Scoreboard.js +3 -3
- package/dist/report/components/metric-views/compute.d.ts +89 -0
- package/dist/report/{compute.js → components/metric-views/compute.js} +32 -415
- package/dist/report/components/metric-views/faces.d.ts +13 -0
- package/dist/report/components/metric-views/faces.js +381 -0
- package/dist/report/components/metric-views/index.d.ts +50 -0
- package/dist/report/components/metric-views/index.js +273 -0
- package/dist/report/{text → components/metric-views}/plot.js +1 -1
- package/dist/report/components/shared-compute.d.ts +22 -0
- package/dist/report/components/shared-compute.js +47 -0
- package/dist/report/components/shared-faces.d.ts +9 -0
- package/dist/report/components/shared-faces.js +26 -0
- package/dist/report/components/shared.d.ts +68 -0
- package/dist/report/components/shared.js +125 -0
- package/dist/report/{react → components/site-components}/CopyFixPrompt.d.ts +2 -2
- package/dist/report/{react → components/site-components}/CopyFixPrompt.js +2 -2
- package/dist/report/{react → components/site-components}/HeroCard.d.ts +2 -2
- package/dist/report/{react → components/site-components}/HeroCard.js +2 -2
- package/dist/report/{react → components/site-components}/ScopeWarnings.d.ts +2 -2
- package/dist/report/{react → components/site-components}/ScopeWarnings.js +3 -3
- package/dist/report/{react → components/site-components}/TraceWaterfall.d.ts +3 -3
- package/dist/report/{react → components/site-components}/TraceWaterfall.js +5 -5
- package/dist/report/components/site-components/compute.d.ts +28 -0
- package/dist/report/components/site-components/compute.js +132 -0
- package/dist/report/components/site-components/faces.d.ts +21 -0
- package/dist/report/components/site-components/faces.js +75 -0
- package/dist/report/components/site-components/index.d.ts +74 -0
- package/dist/report/components/site-components/index.js +220 -0
- package/dist/report/{scope-warnings.d.ts → components/site-components/scope-warnings.d.ts} +2 -2
- package/dist/report/{scope-warnings.js → components/site-components/scope-warnings.js} +2 -2
- package/dist/report/{react → components/summaries}/ScopeSummary.d.ts +2 -2
- package/dist/report/{react → components/summaries}/ScopeSummary.js +17 -8
- package/dist/report/components/summaries/compute.d.ts +7 -0
- package/dist/report/components/summaries/compute.js +51 -0
- package/dist/report/components/summaries/faces.d.ts +7 -0
- package/dist/report/components/summaries/faces.js +38 -0
- package/dist/report/components/summaries/index.d.ts +27 -0
- package/dist/report/components/summaries/index.js +78 -0
- package/dist/report/definition/grid-layout.d.ts +50 -0
- package/dist/report/definition/grid-layout.js +89 -0
- package/dist/report/{primitives.d.ts → definition/primitives.d.ts} +34 -4
- package/dist/report/{primitives.js → definition/primitives.js} +101 -10
- package/dist/report/{report.d.ts → definition/report.d.ts} +36 -65
- package/dist/report/{report.js → definition/report.js} +58 -90
- package/dist/report/{text/table.d.ts → definition/table-text.d.ts} +2 -2
- package/dist/report/{text/table.js → definition/table-text.js} +2 -2
- package/dist/report/{tree.d.ts → definition/tree.d.ts} +44 -12
- package/dist/report/{tree.js → definition/tree.js} +10 -12
- package/dist/report/index.d.ts +33 -18
- package/dist/report/index.js +23 -14
- package/dist/report/{aggregate.d.ts → model/aggregate.d.ts} +12 -4
- package/dist/report/{aggregate.js → model/aggregate.js} +28 -8
- package/dist/report/{flag.d.ts → model/flag.d.ts} +14 -1
- package/dist/report/{flag.js → model/flag.js} +35 -0
- package/dist/report/{format.d.ts → model/format.d.ts} +11 -5
- package/dist/report/{format.js → model/format.js} +48 -4
- package/dist/report/{locale.d.ts → model/locale.d.ts} +17 -17
- package/dist/report/{locale.js → model/locale.js} +31 -33
- package/dist/report/{metrics.d.ts → model/metrics.d.ts} +2 -2
- package/dist/report/{metrics.js → model/metrics.js} +2 -2
- package/dist/report/{types.d.ts → model/types.d.ts} +140 -20
- package/dist/report/react/index.d.ts +32 -21
- package/dist/report/react/index.js +33 -21
- package/dist/report/{load.d.ts → runtime/load.d.ts} +1 -1
- package/dist/report/{load.js → runtime/load.js} +1 -1
- package/dist/report/runtime/text.d.ts +67 -0
- package/dist/report/runtime/text.js +114 -0
- package/dist/report/runtime/web.d.ts +35 -0
- package/dist/report/runtime/web.js +70 -0
- package/dist/results/annotated-source.d.ts +87 -0
- package/dist/results/attempt-evidence.d.ts +74 -0
- package/dist/results/attempt-source.d.ts +15 -0
- package/dist/results/select.d.ts +12 -2
- package/dist/results/select.js +27 -5
- package/dist/runner/eval-selection.d.ts +26 -0
- package/dist/runner/feedback/sink.d.ts +26 -1
- package/dist/runner/types.d.ts +149 -23
- package/dist/sandbox/docker.d.ts +6 -0
- package/dist/sandbox/types.d.ts +23 -21
- package/dist/scoring/display.d.ts +7 -2
- package/dist/scoring/display.js +42 -4
- package/dist/scoring/types.d.ts +3 -3
- package/dist/shared/aggregate.d.ts +15 -1
- package/dist/shared/aggregate.js +32 -1
- package/dist/shared/types.d.ts +6 -1
- package/docs-site/images/logo-dark.svg +7 -0
- package/docs-site/images/logo.svg +6 -5
- package/docs-site/zh/README.md +8 -7
- package/docs-site/zh/examples/ai-agent-application.mdx +5 -5
- package/docs-site/zh/examples/coding-agent-extensions.mdx +4 -4
- package/docs-site/zh/examples/index.mdx +3 -3
- package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +1 -1
- package/docs-site/zh/examples/integrations/claude-sdk.mdx +3 -3
- package/docs-site/zh/examples/integrations/codex-sdk.mdx +3 -3
- package/docs-site/zh/examples/integrations/langgraph.mdx +3 -3
- package/docs-site/zh/examples/integrations/pi-sdk.mdx +2 -2
- package/docs-site/zh/explanation/adapter.mdx +19 -19
- package/docs-site/zh/explanation/assert.mdx +9 -9
- package/docs-site/zh/explanation/drive.mdx +4 -4
- package/docs-site/zh/explanation/evals.mdx +8 -8
- package/docs-site/zh/explanation/experiment.mdx +8 -8
- package/docs-site/zh/explanation/hitl.mdx +13 -13
- package/docs-site/zh/explanation/judge.mdx +3 -3
- package/docs-site/zh/explanation/overview.mdx +7 -7
- package/docs-site/zh/explanation/runner.mdx +11 -11
- package/docs-site/zh/explanation/tier.mdx +6 -6
- package/docs-site/zh/index.mdx +14 -14
- package/docs-site/zh/introduction.mdx +13 -16
- package/docs-site/zh/reference/builtin-agents.mdx +61 -28
- package/docs-site/zh/reference/capabilities.mdx +7 -27
- package/docs-site/zh/reference/cli.mdx +35 -32
- package/docs-site/zh/reference/define-agent.mdx +32 -31
- package/docs-site/zh/reference/define-config.mdx +6 -6
- package/docs-site/zh/reference/define-eval.mdx +33 -20
- package/docs-site/zh/reference/events.mdx +4 -4
- package/docs-site/zh/reference/expect.mdx +3 -3
- package/docs-site/zh/reference/official-adapters.mdx +17 -17
- package/docs-site/zh/reference/report-components.mdx +193 -121
- package/docs-site/zh/reference/results-data.mdx +13 -13
- package/docs-site/zh/troubleshooting/debug-sandbox.mdx +11 -11
- package/docs-site/zh/troubleshooting/debugging.mdx +43 -19
- package/docs-site/zh/{how-to → tutorials}/agent-feedback-loop.mdx +38 -38
- package/docs-site/zh/tutorials/agent-onboarding.mdx +100 -0
- package/docs-site/zh/tutorials/authoring.mdx +211 -0
- package/docs-site/zh/{how-to → tutorials}/ci-integration.mdx +8 -8
- package/docs-site/zh/{how-to → tutorials}/connect-otel.mdx +22 -22
- package/docs-site/zh/{how-to → tutorials}/connect-your-agent.mdx +58 -63
- package/docs-site/zh/tutorials/custom-reports.mdx +453 -0
- package/docs-site/zh/{how-to → tutorials}/dataset-fanout.mdx +4 -4
- package/docs-site/zh/tutorials/experiments.mdx +103 -0
- package/docs-site/zh/{how-to → tutorials}/fixtures.mdx +9 -9
- package/docs-site/zh/{how-to → tutorials}/publish-report.mdx +11 -5
- package/docs-site/zh/tutorials/quickstart.mdx +18 -18
- package/docs-site/zh/{how-to → tutorials}/reporters.mdx +6 -6
- package/docs-site/zh/{how-to → tutorials}/sandbox-agent.mdx +6 -6
- package/docs-site/zh/{how-to → tutorials}/sandbox-providers.mdx +41 -19
- package/docs-site/zh/{how-to → tutorials}/scoring-guide.mdx +4 -4
- package/docs-site/zh/{how-to → tutorials}/viewing-results.mdx +59 -50
- package/docs-site/zh/tutorials/write-experiment.mdx +355 -0
- package/docs-site/zh/{how-to → tutorials}/write-send.mdx +40 -40
- package/package.json +8 -4
- package/src/agents/bub.ts +21 -8
- package/src/agents/claude-code.ts +23 -10
- package/src/agents/codex.test.ts +22 -7
- package/src/agents/codex.ts +22 -9
- package/src/agents/index.ts +2 -2
- package/src/agents/openai-compat.ts +1 -1
- package/src/agents/post-setup.ts +45 -22
- package/src/agents/streaming.ts +1 -1
- package/src/agents/types.ts +20 -17
- package/src/agents/ui-message-stream.test.ts +10 -0
- package/src/agents/ui-message-stream.ts +12 -1
- package/src/cli.ts +77 -64
- package/src/context/types.ts +21 -21
- package/src/define.ts +13 -0
- package/src/i18n/en.ts +30 -15
- package/src/i18n/zh-CN.ts +30 -15
- package/src/index.ts +2 -0
- package/src/report/{react → assets}/colors.ts +22 -0
- package/src/report/{react → assets}/enhance.js +1 -33
- package/src/report/{react → assets}/styles.css +136 -112
- package/src/report/built-in/index.tsx +2 -2
- package/src/report/built-in/standard.tsx +18 -6
- package/src/report/components/attempt-detail/AttemptAssertions.tsx +67 -0
- package/src/report/components/attempt-detail/AttemptConversation.tsx +110 -0
- package/src/report/components/attempt-detail/AttemptDiagnostics.tsx +38 -0
- package/src/report/components/attempt-detail/AttemptDiff.tsx +35 -0
- package/src/report/components/attempt-detail/AttemptError.tsx +31 -0
- package/src/report/components/attempt-detail/AttemptFixPrompt.tsx +26 -0
- package/src/report/components/attempt-detail/AttemptSource.tsx +80 -0
- package/src/report/components/attempt-detail/AttemptSummary.tsx +74 -0
- package/src/report/components/attempt-detail/AttemptTimeline.tsx +108 -0
- package/src/report/components/attempt-detail/AttemptTrace.tsx +63 -0
- package/src/report/components/attempt-detail/AttemptUsage.tsx +29 -0
- package/src/report/components/attempt-detail/attempt-components.test.tsx +680 -0
- package/src/report/components/attempt-detail/compute.ts +287 -0
- package/src/report/components/attempt-detail/faces.ts +257 -0
- package/src/report/components/attempt-detail/index.tsx +583 -0
- package/src/report/components/attempt-detail/validate.test.ts +235 -0
- package/src/report/{react → components}/cell.tsx +6 -3
- package/src/report/{report.test.ts → components/compute.test.ts} +316 -46
- package/src/report/{react → components/entity-lists}/AttemptList.tsx +24 -16
- package/src/report/{react → components/entity-lists}/EvalList.tsx +0 -0
- package/src/report/{react → components/entity-lists}/ExperimentList.tsx +23 -20
- package/src/report/components/entity-lists/compute.ts +196 -0
- package/src/report/components/entity-lists/faces.ts +207 -0
- package/src/report/components/entity-lists/index.tsx +241 -0
- package/src/report/components/entity-lists/validate.test.ts +114 -0
- package/src/report/{react → components}/fixtures.ts +2 -2
- package/src/report/{react → components/metric-views}/DeltaTable.tsx +5 -5
- package/src/report/{react → components/metric-views}/MetricBars.tsx +5 -5
- package/src/report/{react → components/metric-views}/MetricLine.tsx +9 -6
- package/src/report/{react → components/metric-views}/MetricMatrix.tsx +6 -6
- package/src/report/{react → components/metric-views}/MetricScatter.tsx +41 -33
- package/src/report/{react → components/metric-views}/MetricTable.tsx +6 -6
- package/src/report/{react → components/metric-views}/Scoreboard.tsx +4 -4
- package/src/report/{compute.ts → components/metric-views/compute.ts} +51 -477
- package/src/report/components/metric-views/faces.ts +423 -0
- package/src/report/components/metric-views/index.tsx +352 -0
- package/src/report/{text → components/metric-views}/plot.ts +1 -1
- package/src/report/components/metric-views/validate.test.ts +211 -0
- package/src/report/{react → components}/render.test.tsx +47 -17
- package/src/report/components/shared-compute.ts +59 -0
- package/src/report/components/shared-faces.ts +30 -0
- package/src/report/components/shared.ts +192 -0
- package/src/report/{react → components/site-components}/CopyFixPrompt.tsx +3 -3
- package/src/report/{react → components/site-components}/HeroCard.tsx +3 -3
- package/src/report/{react → components/site-components}/ScopeWarnings.tsx +4 -4
- package/src/report/{react → components/site-components}/TraceWaterfall.tsx +13 -10
- package/src/report/components/site-components/compute.ts +144 -0
- package/src/report/components/site-components/faces.ts +80 -0
- package/src/report/components/site-components/index.tsx +265 -0
- package/src/report/{scope-warnings.ts → components/site-components/scope-warnings.ts} +3 -3
- package/src/report/{site-components.test.tsx → components/site-components/site-components.test.tsx} +23 -21
- package/src/report/components/site-components/validate.test.ts +89 -0
- package/src/report/{react → components/summaries}/ScopeSummary.tsx +26 -11
- package/src/report/components/summaries/compute.ts +56 -0
- package/src/report/components/summaries/faces.ts +48 -0
- package/src/report/components/summaries/index.tsx +127 -0
- package/src/report/components/summaries/validate.test.ts +49 -0
- package/src/report/definition/grid-layout.test.ts +124 -0
- package/src/report/definition/grid-layout.ts +146 -0
- package/src/report/{primitives.tsx → definition/primitives.tsx} +168 -18
- package/src/report/{report.ts → definition/report.ts} +98 -165
- package/src/report/{shell-head.test.ts → definition/shell-head.test.ts} +2 -2
- package/src/report/{text/table.ts → definition/table-text.ts} +4 -4
- package/src/report/{tree.ts → definition/tree.ts} +58 -22
- package/src/report/index.ts +126 -66
- package/src/report/{aggregate.ts → model/aggregate.ts} +31 -9
- package/src/report/{flag.ts → model/flag.ts} +39 -1
- package/src/report/{format.ts → model/format.ts} +59 -5
- package/src/report/{locale.ts → model/locale.ts} +34 -36
- package/src/report/{metrics.ts → model/metrics.ts} +3 -3
- package/src/report/{types.ts → model/types.ts} +143 -22
- package/src/report/react/index.tsx +52 -26
- package/src/report/{dual-render.test.tsx → runtime/dual-render.test.tsx} +564 -49
- package/src/report/runtime/host.test.ts +44 -0
- package/src/report/runtime/host.ts +138 -0
- package/src/report/{load.ts → runtime/load.ts} +1 -1
- package/src/report/runtime/text.ts +192 -0
- package/src/report/runtime/web.ts +106 -0
- package/src/results/attempt-evidence.ts +5 -1
- package/src/results/host-equivalence.test.ts +54 -3
- package/src/results/select.ts +30 -6
- package/src/runner/attempt.test.ts +48 -1
- package/src/runner/attempt.ts +62 -42
- package/src/runner/cleanup-timeout.test.ts +16 -0
- package/src/runner/cleanup-timeout.ts +23 -0
- package/src/runner/discover.ts +1 -2
- package/src/runner/eval-selection.test.ts +187 -0
- package/src/runner/eval-selection.ts +109 -0
- package/src/runner/experiment-cleanup-registry.test.ts +89 -0
- package/src/runner/experiment-cleanup-registry.ts +39 -0
- package/src/runner/experiment-labels.test.ts +71 -0
- package/src/runner/feedback/agent.test.ts +33 -1
- package/src/runner/feedback/agent.ts +12 -16
- package/src/runner/feedback/ci.test.ts +35 -1
- package/src/runner/feedback/ci.ts +16 -18
- package/src/runner/feedback/coordinator.ts +28 -0
- package/src/runner/feedback/human.test.ts +108 -1
- package/src/runner/feedback/human.ts +71 -21
- package/src/runner/feedback/reducer.test.ts +64 -0
- package/src/runner/feedback/reducer.ts +26 -0
- package/src/runner/feedback/sink.ts +40 -1
- package/src/runner/fingerprint.ts +2 -1
- package/src/runner/report.test.ts +14 -0
- package/src/runner/report.ts +3 -1
- package/src/runner/run.test.ts +390 -12
- package/src/runner/run.ts +259 -26
- package/src/runner/sandbox-selection.test.ts +13 -3
- package/src/runner/sandbox-selection.ts +4 -2
- package/src/runner/types.ts +158 -23
- package/src/sandbox/docker.ts +7 -0
- package/src/sandbox/e2b.ts +12 -13
- package/src/sandbox/types.ts +23 -21
- package/src/scoring/display.test.ts +28 -2
- package/src/scoring/display.ts +38 -5
- package/src/scoring/types.ts +3 -3
- package/src/shared/aggregate.test.ts +52 -0
- package/src/shared/aggregate.ts +30 -1
- package/src/shared/types.ts +6 -1
- package/src/show/command.test.ts +34 -0
- package/src/show/command.ts +16 -0
- package/src/show/compose.ts +1 -1
- package/src/show/index.ts +58 -22
- package/src/show/render.ts +16 -240
- package/src/show/show.test.ts +128 -35
- package/src/view/app/App.test.tsx +8 -7
- package/src/view/app/App.tsx +135 -51
- package/src/view/app/i18n.ts +7 -147
- package/src/view/app/lib/attempt-dialog.test.ts +65 -0
- package/src/view/app/lib/attempt-dialog.ts +69 -0
- package/src/view/app/main.tsx +0 -1
- package/src/view/app/types.ts +3 -86
- package/src/view/artifact-serving.test.ts +22 -38
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +15 -22
- package/src/view/data.test.ts +48 -36
- package/src/view/data.ts +122 -89
- package/src/view/index.ts +3 -13
- package/src/view/server.ts +36 -6
- package/src/view/shared/types.ts +6 -31
- package/src/view/site-parity.test.ts +24 -1
- package/src/view/site.ts +144 -17
- package/src/view/styles.css +18 -806
- package/src/view/view-report.test.ts +182 -34
- package/dist/report/components.d.ts +0 -179
- package/dist/report/components.js +0 -544
- package/dist/report/compute.d.ts +0 -139
- package/dist/report/react/ExperimentComparison.d.ts +0 -10
- package/dist/report/react/ExperimentComparison.js +0 -12
- package/dist/report/react/MetricScatter.d.ts +0 -9
- package/dist/report/react/format.d.ts +0 -3
- package/dist/report/react/format.js +0 -7
- package/dist/report/text/faces.d.ts +0 -45
- package/dist/report/text/faces.js +0 -671
- package/dist/report/web.d.ts +0 -32
- package/dist/report/web.js +0 -48
- package/docs-site/zh/how-to/authoring.mdx +0 -162
- package/docs-site/zh/how-to/custom-reports.mdx +0 -414
- package/docs-site/zh/how-to/experiments.mdx +0 -86
- package/docs-site/zh/how-to/write-experiment.mdx +0 -164
- package/src/report/components.tsx +0 -925
- package/src/report/react/ExperimentComparison.tsx +0 -73
- package/src/report/react/format.ts +0 -9
- package/src/report/text/faces.ts +0 -767
- package/src/report/web.ts +0 -77
- package/src/show/report-host.test.ts +0 -205
- package/src/show/report-host.ts +0 -389
- package/src/view/app/components/AttemptModal.tsx +0 -496
- package/src/view/app/components/CodeView.test.tsx +0 -142
- package/src/view/app/components/CodeView.tsx +0 -310
- package/src/view/app/components/CopyControls.tsx +0 -106
- package/src/view/app/components/Trace.tsx +0 -100
- package/src/view/app/components/Transcript.tsx +0 -157
- package/src/view/app/components/ui/badge.tsx +0 -21
- package/src/view/app/lib/artifact-url.ts +0 -17
- package/src/view/app/lib/attempt-route.test.ts +0 -80
- package/src/view/app/lib/attempt-route.ts +0 -52
- package/src/view/app/lib/format.ts +0 -70
- package/src/view/app/lib/guards.test.ts +0 -108
- package/src/view/app/lib/guards.ts +0 -71
- package/src/view/app/lib/rows.ts +0 -22
- package/src/view/app/lib/transcript-data.tsx +0 -151
- package/src/view/app/lib/verdict.ts +0 -23
- package/src/view/app/shared.ts +0 -8
- /package/dist/report/{react → components/metric-views}/chart-math.d.ts +0 -0
- /package/dist/report/{react → components/metric-views}/chart-math.js +0 -0
- /package/dist/report/{text → components/metric-views}/plot.d.ts +0 -0
- /package/dist/report/{react → components/site-components}/PoweredBy.d.ts +0 -0
- /package/dist/report/{react → components/site-components}/PoweredBy.js +0 -0
- /package/dist/report/{text/layout.d.ts → model/text-layout.d.ts} +0 -0
- /package/dist/report/{text/layout.js → model/text-layout.js} +0 -0
- /package/dist/report/{types.js → model/types.js} +0 -0
- /package/src/report/{react → components/metric-views}/chart-math.test.ts +0 -0
- /package/src/report/{react → components/metric-views}/chart-math.ts +0 -0
- /package/src/report/{react → components/site-components}/PoweredBy.tsx +0 -0
- /package/src/report/{text/layout.ts → model/text-layout.ts} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
|
-
import type { TraceWaterfallRow } from "
|
|
3
|
-
import type { AttemptLocator } from "
|
|
4
|
-
import { type ReportLocale } from "
|
|
2
|
+
import type { TraceWaterfallRow } from "../../model/types.ts";
|
|
3
|
+
import type { AttemptLocator } from "../../../results/locator.ts";
|
|
4
|
+
import { type ReportLocale } from "../../model/locale.ts";
|
|
5
5
|
/**
|
|
6
6
|
* 执行时间瀑布(纯 web 渲染面):嵌入自有 React 页面时配合 `traceWaterfallData()` 使用。
|
|
7
7
|
* 只画被测 agent 的原始 span;runner 生命周期节点不在 data 里,组合视图归 attempt 详情。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { DEFAULT_REPORT_LOCALE, countText, localeText } from "
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
import { DEFAULT_REPORT_LOCALE, countText, localeText } from "../../model/locale.js";
|
|
3
|
+
import { formatDurationMs } from "../../model/format.js";
|
|
4
|
+
import { cx } from "../shared.js";
|
|
5
5
|
function pct(part, total) {
|
|
6
6
|
if (total <= 0)
|
|
7
7
|
return "0%";
|
|
@@ -11,10 +11,10 @@ function pct(part, total) {
|
|
|
11
11
|
* 执行时间瀑布(纯 web 渲染面):嵌入自有 React 页面时配合 `traceWaterfallData()` 使用。
|
|
12
12
|
* 只画被测 agent 的原始 span;runner 生命周期节点不在 data 里,组合视图归 attempt 详情。
|
|
13
13
|
*/
|
|
14
|
-
export function TraceWaterfall({ data, attemptHref
|
|
14
|
+
export function TraceWaterfall({ data, attemptHref, className, locale = DEFAULT_REPORT_LOCALE, }) {
|
|
15
15
|
return (_jsxs("section", { className: cx("nre", "nre-trace-waterfall", className), children: [data.length === 0 && _jsx("p", { className: "nre-waterfall-empty", children: localeText(locale, "traceWaterfall.empty") }), _jsx("ul", { className: "nre-waterfall", children: data.map((row) => {
|
|
16
16
|
const failedSpans = row.spans.filter((span) => span.failed).length;
|
|
17
|
-
return (_jsxs("li", { className: "nre-waterfall-row", children: [_jsxs("div", { className: "nre-waterfall-head", children: [_jsx("a", { className: "nre-locator", href: attemptHref(row.locator), children: row.locator }), _jsx("span", { className: "nre-waterfall-eval", children: row.evalId }), _jsx("span", { className: "nre-waterfall-experiment", children: row.experimentId }), _jsx("span", { className: "nre-waterfall-duration", children: row.durationMs === null ? localeText(locale, "traceWaterfall.noTrace") : formatDurationMs(row.durationMs) }), _jsx("span", { className: "nre-waterfall-count", children: countText(locale, "traceWaterfall.spans", row.spans.length) }), failedSpans > 0 && (_jsxs("span", { className: "nre-waterfall-failed", children: ["\u2717 ", countText(locale, "traceWaterfall.failedSpans", failedSpans)] }))] }), row.durationMs !== null && row.spans.length > 0 && (_jsx("div", { className: "nre-waterfall-track", children: row.spans.map((span, i) => (_jsx("span", { className: cx("nre-waterfall-span", `nre-span-${span.kind}`, span.failed && "nre-span-failed"), style: {
|
|
17
|
+
return (_jsxs("li", { className: "nre-waterfall-row", children: [_jsxs("div", { className: "nre-waterfall-head", children: [attemptHref ? (_jsx("a", { className: "nre-locator", href: attemptHref(row.locator), children: row.locator })) : (_jsx("span", { className: "nre-locator", children: row.locator })), _jsx("span", { className: "nre-waterfall-eval", children: row.evalId }), _jsx("span", { className: "nre-waterfall-experiment", children: row.experimentId }), _jsx("span", { className: "nre-waterfall-duration", children: row.durationMs === null ? localeText(locale, "traceWaterfall.noTrace") : formatDurationMs(row.durationMs) }), _jsx("span", { className: "nre-waterfall-count", children: countText(locale, "traceWaterfall.spans", row.spans.length) }), failedSpans > 0 && (_jsxs("span", { className: "nre-waterfall-failed", children: ["\u2717 ", countText(locale, "traceWaterfall.failedSpans", failedSpans)] }))] }), row.durationMs !== null && row.spans.length > 0 && (_jsx("div", { className: "nre-waterfall-track", children: row.spans.map((span, i) => (_jsx("span", { className: cx("nre-waterfall-span", `nre-span-${span.kind}`, span.failed && "nre-span-failed"), style: {
|
|
18
18
|
left: pct(span.startOffsetMs, row.durationMs),
|
|
19
19
|
width: `max(${pct(span.durationMs, row.durationMs)}, 0.5%)`,
|
|
20
20
|
}, title: `${span.name} · ${formatDurationMs(span.durationMs)}${span.failed ? " · ✗" : ""}` }, i))) }))] }, row.locator));
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CopyFixPromptData, HeroData, ReportInput, ScopeWarning, TraceWaterfallRow } from "../../model/types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* `heroData(input)`:站点标题区的运行 meta——`latestStartedAt` 取范围内最新快照的开始时间
|
|
4
|
+
* (空范围为 null,不编造当前时间),`snapshots` 计贡献当前水位的快照数
|
|
5
|
+
* (docs/feature/reports/library/site-components.md「HeroCard」)。
|
|
6
|
+
*/
|
|
7
|
+
export declare function heroData(input: ReportInput): Promise<HeroData>;
|
|
8
|
+
/**
|
|
9
|
+
* `scopeWarningsData(input)`:Scope 携带的挑选警告原样透出;`input` 是裸 `Snapshot[]` 时
|
|
10
|
+
* 没有挑选过程、没有警告,返回空数组,也如实
|
|
11
|
+
* (docs/feature/reports/library/site-components.md「ScopeWarnings」)。
|
|
12
|
+
*/
|
|
13
|
+
export declare function scopeWarningsData(input: ReportInput): Promise<readonly ScopeWarning[]>;
|
|
14
|
+
/**
|
|
15
|
+
* `copyFixPromptData(input)`:把范围内全部失败(verdict 为 failed / errored 的 attempt)
|
|
16
|
+
* 整理成一段可交给 coding agent 的修复 prompt——逐失败含 eval id、主失败摘要与 attempt
|
|
17
|
+
* 下钻命令(`niceeval show @<locator>`)。prompt 面向 agent,固定英文
|
|
18
|
+
* (docs/feature/reports/library/site-components.md「CopyFixPrompt」)。
|
|
19
|
+
*/
|
|
20
|
+
export declare function copyFixPromptData(input: ReportInput): Promise<CopyFixPromptData>;
|
|
21
|
+
/**
|
|
22
|
+
* `traceWaterfallData(input)`:每个 attempt 一行的执行时间瀑布摘要。span 事实只来自
|
|
23
|
+
* trace artifact(经 AttemptHandle 懒加载的 canonical OTel span);runner 生命周期节点
|
|
24
|
+
* (`result.phases`)不进瀑布。行内只汇总顶层 span(parentSpanId 缺失或不在本 trace 内),
|
|
25
|
+
* 按 startOffsetMs 升序;trace 缺失或为空时 `durationMs` 为 null、行照常出现
|
|
26
|
+
* (docs/feature/reports/library/site-components.md「TraceWaterfall」)。
|
|
27
|
+
*/
|
|
28
|
+
export declare function traceWaterfallData(input: ReportInput): Promise<readonly TraceWaterfallRow[]>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// 计算函数(*Data):ReportInput → 一份组件数据。站点组件族(Hero / ScopeWarnings /
|
|
2
|
+
// CopyFixPrompt / TraceWaterfall)的 *Data 都住在这里
|
|
3
|
+
// (docs/feature/reports/library/site-components.md)。
|
|
4
|
+
//
|
|
5
|
+
// 共同约定(docs/feature/reports/architecture.md「指标聚合不变量」):
|
|
6
|
+
// - 第一参收 ReportInput = Scope | readonly Snapshot[];warnings 不进组件数据(宿主统一显示);
|
|
7
|
+
// - null ≠ 0:缺数据不编数。
|
|
8
|
+
import { collectItems, evalIdOf, experimentIdOf, locatorOf, resolveInput } from "../../model/aggregate.js";
|
|
9
|
+
import { attemptListData } from "../entity-lists/compute.js";
|
|
10
|
+
// ───────────────────────── 站点组件的计算函数(hero / warnings / fix prompt / trace)─────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* `heroData(input)`:站点标题区的运行 meta——`latestStartedAt` 取范围内最新快照的开始时间
|
|
13
|
+
* (空范围为 null,不编造当前时间),`snapshots` 计贡献当前水位的快照数
|
|
14
|
+
* (docs/feature/reports/library/site-components.md「HeroCard」)。
|
|
15
|
+
*/
|
|
16
|
+
export async function heroData(input) {
|
|
17
|
+
const { snapshots } = resolveInput(input);
|
|
18
|
+
let latest = null;
|
|
19
|
+
for (const snapshot of snapshots) {
|
|
20
|
+
if (latest === null || snapshot.startedAt > latest)
|
|
21
|
+
latest = snapshot.startedAt;
|
|
22
|
+
}
|
|
23
|
+
return { latestStartedAt: latest, snapshots: snapshots.length };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* `scopeWarningsData(input)`:Scope 携带的挑选警告原样透出;`input` 是裸 `Snapshot[]` 时
|
|
27
|
+
* 没有挑选过程、没有警告,返回空数组,也如实
|
|
28
|
+
* (docs/feature/reports/library/site-components.md「ScopeWarnings」)。
|
|
29
|
+
*/
|
|
30
|
+
export async function scopeWarningsData(input) {
|
|
31
|
+
return resolveInput(input).warnings;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `copyFixPromptData(input)`:把范围内全部失败(verdict 为 failed / errored 的 attempt)
|
|
35
|
+
* 整理成一段可交给 coding agent 的修复 prompt——逐失败含 eval id、主失败摘要与 attempt
|
|
36
|
+
* 下钻命令(`niceeval show @<locator>`)。prompt 面向 agent,固定英文
|
|
37
|
+
* (docs/feature/reports/library/site-components.md「CopyFixPrompt」)。
|
|
38
|
+
*/
|
|
39
|
+
export async function copyFixPromptData(input) {
|
|
40
|
+
const items = await attemptListData(input);
|
|
41
|
+
const failures = items.filter((item) => item.verdict === "failed" || item.verdict === "errored");
|
|
42
|
+
if (failures.length === 0)
|
|
43
|
+
return { prompt: "", failures: 0 };
|
|
44
|
+
const lines = failures
|
|
45
|
+
.map((item, i) => {
|
|
46
|
+
const reason = item.failureSummary === null
|
|
47
|
+
? null
|
|
48
|
+
: item.moreFailures > 0
|
|
49
|
+
? `${item.failureSummary} (+${item.moreFailures} more failures)`
|
|
50
|
+
: item.failureSummary;
|
|
51
|
+
return [
|
|
52
|
+
`${i + 1}. eval "${item.evalId}" [experiment ${item.experimentId}] — ${item.verdict}`,
|
|
53
|
+
reason ? ` reason: ${reason}` : null,
|
|
54
|
+
` inspect: niceeval show ${item.locator}`,
|
|
55
|
+
]
|
|
56
|
+
.filter(Boolean)
|
|
57
|
+
.join("\n");
|
|
58
|
+
})
|
|
59
|
+
.join("\n");
|
|
60
|
+
const experiments = [...new Set(failures.map((item) => item.experimentId))].join(" / ");
|
|
61
|
+
const prompt = [
|
|
62
|
+
"Fix the failing evals from this niceeval run.",
|
|
63
|
+
"",
|
|
64
|
+
"## Failures",
|
|
65
|
+
lines,
|
|
66
|
+
"",
|
|
67
|
+
"## Steps",
|
|
68
|
+
"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.",
|
|
69
|
+
"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.",
|
|
70
|
+
"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.",
|
|
71
|
+
`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.`,
|
|
72
|
+
"5. Run `npx niceeval show` and confirm these failures are gone.",
|
|
73
|
+
].join("\n");
|
|
74
|
+
return { prompt, failures: failures.length };
|
|
75
|
+
}
|
|
76
|
+
/** TraceSpan 的语义角色 → 瀑布摘要的 kind:turn 归入 agent(一轮就是一次 agent 调用),未识别落 other。 */
|
|
77
|
+
function waterfallKindOf(kind) {
|
|
78
|
+
switch (kind) {
|
|
79
|
+
case "agent":
|
|
80
|
+
case "turn":
|
|
81
|
+
return "agent";
|
|
82
|
+
case "model":
|
|
83
|
+
return "model";
|
|
84
|
+
case "tool":
|
|
85
|
+
return "tool";
|
|
86
|
+
default:
|
|
87
|
+
return "other";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* `traceWaterfallData(input)`:每个 attempt 一行的执行时间瀑布摘要。span 事实只来自
|
|
92
|
+
* trace artifact(经 AttemptHandle 懒加载的 canonical OTel span);runner 生命周期节点
|
|
93
|
+
* (`result.phases`)不进瀑布。行内只汇总顶层 span(parentSpanId 缺失或不在本 trace 内),
|
|
94
|
+
* 按 startOffsetMs 升序;trace 缺失或为空时 `durationMs` 为 null、行照常出现
|
|
95
|
+
* (docs/feature/reports/library/site-components.md「TraceWaterfall」)。
|
|
96
|
+
*/
|
|
97
|
+
export async function traceWaterfallData(input) {
|
|
98
|
+
const { snapshots } = resolveInput(input);
|
|
99
|
+
const items = collectItems(snapshots);
|
|
100
|
+
return Promise.all(items.map(async (item) => {
|
|
101
|
+
const spans = await item.attempt.trace();
|
|
102
|
+
if (spans === null || spans.length === 0) {
|
|
103
|
+
return {
|
|
104
|
+
experimentId: experimentIdOf(item),
|
|
105
|
+
evalId: evalIdOf(item),
|
|
106
|
+
locator: locatorOf(item),
|
|
107
|
+
durationMs: null,
|
|
108
|
+
spans: [],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const t0 = Math.min(...spans.map((s) => s.startMs));
|
|
112
|
+
const t1 = Math.max(...spans.map((s) => s.endMs));
|
|
113
|
+
const ids = new Set(spans.map((s) => s.spanId));
|
|
114
|
+
const topLevel = spans.filter((s) => s.parentSpanId === undefined || !ids.has(s.parentSpanId));
|
|
115
|
+
const summaries = topLevel
|
|
116
|
+
.map((s) => ({
|
|
117
|
+
name: s.name,
|
|
118
|
+
kind: waterfallKindOf(s.kind),
|
|
119
|
+
startOffsetMs: s.startMs - t0,
|
|
120
|
+
durationMs: s.endMs - s.startMs,
|
|
121
|
+
failed: s.status === "error",
|
|
122
|
+
}))
|
|
123
|
+
.sort((a, b) => a.startOffsetMs - b.startOffsetMs);
|
|
124
|
+
return {
|
|
125
|
+
experimentId: experimentIdOf(item),
|
|
126
|
+
evalId: evalIdOf(item),
|
|
127
|
+
locator: locatorOf(item),
|
|
128
|
+
durationMs: Math.max(0, t1 - t0),
|
|
129
|
+
spans: summaries,
|
|
130
|
+
};
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { HeroData, ScopeWarning, TraceWaterfallRow } from "../../model/types.ts";
|
|
2
|
+
import type { LocalizedText } from "../../model/locale.ts";
|
|
3
|
+
import type { TextContext } from "../../definition/tree.ts";
|
|
4
|
+
/**
|
|
5
|
+
* HeroCard 的 text 面:标题行 + meta 行(最后运行时间;空范围为内置「暂无运行」文案;
|
|
6
|
+
* 多快照时标注合成来源),不含品牌行(品牌行是纯 web 件,text 面零输出)。
|
|
7
|
+
*/
|
|
8
|
+
export declare function heroCardText(title: LocalizedText, data: HeroData, ctx: TextContext): string;
|
|
9
|
+
/**
|
|
10
|
+
* ScopeWarnings 的 text 面:按动作聚合(../scope-warnings.ts,与 web 面共用),同构但不折叠——
|
|
11
|
+
* 多组时首行 "! <分类计数汇总>";每组一行组头 "! <标题> — <徽标> → <组头命令>",其下缩进
|
|
12
|
+
* 逐条原样打印 message(已以下一步收尾,不截断掉尾段)。空警告集零输出。
|
|
13
|
+
*/
|
|
14
|
+
export declare function scopeWarningsText(warnings: readonly ScopeWarning[], ctx: TextContext): string;
|
|
15
|
+
/**
|
|
16
|
+
* TraceWaterfall 的 text 面:每 attempt 一行——locator、总耗时(缺 trace 如实显示缺失)、
|
|
17
|
+
* 顶层 span 计数与失败标记,行尾是可复制的 `--timing` 下钻命令(经宿主注入的 attemptCommand
|
|
18
|
+
* 通道拼出,携带宿主上下文)。当前报告没有 attempt-input page 时 `ctx.attemptCommand`
|
|
19
|
+
* 不存在,行退化为纯文本,不生成假命令(architecture.md「Attempt 详情是一张参数化 page」)。
|
|
20
|
+
*/
|
|
21
|
+
export declare function traceWaterfallText(rows: readonly TraceWaterfallRow[], ctx: TextContext): string;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// 站点组件族(HeroCard / ScopeWarnings / TraceWaterfall)的 text 面:同一份算好的数据,
|
|
2
|
+
// 渲染成终端字符(niceeval show 的形态)。零 react、零 IO、纯同步。
|
|
3
|
+
import { countText, localeText, resolveLocalizedText } from "../../model/locale.js";
|
|
4
|
+
import { formatDurationMs } from "../../model/format.js";
|
|
5
|
+
import { groupScopeWarnings } from "./scope-warnings.js";
|
|
6
|
+
/** ISO 时间 → "YYYY-MM-DD HH:mm"(本地时区);不可解析原样返回。 */
|
|
7
|
+
function formatDateTimeMinute(iso) {
|
|
8
|
+
const date = new Date(iso);
|
|
9
|
+
if (Number.isNaN(date.valueOf()))
|
|
10
|
+
return iso;
|
|
11
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
12
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
13
|
+
}
|
|
14
|
+
// ───────────────────────── 站点组件(HeroCard / ScopeWarnings / TraceWaterfall)─────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* HeroCard 的 text 面:标题行 + meta 行(最后运行时间;空范围为内置「暂无运行」文案;
|
|
17
|
+
* 多快照时标注合成来源),不含品牌行(品牌行是纯 web 件,text 面零输出)。
|
|
18
|
+
*/
|
|
19
|
+
export function heroCardText(title, data, ctx) {
|
|
20
|
+
const locale = ctx.locale;
|
|
21
|
+
const meta = data.latestStartedAt === null
|
|
22
|
+
? localeText(locale, "hero.noRuns")
|
|
23
|
+
: [
|
|
24
|
+
localeText(locale, "hero.lastRun", { time: formatDateTimeMinute(data.latestStartedAt) }),
|
|
25
|
+
...(data.snapshots > 1 ? [localeText(locale, "hero.composedSnapshots", { n: data.snapshots })] : []),
|
|
26
|
+
].join(" · ");
|
|
27
|
+
return `${resolveLocalizedText(title, locale)}\n${meta}`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* ScopeWarnings 的 text 面:按动作聚合(../scope-warnings.ts,与 web 面共用),同构但不折叠——
|
|
31
|
+
* 多组时首行 "! <分类计数汇总>";每组一行组头 "! <标题> — <徽标> → <组头命令>",其下缩进
|
|
32
|
+
* 逐条原样打印 message(已以下一步收尾,不截断掉尾段)。空警告集零输出。
|
|
33
|
+
*/
|
|
34
|
+
export function scopeWarningsText(warnings, ctx) {
|
|
35
|
+
if (warnings.length === 0)
|
|
36
|
+
return "";
|
|
37
|
+
const { summary, groups } = groupScopeWarnings(warnings, ctx.locale);
|
|
38
|
+
const lines = [];
|
|
39
|
+
// 汇总行只在多组时打印;单组时组头即汇总,不另起一行(web 面则恒以汇总行作外层 <summary>)。
|
|
40
|
+
if (groups.length > 1)
|
|
41
|
+
lines.push(`! ${summary}`);
|
|
42
|
+
for (const group of groups) {
|
|
43
|
+
const badges = group.badges.length > 0 ? ` — ${group.badges.map((b) => b.text).join(" · ")}` : "";
|
|
44
|
+
const command = group.headCommand !== null ? ` → ${group.headCommand}` : "";
|
|
45
|
+
lines.push(`! ${group.title}${badges}${command}`);
|
|
46
|
+
for (const w of group.warnings)
|
|
47
|
+
lines.push(`! ${w.message}`);
|
|
48
|
+
}
|
|
49
|
+
return lines.join("\n");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* TraceWaterfall 的 text 面:每 attempt 一行——locator、总耗时(缺 trace 如实显示缺失)、
|
|
53
|
+
* 顶层 span 计数与失败标记,行尾是可复制的 `--timing` 下钻命令(经宿主注入的 attemptCommand
|
|
54
|
+
* 通道拼出,携带宿主上下文)。当前报告没有 attempt-input page 时 `ctx.attemptCommand`
|
|
55
|
+
* 不存在,行退化为纯文本,不生成假命令(architecture.md「Attempt 详情是一张参数化 page」)。
|
|
56
|
+
*/
|
|
57
|
+
export function traceWaterfallText(rows, ctx) {
|
|
58
|
+
const locale = ctx.locale;
|
|
59
|
+
if (rows.length === 0)
|
|
60
|
+
return localeText(locale, "traceWaterfall.empty");
|
|
61
|
+
return rows
|
|
62
|
+
.map((row) => {
|
|
63
|
+
const failedSpans = row.spans.filter((span) => span.failed).length;
|
|
64
|
+
const parts = [
|
|
65
|
+
row.locator,
|
|
66
|
+
row.evalId,
|
|
67
|
+
row.durationMs === null ? localeText(locale, "traceWaterfall.noTrace") : formatDurationMs(row.durationMs),
|
|
68
|
+
countText(locale, "traceWaterfall.spans", row.spans.length),
|
|
69
|
+
...(failedSpans > 0 ? [`✗ ${countText(locale, "traceWaterfall.failedSpans", failedSpans)}`] : []),
|
|
70
|
+
];
|
|
71
|
+
const line = parts.join(" · ");
|
|
72
|
+
return ctx.attemptCommand ? `${line} ${ctx.attemptCommand(row.locator)} --timing` : line;
|
|
73
|
+
})
|
|
74
|
+
.join("\n");
|
|
75
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type ReportComponent } from "../../definition/tree.ts";
|
|
2
|
+
import type { CopyFixPromptData, HeroData, ScopeWarning, TraceWaterfallRow } from "../../model/types.ts";
|
|
3
|
+
import type { LocalizedText } from "../../model/locale.ts";
|
|
4
|
+
import type { AttemptLocator } from "../../../results/locator.ts";
|
|
5
|
+
import { type ChromeProps, type DataProps, type Validator } from "../shared.ts";
|
|
6
|
+
export declare const validateHeroData: Validator;
|
|
7
|
+
export declare const validateScopeWarningsData: Validator;
|
|
8
|
+
export declare const validateCopyFixPromptData: Validator;
|
|
9
|
+
export declare const validateTraceWaterfallData: Validator;
|
|
10
|
+
/** `Hero` 的 props:标题缺省取 `ctx.report.title`(回退链后的站点标题)。 */
|
|
11
|
+
export interface HeroProps {
|
|
12
|
+
/** 覆盖标题;省略时取 ctx.report.title(回退链后的站点标题)。 */
|
|
13
|
+
title?: LocalizedText;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* `HeroCard`:Hero 的渲染件,双面组件,只收 data 形态——标题输入是站点声明与 Scope 的
|
|
18
|
+
* 合成物,没有单独的 spec 等价形。web 面渲染 hero 标题(h1)、按渲染 locale 格式化的运行
|
|
19
|
+
* meta(latestStartedAt 为 null 时内置「暂无运行」文案)与品牌行(等同 PoweredBy,恒含、
|
|
20
|
+
* 无拆除 prop);text 面输出标题行与 meta 行,不含品牌行
|
|
21
|
+
* (docs/feature/reports/library/site-components.md「HeroCard」)。
|
|
22
|
+
*/
|
|
23
|
+
export declare const HeroCard: ReportComponent<HeroCardProps>;
|
|
24
|
+
/** `HeroCard` 的 props:标题 + `heroData()` 的产物,只有 data 形态。 */
|
|
25
|
+
export interface HeroCardProps {
|
|
26
|
+
title: LocalizedText;
|
|
27
|
+
data: HeroData;
|
|
28
|
+
className?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* `Hero`:页首的站点标题区——标题、最后运行时间、快照合成来源,恒含品牌行。官方组合组件,
|
|
32
|
+
* 与手写 `<HeroCard title={title ?? ctx.report.title} data={await heroData(ctx.scope)} />`
|
|
33
|
+
* 严格等价、没有私有能力;读 `ctx.report` 意味着输出跟随站点,要站点无关的标题区直接用
|
|
34
|
+
* `HeroCard` 显式传值(docs/feature/reports/library/site-components.md「Hero」)。
|
|
35
|
+
*/
|
|
36
|
+
export declare const Hero: ReportComponent<HeroProps>;
|
|
37
|
+
/**
|
|
38
|
+
* `PoweredBy`:唯一的品牌件,无 props 双面组件。web 面渲染指向 niceeval 官网的一行品牌色
|
|
39
|
+
* 小字(`utm_source=report&utm_medium=powered-by`,`rel` 仅 `noopener` 以保留 Referer);
|
|
40
|
+
* text 面零输出。没有任何配置——品牌契约是「提供一个组件,不给开关」:不想要品牌就不用
|
|
41
|
+
* 这些组件、自己写替代组件(docs/feature/reports/library/site-components.md「PoweredBy」)。
|
|
42
|
+
*/
|
|
43
|
+
export declare const PoweredBy: ReportComponent<Record<never, never>>;
|
|
44
|
+
/** `ScopeWarnings` 的 props:spec 形态取宿主 Scope 的 warnings,data 形态收 `ScopeWarning[]`。 */
|
|
45
|
+
export type ScopeWarningsProps = DataProps<readonly ScopeWarning[], Record<never, never>, ChromeProps>;
|
|
46
|
+
/**
|
|
47
|
+
* `ScopeWarnings`:选择警告区,警告的唯一呈现组件。把 Scope 携带的 `ScopeWarning[]`
|
|
48
|
+
* 按「下一步动作」聚合渲染(带 experimentId 的按实验聚合、非实验作用域按 kind 聚合;
|
|
49
|
+
* integrity 组在前);web 面组头带去重后的可复制命令、明细收原生 `<details>`(总条数 ≤ 3
|
|
50
|
+
* 默认展开),text 面同构但不折叠。空警告集与裸 `Snapshot[]` 输入两面零输出
|
|
51
|
+
* (docs/feature/reports/library/site-components.md「ScopeWarnings」)。
|
|
52
|
+
*/
|
|
53
|
+
export declare const ScopeWarnings: ReportComponent<ScopeWarningsProps>;
|
|
54
|
+
/** `CopyFixPrompt` 的 props:spec 形态无选项,data 形态收 `copyFixPromptData()` 的产物。 */
|
|
55
|
+
export type CopyFixPromptProps = DataProps<CopyFixPromptData, Record<never, never>, ChromeProps>;
|
|
56
|
+
/**
|
|
57
|
+
* `CopyFixPrompt`:把当前范围的全部失败整理成一段可交给 coding agent 的修复 prompt。
|
|
58
|
+
* prompt 在 resolve 阶段算好、烘进静态 HTML,无 JS 时在折叠块里完整可读,「复制」是增强层
|
|
59
|
+
* 行为;`failures` 为 0 时两面零输出;text 面恒零输出——终端里的等价能力是 `show` 的
|
|
60
|
+
* attempt 下钻命令本身(docs/feature/reports/library/site-components.md「CopyFixPrompt」)。
|
|
61
|
+
*/
|
|
62
|
+
export declare const CopyFixPrompt: ReportComponent<CopyFixPromptProps>;
|
|
63
|
+
/** `TraceWaterfall` 的 props:spec 形态无选项,data 形态收 `traceWaterfallData()` 的产物。 */
|
|
64
|
+
export type TraceWaterfallProps = DataProps<readonly TraceWaterfallRow[], Record<never, never>, ChromeProps & {
|
|
65
|
+
attemptHref?: (locator: AttemptLocator) => string;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* `TraceWaterfall`:每个 attempt 一行的执行时间瀑布,用 canonical OTel 字段显示被测 agent
|
|
69
|
+
* 的原始 span(agent / model / tool)。web 面静态渲染顶层 span 分解条(失败 span 带失败
|
|
70
|
+
* 标记),行链接 attempt 详情;text 面每 attempt 一行(locator、总耗时、span 计数与失败
|
|
71
|
+
* 标记)+ 可复制的 `--timing` 下钻命令。trace 缺失的行照常出现并如实显示缺失;runner
|
|
72
|
+
* 生命周期节点不进瀑布(docs/feature/reports/library/site-components.md「TraceWaterfall」)。
|
|
73
|
+
*/
|
|
74
|
+
export declare const TraceWaterfall: ReportComponent<TraceWaterfallProps>;
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// 官方双面组件的装配点:web 面(./HeroCard.tsx 等纯 React 组件)+ text 面(./faces.ts)+
|
|
3
|
+
// resolve 解析面(spec 形态由管线代调配套 ./compute.ts)。Hero 是组合组件(装配 HeroCard),
|
|
4
|
+
// 不产生自己的 data;PoweredBy 无 props,没有对应的计算函数或 validate。
|
|
5
|
+
import { defineComponent } from "../../definition/tree.js";
|
|
6
|
+
import { arrayProblem, dataShapeError, isObject, makeDataComponent, hrefOf, } from "../shared.js";
|
|
7
|
+
import { copyFixPromptData, heroData, scopeWarningsData, traceWaterfallData } from "./compute.js";
|
|
8
|
+
import { heroCardText, scopeWarningsText, traceWaterfallText } from "./faces.js";
|
|
9
|
+
import { HeroCard as HeroCardWeb } from "./HeroCard.js";
|
|
10
|
+
import { PoweredBy as PoweredByWeb } from "./PoweredBy.js";
|
|
11
|
+
import { ScopeWarnings as ScopeWarningsWeb } from "./ScopeWarnings.js";
|
|
12
|
+
import { CopyFixPrompt as CopyFixPromptWeb } from "./CopyFixPrompt.js";
|
|
13
|
+
import { TraceWaterfall as TraceWaterfallWeb } from "./TraceWaterfall.js";
|
|
14
|
+
export const validateHeroData = (data) => {
|
|
15
|
+
if (!isObject(data))
|
|
16
|
+
return "expected an object";
|
|
17
|
+
if (!(data.latestStartedAt === null || typeof data.latestStartedAt === "string")) {
|
|
18
|
+
return '"latestStartedAt" must be a string or null';
|
|
19
|
+
}
|
|
20
|
+
if (typeof data.snapshots !== "number")
|
|
21
|
+
return '"snapshots" must be a number';
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
const UNREADABLE_SNAPSHOT_REASONS = ["incompatible-version", "malformed", "incomplete"];
|
|
25
|
+
/**
|
|
26
|
+
* ScopeWarning(src/results/types.ts「警告 kind 全集」):按 `kind` 判别的联合,已登记 kind
|
|
27
|
+
* 各自的必填字段单独校验——`unreadable-snapshot` 没有 experimentId(非实验作用域)、
|
|
28
|
+
* `command` 恒可选。未登记的 `kind`(如未来版本新增的 warning)只要求 `kind` / `message`
|
|
29
|
+
* 这份两族共用的最小形状,不拒绝——`ScopeWarnings` 的分组渲染对未识别 kind 有专门的
|
|
30
|
+
* 单独成组回退(message 原样、按 integrity 归位),这条前向兼容路径本身就是契约的一部分,
|
|
31
|
+
* 结构校验不能比渲染逻辑更严。
|
|
32
|
+
*/
|
|
33
|
+
function scopeWarningProblem(value, path) {
|
|
34
|
+
if (!isObject(value))
|
|
35
|
+
return `"${path}" must be a ScopeWarning object`;
|
|
36
|
+
if (typeof value.kind !== "string")
|
|
37
|
+
return `"${path}.kind" must be a string`;
|
|
38
|
+
if (typeof value.message !== "string")
|
|
39
|
+
return `"${path}.message" must be a string`;
|
|
40
|
+
switch (value.kind) {
|
|
41
|
+
case "partial-coverage":
|
|
42
|
+
if (typeof value.experimentId !== "string")
|
|
43
|
+
return `"${path}.experimentId" must be a string`;
|
|
44
|
+
if (typeof value.covered !== "number")
|
|
45
|
+
return `"${path}.covered" must be a number`;
|
|
46
|
+
if (typeof value.total !== "number")
|
|
47
|
+
return `"${path}.total" must be a number`;
|
|
48
|
+
if (typeof value.command !== "string")
|
|
49
|
+
return `"${path}.command" must be a string`;
|
|
50
|
+
return null;
|
|
51
|
+
case "stale-snapshot":
|
|
52
|
+
if (typeof value.experimentId !== "string")
|
|
53
|
+
return `"${path}.experimentId" must be a string`;
|
|
54
|
+
if (typeof value.startedAt !== "string")
|
|
55
|
+
return `"${path}.startedAt" must be a string`;
|
|
56
|
+
if (typeof value.latestStartedAt !== "string")
|
|
57
|
+
return `"${path}.latestStartedAt" must be a string`;
|
|
58
|
+
if (typeof value.command !== "string")
|
|
59
|
+
return `"${path}.command" must be a string`;
|
|
60
|
+
return null;
|
|
61
|
+
case "unfinished-snapshot":
|
|
62
|
+
if (typeof value.experimentId !== "string")
|
|
63
|
+
return `"${path}.experimentId" must be a string`;
|
|
64
|
+
if (typeof value.startedAt !== "string")
|
|
65
|
+
return `"${path}.startedAt" must be a string`;
|
|
66
|
+
if (typeof value.dir !== "string")
|
|
67
|
+
return `"${path}.dir" must be a string`;
|
|
68
|
+
if (typeof value.command !== "string")
|
|
69
|
+
return `"${path}.command" must be a string`;
|
|
70
|
+
return null;
|
|
71
|
+
case "unreadable-snapshot":
|
|
72
|
+
if (typeof value.dir !== "string")
|
|
73
|
+
return `"${path}.dir" must be a string`;
|
|
74
|
+
if (typeof value.reason !== "string" || !UNREADABLE_SNAPSHOT_REASONS.includes(value.reason)) {
|
|
75
|
+
return `"${path}.reason" must be one of ${JSON.stringify(UNREADABLE_SNAPSHOT_REASONS)}`;
|
|
76
|
+
}
|
|
77
|
+
if (value.command !== undefined && typeof value.command !== "string") {
|
|
78
|
+
return `"${path}.command" must be a string when present`;
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
default:
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export const validateScopeWarningsData = (data) => arrayProblem(data, "data", scopeWarningProblem);
|
|
86
|
+
export const validateCopyFixPromptData = (data) => {
|
|
87
|
+
if (!isObject(data))
|
|
88
|
+
return "expected an object";
|
|
89
|
+
if (typeof data.prompt !== "string")
|
|
90
|
+
return '"prompt" must be a string';
|
|
91
|
+
if (typeof data.failures !== "number")
|
|
92
|
+
return '"failures" must be a number';
|
|
93
|
+
return null;
|
|
94
|
+
};
|
|
95
|
+
const TRACE_SPAN_KINDS = ["agent", "model", "tool", "other"];
|
|
96
|
+
/** TraceSpanSummary(src/report/model/types.ts):瀑布行里的一个顶层 span 摘要。 */
|
|
97
|
+
function traceSpanSummaryProblem(value, path) {
|
|
98
|
+
if (!isObject(value))
|
|
99
|
+
return `"${path}" must be a TraceSpanSummary { name, kind, startOffsetMs, durationMs, failed }`;
|
|
100
|
+
if (typeof value.name !== "string")
|
|
101
|
+
return `"${path}.name" must be a string`;
|
|
102
|
+
if (typeof value.kind !== "string" || !TRACE_SPAN_KINDS.includes(value.kind)) {
|
|
103
|
+
return `"${path}.kind" must be one of ${JSON.stringify(TRACE_SPAN_KINDS)}`;
|
|
104
|
+
}
|
|
105
|
+
if (typeof value.startOffsetMs !== "number")
|
|
106
|
+
return `"${path}.startOffsetMs" must be a number`;
|
|
107
|
+
if (typeof value.durationMs !== "number")
|
|
108
|
+
return `"${path}.durationMs" must be a number`;
|
|
109
|
+
if (typeof value.failed !== "boolean")
|
|
110
|
+
return `"${path}.failed" must be a boolean`;
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
export const validateTraceWaterfallData = (data) => arrayProblem(data, "data", (row, path) => {
|
|
114
|
+
if (!isObject(row))
|
|
115
|
+
return `"${path}" must be an object`;
|
|
116
|
+
if (typeof row.experimentId !== "string")
|
|
117
|
+
return `"${path}.experimentId" must be a string`;
|
|
118
|
+
if (typeof row.evalId !== "string")
|
|
119
|
+
return `"${path}.evalId" must be a string`;
|
|
120
|
+
if (typeof row.locator !== "string")
|
|
121
|
+
return `"${path}.locator" must be a string`;
|
|
122
|
+
if (!(row.durationMs === null || typeof row.durationMs === "number")) {
|
|
123
|
+
return `"${path}.durationMs" must be a number or null`;
|
|
124
|
+
}
|
|
125
|
+
return arrayProblem(row.spans, `${path}.spans`, traceSpanSummaryProblem);
|
|
126
|
+
});
|
|
127
|
+
/** HeroCard 的 data 校验入口(它不经 makeDataComponent,数据形态是唯一形态)。 */
|
|
128
|
+
const assertHeroData = (data) => {
|
|
129
|
+
const problem = validateHeroData(data);
|
|
130
|
+
if (problem !== null)
|
|
131
|
+
throw dataShapeError("HeroCard", "heroData", "HeroData", problem);
|
|
132
|
+
return data;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* `HeroCard`:Hero 的渲染件,双面组件,只收 data 形态——标题输入是站点声明与 Scope 的
|
|
136
|
+
* 合成物,没有单独的 spec 等价形。web 面渲染 hero 标题(h1)、按渲染 locale 格式化的运行
|
|
137
|
+
* meta(latestStartedAt 为 null 时内置「暂无运行」文案)与品牌行(等同 PoweredBy,恒含、
|
|
138
|
+
* 无拆除 prop);text 面输出标题行与 meta 行,不含品牌行
|
|
139
|
+
* (docs/feature/reports/library/site-components.md「HeroCard」)。
|
|
140
|
+
*/
|
|
141
|
+
export const HeroCard = defineComponent({
|
|
142
|
+
web: (props, ctx) => {
|
|
143
|
+
assertHeroData(props.data);
|
|
144
|
+
return _jsx(HeroCardWeb, { title: props.title, data: props.data, className: props.className, locale: ctx.locale });
|
|
145
|
+
},
|
|
146
|
+
text: (props, ctx) => {
|
|
147
|
+
assertHeroData(props.data);
|
|
148
|
+
return heroCardText(props.title, props.data, ctx);
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
HeroCard.displayName = "HeroCard";
|
|
152
|
+
/**
|
|
153
|
+
* `Hero`:页首的站点标题区——标题、最后运行时间、快照合成来源,恒含品牌行。官方组合组件,
|
|
154
|
+
* 与手写 `<HeroCard title={title ?? ctx.report.title} data={await heroData(ctx.scope)} />`
|
|
155
|
+
* 严格等价、没有私有能力;读 `ctx.report` 意味着输出跟随站点,要站点无关的标题区直接用
|
|
156
|
+
* `HeroCard` 显式传值(docs/feature/reports/library/site-components.md「Hero」)。
|
|
157
|
+
*/
|
|
158
|
+
export const Hero = defineComponent(async ({ title, className }, ctx) => (_jsx(HeroCard, { title: title ?? ctx.report.title, data: await heroData(ctx.scope), className: className })));
|
|
159
|
+
Hero.displayName = "Hero";
|
|
160
|
+
/**
|
|
161
|
+
* `PoweredBy`:唯一的品牌件,无 props 双面组件。web 面渲染指向 niceeval 官网的一行品牌色
|
|
162
|
+
* 小字(`utm_source=report&utm_medium=powered-by`,`rel` 仅 `noopener` 以保留 Referer);
|
|
163
|
+
* text 面零输出。没有任何配置——品牌契约是「提供一个组件,不给开关」:不想要品牌就不用
|
|
164
|
+
* 这些组件、自己写替代组件(docs/feature/reports/library/site-components.md「PoweredBy」)。
|
|
165
|
+
*/
|
|
166
|
+
export const PoweredBy = defineComponent({
|
|
167
|
+
web: () => _jsx(PoweredByWeb, {}),
|
|
168
|
+
text: () => "",
|
|
169
|
+
});
|
|
170
|
+
PoweredBy.displayName = "PoweredBy";
|
|
171
|
+
/**
|
|
172
|
+
* `ScopeWarnings`:选择警告区,警告的唯一呈现组件。把 Scope 携带的 `ScopeWarning[]`
|
|
173
|
+
* 按「下一步动作」聚合渲染(带 experimentId 的按实验聚合、非实验作用域按 kind 聚合;
|
|
174
|
+
* integrity 组在前);web 面组头带去重后的可复制命令、明细收原生 `<details>`(总条数 ≤ 3
|
|
175
|
+
* 默认展开),text 面同构但不折叠。空警告集与裸 `Snapshot[]` 输入两面零输出
|
|
176
|
+
* (docs/feature/reports/library/site-components.md「ScopeWarnings」)。
|
|
177
|
+
*/
|
|
178
|
+
export const ScopeWarnings = makeDataComponent({
|
|
179
|
+
name: "ScopeWarnings",
|
|
180
|
+
dataFnName: "scopeWarningsData",
|
|
181
|
+
shapeName: "ScopeWarning[]",
|
|
182
|
+
dataFn: (input) => scopeWarningsData(input),
|
|
183
|
+
specKeys: [],
|
|
184
|
+
validate: validateScopeWarningsData,
|
|
185
|
+
web: (props, ctx) => props.data.length === 0 ? null : (_jsx(ScopeWarningsWeb, { data: props.data, locale: props.locale ?? ctx.locale, className: props.className })),
|
|
186
|
+
text: (props, ctx) => scopeWarningsText(props.data, ctx),
|
|
187
|
+
});
|
|
188
|
+
/**
|
|
189
|
+
* `CopyFixPrompt`:把当前范围的全部失败整理成一段可交给 coding agent 的修复 prompt。
|
|
190
|
+
* prompt 在 resolve 阶段算好、烘进静态 HTML,无 JS 时在折叠块里完整可读,「复制」是增强层
|
|
191
|
+
* 行为;`failures` 为 0 时两面零输出;text 面恒零输出——终端里的等价能力是 `show` 的
|
|
192
|
+
* attempt 下钻命令本身(docs/feature/reports/library/site-components.md「CopyFixPrompt」)。
|
|
193
|
+
*/
|
|
194
|
+
export const CopyFixPrompt = makeDataComponent({
|
|
195
|
+
name: "CopyFixPrompt",
|
|
196
|
+
dataFnName: "copyFixPromptData",
|
|
197
|
+
shapeName: "CopyFixPromptData",
|
|
198
|
+
dataFn: (input) => copyFixPromptData(input),
|
|
199
|
+
specKeys: [],
|
|
200
|
+
validate: validateCopyFixPromptData,
|
|
201
|
+
web: (props, ctx) => props.data.failures === 0 ? null : (_jsx(CopyFixPromptWeb, { data: props.data, locale: props.locale ?? ctx.locale, className: props.className })),
|
|
202
|
+
text: () => "",
|
|
203
|
+
});
|
|
204
|
+
/**
|
|
205
|
+
* `TraceWaterfall`:每个 attempt 一行的执行时间瀑布,用 canonical OTel 字段显示被测 agent
|
|
206
|
+
* 的原始 span(agent / model / tool)。web 面静态渲染顶层 span 分解条(失败 span 带失败
|
|
207
|
+
* 标记),行链接 attempt 详情;text 面每 attempt 一行(locator、总耗时、span 计数与失败
|
|
208
|
+
* 标记)+ 可复制的 `--timing` 下钻命令。trace 缺失的行照常出现并如实显示缺失;runner
|
|
209
|
+
* 生命周期节点不进瀑布(docs/feature/reports/library/site-components.md「TraceWaterfall」)。
|
|
210
|
+
*/
|
|
211
|
+
export const TraceWaterfall = makeDataComponent({
|
|
212
|
+
name: "TraceWaterfall",
|
|
213
|
+
dataFnName: "traceWaterfallData",
|
|
214
|
+
shapeName: "TraceWaterfallRow[]",
|
|
215
|
+
dataFn: (input) => traceWaterfallData(input),
|
|
216
|
+
specKeys: [],
|
|
217
|
+
validate: validateTraceWaterfallData,
|
|
218
|
+
web: (props, ctx) => (_jsx(TraceWaterfallWeb, { data: props.data, attemptHref: hrefOf(props, ctx), locale: props.locale ?? ctx.locale, className: props.className })),
|
|
219
|
+
text: (props, ctx) => traceWaterfallText(props.data, ctx),
|
|
220
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ScopeWarning } from "
|
|
2
|
-
import { type ReportLocale } from "
|
|
1
|
+
import type { ScopeWarning } from "../../../results/types.ts";
|
|
2
|
+
import { type ReportLocale } from "../../model/locale.ts";
|
|
3
3
|
/** kind 表登记的类别:integrity(选中集合的分母可能不对)组排在 freshness(可能过期)之前。 */
|
|
4
4
|
export type WarningCategory = "integrity" | "freshness";
|
|
5
5
|
export interface ScopeWarningGroup {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// message 是完整叙述的单源,这里只组织、不改写;徽标 / 组头文案按 kind 表登记的模板
|
|
4
4
|
// (docs/feature/results/library.md「警告 kind 全集」)经 locale 词典渲染,未登记的 kind
|
|
5
5
|
// 回退为单独成组、逐条 message 原样。
|
|
6
|
-
import { gapParts } from "
|
|
7
|
-
import { localeText } from "
|
|
6
|
+
import { gapParts } from "../../../results/select.js";
|
|
7
|
+
import { localeText } from "../../model/locale.js";
|
|
8
8
|
const CATEGORY = {
|
|
9
9
|
"partial-coverage": "integrity",
|
|
10
10
|
"unfinished-snapshot": "integrity",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
|
-
import type { ScopeSummaryData } from "
|
|
3
|
-
import { type ReportLocale } from "
|
|
2
|
+
import type { ScopeSummaryData } from "../../model/types.ts";
|
|
3
|
+
import { type ReportLocale } from "../../model/locale.ts";
|
|
4
4
|
export declare function ScopeSummary({ data, votes, className, locale, }: {
|
|
5
5
|
data: ScopeSummaryData;
|
|
6
6
|
/** 显示哪一级计票;默认 "eval"。data 恒携带两级,votes 只选择呈现。 */
|