niceeval 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INDEX.md +23 -23
- package/README.zh.md +6 -6
- package/dist/agents/types.d.ts +69 -7
- package/dist/context/types.d.ts +32 -12
- package/dist/i18n/en.d.ts +54 -0
- package/dist/i18n/zh-CN.d.ts +57 -3
- package/dist/o11y/types.d.ts +16 -2
- package/dist/report/aggregate.d.ts +32 -24
- package/dist/report/aggregate.js +158 -50
- package/dist/report/built-in/index.d.ts +2 -0
- package/dist/report/built-in/index.js +8 -0
- package/dist/report/components.d.ts +93 -160
- package/dist/report/components.js +377 -114
- package/dist/report/compute.d.ts +87 -81
- package/dist/report/compute.js +597 -417
- package/dist/report/flag.d.ts +32 -6
- package/dist/report/flag.js +92 -4
- package/dist/report/format.d.ts +19 -11
- package/dist/report/format.js +30 -13
- package/dist/report/index.d.ts +16 -16
- package/dist/report/index.js +20 -21
- package/dist/report/load.js +3 -2
- package/dist/report/locale.d.ts +57 -33
- package/dist/report/locale.js +122 -56
- package/dist/report/metrics.d.ts +23 -4
- package/dist/report/metrics.js +110 -25
- package/dist/report/primitives.d.ts +48 -15
- package/dist/report/primitives.js +135 -26
- package/dist/report/react/AttemptList.d.ts +9 -7
- package/dist/report/react/AttemptList.js +17 -10
- package/dist/report/react/DeltaTable.js +19 -18
- package/dist/report/react/EvalList.d.ts +4 -4
- package/dist/report/react/EvalList.js +0 -0
- package/dist/report/react/ExperimentComparison.d.ts +10 -0
- package/dist/report/react/ExperimentComparison.js +12 -0
- package/dist/report/react/ExperimentList.d.ts +4 -3
- package/dist/report/react/ExperimentList.js +17 -18
- package/dist/report/react/MetricBars.js +5 -4
- package/dist/report/react/MetricLine.js +12 -5
- package/dist/report/react/MetricMatrix.js +1 -1
- package/dist/report/react/MetricScatter.js +59 -28
- package/dist/report/react/MetricTable.js +2 -12
- package/dist/report/react/ScopeSummary.d.ts +10 -0
- package/dist/report/react/ScopeSummary.js +17 -0
- package/dist/report/react/Scoreboard.js +6 -6
- package/dist/report/react/cell.js +2 -2
- package/dist/report/react/chart-math.d.ts +23 -6
- package/dist/report/react/chart-math.js +71 -19
- package/dist/report/react/fixtures.d.ts +5 -9
- package/dist/report/react/fixtures.js +110 -147
- package/dist/report/react/index.d.ts +15 -5
- package/dist/report/react/index.js +18 -7
- package/dist/report/report.d.ts +137 -16
- package/dist/report/report.js +259 -28
- package/dist/report/text/faces.d.ts +17 -19
- package/dist/report/text/faces.js +253 -184
- package/dist/report/text/plot.js +1 -1
- package/dist/report/text/table.js +38 -7
- package/dist/report/tree.d.ts +90 -40
- package/dist/report/tree.js +252 -94
- package/dist/report/types.d.ts +247 -284
- package/dist/report/types.js +4 -3
- package/dist/report/web.d.ts +21 -5
- package/dist/report/web.js +42 -16
- package/dist/results/select.d.ts +38 -16
- package/dist/results/select.js +73 -25
- package/dist/results/types.d.ts +49 -14
- package/dist/runner/feedback/sink.d.ts +110 -0
- package/dist/runner/types.d.ts +513 -22
- package/dist/sandbox/docker.d.ts +23 -2
- package/dist/sandbox/e2b.d.ts +15 -1
- package/dist/sandbox/errors.d.ts +30 -3
- package/dist/sandbox/io-retry.d.ts +17 -0
- package/dist/sandbox/registry.d.ts +2 -0
- package/dist/sandbox/resolve.d.ts +18 -5
- package/dist/sandbox/retry.d.ts +11 -1
- package/dist/sandbox/types.d.ts +39 -5
- package/dist/sandbox/vercel.d.ts +7 -1
- package/dist/scoring/coverage.d.ts +30 -0
- package/dist/scoring/display.d.ts +21 -0
- package/dist/scoring/display.js +120 -0
- package/dist/scoring/types.d.ts +103 -20
- package/dist/shared/aggregate.d.ts +4 -2
- package/dist/shared/aggregate.js +8 -7
- package/dist/shared/types.d.ts +28 -0
- package/dist/tty-line.d.ts +0 -4
- package/dist/util.d.ts +23 -0
- package/docs-site/zh/README.md +44 -0
- package/docs-site/zh/examples/ai-agent-application.mdx +63 -0
- package/docs-site/zh/examples/coding-agent-extensions.mdx +57 -0
- package/docs-site/zh/examples/index.mdx +50 -0
- package/docs-site/zh/{concepts → explanation}/adapter.mdx +31 -13
- package/docs-site/zh/{concepts → explanation}/assert.mdx +7 -7
- package/docs-site/zh/{concepts → explanation}/drive.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/evals.mdx +4 -4
- package/docs-site/zh/{concepts → explanation}/experiment.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/hitl.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/judge.mdx +5 -5
- package/docs-site/zh/{concepts → explanation}/overview.mdx +11 -11
- package/docs-site/zh/{guides → explanation}/runner.mdx +18 -8
- package/docs-site/zh/{concepts → explanation}/tier.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/agent-feedback-loop.mdx +35 -33
- package/docs-site/zh/{guides → how-to}/authoring.mdx +35 -2
- package/docs-site/zh/{guides → how-to}/ci-integration.mdx +23 -12
- package/docs-site/zh/{guides → how-to}/connect-otel.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/connect-your-agent.mdx +47 -21
- package/docs-site/zh/{guides → how-to}/custom-reports.mdx +34 -39
- package/docs-site/zh/{guides → how-to}/dataset-fanout.mdx +25 -3
- package/docs-site/zh/{guides → how-to}/experiments.mdx +12 -5
- package/docs-site/zh/how-to/publish-report.mdx +105 -0
- package/docs-site/zh/{guides → how-to}/reporters.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/sandbox-agent.mdx +56 -7
- package/docs-site/zh/how-to/sandbox-providers.mdx +350 -0
- package/docs-site/zh/{guides → how-to}/scoring-guide.mdx +4 -4
- package/docs-site/zh/{guides → how-to}/viewing-results.mdx +82 -39
- package/docs-site/zh/{guides → how-to}/write-experiment.mdx +6 -4
- package/docs-site/zh/{guides → how-to}/write-send.mdx +30 -14
- package/docs-site/zh/index.mdx +24 -26
- package/docs-site/zh/introduction.mdx +8 -8
- package/docs-site/zh/reference/builtin-agents.mdx +32 -5
- package/docs-site/zh/reference/capabilities.mdx +8 -8
- package/docs-site/zh/reference/cli.mdx +40 -12
- package/docs-site/zh/reference/define-agent.mdx +58 -5
- package/docs-site/zh/reference/define-config.mdx +1 -1
- package/docs-site/zh/reference/define-eval.mdx +42 -9
- package/docs-site/zh/reference/events.mdx +3 -3
- package/docs-site/zh/reference/expect.mdx +26 -1
- package/docs-site/zh/{guides → reference}/official-adapters.mdx +32 -8
- package/docs-site/zh/{guides → reference}/report-components.mdx +45 -33
- package/docs-site/zh/{guides → reference}/results-data.mdx +21 -13
- package/docs-site/zh/troubleshooting/debug-sandbox.mdx +57 -0
- package/docs-site/zh/troubleshooting/debugging.mdx +212 -0
- package/docs-site/zh/{quickstart.mdx → tutorials/quickstart.mdx} +5 -17
- package/package.json +10 -2
- package/src/agents/ai-sdk-otel.test.ts +1 -0
- package/src/agents/ai-sdk.test.ts +3 -0
- package/src/agents/ai-sdk.ts +3 -0
- package/src/agents/bub-install-spec.test.ts +34 -0
- package/src/agents/bub-install-spec.ts +32 -0
- package/src/agents/bub.ts +31 -32
- package/src/agents/claude-code.test.ts +130 -9
- package/src/agents/claude-code.ts +76 -4
- package/src/agents/codex.test.ts +189 -40
- package/src/agents/codex.ts +155 -14
- package/src/agents/coding-cli-versions.test.ts +15 -0
- package/src/agents/coding-cli-versions.ts +3 -0
- package/src/agents/index.ts +13 -2
- package/src/agents/langgraph.test.ts +204 -0
- package/src/agents/langgraph.ts +495 -0
- package/src/agents/marketplace.ts +85 -0
- package/src/agents/native-config.test.ts +179 -0
- package/src/agents/native-config.ts +267 -0
- package/src/agents/openai-compat.test.ts +1 -0
- package/src/agents/openai-compat.ts +1 -1
- package/src/agents/openclaw.test.ts +31 -0
- package/src/agents/openclaw.ts +171 -0
- package/src/agents/plugin-config.test.ts +1 -0
- package/src/agents/sdk-streams.test.ts +79 -0
- package/src/agents/sdk-streams.ts +55 -10
- package/src/agents/skills.test.ts +1 -0
- package/src/agents/streaming.test.ts +3 -9
- package/src/agents/streaming.ts +2 -2
- package/src/agents/types.ts +71 -8
- package/src/agents/ui-message-stream.test.ts +3 -0
- package/src/cli.ts +446 -124
- package/src/context/context.test.ts +51 -12
- package/src/context/context.ts +162 -30
- package/src/context/session.test.ts +2 -1
- package/src/context/session.ts +115 -7
- package/src/context/types.ts +30 -12
- package/src/define.test.ts +13 -8
- package/src/define.ts +25 -4
- package/src/expect/index.ts +53 -23
- package/src/i18n/en.ts +81 -17
- package/src/i18n/zh-CN.ts +80 -17
- package/src/o11y/cost.test.ts +1 -0
- package/src/o11y/execution-tree.test.ts +1 -20
- package/src/o11y/otlp/mappers/claude-code.test.ts +1 -0
- package/src/o11y/otlp/parse.test.ts +1 -0
- package/src/o11y/otlp/turn-otel.test.ts +1 -0
- package/src/o11y/parsers/bub.test.ts +1 -0
- package/src/o11y/parsers/claude-code.test.ts +1 -34
- package/src/o11y/parsers/openclaw.test.ts +154 -0
- package/src/o11y/parsers/openclaw.ts +310 -0
- package/src/o11y/prices.json +746 -311
- package/src/o11y/tool-names.test.ts +1 -0
- package/src/o11y/types.ts +16 -2
- package/src/report/aggregate.ts +178 -61
- package/src/report/built-in/index.tsx +9 -0
- package/src/report/components.tsx +625 -279
- package/src/report/compute.ts +723 -491
- package/src/report/dual-render.test.tsx +741 -1024
- package/src/report/flag.ts +104 -12
- package/src/report/format.ts +32 -12
- package/src/report/index.ts +119 -46
- package/src/report/load.ts +3 -2
- package/src/report/locale.ts +136 -65
- package/src/report/metrics.ts +108 -25
- package/src/report/primitives.tsx +196 -45
- package/src/report/react/AttemptList.tsx +30 -43
- package/src/report/react/DeltaTable.tsx +63 -45
- package/src/report/react/EvalList.tsx +0 -0
- package/src/report/react/ExperimentComparison.tsx +73 -0
- package/src/report/react/ExperimentList.tsx +50 -32
- package/src/report/react/MetricBars.tsx +5 -4
- package/src/report/react/MetricLine.tsx +13 -8
- package/src/report/react/MetricMatrix.tsx +2 -2
- package/src/report/react/MetricScatter.tsx +86 -34
- package/src/report/react/MetricTable.tsx +4 -76
- package/src/report/react/ScopeSummary.tsx +86 -0
- package/src/report/react/Scoreboard.tsx +28 -10
- package/src/report/react/cell.tsx +2 -2
- package/src/report/react/chart-math.test.ts +85 -0
- package/src/report/react/chart-math.ts +101 -22
- package/src/report/react/enhance.js +89 -5
- package/src/report/react/fixtures.ts +114 -154
- package/src/report/react/index.tsx +24 -39
- package/src/report/react/render.test.tsx +138 -158
- package/src/report/react/styles.css +243 -82
- package/src/report/report.test.ts +779 -841
- package/src/report/report.ts +423 -41
- package/src/report/text/faces.ts +290 -193
- package/src/report/text/plot.ts +1 -1
- package/src/report/text/table.ts +44 -7
- package/src/report/tree.ts +362 -104
- package/src/report/types.ts +261 -271
- package/src/report/web.ts +63 -20
- package/src/results/annotated-source.test.ts +62 -9
- package/src/results/annotated-source.ts +64 -6
- package/src/results/attempt-evidence.test.ts +13 -11
- package/src/results/attempt-evidence.ts +20 -13
- package/src/results/attempt-source.ts +6 -3
- package/src/results/copy.ts +150 -60
- package/src/results/host-equivalence.test.ts +34 -20
- package/src/results/index.ts +12 -4
- package/src/results/locator.test.ts +1 -22
- package/src/results/open.ts +15 -5
- package/src/results/publish.ts +149 -0
- package/src/results/results.test.ts +89 -54
- package/src/results/select.ts +104 -34
- package/src/results/truncate.ts +90 -0
- package/src/results/types.ts +43 -14
- package/src/results/writer.ts +31 -13
- package/src/runner/attempt.test.ts +138 -7
- package/src/runner/attempt.ts +603 -104
- package/src/runner/discover.test.ts +47 -0
- package/src/runner/discover.ts +36 -2
- package/src/runner/eval-source.test.ts +1 -27
- package/src/runner/feedback/agent.test.ts +504 -0
- package/src/runner/feedback/agent.ts +409 -0
- package/src/runner/feedback/ci.test.ts +562 -0
- package/src/runner/feedback/ci.ts +401 -0
- package/src/runner/feedback/coordinator.test.ts +317 -0
- package/src/runner/feedback/coordinator.ts +397 -0
- package/src/runner/feedback/failure.ts +40 -0
- package/src/runner/feedback/human.test.ts +616 -0
- package/src/runner/feedback/human.ts +535 -0
- package/src/runner/feedback/index.ts +66 -0
- package/src/runner/feedback/io.ts +78 -0
- package/src/runner/feedback/profile.test.ts +50 -0
- package/src/runner/feedback/profile.ts +58 -0
- package/src/runner/feedback/reducer.test.ts +395 -0
- package/src/runner/feedback/reducer.ts +260 -0
- package/src/runner/feedback/renderer.ts +82 -0
- package/src/runner/feedback/sink.ts +203 -0
- package/src/runner/feedback/testing.ts +106 -0
- package/src/runner/ledger.test.ts +230 -0
- package/src/runner/ledger.ts +329 -0
- package/src/runner/report.test.ts +128 -3
- package/src/runner/report.ts +33 -9
- package/src/runner/reporters/artifacts.ts +8 -2
- package/src/runner/reporters/braintrust.test.ts +8 -7
- package/src/runner/reporters/braintrust.ts +9 -2
- package/src/runner/reporters/index.ts +2 -2
- package/src/runner/reporters/json.test.ts +162 -0
- package/src/runner/reporters/json.ts +35 -8
- package/src/runner/reporters/shared.ts +1 -5
- package/src/runner/run.test.ts +760 -3
- package/src/runner/run.ts +243 -37
- package/src/runner/sandbox-prep.ts +3 -42
- package/src/runner/timing.ts +158 -0
- package/src/runner/types.ts +518 -22
- package/src/sandbox/checkpoint.test.ts +55 -0
- package/src/sandbox/checkpoint.ts +29 -8
- package/src/sandbox/cli-commands.ts +407 -0
- package/src/sandbox/docker.ts +115 -16
- package/src/sandbox/e2b-agent-template.test.ts +56 -0
- package/src/sandbox/e2b-agent-template.ts +94 -0
- package/src/sandbox/e2b.ts +74 -9
- package/src/sandbox/errors.ts +111 -4
- package/src/sandbox/index.ts +2 -0
- package/src/sandbox/io-retry.test.ts +58 -0
- package/src/sandbox/io-retry.ts +45 -0
- package/src/sandbox/keep-registry.test.ts +86 -0
- package/src/sandbox/keep-registry.ts +142 -0
- package/src/sandbox/keep.ts +178 -0
- package/src/sandbox/paths.test.ts +1 -0
- package/src/sandbox/paths.ts +19 -8
- package/src/sandbox/registry.ts +20 -3
- package/src/sandbox/resolve.ts +76 -11
- package/src/sandbox/retry.test.ts +70 -0
- package/src/sandbox/retry.ts +46 -4
- package/src/sandbox/types.ts +44 -6
- package/src/sandbox/vercel.ts +43 -20
- package/src/scoring/collector.ts +60 -17
- package/src/scoring/coverage.ts +95 -0
- package/src/scoring/diff.ts +81 -0
- package/src/scoring/display.test.ts +121 -0
- package/src/scoring/display.ts +133 -0
- package/src/scoring/evidence.test.ts +189 -0
- package/src/scoring/judge.test.ts +142 -0
- package/src/scoring/judge.ts +15 -18
- package/src/scoring/scoped.ts +217 -50
- package/src/scoring/types.ts +117 -20
- package/src/scoring/verdict.ts +16 -4
- package/src/shared/aggregate.ts +8 -6
- package/src/shared/types.ts +31 -0
- package/src/show/compose.ts +50 -67
- package/src/show/index.ts +127 -56
- package/src/show/render.ts +662 -131
- package/src/show/report-host.test.ts +188 -0
- package/src/show/report-host.ts +375 -0
- package/src/show/show.test.ts +320 -54
- package/src/tty-line.ts +8 -26
- package/src/util.test.ts +1 -0
- package/src/util.ts +41 -0
- package/src/view/app/App.test.tsx +69 -0
- package/src/view/app/App.tsx +144 -48
- package/src/view/app/components/AttemptModal.tsx +423 -11
- package/src/view/app/components/CodeView.tsx +41 -14
- package/src/view/app/components/CopyControls.tsx +2 -2
- package/src/view/app/i18n.ts +37 -17
- package/src/view/app/lib/attempt-route.test.ts +1 -0
- package/src/view/app/lib/verdict.ts +7 -9
- package/src/view/app/main.tsx +13 -8
- package/src/view/app/pages/{RunsPage.tsx → AttemptsPage.tsx} +6 -6
- package/src/view/app/types.ts +4 -1
- package/src/view/artifact-serving.test.ts +2 -1
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +17 -17
- package/src/view/data.test.ts +10 -3
- package/src/view/data.ts +155 -49
- package/src/view/index.ts +56 -41
- package/src/view/server.ts +37 -15
- package/src/view/shared/types.ts +34 -5
- package/src/view/styles.css +227 -0
- package/src/view/view-report.test.ts +167 -62
- package/dist/report/built-ins/experiment-comparison.d.ts +0 -1
- package/dist/report/built-ins/experiment-comparison.js +0 -13
- package/dist/report/built-ins/index.d.ts +0 -1
- package/dist/report/built-ins/index.js +0 -2
- package/dist/report/react/GroupSummary.d.ts +0 -8
- package/dist/report/react/GroupSummary.js +0 -8
- package/dist/report/react/RunOverview.d.ts +0 -8
- package/dist/report/react/RunOverview.js +0 -12
- package/docs-site/zh/example/ai-agent-application.mdx +0 -152
- package/docs-site/zh/example/claude-code-codex-plugin.mdx +0 -167
- package/docs-site/zh/example/claude-code-codex-skill.mdx +0 -152
- package/docs-site/zh/example/showcase.mdx +0 -39
- package/docs-site/zh/guides/publish-report.mdx +0 -91
- package/docs-site/zh/guides/sandbox-providers.mdx +0 -102
- package/src/report/built-in-user-parity.test.tsx +0 -640
- package/src/report/built-ins/experiment-comparison.tsx +0 -19
- package/src/report/built-ins/index.ts +0 -2
- package/src/report/react/GroupSummary.tsx +0 -66
- package/src/report/react/RunOverview.tsx +0 -109
- package/src/runner/reporters/console.ts +0 -70
- package/src/runner/reporters/live.test.ts +0 -56
- package/src/runner/reporters/live.ts +0 -247
- package/src/runner/reporters/quiet.test.ts +0 -66
- package/src/runner/reporters/quiet.ts +0 -49
- package/src/runner/reporters/table.ts +0 -277
- /package/docs-site/zh/{example/tier1-ai-sdk-v7.mdx → examples/integrations/ai-sdk-v7.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-claude-sdk.mdx → examples/integrations/claude-sdk.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-codex-sdk.mdx → examples/integrations/codex-sdk.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-langgraph.mdx → examples/integrations/langgraph.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-pi-sdk.mdx → examples/integrations/pi-sdk.mdx} +0 -0
- /package/docs-site/zh/{guides → how-to}/fixtures.mdx +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// cases: docs/engineering/unit-tests/adapters/cases.md
|
|
1
2
|
import { describe, expect, it } from "vitest";
|
|
2
3
|
|
|
3
4
|
import { fromClaudeSdkMessages, fromCodexThreadEvents, fromPiAgentEvents, sseJsonFrames } from "./sdk-streams.ts";
|
|
@@ -50,6 +51,26 @@ describe("fromClaudeSdkMessages", () => {
|
|
|
50
51
|
expect(s.add({ type: "user", message: { content: [{ type: "tool_result", tool_use_id: "tu1", content: "denied" }] } })).toEqual([]);
|
|
51
52
|
});
|
|
52
53
|
|
|
54
|
+
it("assistant 的 thinking 块 → thinking 事件,与 text/tool_use 保持原始顺序", () => {
|
|
55
|
+
const s = fromClaudeSdkMessages();
|
|
56
|
+
expect(
|
|
57
|
+
s.add({
|
|
58
|
+
type: "assistant",
|
|
59
|
+
message: {
|
|
60
|
+
content: [
|
|
61
|
+
{ type: "thinking", thinking: "先查天气", signature: "sig-1" },
|
|
62
|
+
{ type: "text", text: "我来查" },
|
|
63
|
+
{ type: "tool_use", id: "tu1", name: "get_weather", input: { city: "北京" } },
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
).toEqual([
|
|
68
|
+
{ type: "thinking", text: "先查天气" },
|
|
69
|
+
{ type: "message", role: "assistant", text: "我来查" },
|
|
70
|
+
{ type: "action.called", callId: "tu1", name: "get_weather", input: { city: "北京" } },
|
|
71
|
+
]);
|
|
72
|
+
});
|
|
73
|
+
|
|
53
74
|
it("stream_event 等未知帧返回 []", () => {
|
|
54
75
|
expect(fromClaudeSdkMessages().add({ type: "stream_event" })).toEqual([]);
|
|
55
76
|
});
|
|
@@ -86,6 +107,64 @@ describe("fromPiAgentEvents", () => {
|
|
|
86
107
|
{ type: "action.result", callId: "c9", output: undefined, status: "rejected" },
|
|
87
108
|
]);
|
|
88
109
|
});
|
|
110
|
+
|
|
111
|
+
it("三段式聚合成一条:start/delta 不产事件,end 帧的完整 content 只落一条", () => {
|
|
112
|
+
const s = fromPiAgentEvents();
|
|
113
|
+
expect(s.add({ type: "message_start", message: { role: "assistant", content: [] } })).toEqual([]);
|
|
114
|
+
expect(s.add({ type: "message_update", assistantMessageEvent: { type: "text_delta", contentIndex: 0, delta: "18" } })).toEqual([]);
|
|
115
|
+
expect(s.add({ type: "message_update", assistantMessageEvent: { type: "text_delta", contentIndex: 0, delta: " 度" } })).toEqual([]);
|
|
116
|
+
// end 帧带完整 content:以它为准,增量不重复落地
|
|
117
|
+
expect(s.add({ type: "message_end", message: { role: "assistant", content: [{ type: "text", text: "18 度" }] } })).toEqual([
|
|
118
|
+
{ type: "message", role: "assistant", text: "18 度" },
|
|
119
|
+
]);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("end 帧缺 content 时用累加的 text/thinking 增量兜底", () => {
|
|
123
|
+
const s = fromPiAgentEvents();
|
|
124
|
+
s.add({ type: "message_start", message: { role: "assistant" } });
|
|
125
|
+
s.add({ type: "message_update", assistantMessageEvent: { type: "thinking_delta", contentIndex: 0, delta: "想" } });
|
|
126
|
+
s.add({ type: "message_update", assistantMessageEvent: { type: "thinking_delta", contentIndex: 0, delta: "想" } });
|
|
127
|
+
s.add({ type: "message_update", assistantMessageEvent: { type: "text_delta", contentIndex: 1, delta: "18 度" } });
|
|
128
|
+
expect(s.add({ type: "message_end", message: { role: "assistant" } })).toEqual([
|
|
129
|
+
{ type: "message", role: "assistant", text: "18 度" },
|
|
130
|
+
{ type: "thinking", text: "想想" },
|
|
131
|
+
]);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("只有 start/delta 的截断流不产半条消息,下一条消息不串入旧增量", () => {
|
|
135
|
+
const s = fromPiAgentEvents();
|
|
136
|
+
expect(s.add({ type: "message_start", message: { role: "assistant" } })).toEqual([]);
|
|
137
|
+
expect(s.add({ type: "message_update", assistantMessageEvent: { type: "text_delta", contentIndex: 0, delta: "半截" } })).toEqual([]);
|
|
138
|
+
// 流在这里断掉:没有 message_end,什么都不落地。新消息开始后旧增量作废。
|
|
139
|
+
expect(s.add({ type: "message_start", message: { role: "assistant" } })).toEqual([]);
|
|
140
|
+
expect(s.add({ type: "message_end", message: { role: "assistant", content: [{ type: "text", text: "新消息" }] } })).toEqual([
|
|
141
|
+
{ type: "message", role: "assistant", text: "新消息" },
|
|
142
|
+
]);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("失败状态帧:stopReason error/aborted → error 事件 + failed", () => {
|
|
146
|
+
const s = fromPiAgentEvents();
|
|
147
|
+
expect(s.failed).toBe(false);
|
|
148
|
+
expect(
|
|
149
|
+
s.add({ type: "message_end", message: { role: "assistant", content: [{ type: "text", text: "试到一半" }], stopReason: "error", errorMessage: "boom" } }),
|
|
150
|
+
).toEqual([
|
|
151
|
+
{ type: "message", role: "assistant", text: "试到一半" },
|
|
152
|
+
{ type: "error", message: "boom" },
|
|
153
|
+
]);
|
|
154
|
+
expect(s.failed).toBe(true);
|
|
155
|
+
|
|
156
|
+
const aborted = fromPiAgentEvents();
|
|
157
|
+
expect(aborted.add({ type: "message_end", message: { role: "assistant", stopReason: "aborted" } })).toEqual([
|
|
158
|
+
{ type: "error", message: "pi agent stopReason=aborted" },
|
|
159
|
+
]);
|
|
160
|
+
expect(aborted.failed).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("正常收尾(stopReason stop/toolUse)不置 failed", () => {
|
|
164
|
+
const s = fromPiAgentEvents();
|
|
165
|
+
s.add({ type: "message_end", message: { role: "assistant", content: [{ type: "text", text: "好了" }], stopReason: "stop" } });
|
|
166
|
+
expect(s.failed).toBe(false);
|
|
167
|
+
});
|
|
89
168
|
});
|
|
90
169
|
|
|
91
170
|
describe("fromCodexThreadEvents", () => {
|
|
@@ -96,10 +96,10 @@ export interface ClaudeSdkStream {
|
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
98
|
* Claude Agent SDK 消息流(`system` / `assistant` / `user` / `result`)→ 标准事件。
|
|
99
|
-
* `assistant` 的 text/tool_use 块 → message / action.called;`user` 的
|
|
100
|
-
* action.result;`system`/`permission_denied` → rejected;`stream_event`
|
|
101
|
-
* 整个忽略。HITL 的停轮判定(哪个工具被门控)
|
|
102
|
-
* 返回的 action.called 自行决定。
|
|
99
|
+
* `assistant` 的 text/thinking/tool_use 块 → message / thinking / action.called;`user` 的
|
|
100
|
+
* tool_result 块 → action.result;`system`/`permission_denied` → rejected;`stream_event`
|
|
101
|
+
* (逐 token 渲染)整个忽略。HITL 的停轮判定(哪个工具被门控)是应用侧的知识,不在这里——
|
|
102
|
+
* 扫描 add() 返回的 action.called 自行决定。
|
|
103
103
|
*/
|
|
104
104
|
export function fromClaudeSdkMessages(): ClaudeSdkStream {
|
|
105
105
|
let sessionId: string | undefined;
|
|
@@ -152,6 +152,8 @@ export function fromClaudeSdkMessages(): ClaudeSdkStream {
|
|
|
152
152
|
if (!isRecord(block)) continue;
|
|
153
153
|
if (block.type === "text" && typeof block.text === "string" && block.text) {
|
|
154
154
|
events.push({ type: "message", role: "assistant", text: block.text });
|
|
155
|
+
} else if (block.type === "thinking" && typeof block.thinking === "string" && block.thinking) {
|
|
156
|
+
events.push({ type: "thinking", text: block.thinking });
|
|
155
157
|
} else if (block.type === "tool_use" && typeof block.id === "string" && typeof block.name === "string") {
|
|
156
158
|
events.push({ type: "action.called", callId: block.id, name: block.name, input: block.input as JsonValue });
|
|
157
159
|
}
|
|
@@ -209,8 +211,14 @@ export interface PiAgentEventLike {
|
|
|
209
211
|
message?: {
|
|
210
212
|
role?: string;
|
|
211
213
|
content?: unknown;
|
|
214
|
+
/** assistant 消息的收尾原因;"error" / "aborted" 表示这条消息以失败告终。 */
|
|
215
|
+
stopReason?: string;
|
|
216
|
+
/** stopReason 为 "error" 时的错误说明。 */
|
|
217
|
+
errorMessage?: string;
|
|
212
218
|
usage?: { input: number; output: number; cacheRead: number; cacheWrite: number; cost: { total: number } };
|
|
213
219
|
};
|
|
220
|
+
/** `message_update` 帧携带的增量事件(text_delta / thinking_delta 等)——只读 type/delta,防御式解析。 */
|
|
221
|
+
assistantMessageEvent?: { type?: string; delta?: unknown; [key: string]: unknown };
|
|
214
222
|
[key: string]: unknown;
|
|
215
223
|
}
|
|
216
224
|
|
|
@@ -219,17 +227,27 @@ export interface PiAgentStream {
|
|
|
219
227
|
add(event: PiAgentEventLike): StreamEvent[];
|
|
220
228
|
/** assistant `message_end` 逐条累加的用量。 */
|
|
221
229
|
readonly usage: Usage | undefined;
|
|
230
|
+
/** assistant 消息以 stopReason "error" / "aborted" 收尾过。 */
|
|
231
|
+
readonly failed: boolean;
|
|
222
232
|
/** 拒绝审批后续读前登记:该调用 `tool_execution_end` 的 isError 判成 "rejected" 而非 "failed"。 */
|
|
223
233
|
markRejected(toolCallId: string): void;
|
|
224
234
|
}
|
|
225
235
|
|
|
226
236
|
/**
|
|
227
|
-
* pi-agent-core 事件流(`
|
|
228
|
-
*
|
|
237
|
+
* pi-agent-core 事件流(`message_start` / `message_update` / `message_end` /
|
|
238
|
+
* `tool_execution_start` / `tool_execution_end`)→ 标准事件。消息三段式聚合成一条:
|
|
239
|
+
* message_start 清空增量缓冲、message_update 的 text_delta / thinking_delta 逐段累加、
|
|
240
|
+
* message_end 落地成 message / thinking(优先取 end 帧的完整 content,缺了用累加的增量兜底);
|
|
241
|
+
* 只有 start/delta 的截断流不产出半条消息。message_end 同时累加 usage;assistant 消息以
|
|
242
|
+
* stopReason "error" / "aborted" 收尾时记失败(`failed`)并发一条 error 事件。
|
|
229
243
|
* tool_execution_start/end → action.called / action.result。
|
|
230
244
|
*/
|
|
231
245
|
export function fromPiAgentEvents(): PiAgentStream {
|
|
232
246
|
let usage: Usage | undefined;
|
|
247
|
+
let failed = false;
|
|
248
|
+
// message_start/update 累加的增量缓冲;message_end 落地后清空,截断流(无 end)不落地。
|
|
249
|
+
let deltaText = "";
|
|
250
|
+
let deltaThinking = "";
|
|
233
251
|
const rejected = new Set<string>();
|
|
234
252
|
|
|
235
253
|
const partText = (event: PiAgentEventLike, type: "text" | "thinking"): string => {
|
|
@@ -247,17 +265,44 @@ export function fromPiAgentEvents(): PiAgentStream {
|
|
|
247
265
|
get usage() {
|
|
248
266
|
return usage;
|
|
249
267
|
},
|
|
268
|
+
get failed() {
|
|
269
|
+
return failed;
|
|
270
|
+
},
|
|
250
271
|
markRejected(toolCallId) {
|
|
251
272
|
rejected.add(toolCallId);
|
|
252
273
|
},
|
|
253
274
|
add(event) {
|
|
254
275
|
const events: StreamEvent[] = [];
|
|
255
276
|
switch (event.type) {
|
|
277
|
+
case "message_start": {
|
|
278
|
+
// 新消息开始:上一条没等到 message_end 的增量作废(不落地半条消息)。
|
|
279
|
+
deltaText = "";
|
|
280
|
+
deltaThinking = "";
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
case "message_update": {
|
|
284
|
+
const e = event.assistantMessageEvent;
|
|
285
|
+
if (isRecord(e) && typeof e.delta === "string") {
|
|
286
|
+
if (e.type === "text_delta") deltaText += e.delta;
|
|
287
|
+
else if (e.type === "thinking_delta") deltaThinking += e.delta;
|
|
288
|
+
}
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
256
291
|
case "message_end": {
|
|
257
|
-
|
|
292
|
+
// 优先取 end 帧的完整 content;缺了(部分传输只带增量)用累加的 delta 兜底。
|
|
293
|
+
const text = partText(event, "text") || (event.message?.role === "assistant" ? deltaText : "");
|
|
258
294
|
if (text) events.push({ type: "message", role: "assistant", text });
|
|
259
|
-
const thinking = partText(event, "thinking");
|
|
295
|
+
const thinking = partText(event, "thinking") || (event.message?.role === "assistant" ? deltaThinking : "");
|
|
260
296
|
if (thinking) events.push({ type: "thinking", text: thinking });
|
|
297
|
+
deltaText = "";
|
|
298
|
+
deltaThinking = "";
|
|
299
|
+
if (event.message?.role === "assistant") {
|
|
300
|
+
const stopReason = event.message.stopReason;
|
|
301
|
+
if (stopReason === "error" || stopReason === "aborted") {
|
|
302
|
+
failed = true;
|
|
303
|
+
events.push({ type: "error", message: event.message.errorMessage ?? `pi agent stopReason=${stopReason}` });
|
|
304
|
+
}
|
|
305
|
+
}
|
|
261
306
|
const u = event.message?.role === "assistant" ? event.message.usage : undefined;
|
|
262
307
|
if (u) {
|
|
263
308
|
usage = {
|
|
@@ -284,8 +329,8 @@ export function fromPiAgentEvents(): PiAgentStream {
|
|
|
284
329
|
}
|
|
285
330
|
break;
|
|
286
331
|
}
|
|
287
|
-
// agent_start / turn_start / turn_end /
|
|
288
|
-
//
|
|
332
|
+
// agent_start / turn_start / turn_end / tool_execution_update / agent_end:
|
|
333
|
+
// 无对应 StreamEvent(消息文本统一在 message_end 落地)。
|
|
289
334
|
default:
|
|
290
335
|
break;
|
|
291
336
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// cases: docs/engineering/unit-tests/adapters/cases.md
|
|
1
2
|
import { describe, expect, it } from "vitest";
|
|
2
3
|
|
|
3
4
|
import { deltaStream, driveFrameStream } from "./streaming.ts";
|
|
@@ -12,6 +13,8 @@ function lineCtx(): AgentContext {
|
|
|
12
13
|
flags: {},
|
|
13
14
|
session: createAgentSession(),
|
|
14
15
|
sandbox: undefined as never,
|
|
16
|
+
progress() {},
|
|
17
|
+
diagnostic() {},
|
|
15
18
|
log() {},
|
|
16
19
|
};
|
|
17
20
|
}
|
|
@@ -73,15 +76,6 @@ describe("deltaStream", () => {
|
|
|
73
76
|
expect(s.add({ finish_reason: "tool_calls" })).toEqual([{ type: "action.called", callId: "call_2", name: "broken", input: "not json" }]);
|
|
74
77
|
});
|
|
75
78
|
|
|
76
|
-
it("tool-result 独立到达,配对靠 core 的 deriveRunFacts,这里只管落地成 action.result", () => {
|
|
77
|
-
const s = deltaStream<{ result?: { callId: string; output: string } }>({
|
|
78
|
-
toOps: (f) => (f.result ? [{ kind: "tool-result", callId: f.result.callId, output: f.result.output, status: "completed" }] : []),
|
|
79
|
-
});
|
|
80
|
-
expect(s.add({ result: { callId: "call_1", output: "22C" } })).toEqual([
|
|
81
|
-
{ type: "action.result", callId: "call_1", output: "22C", status: "completed" },
|
|
82
|
-
]);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
79
|
it("error 操作:落地未完成的文本、置 failed、附一条 error 事件", () => {
|
|
86
80
|
const s = deltaStream({ toOps });
|
|
87
81
|
s.add({ delta: { content: "还没说完" } });
|
package/src/agents/streaming.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// 官方的「拼装方式」件:把一个手写 send 里反复出现的事收成可复用的小东西,
|
|
2
2
|
// 而不是每接一个新后端就重写一遍循环 + Map + if/else。
|
|
3
3
|
//
|
|
4
|
-
// 背景(见 docs-site/zh/
|
|
4
|
+
// 背景(见 docs-site/zh/how-to/write-send.mdx):一轮交互里真正互不相干的事只有几类——
|
|
5
5
|
// 1. 怎么把输入发出去(transport)——真做不掉,adapter 只写这个;
|
|
6
6
|
// 2. 原始数据怎么变成 StreamEvent[]——按数据到达形状分「整段落地」(sdk-streams.ts 的
|
|
7
7
|
// fromXxxEvents,已有)和「逐 token / 逐参数增量」(deltaStream,这里新增)两种官方 reducer;
|
|
@@ -79,7 +79,7 @@ export async function driveFrameStream<Frame, RFrame = Frame>(
|
|
|
79
79
|
|
|
80
80
|
// 会话续接(id/capture、history)与 HITL 停轮现场(hold/take)不再是这里的可选「拼装件」——
|
|
81
81
|
// 它们是 ctx.session(AgentSession)本身的存取器,任何 adapter 直接取用,不需要额外声明什么。
|
|
82
|
-
// 见 docs-site/zh/
|
|
82
|
+
// 见 docs-site/zh/explanation/adapter.mdx 与 src/context/session.ts 的 createAgentSession。
|
|
83
83
|
|
|
84
84
|
// ───────────────────────── deltaStream:逐 token / 逐参数增量累加器 ─────────────────────────
|
|
85
85
|
|
package/src/agents/types.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// agent 域类型:Agent / Adapter 契约、会话与 tracing 导出配置。
|
|
2
|
-
// 「连到哪个被测对象、协议怎么说」的全部契约在这里(见 docs-site/zh/
|
|
2
|
+
// 「连到哪个被测对象、协议怎么说」的全部契约在这里(见 docs-site/zh/explanation/adapter.mdx)。
|
|
3
3
|
// 能力不再是问卷式声明:t 上解锁什么完全由构造证据决定(见 docs-site 「能力从哪来」一节)。
|
|
4
4
|
|
|
5
|
-
import type { Cleanup } from "../shared/types.ts";
|
|
5
|
+
import type { Cleanup, DiagnosticInput, ProgressUpdate } from "../shared/types.ts";
|
|
6
6
|
import type { StreamEvent, TraceSpan, Usage } from "../o11y/types.ts";
|
|
7
7
|
import type { Sandbox } from "../sandbox/types.ts";
|
|
8
8
|
|
|
@@ -69,10 +69,51 @@ export interface AgentSetupManifest {
|
|
|
69
69
|
}>;
|
|
70
70
|
/** 挂上的 MCP server(不含 env:secret 不进 manifest)。 */
|
|
71
71
|
mcpServers?: Array<{ name: string; command: string; args?: string[] }>;
|
|
72
|
+
/**
|
|
73
|
+
* 官方原生配置文件(Claude Code `settings.json` / Codex `config.toml`):只记 Agent 名、
|
|
74
|
+
* 项目相对来源路径与原始字节的 SHA-256,不落正文 —— 任意官方配置都可能携带敏感字符串,
|
|
75
|
+
* 不能靠字段白名单证明适合原样落盘。
|
|
76
|
+
*/
|
|
77
|
+
nativeConfigFile?: { agent: "claude-code" | "codex"; path: string; sha256: string };
|
|
72
78
|
/** Bub 的 Python Plugin(规范化后的 package 串)。 */
|
|
73
79
|
pythonPlugins?: Array<{ package: string }>;
|
|
74
80
|
}
|
|
75
81
|
|
|
82
|
+
// ───────────────────────── 证据覆盖声明 ─────────────────────────
|
|
83
|
+
|
|
84
|
+
/** 证据通道的覆盖状态。省略(不声明)= unknown,不是 complete——消费侧与 unavailable 同样保守。 */
|
|
85
|
+
export type CoverageStatus = "complete" | "partial" | "unavailable";
|
|
86
|
+
|
|
87
|
+
/** 单个证据通道的覆盖声明:状态 + 可选的人可读原因(如 "stream reconnected mid-turn")。 */
|
|
88
|
+
export interface CoverageDeclaration {
|
|
89
|
+
status: CoverageStatus;
|
|
90
|
+
reason?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 覆盖声明(EvidenceCoverage):完整性不是口头承诺,是随数据走的声明
|
|
95
|
+
* (见 docs/feature/adapters/architecture/evidence.md)。两层:
|
|
96
|
+
* - Agent 级默认(`defineAgent` / `defineSandboxAgent` 的 `coverage`)声明该 Adapter 的常态覆盖;
|
|
97
|
+
* 官方 SDK 适配器显式声明全通道 complete(用 `completeCoverage` 常量)。
|
|
98
|
+
* - Turn 级降级(`Turn.coverage`)只用于相对 Agent 默认值降级(这一轮流断了 / 拿不到 usage),
|
|
99
|
+
* 不能把 Agent 未声明的通道升格成 complete。
|
|
100
|
+
* 整个 Agent 不声明时全部通道视为 unknown。
|
|
101
|
+
*/
|
|
102
|
+
export interface EvidenceCoverage {
|
|
103
|
+
/** 完整事件流(event / notEvent / order 的依据)。 */
|
|
104
|
+
events?: CoverageDeclaration;
|
|
105
|
+
/** action 生命周期(工具正负断言、顺序、失败的依据)。 */
|
|
106
|
+
actions?: CoverageDeclaration;
|
|
107
|
+
/** assistant / user message(reply、messageIncludes 的依据)。 */
|
|
108
|
+
messages?: CoverageDeclaration;
|
|
109
|
+
/** usage(token / cost 上限断言的依据)。 */
|
|
110
|
+
usage?: CoverageDeclaration;
|
|
111
|
+
/** Turn status 的真实性(succeeded / parked 的依据)——恒 completed 的映射必须声明非 complete。 */
|
|
112
|
+
status?: CoverageDeclaration;
|
|
113
|
+
/** Turn.data(outputEquals / outputMatches 的依据)。 */
|
|
114
|
+
data?: CoverageDeclaration;
|
|
115
|
+
}
|
|
116
|
+
|
|
76
117
|
/** 随一轮消息附带的文件(图片等多模态输入)。 */
|
|
77
118
|
export interface InputFile {
|
|
78
119
|
/** 文件名(可选,供 adapter / 模型参考)。 */
|
|
@@ -85,7 +126,7 @@ export interface InputFile {
|
|
|
85
126
|
|
|
86
127
|
/**
|
|
87
128
|
* HITL 回答轮里,人的裁决以结构化形式随 `input.responses` 到达——adapter 不需要解析
|
|
88
|
-
* `text` 去猜哪句回答对应哪个请求、算不算批准。见 docs-site/zh/
|
|
129
|
+
* `text` 去猜哪句回答对应哪个请求、算不算批准。见 docs-site/zh/explanation/adapter.mdx
|
|
89
130
|
* 「不同回答的入参」一节的四种典型形态。
|
|
90
131
|
*/
|
|
91
132
|
export interface InputResponse {
|
|
@@ -111,6 +152,11 @@ export interface Turn {
|
|
|
111
152
|
readonly data?: unknown;
|
|
112
153
|
readonly status: "completed" | "failed" | "waiting";
|
|
113
154
|
readonly usage?: Usage;
|
|
155
|
+
/**
|
|
156
|
+
* 本轮相对 Agent 默认覆盖的降级声明(这一轮流断了、拿不到 usage 等);
|
|
157
|
+
* 只能降级,不能把 Agent 未声明的通道升格成 complete(见 EvidenceCoverage)。
|
|
158
|
+
*/
|
|
159
|
+
readonly coverage?: EvidenceCoverage;
|
|
114
160
|
}
|
|
115
161
|
|
|
116
162
|
/**
|
|
@@ -177,7 +223,7 @@ export interface AgentTracing {
|
|
|
177
223
|
* 新会话线(eval 第一轮 / t.newSession() 之后)拿到一个全新的。**
|
|
178
224
|
* 会话续接(`id`/`capture`、`history`)和 HITL 停轮现场(`hold`/`take`)的存取器都在它上面,
|
|
179
225
|
* "第一轮"是新会话线的自然形态,没有要判断的分支;`state` 是这些存取器之外的逃生舱,
|
|
180
|
-
* 框架从不往里写数据。见 docs-site/zh/
|
|
226
|
+
* 框架从不往里写数据。见 docs-site/zh/explanation/adapter.mdx「AgentContext」一节。
|
|
181
227
|
*/
|
|
182
228
|
export interface AgentSession {
|
|
183
229
|
/** 会话续接:服务端记历史。本线记过的会话 id;新会话线是 undefined。 */
|
|
@@ -238,10 +284,21 @@ export interface AgentContext {
|
|
|
238
284
|
*/
|
|
239
285
|
readonly telemetry?: Telemetry;
|
|
240
286
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
* (
|
|
287
|
+
* 作用域反馈:报告此刻正在做什么(turn / tool / 安装进度)。短命状态——Human profile
|
|
288
|
+
* 更新 active 行,`agent`/`ci` 不逐条打印,也不进最终结果;不要每个 token/delta 都调用。
|
|
289
|
+
* runner 按当前回调所处的生命周期阶段(agent.setup / agent.run / agent.teardown)归因,
|
|
290
|
+
* 调用方不能冒充其它阶段(见 docs/feature/experiments/library.md)。
|
|
291
|
+
*/
|
|
292
|
+
progress(update: ProgressUpdate): void;
|
|
293
|
+
/**
|
|
294
|
+
* 作用域反馈:报告运行结束后仍应保留的问题(协议降级、数据不完整、cleanup 问题)。
|
|
295
|
+
* 永久事件,落进 attempt 的 diagnostics 并进各 profile 的永久输出;`dedupeKey` 去重。
|
|
296
|
+
* 即使 level 为 "error" 也不改变 Turn.status / verdict——无法继续时抛异常。
|
|
297
|
+
*/
|
|
298
|
+
diagnostic(input: DiagnosticInput): void;
|
|
299
|
+
/**
|
|
300
|
+
* `progress({ message: msg })` 的别名,不是第二条通道(见 docs/feature/experiments/cli.md
|
|
301
|
+
* 「Attempt 阶段」)。超时失败时最近若干行会并入结果的 error 信息,方便定位卡在哪一步。
|
|
245
302
|
*/
|
|
246
303
|
log(msg: string): void;
|
|
247
304
|
}
|
|
@@ -272,6 +329,8 @@ export interface Agent {
|
|
|
272
329
|
* `t.sandbox`/`t.sandbox.fileChanged()` 等文件系统断言,见 docs-site「能力从哪来」一节。
|
|
273
330
|
*/
|
|
274
331
|
readonly kind: "sandbox" | "remote";
|
|
332
|
+
/** 该 Adapter 的常态证据覆盖声明;省略 = 全通道 unknown(见 EvidenceCoverage)。 */
|
|
333
|
+
coverage?: EvidenceCoverage;
|
|
275
334
|
setup?: AgentSetup;
|
|
276
335
|
/** OTLP 导出配置(仅当此字段存在时运行器才为该 agent 开 OTLP 接收);与 setup 分开,见 AgentTracing。 */
|
|
277
336
|
tracing?: AgentTracing;
|
|
@@ -285,6 +344,8 @@ export interface Agent {
|
|
|
285
344
|
export interface SandboxAgentDef {
|
|
286
345
|
/** agent 的显示名/标识,原样进入 `Agent.name`——不是注册表查找 key,只用于展示、结果归属与去重指纹。 */
|
|
287
346
|
name: string;
|
|
347
|
+
/** 该 Adapter 的常态证据覆盖声明(完整采集的用 `completeCoverage` 常量);省略 = 全通道 unknown。 */
|
|
348
|
+
coverage?: EvidenceCoverage;
|
|
288
349
|
/**
|
|
289
350
|
* 每个沙箱一次(不是每轮一次):装 CLI、写 config.toml / 鉴权配置(model/base/auth 等
|
|
290
351
|
* 本轮内不变的东西)。运行器在沙箱备好(上传/基线/eval.setup 之后)、第一次 send 前
|
|
@@ -305,6 +366,8 @@ export interface SandboxAgentDef {
|
|
|
305
366
|
export interface RemoteAgentDef {
|
|
306
367
|
/** agent 的显示名/标识,原样进入 `Agent.name`——不是注册表查找 key,只用于展示、结果归属与去重指纹。 */
|
|
307
368
|
name: string;
|
|
369
|
+
/** 该 Adapter 的常态证据覆盖声明(完整采集的用 `completeCoverage` 常量);省略 = 全通道 unknown。 */
|
|
370
|
+
coverage?: EvidenceCoverage;
|
|
308
371
|
/**
|
|
309
372
|
* 每个 attempt 一次(remote agent 没有真实沙箱,运行器会传入一个仅含 `workdir`/`sandboxId`/
|
|
310
373
|
* `otlpHost`/`stop` 等元信息的 stub `Sandbox`,其余方法调用即抛错——不要在这里调用
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// cases: docs/engineering/unit-tests/adapters/cases.md
|
|
1
2
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
3
|
|
|
3
4
|
import type { AgentContext } from "../types.ts";
|
|
@@ -77,6 +78,8 @@ function ctx(overrides: Partial<{ model: string }> = {}): AgentContext {
|
|
|
77
78
|
sandbox: undefined as never,
|
|
78
79
|
// 同一个 ctx 重复用 = 同一条会话线(续接,同一个 ctx.session);新造 = 新线。
|
|
79
80
|
session: createAgentSession(),
|
|
81
|
+
progress: () => {},
|
|
82
|
+
diagnostic: () => {},
|
|
80
83
|
log: () => {},
|
|
81
84
|
} as AgentContext;
|
|
82
85
|
}
|