niceeval 0.4.4 → 0.4.5
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/README.md +21 -12
- package/README.zh.md +8 -9
- package/docs-site/.mintignore +13 -0
- package/docs-site/AGENTS.md +46 -0
- package/docs-site/concepts/adapter.mdx +287 -0
- package/docs-site/concepts/assert.mdx +243 -0
- package/docs-site/concepts/drive.mdx +118 -0
- package/docs-site/concepts/evals.mdx +108 -0
- package/docs-site/concepts/experiment.mdx +37 -0
- package/docs-site/concepts/hitl.mdx +83 -0
- package/docs-site/concepts/judge.mdx +129 -0
- package/docs-site/concepts/overview.mdx +98 -0
- package/docs-site/concepts/tier.mdx +42 -0
- package/docs-site/docs-ref/00-index.md +23 -0
- package/docs-site/docs-ref/01-page-types.md +43 -0
- package/docs-site/docs-ref/03-style-rules.md +45 -0
- package/docs-site/docs-ref/04-code-examples.md +37 -0
- package/docs-site/docs-ref/05-dx-failure-paths.md +45 -0
- package/docs-site/docs-ref/06-checklists.md +53 -0
- package/docs-site/docs.json +256 -0
- package/docs-site/example/ai-agent-application.mdx +148 -0
- package/docs-site/example/claude-code-codex-plugin.mdx +162 -0
- package/docs-site/example/claude-code-codex-skill.mdx +147 -0
- package/docs-site/example/showcase.mdx +39 -0
- package/docs-site/example/tier1-ai-sdk-v7.mdx +136 -0
- package/docs-site/example/tier1-claude-sdk.mdx +119 -0
- package/docs-site/example/tier1-codex-sdk.mdx +111 -0
- package/docs-site/example/tier1-langgraph.mdx +119 -0
- package/docs-site/example/tier1-pi-sdk.mdx +119 -0
- package/docs-site/favicon.svg +5 -0
- package/docs-site/github-diff.css +135 -0
- package/docs-site/github-diff.js +11 -0
- package/docs-site/guides/authoring.mdx +129 -0
- package/docs-site/guides/ci-integration.mdx +97 -0
- package/docs-site/guides/connect-otel.mdx +209 -0
- package/docs-site/guides/connect-your-agent.mdx +221 -0
- package/docs-site/guides/dataset-fanout.mdx +98 -0
- package/docs-site/guides/experiments.mdx +71 -0
- package/docs-site/guides/fixtures.mdx +147 -0
- package/docs-site/guides/reporters.mdx +113 -0
- package/docs-site/guides/runner.mdx +79 -0
- package/docs-site/guides/sandbox-agent.mdx +138 -0
- package/docs-site/guides/sandbox-backends.mdx +64 -0
- package/docs-site/guides/scoring-guide.mdx +92 -0
- package/docs-site/guides/viewing-results.mdx +195 -0
- package/docs-site/guides/write-experiment.mdx +81 -0
- package/docs-site/guides/write-send.mdx +347 -0
- package/docs-site/images/adapter-tiers-zh.svg +60 -0
- package/docs-site/images/agent-turn-roundtrip-en.svg +62 -0
- package/docs-site/images/agent-turn-roundtrip-zh.svg +77 -0
- package/docs-site/images/hitl-handshake-zh.svg +89 -0
- package/docs-site/images/logo.svg +6 -0
- package/docs-site/index.mdx +181 -0
- package/docs-site/introduction.mdx +141 -0
- package/docs-site/quickstart.mdx +136 -0
- package/docs-site/reference/builtin-agents.mdx +161 -0
- package/docs-site/reference/capabilities.mdx +76 -0
- package/docs-site/reference/cli.mdx +120 -0
- package/docs-site/reference/define-agent.mdx +168 -0
- package/docs-site/reference/define-config.mdx +41 -0
- package/docs-site/reference/define-eval.mdx +160 -0
- package/docs-site/reference/events.mdx +131 -0
- package/docs-site/reference/expect.mdx +112 -0
- package/docs-site/tracker.js +8 -0
- package/docs-site/zh/concepts/adapter.mdx +286 -0
- package/docs-site/zh/concepts/assert.mdx +243 -0
- package/docs-site/zh/concepts/drive.mdx +118 -0
- package/docs-site/zh/concepts/evals.mdx +124 -0
- package/docs-site/zh/concepts/experiment.mdx +37 -0
- package/docs-site/zh/concepts/hitl.mdx +83 -0
- package/docs-site/zh/concepts/judge.mdx +130 -0
- package/docs-site/zh/concepts/overview.mdx +109 -0
- package/docs-site/zh/concepts/tier.mdx +44 -0
- package/docs-site/zh/example/ai-agent-application.mdx +152 -0
- package/docs-site/zh/example/claude-code-codex-plugin.mdx +163 -0
- package/docs-site/zh/example/claude-code-codex-skill.mdx +147 -0
- package/docs-site/zh/example/showcase.mdx +39 -0
- package/docs-site/zh/example/tier1-ai-sdk-v7.mdx +140 -0
- package/docs-site/zh/example/tier1-claude-sdk.mdx +122 -0
- package/docs-site/zh/example/tier1-codex-sdk.mdx +117 -0
- package/docs-site/zh/example/tier1-langgraph.mdx +123 -0
- package/docs-site/zh/example/tier1-pi-sdk.mdx +122 -0
- package/docs-site/zh/guides/agent-feedback-loop.mdx +79 -0
- package/docs-site/zh/guides/authoring.mdx +129 -0
- package/docs-site/zh/guides/ci-integration.mdx +97 -0
- package/docs-site/zh/guides/connect-otel.mdx +208 -0
- package/docs-site/zh/guides/connect-your-agent.mdx +226 -0
- package/docs-site/zh/guides/dataset-fanout.mdx +83 -0
- package/docs-site/zh/guides/experiments.mdx +72 -0
- package/docs-site/zh/guides/fixtures.mdx +147 -0
- package/docs-site/zh/guides/official-adapters.mdx +132 -0
- package/docs-site/zh/guides/reporters.mdx +113 -0
- package/docs-site/zh/guides/runner.mdx +82 -0
- package/docs-site/zh/guides/sandbox-agent.mdx +139 -0
- package/docs-site/zh/guides/sandbox-backends.mdx +75 -0
- package/docs-site/zh/guides/scoring-guide.mdx +92 -0
- package/docs-site/zh/guides/viewing-results.mdx +195 -0
- package/docs-site/zh/guides/write-experiment.mdx +101 -0
- package/docs-site/zh/guides/write-send.mdx +353 -0
- package/docs-site/zh/index.mdx +180 -0
- package/docs-site/zh/introduction.mdx +140 -0
- package/docs-site/zh/quickstart.mdx +137 -0
- package/docs-site/zh/reference/builtin-agents.mdx +364 -0
- package/docs-site/zh/reference/capabilities.mdx +76 -0
- package/docs-site/zh/reference/cli.mdx +140 -0
- package/docs-site/zh/reference/define-agent.mdx +461 -0
- package/docs-site/zh/reference/define-config.mdx +107 -0
- package/docs-site/zh/reference/define-eval.mdx +674 -0
- package/docs-site/zh/reference/events.mdx +252 -0
- package/docs-site/zh/reference/expect.mdx +208 -0
- package/package.json +3 -2
- package/src/agents/bub.ts +1 -1
- package/src/agents/claude-code.ts +8 -5
- package/src/agents/codex.ts +9 -5
- package/src/agents/sdk-streams.test.ts +4 -4
- package/src/agents/sdk-streams.ts +14 -9
- package/src/agents/types.ts +40 -1
- package/src/agents/ui-message-stream.ts +1 -0
- package/src/cli.ts +36 -7
- package/src/context/types.ts +140 -0
- package/src/expect/index.ts +15 -8
- package/src/i18n/en.ts +19 -6
- package/src/i18n/zh-CN.ts +19 -6
- package/src/o11y/parsers/bub.test.ts +71 -0
- package/src/o11y/parsers/bub.ts +5 -0
- package/src/o11y/types.ts +27 -2
- package/src/runner/reporters/artifacts.ts +11 -3
- package/src/runner/reporters/live.ts +45 -8
- package/src/runner/run.ts +71 -21
- package/src/runner/types.ts +45 -2
- package/src/sandbox/types.ts +18 -0
- package/src/scoring/types.ts +5 -0
- package/src/shared/types.ts +3 -0
- package/src/util.test.ts +26 -1
- package/src/util.ts +16 -0
- package/src/view/app/App.tsx +2 -2
- package/src/view/app/components/AttemptModal.tsx +2 -0
- package/src/view/app/components/CopyControls.tsx +87 -28
- package/src/view/app/i18n.ts +3 -3
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +18 -18
- package/docs/README.md +0 -120
- package/docs/adapters/README.md +0 -60
- package/docs/adapters/authoring.md +0 -179
- package/docs/adapters/coding-agent-skills-plugins.md +0 -324
- package/docs/adapters/collection.md +0 -128
- package/docs/adapters/contract.md +0 -264
- package/docs/adapters/reference/agent-eval.md +0 -215
- package/docs/adapters/reference/agent-loop-apis.md +0 -69
- package/docs/adapters/reference/claude-code-otel-telemetry.md +0 -100
- package/docs/adapters/reference/eve-protocol.md +0 -127
- package/docs/adapters/reference/otel-genai.md +0 -107
- package/docs/adapters/reference/otel-instrumentation.md +0 -65
- package/docs/adapters/targets.md +0 -99
- package/docs/architecture.md +0 -140
- package/docs/assertions.md +0 -387
- package/docs/capabilities-by-construction.md +0 -48
- package/docs/cli.md +0 -173
- package/docs/concepts.md +0 -106
- package/docs/e2e-ci.md +0 -332
- package/docs/eval-authoring.md +0 -319
- package/docs/experiments.md +0 -157
- package/docs/getting-started.md +0 -224
- package/docs/multi-agent.md +0 -145
- package/docs/observability.md +0 -337
- package/docs/origin-integration.md +0 -195
- package/docs/references.md +0 -35
- package/docs/reports.md +0 -551
- package/docs/results-format.md +0 -228
- package/docs/results-lib.md +0 -191
- package/docs/runner.md +0 -104
- package/docs/sandbox.md +0 -276
- package/docs/scoring.md +0 -119
- package/docs/source-map.md +0 -126
- package/docs/tier-sync.md +0 -193
- package/docs/view.md +0 -194
- package/docs/vision.md +0 -88
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Integrate LangGraph with NiceEval non-invasively"
|
|
3
|
+
sidebarTitle: "LangGraph integration"
|
|
4
|
+
description: "The complete before/after diff for connecting a pure Python LangGraph app with LangSmith OTel export to NiceEval."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
{/* Generated by scripts/gen-diff-code.ts (pnpm run gen:diff-code). Do not edit by hand. */}
|
|
8
|
+
|
|
9
|
+
Comparison targets:
|
|
10
|
+
|
|
11
|
+
- **before**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/langgraph](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin/langgraph) -- a pure Python `create_agent` (LangChain 1.x / LangGraph) HTTP service, before any eval integration.
|
|
12
|
+
- **after**:[https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/langgraph](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1/langgraph) -- the same app after integrating NiceEval.
|
|
13
|
+
|
|
14
|
+
**Integration path**: handwritten frame mapping -- custom JSON frames from `server.py` are translated one by one into standard events (`tool-input` -> `action.called`, `tool-output` -> `action.result`, accumulated `text-delta` -> `message`, `tool-approval-request` -> stop turn + `input.requested`). HITL stop-turn state is stored through `ctx.session`. The subject app is Python, while the eval side is a separate TypeScript project. App-side `src/backend/*.py` files are byte-for-byte unchanged. Use `tier2/` for OTel waterfalls and `tier3/` for feature A/B.
|
|
15
|
+
|
|
16
|
+
All integration code changes (measured from both directories when generated):
|
|
17
|
+
|
|
18
|
+
<table className="gd-summary"><tbody><tr><th>{"Category"}</th><th>{"Files"}</th><th>{"Lines"}</th></tr><tr><td>{"Eval-side TypeScript scaffolding (required because the subject app is Python; all-new files)"}</td><td>{"3"}</td><td>{"+42"}</td></tr><tr><td>{"adapter (required: transport glue; protocol mapping is in the official package)"}</td><td>{"2"}</td><td>{"+182"}</td></tr><tr><td>{"evals and experiments (test content, grows as needed)"}</td><td>{"6"}</td><td>{"+118"}</td></tr><tr className="gd-total"><td>{"Total"}</td><td>{"11"}</td><td>{"+342"}</td></tr></tbody></table>
|
|
19
|
+
|
|
20
|
+
## File list
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
langgraph/
|
|
24
|
+
├── package.json added
|
|
25
|
+
├── tsconfig.json added
|
|
26
|
+
├── pnpm-workspace.yaml added
|
|
27
|
+
├── niceeval.config.ts added
|
|
28
|
+
├── agents/
|
|
29
|
+
│ └── langgraph.ts added
|
|
30
|
+
├── evals/
|
|
31
|
+
│ ├── basic-qa.eval.ts added
|
|
32
|
+
│ ├── hitl-approve.eval.ts added
|
|
33
|
+
│ ├── hitl-deny.eval.ts added
|
|
34
|
+
│ ├── session-isolation.eval.ts added
|
|
35
|
+
│ └── weather-tool.eval.ts added
|
|
36
|
+
└── experiments/
|
|
37
|
+
└── langgraph.ts added
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Added TypeScript-side scaffolding (the app itself is unchanged)
|
|
41
|
+
|
|
42
|
+
<div className="gd-file">
|
|
43
|
+
<div className="gd-head"><span className="gd-name">{"package.json"}</span><span className="gd-stats"><span className="gd-plus">{"+16"}</span></span></div>
|
|
44
|
+
<div className="gd-body">
|
|
45
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"{"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"name\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"langgraph-example\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"version\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"0.1.0\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"private\""}</span><span className="gdt0">{": "}</span><span className="gdt1">{"true"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"type\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"module\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"scripts\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"eval\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"typecheck\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"tsc --noEmit\""}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"devDependencies\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"@types/node\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"^22.0.0\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"niceeval\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"file:../../../..\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"tsx\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"^4.19.2\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"typescript\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"^5.7.2\""}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"15"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"16"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"}"}</span></td></tr></tbody></table>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div className="gd-file">
|
|
50
|
+
<div className="gd-head"><span className="gd-name">{"tsconfig.json"}</span><span className="gd-stats"><span className="gd-plus">{"+16"}</span></span></div>
|
|
51
|
+
<div className="gd-body">
|
|
52
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"{"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"compilerOptions\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"target\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"ES2022\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"module\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"NodeNext\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"moduleResolution\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"NodeNext\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"lib\""}</span><span className="gdt0">{": ["}</span><span className="gdt2">{"\"ES2023\""}</span><span className="gdt0">{"],"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"types\""}</span><span className="gdt0">{": ["}</span><span className="gdt2">{"\"node\""}</span><span className="gdt0">{"],"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"strict\""}</span><span className="gdt0">{": "}</span><span className="gdt1">{"true"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"esModuleInterop\""}</span><span className="gdt0">{": "}</span><span className="gdt1">{"true"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"skipLibCheck\""}</span><span className="gdt0">{": "}</span><span className="gdt1">{"true"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"allowImportingTsExtensions\""}</span><span className="gdt0">{": "}</span><span className="gdt1">{"true"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"noEmit\""}</span><span className="gdt0">{": "}</span><span className="gdt1">{"true"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"forceConsistentCasingInFileNames\""}</span><span className="gdt0">{": "}</span><span className="gdt1">{"true"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"15"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt1">{"\"include\""}</span><span className="gdt0">{": ["}</span><span className="gdt2">{"\"niceeval.config.ts\""}</span><span className="gdt0">{", "}</span><span className="gdt2">{"\"agents\""}</span><span className="gdt0">{", "}</span><span className="gdt2">{"\"evals\""}</span><span className="gdt0">{", "}</span><span className="gdt2">{"\"experiments\""}</span><span className="gdt0">{"]"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"16"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"}"}</span></td></tr></tbody></table>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div className="gd-file">
|
|
57
|
+
<div className="gd-head"><span className="gd-name">{"pnpm-workspace.yaml"}</span><span className="gd-stats"><span className="gd-plus">{"+10"}</span></span></div>
|
|
58
|
+
<div className="gd-body">
|
|
59
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"# origin/langgraph 没有这个文件(纯 Python 项目,没有 package.json)。这是added的"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"# TS 侧脚手架——niceeval 的 adapter/eval/experiment 代码要跑起来需要一个独立 npm 项目,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"# 与 Python 应用本身(src/backend/、requirements.txt、.venv)完全分开、互不干扰。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt3">{"packages"}</span><span className="gdt0">{": []"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt3">{"allowBuilds"}</span><span className="gdt0">{":"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt3">{"esbuild"}</span><span className="gdt0">{": "}</span><span className="gdt1">{"true"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt3">{"overrides"}</span><span className="gdt0">{":"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt3">{"niceeval"}</span><span className="gdt0">{": "}</span><span className="gdt2">{"link:../../../.."}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt3">{"minimumReleaseAgeExclude"}</span><span className="gdt0">{":"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" - "}</span><span className="gdt2">{"niceeval@0.1.1"}</span></td></tr></tbody></table>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
## Added adapter, evals, and experiments
|
|
64
|
+
|
|
65
|
+
<div className="gd-file">
|
|
66
|
+
<div className="gd-head"><span className="gd-name">{"niceeval.config.ts"}</span><span className="gd-stats"><span className="gd-plus">{"+14"}</span></span></div>
|
|
67
|
+
<div className="gd-body">
|
|
68
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { defineConfig } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 注:这个 app 的 .env 把标准的 OPENAI_API_KEY / OPENAI_BASE_URL 挪用给了 DeepSeek"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// (agent.py 里 ChatOpenAI 直接读这两个 env 名)。niceeval 的 judge(t.judge.autoevals.*)"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 兜底链路最后也会读这两个名字,和应用自己的凭证会撞车——真的要用 judge 时在 .env 里另配"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// NICEEVAL_JUDGE_KEY / NICEEVAL_JUDGE_BASE(judge.ts 里优先级最高),judge 走独立凭证,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 不和应用的模型配置互相干扰。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"export"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"defineConfig"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" name: { "}</span><span className="gdt2">{"\"zh-CN\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"LangGraph 示例\""}</span><span className="gdt0">{", en: "}</span><span className="gdt2">{"\"LangGraph example\""}</span><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" judge: { model: "}</span><span className="gdt2">{"\"gpt-5.4\""}</span><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" timeoutMs: "}</span><span className="gdt1">{"120_000"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 被测应用是用户自己起的长驻服务,别开太高并发。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" maxConcurrency: "}</span><span className="gdt1">{"2"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"});"}</span></td></tr></tbody></table>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<div className="gd-file">
|
|
73
|
+
<div className="gd-head"><span className="gd-name">{"agents/langgraph.ts"}</span><span className="gd-stats"><span className="gd-plus">{"+168"}</span></span></div>
|
|
74
|
+
<div className="gd-body">
|
|
75
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// langgraph 的 adapter:无侵入对接 ../src/backend/server.py —— 自定义 JSON 帧 over SSE"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// (server.py 不透传 LangGraph 原生 stream 事件,自己翻译成一套小协议,见其头注释)。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"//"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 断言依据全部来自这条流,零 OTel 依赖:"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// · `tool-input` → action.called、`tool-output` → action.result(completed,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 带 isError 时 failed)、`tool-output-denied` → action.result(rejected)——"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 协议帧里本来就有全量工具过程;"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// · `text-delta` 累积成完整回复,轮次结束补一条 message 事件;"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// · HITL:`tool-approval-request` → input.requested + waiting,停轮现场(还开着的流 +"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 挂起的 toolCallId)用 ctx.session.hold 存住,回答轮 ctx.session.take 取回接着读。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"//"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 这是 Tier 1(只接 send):要 `niceeval view` 的调用瀑布图时升 Tier 2,见"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// ../../tier2/langgraph/——config 加一行 telemetry、本文件加一段 span 收尾宽限,其它不变。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { defineAgent, sseJsonFrames } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval/adapter\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"15"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"type"}</span><span className="gdt0">{" { AgentContext, SseFrameCursor } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval/adapter\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"16"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"type"}</span><span className="gdt0">{" { JsonValue, StreamEvent, Turn, TurnInput } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"17"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"18"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 被测应用由你自己按它的方式启动(python server.py / 部署在哪都行),eval 不代管进程、"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"19"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 不另开端口。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"20"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"BASE_URL"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" process.env."}</span><span className="gdt1">{"LANGGRAPH_URL"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"??"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"http://127.0.0.1:35000\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"21"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"22"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"async"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"function"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"appFetch"}</span><span className="gdt0">{"("}</span><span className="gdt7">{"path"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{", "}</span><span className="gdt7">{"body"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"unknown"}</span><span className="gdt0">{", "}</span><span className="gdt7">{"signal"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"AbortSignal"}</span><span className="gdt0">{")"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"Promise"}</span><span className="gdt0">{"<"}</span><span className="gdt5">{"Response"}</span><span className="gdt0">{"> {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"23"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"try"}</span><span className="gdt0">{" {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"24"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"return"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"fetch"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"`${"}</span><span className="gdt1">{"BASE_URL"}</span><span className="gdt2">{"}${"}</span><span className="gdt0">{"path"}</span><span className="gdt2">{"}`"}</span><span className="gdt0">{", {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"25"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" method: "}</span><span className="gdt2">{"\"POST\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"26"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" headers: { "}</span><span className="gdt2">{"\"content-type\""}</span><span className="gdt0">{": "}</span><span className="gdt2">{"\"application/json\""}</span><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"27"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" body: "}</span><span className="gdt1">{"JSON"}</span><span className="gdt0">{"."}</span><span className="gdt5">{"stringify"}</span><span className="gdt0">{"(body),"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"28"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" signal,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"29"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"30"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" } "}</span><span className="gdt4">{"catch"}</span><span className="gdt0">{" (err) {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"31"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"if"}</span><span className="gdt0">{" (signal.aborted) "}</span><span className="gdt4">{"throw"}</span><span className="gdt0">{" err;"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"32"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"throw"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"new"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"Error"}</span><span className="gdt0">{"("}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"33"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt2">{"`连不上 ${"}</span><span className="gdt1">{"BASE_URL"}</span><span className="gdt2">{"}${"}</span><span className="gdt0">{"path"}</span><span className="gdt2">{"}。被测应用在跑吗?先起它(见 README「跑起来」),或设 LANGGRAPH_URL 指向已部署实例。`"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"34"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" );"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"35"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"36"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"}"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"37"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"38"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"type"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"LanggraphFrame"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"39"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" { "}</span><span className="gdt7">{"type"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"session\""}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"sessionId"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"40"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" { "}</span><span className="gdt7">{"type"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"text-delta\""}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"delta"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"41"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" { "}</span><span className="gdt7">{"type"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool-input\""}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"toolCallId"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"name"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"input"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"unknown"}</span><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"42"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" { "}</span><span className="gdt7">{"type"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool-output\""}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"toolCallId"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"output"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"unknown"}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"isError"}</span><span className="gdt4">{"?:"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"boolean"}</span><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"43"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" { "}</span><span className="gdt7">{"type"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool-approval-request\""}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"toolCallId"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"44"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" { "}</span><span className="gdt7">{"type"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool-output-denied\""}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"toolCallId"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"45"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" { "}</span><span className="gdt7">{"type"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"error\""}</span><span className="gdt0">{"; "}</span><span className="gdt7">{"message"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"46"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" { "}</span><span className="gdt7">{"type"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"finish\""}</span><span className="gdt0">{" };"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"47"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"48"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"type"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"SseCursor"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt5">{"SseFrameCursor"}</span><span className="gdt0">{"<"}</span><span className="gdt5">{"LanggraphFrame"}</span><span className="gdt0">{">;"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"49"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"50"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// HITL 停轮现场:还开着的流 + 挂起的审批 toolCallId。approve/deny 的续读发生在下一次"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"51"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// send()(一个全新的 drainStream 调用),局部变量活不过这次函数返回——存进 ctx.session.hold,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"52"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 回答轮 ctx.session.take 取回(取到即清除,一次消费)。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"53"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"interface"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"PendingApproval"}</span><span className="gdt0">{" {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"54"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"readonly"}</span><span className="gdt0">{" "}</span><span className="gdt7">{"cursor"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"SseCursor"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"55"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"readonly"}</span><span className="gdt0">{" "}</span><span className="gdt7">{"toolCallId"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"56"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"}"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"57"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"58"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"async"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"function"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"drainStream"}</span><span className="gdt0">{"("}</span><span className="gdt7">{"cursor"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"SseCursor"}</span><span className="gdt0">{", "}</span><span className="gdt7">{"ctx"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"AgentContext"}</span><span className="gdt0">{")"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"Promise"}</span><span className="gdt0">{"<"}</span><span className="gdt5">{"Turn"}</span><span className="gdt0">{"> {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"59"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"events"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"StreamEvent"}</span><span className="gdt0">{"[] "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" [];"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"60"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"let"}</span><span className="gdt0">{" status"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"completed\""}</span><span className="gdt0">{" "}</span><span className="gdt4">{"|"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"failed\""}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"completed\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"61"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"let"}</span><span className="gdt0">{" messageText "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"62"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 本次 drain 里见过的 tool-input,按 callId 记名字——tool-approval-request 帧不带工具名,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"63"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// input.requested 的 action 字段从这里查。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"64"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"toolNames"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"new"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"Map"}</span><span className="gdt0">{"<"}</span><span className="gdt1">{"string"}</span><span className="gdt0">{", "}</span><span className="gdt1">{"string"}</span><span className="gdt0">{">();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"65"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"66"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"finalize"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"async"}</span><span className="gdt0">{" ()"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"Promise"}</span><span className="gdt0">{"<"}</span><span className="gdt5">{"Turn"}</span><span className="gdt0">{"> "}</span><span className="gdt4">{"=>"}</span><span className="gdt0">{" {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"67"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"if"}</span><span className="gdt0">{" (messageText) events."}</span><span className="gdt5">{"push"}</span><span className="gdt0">{"({ type: "}</span><span className="gdt2">{"\"message\""}</span><span className="gdt0">{", role: "}</span><span className="gdt2">{"\"assistant\""}</span><span className="gdt0">{", text: messageText });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"68"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"return"}</span><span className="gdt0">{" { status, events };"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"69"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" };"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"70"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"71"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"for"}</span><span className="gdt0">{" (;;) {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"72"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"frame"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" cursor."}</span><span className="gdt5">{"next"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"73"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"if"}</span><span className="gdt0">{" (frame "}</span><span className="gdt4">{"==="}</span><span className="gdt0">{" "}</span><span className="gdt1">{"null"}</span><span className="gdt0">{") "}</span><span className="gdt4">{"break"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"74"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"75"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"switch"}</span><span className="gdt0">{" (frame.type) {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"76"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"case"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"session\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"77"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 会话续接走「服务端记历史」范式:session 帧回传的 id 用 ctx.session.capture 写回。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"78"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" ctx.session."}</span><span className="gdt5">{"capture"}</span><span className="gdt0">{"(frame.sessionId);"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"79"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"break"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"80"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"81"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"case"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"text-delta\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"82"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" messageText "}</span><span className="gdt4">{"+="}</span><span className="gdt0">{" frame.delta;"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"83"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"break"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"84"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"85"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"case"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool-input\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"86"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" toolNames."}</span><span className="gdt5">{"set"}</span><span className="gdt0">{"(frame.toolCallId, frame.name);"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"87"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" events."}</span><span className="gdt5">{"push"}</span><span className="gdt0">{"({ type: "}</span><span className="gdt2">{"\"action.called\""}</span><span className="gdt0">{", callId: frame.toolCallId, name: frame.name, input: frame.input "}</span><span className="gdt4">{"as"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"JsonValue"}</span><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"88"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"break"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"89"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"90"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"case"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool-output\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"91"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" events."}</span><span className="gdt5">{"push"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"92"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" type: "}</span><span className="gdt2">{"\"action.result\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"93"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" callId: frame.toolCallId,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"94"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" output: frame.output "}</span><span className="gdt4">{"as"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"JsonValue"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"95"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" status: frame.isError "}</span><span className="gdt4">{"==="}</span><span className="gdt0">{" "}</span><span className="gdt1">{"true"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"?"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"failed\""}</span><span className="gdt0">{" "}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"completed\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"96"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"97"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"break"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"98"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"99"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"case"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool-approval-request\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"100"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 停轮:流不关,现场 hold 住;回答轮 take 回来接着读同一条流,不重新发起请求。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"101"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 中断前模型可能已经吐了一段前言(比如\"好的,我来算一下\"),一并收进这一轮。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"102"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" ctx.session."}</span><span className="gdt5">{"hold"}</span><span className="gdt0">{"<"}</span><span className="gdt5">{"PendingApproval"}</span><span className="gdt0">{">({ cursor, toolCallId: frame.toolCallId });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"103"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"if"}</span><span className="gdt0">{" (messageText) events."}</span><span className="gdt5">{"push"}</span><span className="gdt0">{"({ type: "}</span><span className="gdt2">{"\"message\""}</span><span className="gdt0">{", role: "}</span><span className="gdt2">{"\"assistant\""}</span><span className="gdt0">{", text: messageText });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"104"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" events."}</span><span className="gdt5">{"push"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"105"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" type: "}</span><span className="gdt2">{"\"input.requested\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"106"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" request: {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"107"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" id: frame.toolCallId,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"108"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" action: toolNames."}</span><span className="gdt5">{"get"}</span><span className="gdt0">{"(frame.toolCallId) "}</span><span className="gdt4">{"??"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"109"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" options: [{ id: "}</span><span className="gdt2">{"\"approve\""}</span><span className="gdt0">{" }, { id: "}</span><span className="gdt2">{"\"deny\""}</span><span className="gdt0">{" }],"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"110"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"111"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"112"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"return"}</span><span className="gdt0">{" { status: "}</span><span className="gdt2">{"\"waiting\""}</span><span className="gdt0">{", events };"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"113"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"114"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"case"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"tool-output-denied\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"115"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 被拒绝的调用不执行:action.called 在 tool-input 帧(上一轮)已落,这里只补 rejected"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"116"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 的 result——同一个 toolCallId,跨轮配对。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"117"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" events."}</span><span className="gdt5">{"push"}</span><span className="gdt0">{"({ type: "}</span><span className="gdt2">{"\"action.result\""}</span><span className="gdt0">{", callId: frame.toolCallId, status: "}</span><span className="gdt2">{"\"rejected\""}</span><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"118"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"break"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"119"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"120"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"case"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"error\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"121"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" status "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"failed\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"122"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" events."}</span><span className="gdt5">{"push"}</span><span className="gdt0">{"({ type: "}</span><span className="gdt2">{"\"error\""}</span><span className="gdt0">{", message: frame.message });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"123"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"break"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"124"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"125"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"case"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"finish\""}</span><span className="gdt0">{": {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"126"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"return"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"finalize"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"127"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"128"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{":"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"129"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"break"}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"130"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"131"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"132"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"133"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"return"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"finalize"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"134"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"}"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"135"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"136"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"async"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"function"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"send"}</span><span className="gdt0">{"("}</span><span className="gdt7">{"input"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"TurnInput"}</span><span className="gdt0">{", "}</span><span className="gdt7">{"ctx"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"AgentContext"}</span><span className="gdt0">{")"}</span><span className="gdt4">{":"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"Promise"}</span><span className="gdt0">{"<"}</span><span className="gdt5">{"Turn"}</span><span className="gdt0">{"> {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"137"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 回答轮:取回停轮现场,把裁决交回应用,接着读同一条流。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"138"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"pending"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" ctx.session."}</span><span className="gdt5">{"take"}</span><span className="gdt0">{"<"}</span><span className="gdt5">{"PendingApproval"}</span><span className="gdt0">{">();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"139"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"if"}</span><span className="gdt0">{" (pending) {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"140"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 按 requestId(挂起的 toolCallId)从 input.responses 里对位取裁决,不从 text 猜;"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"141"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt6">{"// 这里每次只挂一条审批,取第一条即可——多请求并停时按 requestId 对位。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"142"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"approved"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" input.responses?.["}</span><span className="gdt1">{"0"}</span><span className="gdt0">{"]?.optionId "}</span><span className="gdt4">{"==="}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"approve\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"143"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"approveRes"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"appFetch"}</span><span className="gdt0">{"("}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"144"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt2">{"\"/api/chat/approve\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"145"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" { toolCallId: pending.toolCallId, approved },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"146"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" ctx.signal,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"147"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" );"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"148"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"if"}</span><span className="gdt0">{" ("}</span><span className="gdt4">{"!"}</span><span className="gdt0">{"approveRes.ok) {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"149"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"throw"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"new"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"Error"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"`POST /api/chat/approve 失败: ${"}</span><span className="gdt0">{"approveRes"}</span><span className="gdt2">{"."}</span><span className="gdt0">{"status"}</span><span className="gdt2">{"} ${"}</span><span className="gdt4">{"await"}</span><span className="gdt2">{" "}</span><span className="gdt0">{"approveRes"}</span><span className="gdt2">{"."}</span><span className="gdt5">{"text"}</span><span className="gdt2">{"()"}</span><span className="gdt2">{"}`"}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"150"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"151"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"return"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"drainStream"}</span><span className="gdt0">{"(pending.cursor, ctx);"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"152"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"153"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"154"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"res"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"appFetch"}</span><span className="gdt0">{"("}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"155"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt2">{"\"/api/chat\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"156"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" { message: input.text, sessionId: ctx.session.id },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"157"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" ctx.signal,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"158"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" );"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"159"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"if"}</span><span className="gdt0">{" ("}</span><span className="gdt4">{"!"}</span><span className="gdt0">{"res.ok "}</span><span className="gdt4">{"||"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"!"}</span><span className="gdt0">{"res.body) {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"160"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"throw"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"new"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"Error"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"`POST /api/chat 失败: ${"}</span><span className="gdt0">{"res"}</span><span className="gdt2">{"."}</span><span className="gdt0">{"status"}</span><span className="gdt2">{"} ${"}</span><span className="gdt4">{"await"}</span><span className="gdt2">{" "}</span><span className="gdt0">{"res"}</span><span className="gdt2">{"."}</span><span className="gdt5">{"text"}</span><span className="gdt2">{"()."}</span><span className="gdt5">{"catch"}</span><span className="gdt2">{"(() "}</span><span className="gdt4">{"=>"}</span><span className="gdt2">{" "}</span><span className="gdt2">{"\"\""}</span><span className="gdt2">{")"}</span><span className="gdt2">{"}`"}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"161"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"162"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"return"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"drainStream"}</span><span className="gdt0">{"("}</span><span className="gdt5">{"sseJsonFrames"}</span><span className="gdt0">{"<"}</span><span className="gdt5">{"LanggraphFrame"}</span><span className="gdt0">{">(res.body), ctx);"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"163"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"}"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"164"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"165"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"export"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"defineAgent"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"166"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" name: "}</span><span className="gdt2">{"\"langgraph\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"167"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" send,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"168"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"});"}</span></td></tr></tbody></table>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<div className="gd-file">
|
|
80
|
+
<div className="gd-head"><span className="gd-name">{"evals/basic-qa.eval.ts"}</span><span className="gd-stats"><span className="gd-plus">{"+17"}</span></span></div>
|
|
81
|
+
<div className="gd-body">
|
|
82
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { defineEval } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 这条 eval 验证 agent 能正常问答、不瞎调工具。断言依据全部来自 adapter 从应用自己的"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// SSE 帧映射的事件;应用协议里没有 usage,所以这里不做用量断言(OTel span 只进瀑布图)。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"export"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"defineEval"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" description: "}</span><span className="gdt2">{"\"测试 agent 能正常问答且不瞎调工具\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"async"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"test"}</span><span className="gdt0">{"("}</span><span className="gdt7">{"t"}</span><span className="gdt0">{") {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"turn"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"send"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"用一句话介绍一下你自己,这轮不用查天气也不用算数。\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" turn."}</span><span className="gdt5">{"expectOk"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"group"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"正常收发、没有多余工具调用\""}</span><span className="gdt0">{", () "}</span><span className="gdt4">{"=>"}</span><span className="gdt0">{" {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"succeeded"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"usedNoTools"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"15"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"16"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"17"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"});"}</span></td></tr></tbody></table>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<div className="gd-file">
|
|
87
|
+
<div className="gd-head"><span className="gd-name">{"evals/hitl-approve.eval.ts"}</span><span className="gd-stats"><span className="gd-plus">{"+24"}</span></span></div>
|
|
88
|
+
<div className="gd-body">
|
|
89
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { defineEval } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { equals } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval/expect\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// calculate 工具经 LangChain HumanInTheLoopMiddleware 挂了审批(见 agents/langgraph.ts、"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// origin src/backend/agent.py)。这条验证批准分支:approve 之后工具正常执行。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"//"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 提示词不提\"审批\"——不同模型看到提示词里的\"审批\"字样,有的会倾向于用文字反问用户"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// \"可以吗\"而不是真的发起工具调用(在 pi-sdk / claude-sdk 的接入里都复现过);审批门是"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 服务端中间件自动挂的,跟用户怎么问无关。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"export"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"defineEval"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" description: "}</span><span className="gdt2">{"\"HITL:calculate 经批准后正常执行\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"async"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"test"}</span><span className="gdt0">{"("}</span><span className="gdt7">{"t"}</span><span className="gdt0">{") {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"draft"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"send"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"用计算器算一下 (23+19)*3 等于多少\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"15"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"check"}</span><span className="gdt0">{"(draft.status, "}</span><span className="gdt5">{"equals"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"waiting\""}</span><span className="gdt0">{"));"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"16"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"17"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"requireInputRequest"}</span><span className="gdt0">{"({ action: "}</span><span className="gdt2">{"\"calculate\""}</span><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"18"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"19"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"approved"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"respond"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"approve\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"20"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" approved."}</span><span className="gdt5">{"succeeded"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"21"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"calledTool"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"calculate\""}</span><span className="gdt0">{", { status: "}</span><span className="gdt2">{"\"completed\""}</span><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"22"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"messageIncludes"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"/"}</span><span className="gdt8">{"126"}</span><span className="gdt2">{"/"}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"23"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"24"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"});"}</span></td></tr></tbody></table>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<div className="gd-file">
|
|
94
|
+
<div className="gd-head"><span className="gd-name">{"evals/hitl-deny.eval.ts"}</span><span className="gd-stats"><span className="gd-plus">{"+25"}</span></span></div>
|
|
95
|
+
<div className="gd-body">
|
|
96
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { defineEval } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { equals } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval/expect\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// deny 分支:人否决和工具故障是两回事——calledTool 的 status 应该是 \"rejected\""}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// (来自 tool-output-denied 帧,span 里没有\"人拒绝\"这个语义,adapter 手动补的,见"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// agents/langgraph.ts),noFailedActions() 依然通过。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"//"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 有的模型被拒绝一次后会不死心、原样再试一次同一个工具调用(在 claude-sdk 的接入里复现过),"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 不是 adapter 的映射 bug,是模型行为。deny 到它放弃为止,给个上限避免死循环。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"export"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"defineEval"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" description: "}</span><span className="gdt2">{"\"HITL:calculate 被拒绝后标记 rejected 而不是 failed\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"async"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"test"}</span><span className="gdt0">{"("}</span><span className="gdt7">{"t"}</span><span className="gdt0">{") {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"send"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"用计算器算一下 (23+19)*3 等于多少\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"15"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"requireInputRequest"}</span><span className="gdt0">{"({ action: "}</span><span className="gdt2">{"\"calculate\""}</span><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"16"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"17"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"let"}</span><span className="gdt0">{" denied "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"respond"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"deny\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"18"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"for"}</span><span className="gdt0">{" ("}</span><span className="gdt4">{"let"}</span><span className="gdt0">{" attempt "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt1">{"0"}</span><span className="gdt0">{"; attempt "}</span><span className="gdt4">{"<"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"3"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"&&"}</span><span className="gdt0">{" denied.status "}</span><span className="gdt4">{"==="}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"waiting\""}</span><span className="gdt0">{"; attempt"}</span><span className="gdt4">{"++"}</span><span className="gdt0">{") {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"19"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" denied "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"respond"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"deny\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"20"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" }"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"21"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"check"}</span><span className="gdt0">{"(denied.status, "}</span><span className="gdt5">{"equals"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"completed\""}</span><span className="gdt0">{"));"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"22"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"calledTool"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"calculate\""}</span><span className="gdt0">{", { status: "}</span><span className="gdt2">{"\"rejected\""}</span><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"23"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"noFailedActions"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"24"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"25"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"});"}</span></td></tr></tbody></table>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div className="gd-file">
|
|
101
|
+
<div className="gd-head"><span className="gd-name">{"evals/session-isolation.eval.ts"}</span><span className="gd-stats"><span className="gd-plus">{"+19"}</span></span></div>
|
|
102
|
+
<div className="gd-body">
|
|
103
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { defineEval } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { includes, excludes } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval/expect\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 这条 eval 专门验证会话续接的两半承诺:同一条会话线里第二轮记得住第一轮说的名字"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// (LangGraph InMemorySaver 按 thread_id 续接成功);t.newSession() 造出的新会话线不共享历史。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"export"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"defineEval"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" description: "}</span><span className="gdt2">{"\"测试跨轮记忆与 newSession() 隔离\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"async"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"test"}</span><span className="gdt0">{"("}</span><span className="gdt7">{"t"}</span><span className="gdt0">{") {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"send"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"我叫小明,帮我记住这个名字。\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"recall"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"send"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"我刚才说我叫什么名字?\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" recall."}</span><span className="gdt5">{"messageIncludes"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"小明\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"check"}</span><span className="gdt0">{"(t.reply, "}</span><span className="gdt5">{"includes"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"小明\""}</span><span className="gdt0">{"));"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"15"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"fresh"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"newSession"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"16"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" fresh."}</span><span className="gdt5">{"send"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"我叫什么名字?\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"17"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"check"}</span><span className="gdt0">{"(fresh.reply, "}</span><span className="gdt5">{"excludes"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"小明\""}</span><span className="gdt0">{"));"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"18"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"19"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"});"}</span></td></tr></tbody></table>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div className="gd-file">
|
|
108
|
+
<div className="gd-head"><span className="gd-name">{"evals/weather-tool.eval.ts"}</span><span className="gd-stats"><span className="gd-plus">{"+22"}</span></span></div>
|
|
109
|
+
<div className="gd-body">
|
|
110
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { defineEval } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 这条 eval 验证 agent 遇到实时天气问题时调 get_weather,而不是直接编一个答案。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// get_weather 不是 gated 工具,它的 action.called/action.result 完全来自 LangSmith span"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 派生,adapter 没有为它写一行帧映射(帧映射只补了 gated 的 calculate,见 agents/langgraph.ts)。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"export"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"defineEval"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" description: "}</span><span className="gdt2">{"\"测试 agent 在天气问题中正确调用 get_weather 并基于结果作答\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"async"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"test"}</span><span className="gdt0">{"("}</span><span className="gdt7">{"t"}</span><span className="gdt0">{") {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"const"}</span><span className="gdt0">{" "}</span><span className="gdt1">{"turn"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"="}</span><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"send"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"北京今天天气怎么样?\""}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" turn."}</span><span className="gdt5">{"expectOk"}</span><span className="gdt0">{"();"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"12"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"13"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" "}</span><span className="gdt4">{"await"}</span><span className="gdt0">{" t."}</span><span className="gdt5">{"group"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"调用 get_weather 且城市正确\""}</span><span className="gdt0">{", () "}</span><span className="gdt4">{"=>"}</span><span className="gdt0">{" {"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"14"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"calledTool"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"get_weather\""}</span><span className="gdt0">{", { input: { city: "}</span><span className="gdt2">{"\"北京\""}</span><span className="gdt0">{" } });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"15"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t."}</span><span className="gdt5">{"messageIncludes"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"/"}</span><span className="gdt8">{"°C"}</span><span className="gdt4">{"|"}</span><span className="gdt8">{"气温"}</span><span className="gdt4">{"|"}</span><span className="gdt8">{"天气"}</span><span className="gdt4">{"|"}</span><span className="gdt8">{"晴"}</span><span className="gdt4">{"|"}</span><span className="gdt8">{"多云"}</span><span className="gdt4">{"|"}</span><span className="gdt8">{"雨"}</span><span className="gdt4">{"|"}</span><span className="gdt8">{"阴"}</span><span className="gdt2">{"/"}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"16"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" });"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"17"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"18"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" t.judge.autoevals"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"19"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" ."}</span><span className="gdt5">{"closedQA"}</span><span className="gdt0">{"("}</span><span className="gdt2">{"\"助手是否给出了具体的天气数据(温度或天气状况),而不是拒绝回答或含糊其辞?\""}</span><span className="gdt0">{")"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"20"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" ."}</span><span className="gdt5">{"atLeast"}</span><span className="gdt0">{"("}</span><span className="gdt1">{"0.7"}</span><span className="gdt0">{");"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"21"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" },"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"22"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"});"}</span></td></tr></tbody></table>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<div className="gd-file">
|
|
115
|
+
<div className="gd-head"><span className="gd-name">{"experiments/langgraph.ts"}</span><span className="gd-stats"><span className="gd-plus">{"+11"}</span></span></div>
|
|
116
|
+
<div className="gd-body">
|
|
117
|
+
<table className="gd-table"><tbody><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"1"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" { defineExperiment } "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"niceeval\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"2"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"import"}</span><span className="gdt0">{" agent "}</span><span className="gdt4">{"from"}</span><span className="gdt0">{" "}</span><span className="gdt2">{"\"../agents/langgraph.ts\""}</span><span className="gdt0">{";"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"3"}</td><td className="gd-sign">{"+"}</td><td className="gd-code">{" "}</td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"4"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// 单配置基线:不比较模型,用 .env 里的默认模型(deepseek-v4-flash,经 OpenAI 兼容端点)。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"5"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// docs/origin-integration.md 的验收清单里,多模型对比只点名了 ai-sdk-v7 / claude-sdk /"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"6"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt6">{"// pi-sdk 三个,这里不建 experiments/compare-models/。"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"7"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt4">{"export"}</span><span className="gdt0">{" "}</span><span className="gdt4">{"default"}</span><span className="gdt0">{" "}</span><span className="gdt5">{"defineExperiment"}</span><span className="gdt0">{"({"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"8"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" description: "}</span><span className="gdt2">{"\"langgraph:真实 LangGraph + DeepSeek 后端\""}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"9"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" agent,"}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"10"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{" runs: "}</span><span className="gdt1">{"1"}</span><span className="gdt0">{","}</span></td></tr><tr className="gd-add"><td className="gd-ln"></td><td className="gd-ln">{"11"}</td><td className="gd-sign">{"+"}</td><td className="gd-code"><span className="gdt0">{"});"}</span></td></tr></tbody></table>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|