niceeval 0.9.1 → 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 +14 -6
- 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} +43 -11
- package/dist/report/{tree.js → definition/tree.js} +9 -11
- 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 +11 -1
- 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 +14 -0
- package/dist/shared/aggregate.js +31 -0
- 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 +40 -16
- 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 +6 -6
- 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 +49 -49
- 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 +71 -57
- package/src/context/types.ts +21 -21
- package/src/define.ts +13 -0
- package/src/i18n/en.ts +27 -12
- package/src/i18n/zh-CN.ts +27 -12
- 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 +124 -106
- 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} +56 -20
- 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 +53 -2
- package/src/results/select.ts +29 -5
- 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 +29 -0
- 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 +56 -20
- package/src/show/render.ts +15 -239
- package/src/show/show.test.ts +127 -34
- package/src/view/app/App.test.tsx +1 -1
- package/src/view/app/App.tsx +119 -47
- 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 +105 -83
- package/src/view/index.ts +1 -1
- package/src/view/server.ts +32 -2
- 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 +0 -805
- package/src/view/view-report.test.ts +141 -22
- 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
package/src/view/app/i18n.ts
CHANGED
|
@@ -1,61 +1,11 @@
|
|
|
1
1
|
// view 前端 i18n:内核(插值/归一)在 src/i18n/core.ts;这里只注入
|
|
2
2
|
// localStorage + navigator 的 locale 来源与 en 默认值。字典与 CLI 侧分开维护。
|
|
3
|
-
// 词条只覆盖宿主机器(导航标签、attempt
|
|
4
|
-
// 是报告组件,文案在 niceeval/report 的组件词典里(src/report/locale.ts)。
|
|
3
|
+
// 词条只覆盖宿主机器(导航标签、attempt dialog 的关闭按钮):页面内容(hero、警告、列表、瀑布、
|
|
4
|
+
// attempt 详情)是报告组件,文案在 niceeval/report 的组件词典里(src/report/locale.ts)。
|
|
5
5
|
|
|
6
6
|
import { interpolate, normalizeLocale, type Locale, type Vars } from "../../i18n/core.ts";
|
|
7
7
|
|
|
8
|
-
export type MessageKey =
|
|
9
|
-
| "nav.label"
|
|
10
|
-
| "hero.title"
|
|
11
|
-
| "status.pass"
|
|
12
|
-
| "status.fail"
|
|
13
|
-
| "status.error"
|
|
14
|
-
| "status.skipped"
|
|
15
|
-
| "action.close"
|
|
16
|
-
| "action.copyPrompt"
|
|
17
|
-
| "action.copied"
|
|
18
|
-
| "trace.loading"
|
|
19
|
-
| "trace.loadFailed"
|
|
20
|
-
| "trace.timing"
|
|
21
|
-
| "trace.noSpans"
|
|
22
|
-
| "trace.total"
|
|
23
|
-
| "trace.spans"
|
|
24
|
-
| "trace.clickDetails"
|
|
25
|
-
| "trace.enableHint"
|
|
26
|
-
| "trace.enableHintLink"
|
|
27
|
-
| "trace.enableHintUrl"
|
|
28
|
-
| "transcript.noEvents"
|
|
29
|
-
| "transcript.user"
|
|
30
|
-
| "transcript.assistant"
|
|
31
|
-
| "transcript.thinking"
|
|
32
|
-
| "transcript.inputRequested"
|
|
33
|
-
| "transcript.awaitingInput"
|
|
34
|
-
| "transcript.contextCompacted"
|
|
35
|
-
| "transcript.skillLoaded"
|
|
36
|
-
| "transcript.rawEvent"
|
|
37
|
-
| "transcript.running"
|
|
38
|
-
| "transcript.input"
|
|
39
|
-
| "transcript.output"
|
|
40
|
-
| "transcript.empty"
|
|
41
|
-
| "code.otherAssertions"
|
|
42
|
-
| "code.noReply"
|
|
43
|
-
| "code.reply"
|
|
44
|
-
| "code.hide"
|
|
45
|
-
| "code.checks"
|
|
46
|
-
| "code.conversation"
|
|
47
|
-
| "code.noSource"
|
|
48
|
-
| "code.sourceUnavailable"
|
|
49
|
-
| "attempt.timing"
|
|
50
|
-
| "attempt.teardown"
|
|
51
|
-
| "attempt.diagnostics"
|
|
52
|
-
| "assert.pass"
|
|
53
|
-
| "assert.fail"
|
|
54
|
-
| "assert.passedCollapsed"
|
|
55
|
-
| "assert.unavailable"
|
|
56
|
-
| "assert.optional"
|
|
57
|
-
| "assert.soft"
|
|
58
|
-
| "assert.evidence";
|
|
8
|
+
export type MessageKey = "nav.label" | "hero.title" | "action.close" | "dialog.attemptTitle";
|
|
59
9
|
|
|
60
10
|
type Dictionary = Record<MessageKey, string>;
|
|
61
11
|
|
|
@@ -65,106 +15,16 @@ const dictionaries: Record<Locale, Dictionary> = {
|
|
|
65
15
|
// 标题回退链终点的内置文案(shell.md:「Eval 运行结果 / Eval Results」);
|
|
66
16
|
// 正常路径 server 侧已走完回退链,这里只兜旧数据 / 缺声明。
|
|
67
17
|
"hero.title": "Eval Results",
|
|
68
|
-
"status.pass": "pass",
|
|
69
|
-
"status.fail": "fail",
|
|
70
|
-
"status.error": "error",
|
|
71
|
-
"status.skipped": "skipped",
|
|
72
18
|
"action.close": "Close",
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
"trace.loadFailed": "load failed (static report has no server - use niceeval view):",
|
|
77
|
-
"trace.timing": "timing trace",
|
|
78
|
-
"trace.noSpans": "no spans",
|
|
79
|
-
"trace.total": "total",
|
|
80
|
-
"trace.spans": "spans",
|
|
81
|
-
"trace.clickDetails": "click a row for details",
|
|
82
|
-
"trace.enableHint": "No trace for this run. Wire up OTel to get a call waterfall — see the ",
|
|
83
|
-
"trace.enableHintLink": "OTel guide",
|
|
84
|
-
"trace.enableHintUrl": "https://niceeval.com/docs/guides/connect-otel",
|
|
85
|
-
"transcript.noEvents": "no events",
|
|
86
|
-
"transcript.user": "user",
|
|
87
|
-
"transcript.assistant": "assistant",
|
|
88
|
-
"transcript.thinking": "thinking",
|
|
89
|
-
"transcript.inputRequested": "input requested",
|
|
90
|
-
"transcript.awaitingInput": "(awaiting input)",
|
|
91
|
-
"transcript.contextCompacted": "context compacted",
|
|
92
|
-
"transcript.skillLoaded": "skill loaded",
|
|
93
|
-
"transcript.rawEvent": "unrecognized event, shown as-is",
|
|
94
|
-
"transcript.running": "running...",
|
|
95
|
-
"transcript.input": "input",
|
|
96
|
-
"transcript.output": "output",
|
|
97
|
-
"transcript.empty": "(empty)",
|
|
98
|
-
"code.otherAssertions": "other assertions",
|
|
99
|
-
"code.noReply": "(no reply)",
|
|
100
|
-
"code.reply": "reply",
|
|
101
|
-
"code.hide": "hide",
|
|
102
|
-
"code.checks": "checks",
|
|
103
|
-
"code.conversation": "conversation",
|
|
104
|
-
"code.noSource": "Source was not captured. This run may predate source-loc or the source may be unavailable. Re-run this eval to see the code view.",
|
|
105
|
-
"code.sourceUnavailable": "Source was captured for this run, but its artifact files are missing from this deployment. Re-export with `niceeval view --out <dir>` (directory mode bundles artifacts), or open the results locally with `niceeval view`.",
|
|
106
|
-
"attempt.timing": "timing",
|
|
107
|
-
"attempt.teardown": "teardown (not counted in total)",
|
|
108
|
-
"attempt.diagnostics": "diagnostics",
|
|
109
|
-
"assert.pass": "pass",
|
|
110
|
-
"assert.fail": "fail",
|
|
111
|
-
"assert.passedCollapsed": "{{count}} passed",
|
|
112
|
-
"assert.unavailable": "unavailable",
|
|
113
|
-
"assert.optional": "optional",
|
|
114
|
-
"assert.soft": "soft",
|
|
115
|
-
"assert.evidence": "What was checked",
|
|
19
|
+
// 屏幕阅读器专用(Radix Dialog 的可访问标题),视觉上不出现——内容本身的身份 / verdict
|
|
20
|
+
// 已经在 dialog 里可见。
|
|
21
|
+
"dialog.attemptTitle": "Attempt details",
|
|
116
22
|
},
|
|
117
23
|
"zh-CN": {
|
|
118
24
|
"nav.label": "报告",
|
|
119
25
|
"hero.title": "Eval 运行结果",
|
|
120
|
-
"status.pass": "通过",
|
|
121
|
-
"status.fail": "失败",
|
|
122
|
-
"status.error": "错误",
|
|
123
|
-
"status.skipped": "跳过",
|
|
124
26
|
"action.close": "关闭",
|
|
125
|
-
"
|
|
126
|
-
"action.copied": "已复制",
|
|
127
|
-
"trace.loading": "加载中...",
|
|
128
|
-
"trace.loadFailed": "加载失败(静态报告没有服务端 - 请用 niceeval view):",
|
|
129
|
-
"trace.timing": "耗时追踪",
|
|
130
|
-
"trace.noSpans": "没有 span",
|
|
131
|
-
"trace.total": "总计",
|
|
132
|
-
"trace.spans": "spans",
|
|
133
|
-
"trace.clickDetails": "点击行查看详情",
|
|
134
|
-
"trace.enableHint": "这次运行没有 trace。接入 OTel 才有调用瀑布图——看",
|
|
135
|
-
"trace.enableHintLink": "OTel 接入指南",
|
|
136
|
-
"trace.enableHintUrl": "https://niceeval.com/docs/zh/how-to/connect-otel",
|
|
137
|
-
"transcript.noEvents": "没有事件",
|
|
138
|
-
"transcript.user": "user",
|
|
139
|
-
"transcript.assistant": "assistant",
|
|
140
|
-
"transcript.thinking": "thinking",
|
|
141
|
-
"transcript.inputRequested": "请求输入",
|
|
142
|
-
"transcript.awaitingInput": "(等待输入)",
|
|
143
|
-
"transcript.contextCompacted": "上下文已压缩",
|
|
144
|
-
"transcript.skillLoaded": "已加载 Skill",
|
|
145
|
-
"transcript.rawEvent": "未识别事件,原样展示",
|
|
146
|
-
"transcript.running": "运行中...",
|
|
147
|
-
"transcript.input": "输入",
|
|
148
|
-
"transcript.output": "输出",
|
|
149
|
-
"transcript.empty": "(空)",
|
|
150
|
-
"code.otherAssertions": "其它断言",
|
|
151
|
-
"code.noReply": "(无回复)",
|
|
152
|
-
"code.reply": "回复",
|
|
153
|
-
"code.hide": "收起",
|
|
154
|
-
"code.checks": "检查",
|
|
155
|
-
"code.conversation": "会话",
|
|
156
|
-
"code.noSource": "源码未捕获。此 run 可能早于 source-loc,或源码不可读。重跑此 eval 即可看到代码视图。",
|
|
157
|
-
"code.sourceUnavailable": "此 run 捕获过源码,但当前部署里缺少它的 artifact 文件。用 `niceeval view --out <目录>` 重新导出(目录模式会带上 artifact),或在本地 `niceeval view` 查看。",
|
|
158
|
-
"attempt.timing": "耗时",
|
|
159
|
-
"attempt.teardown": "收尾(不计入总耗时)",
|
|
160
|
-
"attempt.diagnostics": "诊断",
|
|
161
|
-
"assert.pass": "通过",
|
|
162
|
-
"assert.fail": "失败",
|
|
163
|
-
"assert.passedCollapsed": "{{count}} 条通过",
|
|
164
|
-
"assert.unavailable": "评不了",
|
|
165
|
-
"assert.optional": "可缺席",
|
|
166
|
-
"assert.soft": "soft",
|
|
167
|
-
"assert.evidence": "实际被检查的内容",
|
|
27
|
+
"dialog.attemptTitle": "Attempt 详情",
|
|
168
28
|
},
|
|
169
29
|
};
|
|
170
30
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// cases: docs/engineering/unit-tests/reports/cases.md
|
|
2
|
+
// 第 207 行:增强脚本拦截 locator 链接后,dialog 内容与直接打开该文档的内容是同一份
|
|
3
|
+
// server-rendered 字节/DOM 片段。
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { attemptHrefFor, attemptLocatorFromHref, hashForAttempt, locatorFromHash, parseAttemptDocument } from "./attempt-dialog.ts";
|
|
6
|
+
|
|
7
|
+
describe("attemptHrefFor / attemptLocatorFromHref", () => {
|
|
8
|
+
it("互为逆运算(编码/解码往返)", () => {
|
|
9
|
+
const locator = "@1kijjdij";
|
|
10
|
+
const href = attemptHrefFor(locator);
|
|
11
|
+
expect(href).toBe("attempt/%401kijjdij.html");
|
|
12
|
+
expect(attemptLocatorFromHref(href)).toBe(locator);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("不是 attempt 文档链接或形状不对时返回 undefined", () => {
|
|
16
|
+
expect(attemptLocatorFromHref("index.html")).toBeUndefined();
|
|
17
|
+
expect(attemptLocatorFromHref("artifact/e/run/a0/events.json")).toBeUndefined();
|
|
18
|
+
expect(attemptLocatorFromHref("attempt/not-a-locator.html")).toBeUndefined();
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe("hashForAttempt / locatorFromHash", () => {
|
|
23
|
+
it("互为逆运算", () => {
|
|
24
|
+
expect(locatorFromHash(hashForAttempt("@abc123"))).toBe("@abc123");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("非 attempt 路由或形状不对返回 undefined", () => {
|
|
28
|
+
expect(locatorFromHash("#/page/report")).toBeUndefined();
|
|
29
|
+
expect(locatorFromHash("#/attempt/not-valid")).toBeUndefined();
|
|
30
|
+
expect(locatorFromHash("")).toBeUndefined();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("parseAttemptDocument", () => {
|
|
35
|
+
function fakeDocument(en: string, zh: string): string {
|
|
36
|
+
return [
|
|
37
|
+
"<!doctype html>",
|
|
38
|
+
"<html><head></head><body>",
|
|
39
|
+
`<div data-nre-locale="en">${en}</div>`,
|
|
40
|
+
`<div data-nre-locale="zh-CN" hidden>${zh}</div>`,
|
|
41
|
+
"<script>/* locale swap */</script>",
|
|
42
|
+
"</body></html>",
|
|
43
|
+
].join("\n");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
it("取出两种语言的内容片段,不含包裹的 div 标签本身", () => {
|
|
47
|
+
const html = fakeDocument("<p>hello</p>", "<p>你好</p>");
|
|
48
|
+
expect(parseAttemptDocument(html)).toEqual({ en: "<p>hello</p>", "zh-CN": "<p>你好</p>" });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("内容里嵌套的 <div> 不会打断切分(现实里的 AttemptDetail 输出全是嵌套 div)", () => {
|
|
52
|
+
const html = fakeDocument(
|
|
53
|
+
'<div class="nre nre-col"><div class="nre-attempt-summary">stuff</div></div>',
|
|
54
|
+
'<div class="nre nre-col"><div class="nre-attempt-summary">东西</div></div>',
|
|
55
|
+
);
|
|
56
|
+
expect(parseAttemptDocument(html)).toEqual({
|
|
57
|
+
en: '<div class="nre nre-col"><div class="nre-attempt-summary">stuff</div></div>',
|
|
58
|
+
"zh-CN": '<div class="nre nre-col"><div class="nre-attempt-summary">东西</div></div>',
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("不是这份渲染器产出的文档(缺少标记)返回 null,不开空 dialog", () => {
|
|
63
|
+
expect(parseAttemptDocument("<html><body>not an attempt document</body></html>")).toBeNull();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// 独立 attempt 文档(attempt/<locator>.html,site.ts 的 renderAttemptDocument)的客户端消费面:
|
|
2
|
+
// 拦截同源链接、按 locator 拼 href、把 fetch 回来的文档两种语言内容抠出来塞进 dialog——
|
|
3
|
+
// 内容片段与直接打开该文档看到的完全一致,不维护第二份客户端渲染(view.md「静态导出」)。
|
|
4
|
+
// 纯字符串切分,不用 DOMParser:结构由同一个 site.ts 的固定模板产出,不需要通用 HTML 解析。
|
|
5
|
+
|
|
6
|
+
const EN_MARK = '<div data-nre-locale="en">';
|
|
7
|
+
const ZH_MARK = '<div data-nre-locale="zh-CN"';
|
|
8
|
+
const SCRIPT_MARK = "<script>";
|
|
9
|
+
|
|
10
|
+
export interface AttemptDocumentContent {
|
|
11
|
+
en: string;
|
|
12
|
+
"zh-CN": string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** attempt/<locator>.html 链接的形状(相对于当前文档的相对 href,与 encodeURIComponent(locator) 对应)。 */
|
|
16
|
+
const ATTEMPT_HREF_PATTERN = /^attempt\/(.+)\.html$/;
|
|
17
|
+
|
|
18
|
+
/** locator 串的最小形状:`@` + 至少一个 base36 字符——与 site.ts DEFAULT_ATTEMPT_HREF 编码前的原始值同形。 */
|
|
19
|
+
const LOCATOR_SHAPE = /^@[0-9a-z]+$/;
|
|
20
|
+
|
|
21
|
+
/** 相对 href → 解码后的 locator;不是 attempt 文档链接或 locator 形状不对都返回 undefined。 */
|
|
22
|
+
export function attemptLocatorFromHref(href: string): string | undefined {
|
|
23
|
+
const match = ATTEMPT_HREF_PATTERN.exec(href);
|
|
24
|
+
if (!match) return undefined;
|
|
25
|
+
const locator = decodeURIComponent(match[1]!);
|
|
26
|
+
return LOCATOR_SHAPE.test(locator) ? locator : undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** locator → 该文档的根相对 href(与 report/web.ts DEFAULT_ATTEMPT_HREF 同一编码规则)。 */
|
|
30
|
+
export function attemptHrefFor(locator: string): string {
|
|
31
|
+
return `attempt/${encodeURIComponent(locator)}.html`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const ATTEMPT_HASH_PREFIX = "#/attempt/";
|
|
35
|
+
|
|
36
|
+
/** hash → locator;不是这条路由或形状不对(旧格式深链、手打错的 hash)都返回 undefined。 */
|
|
37
|
+
export function locatorFromHash(hash: string): string | undefined {
|
|
38
|
+
if (!hash.startsWith(ATTEMPT_HASH_PREFIX)) return undefined;
|
|
39
|
+
const locator = hash.slice(ATTEMPT_HASH_PREFIX.length);
|
|
40
|
+
return LOCATOR_SHAPE.test(locator) ? locator : undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function hashForAttempt(locator: string): string {
|
|
44
|
+
return `${ATTEMPT_HASH_PREFIX}${locator}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 从 attempt 文档的响应文本里取出两种语言的内容片段。两个 locale 块紧邻、且两者之间/之后
|
|
49
|
+
* 不会出现这里搜索的标记字符串(site.ts 的固定模板保证),纯字符串切分足够,不需要 DOMParser。
|
|
50
|
+
* 形状不对(不是这份渲染器产出的文档)返回 null,调用方不开空 dialog。
|
|
51
|
+
*/
|
|
52
|
+
export function parseAttemptDocument(html: string): AttemptDocumentContent | null {
|
|
53
|
+
const enStart = html.indexOf(EN_MARK);
|
|
54
|
+
if (enStart === -1) return null;
|
|
55
|
+
const afterEnOpen = html.slice(enStart + EN_MARK.length);
|
|
56
|
+
const zhMarkIdx = afterEnOpen.indexOf(ZH_MARK);
|
|
57
|
+
if (zhMarkIdx === -1) return null;
|
|
58
|
+
const en = afterEnOpen.slice(0, zhMarkIdx).replace(/<\/div>\s*$/, "");
|
|
59
|
+
|
|
60
|
+
const afterZhMark = afterEnOpen.slice(zhMarkIdx);
|
|
61
|
+
const zhTagEnd = afterZhMark.indexOf(">");
|
|
62
|
+
if (zhTagEnd === -1) return null;
|
|
63
|
+
const afterZhOpen = afterZhMark.slice(zhTagEnd + 1);
|
|
64
|
+
const scriptIdx = afterZhOpen.indexOf(SCRIPT_MARK);
|
|
65
|
+
if (scriptIdx === -1) return null;
|
|
66
|
+
const zh = afterZhOpen.slice(0, scriptIdx).replace(/<\/div>\s*$/, "");
|
|
67
|
+
|
|
68
|
+
return { en, "zh-CN": zh };
|
|
69
|
+
}
|
package/src/view/app/main.tsx
CHANGED
package/src/view/app/types.ts
CHANGED
|
@@ -1,96 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AssertionResult,
|
|
3
|
-
JsonValue,
|
|
4
|
-
LocalizedText,
|
|
5
|
-
SourceArtifact,
|
|
6
|
-
SourceLoc,
|
|
7
|
-
StreamEvent,
|
|
8
|
-
TraceSpan,
|
|
9
|
-
Usage,
|
|
10
|
-
} from "../../types.ts";
|
|
11
|
-
import type { ViewData, ViewEvalResult } from "../shared/types.ts";
|
|
12
|
-
|
|
13
|
-
export type { LocalizedText };
|
|
14
1
|
// Locale 只在 i18n 内核声明一次;页面数据形状与 server 共用 shared/types.ts 的声明。
|
|
15
2
|
export type { Locale } from "../../i18n/core.ts";
|
|
16
|
-
export type {
|
|
17
|
-
|
|
18
|
-
ReportSlotHtml,
|
|
19
|
-
SkippedRunNotice,
|
|
20
|
-
ViewData,
|
|
21
|
-
ViewReportMeta,
|
|
22
|
-
ViewReportPageMeta,
|
|
23
|
-
ViewSnapshot,
|
|
24
|
-
} from "../shared/types.ts";
|
|
3
|
+
export type { LocalizedText } from "../../types.ts";
|
|
4
|
+
export type { ReportSlotHtml, ViewData, ViewReportPageMeta } from "../shared/types.ts";
|
|
25
5
|
|
|
26
6
|
/** 导航 tab:只有报告定义声明的页(`page:<id>`,路由 `#/page/<id>`),按声明序;宿主不追加任何项。 */
|
|
27
7
|
export type Tab = `page:${string}`;
|
|
28
8
|
|
|
29
|
-
/** 前端拿到的单条 attempt 结果就是瘦身后的 EvalResult(locator / artifactBase 由 loader 注入)。 */
|
|
30
|
-
export type ViewResult = ViewEvalResult;
|
|
31
|
-
|
|
32
|
-
export type Assertion = AssertionResult;
|
|
33
|
-
|
|
34
|
-
export type Verdict = "passed" | "failed" | "errored" | "skipped" | string;
|
|
35
|
-
|
|
36
|
-
export interface SourceTurn {
|
|
37
|
-
loc?: SourceLoc;
|
|
38
|
-
sent: string;
|
|
39
|
-
replies: Reply[];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export type Reply =
|
|
43
|
-
| { kind: "text"; text: string }
|
|
44
|
-
| { kind: "user"; text: string }
|
|
45
|
-
| { kind: "thinking"; text: string }
|
|
46
|
-
| { kind: "error"; text: string }
|
|
47
|
-
| { kind: "skill"; skill: string }
|
|
48
|
-
| { kind: "raw"; raw: ObjectRecord }
|
|
49
|
-
| { kind: "tool"; ev: ActionCalledEvent; result?: ActionResultEvent }
|
|
50
|
-
| { kind: "input"; ev: InputRequestedEvent };
|
|
51
|
-
|
|
52
|
-
export type ActionCalledEvent = Extract<StreamEvent, { type: "action.called" }>;
|
|
53
|
-
export type InputRequestedEvent = Extract<StreamEvent, { type: "input.requested" }>;
|
|
54
|
-
export type ActionResultEvent = Extract<StreamEvent, { type: "action.result" }>;
|
|
55
|
-
export type SubagentCalledEvent = Extract<StreamEvent, { type: "subagent.called" }>;
|
|
56
|
-
export type SubagentCompletedEvent = Extract<StreamEvent, { type: "subagent.completed" }>;
|
|
57
|
-
export type ToolResultEvent = ActionResultEvent | SubagentCompletedEvent;
|
|
58
|
-
export type ViewJson = JsonValue;
|
|
59
|
-
export type ViewUsage = Usage;
|
|
60
|
-
|
|
61
|
-
/** 标准事件流里前端认识的词汇。 */
|
|
62
|
-
export type KnownTranscriptEvent = StreamEvent;
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 未识别或形状不合的事件条目,由 asEvents 包装:不静默丢弃,渲染面原样展示
|
|
66
|
-
* (带原始 type 标签),让词汇演进在界面上可被发现、后续补一等呈现。
|
|
67
|
-
* `view.raw` 是 view 内部标记,不属于标准事件流词汇。
|
|
68
|
-
*/
|
|
69
|
-
export interface RawTranscriptEvent {
|
|
70
|
-
type: "view.raw";
|
|
71
|
-
raw: ObjectRecord;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export type TranscriptEvent = KnownTranscriptEvent | RawTranscriptEvent;
|
|
75
|
-
|
|
76
|
-
export interface Indexed<T> {
|
|
77
|
-
byKey: Map<string, T[]>;
|
|
78
|
-
noloc: T[];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface IndexedTurns {
|
|
82
|
-
byKey: Map<string, SourceTurn>;
|
|
83
|
-
noloc: SourceTurn[];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface CodeSource extends SourceArtifact {}
|
|
87
|
-
|
|
88
|
-
export type Span = TraceSpan;
|
|
89
|
-
|
|
90
|
-
export type ObjectRecord = Record<string, JsonValue | undefined>;
|
|
91
|
-
|
|
92
9
|
declare global {
|
|
93
10
|
interface Window {
|
|
94
|
-
__NICEEVAL_VIEW_DATA__?: ViewData;
|
|
11
|
+
__NICEEVAL_VIEW_DATA__?: import("../shared/types.ts").ViewData;
|
|
95
12
|
}
|
|
96
13
|
}
|
|
@@ -14,12 +14,20 @@
|
|
|
14
14
|
import { mkdtemp, readFile, readdir, rm } from "node:fs/promises";
|
|
15
15
|
import { tmpdir } from "node:os";
|
|
16
16
|
import { join } from "node:path";
|
|
17
|
-
import { afterEach, describe, expect, it
|
|
17
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
18
18
|
import { createResultsWriter } from "../results/index.ts";
|
|
19
|
-
import {
|
|
19
|
+
import type { AttemptHandle } from "../results/index.ts";
|
|
20
|
+
import { loadViewScan, type ViewScan } from "./data.ts";
|
|
20
21
|
import { buildView } from "./index.ts";
|
|
21
22
|
import { startViewServer, type ViewServer } from "./server.ts";
|
|
22
|
-
|
|
23
|
+
|
|
24
|
+
/** scan.attemptsByBase 按 base 建索引;测试只关心按 eval id 找回 (handle, base)。 */
|
|
25
|
+
function attemptByEvalId(scan: ViewScan, evalId: string): { handle: AttemptHandle; base: string } {
|
|
26
|
+
for (const [base, handle] of scan.attemptsByBase) {
|
|
27
|
+
if (handle.evalId === evalId) return { handle, base };
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`no attempt found for eval id "${evalId}"`);
|
|
30
|
+
}
|
|
23
31
|
|
|
24
32
|
const SHARED_CONTENT = "export default { test() {} };\n";
|
|
25
33
|
const SHARED_PATH = "evals/shared.eval.ts";
|
|
@@ -80,17 +88,15 @@ describe("server.ts · serveArtifact 对 sources.json 解引用", () => {
|
|
|
80
88
|
await seedDedupedSnapshot(root);
|
|
81
89
|
|
|
82
90
|
const scan = await loadViewScan(root);
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
expect(
|
|
87
|
-
expect(q2.hasSources).toBe(true);
|
|
91
|
+
const q1 = attemptByEvalId(scan, "q1");
|
|
92
|
+
const q2 = attemptByEvalId(scan, "q2");
|
|
93
|
+
expect(q1.handle.result.hasSources).toBe(true);
|
|
94
|
+
expect(q2.handle.result.hasSources).toBe(true);
|
|
88
95
|
|
|
89
96
|
server = await startViewServer({ input: root });
|
|
90
97
|
|
|
91
|
-
for (const
|
|
92
|
-
const
|
|
93
|
-
const res = await fetch(url);
|
|
98
|
+
for (const { base } of [q1, q2]) {
|
|
99
|
+
const res = await fetch(new URL(`artifact/${base}/sources.json`, server.url));
|
|
94
100
|
expect(res.status).toBe(200);
|
|
95
101
|
const body = await res.json();
|
|
96
102
|
expect(body).toEqual([{ path: SHARED_PATH, content: SHARED_CONTENT }]);
|
|
@@ -102,12 +108,11 @@ describe("server.ts · serveArtifact 对 sources.json 解引用", () => {
|
|
|
102
108
|
const root = await makeRoot();
|
|
103
109
|
await seedDedupedSnapshot(root);
|
|
104
110
|
const scan = await loadViewScan(root);
|
|
105
|
-
const q3 = scan
|
|
106
|
-
expect(q3.hasEvents).toBe(true);
|
|
111
|
+
const q3 = attemptByEvalId(scan, "q3");
|
|
112
|
+
expect(q3.handle.result.hasEvents).toBe(true);
|
|
107
113
|
|
|
108
114
|
server = await startViewServer({ input: root });
|
|
109
|
-
const
|
|
110
|
-
const res = await fetch(url);
|
|
115
|
+
const res = await fetch(new URL(`artifact/${q3.base}/events.json`, server.url));
|
|
111
116
|
expect(res.status).toBe(200);
|
|
112
117
|
expect(await res.json()).toEqual([{ type: "message", role: "user", text: "hi" }]);
|
|
113
118
|
});
|
|
@@ -122,36 +127,15 @@ describe("index.ts · copyFetchedArtifacts(--out 静态导出)对 sources.json
|
|
|
122
127
|
await buildView({ input: root, out });
|
|
123
128
|
|
|
124
129
|
const scan = await loadViewScan(root);
|
|
125
|
-
const byId = new Map(scan.viewData.snapshots.flatMap((s) => s.results.map((r) => [r.id, r])));
|
|
126
130
|
for (const id of ["q1", "q2"]) {
|
|
127
|
-
const base =
|
|
131
|
+
const { base } = attemptByEvalId(scan, id);
|
|
128
132
|
const exported = JSON.parse(await readFile(join(out, "artifact", base, "sources.json"), "utf-8"));
|
|
129
133
|
expect(exported).toEqual([{ path: SHARED_PATH, content: SHARED_CONTENT }]);
|
|
130
134
|
expect(exported[0]).not.toHaveProperty("sha256");
|
|
131
135
|
}
|
|
132
136
|
|
|
133
|
-
const q3Base =
|
|
137
|
+
const q3Base = attemptByEvalId(scan, "q3").base;
|
|
134
138
|
const exportedEvents = JSON.parse(await readFile(join(out, "artifact", q3Base, "events.json"), "utf-8"));
|
|
135
139
|
expect(exportedEvents).toEqual([{ type: "message", role: "user", text: "hi" }]);
|
|
136
140
|
});
|
|
137
141
|
});
|
|
138
|
-
|
|
139
|
-
describe("artifact-url.ts · fetch 基底 = 页面所在目录(无尾斜杠托管不断链)", () => {
|
|
140
|
-
// bug: memory/showcase-subpath-no-trailing-slash-breaks-artifact-fetch.md
|
|
141
|
-
afterEach(() => vi.unstubAllGlobals());
|
|
142
|
-
|
|
143
|
-
it("页面服务在无尾斜杠子路径(反代 rewrite)时,fetch 拼在该路径目录下", () => {
|
|
144
|
-
vi.stubGlobal("location", { pathname: "/showcase/memory" });
|
|
145
|
-
expect(artifactUrl("e/run/a0/sources.json")).toBe("/showcase/memory/artifact/e/run/a0/sources.json");
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("直接打开 <dir>/index.html 时末段按文件名去掉,fetch 落在 <dir>/ 下", () => {
|
|
149
|
-
vi.stubGlobal("location", { pathname: "/foo/index.html" });
|
|
150
|
-
expect(artifactUrl("e/run/a0/trace.json")).toBe("/foo/artifact/e/run/a0/trace.json");
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it("站点根路径不产生双斜杠", () => {
|
|
154
|
-
vi.stubGlobal("location", { pathname: "/" });
|
|
155
|
-
expect(artifactUrl("e/run/a0/events.json")).toBe("/artifact/e/run/a0/events.json");
|
|
156
|
-
});
|
|
157
|
-
});
|