evals: consume agent mounts generically in the claude_code tool adapter - #2596
Conversation
|
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Architecture diagram
sequenceDiagram
participant Test as Eval Test
participant Adapter as ClaudeCodeToolAdapter
participant Exposure as LLMExposure (code_handles)
participant Runner as Eval Runner (CDP/Browser)
participant MCP as Local MCP Server
participant Surface as Surface Module (v4/playwright/cdp_code)
Note over Test,Adapter: SURFACE RESOLUTION
Test->>Adapter: prepareClaudeCodeToolAdapter(toolSurface, startupProfile)
alt browse_cli
Adapter->>Adapter: prepareBrowseCliHarnessAdapter()
Adapter-->>Test: browse_cli adapter
else playwright_code/cdp_code/v4_code (NEW generic path)
Adapter->>Surface: prepareLLMExposure(plan, environment, logger, startupProfile)
Surface-->>Adapter: exposure (kind: "code_handles", handles, prompt, cleanup)
Adapter->>Adapter: prepareCodeExposureAdapter(exposure, input)
Note over Adapter,Exposure: VERIFY kind="code_handles" with handles
Adapter->>Adapter: Create per-surface temp dir (v4/playwright/cdp)
Adapter->>Adapter: Build AsyncFunction scope over handle names
Adapter->>MCP: Mount "run" tool with surface handles + startUrl/task/console
Adapter-->>Test: Generic exposure adapter
end
Note over Test,MCP: STARTUP PROFILE RESOLUTION
alt v4_code (NEW)
Test->>Adapter: resolveClaudeCodeStartupProfile("v4_code", env)
Adapter-->>Test: tool_create_browserbase / tool_launch_local
Note over Adapter,Runner: v4 SDK owns its browser instance
else playwright_code/cdp_code
Test->>Adapter: resolveClaudeCodeStartupProfile("playwright_code", env)
Adapter-->>Test: runner_provided_local_cdp / runner_provided_browserbase_cdp
Note over Adapter,Runner: Runner provides CDP endpoint
end
Note over Test,MCP: RUNTIME EXECUTION
Test->>Adapter: runTool(toolName, input)
Adapter->>MCP: Execute code with surface handles
MCP->>Surface: Call handle functions (browser/page/CDP/console)
Surface-->>MCP: Results
MCP-->>Adapter: Tool output
Adapter-->>Test: Record<string, unknown>
Note over Test,Adapter: FINAL STATE CAPTURE (NEW optional)
alt Surface exposure implements captureFinalState
Test->>Adapter: captureFinalState()
Adapter->>Surface: captureFinalState() (bounded by EVAL_FINAL_STATE_TIMEOUT_MS)
Surface-->>Adapter: TerminalArtifact
Adapter-->>Test: captureFinalState result
end
Note over Adapter,Surface: CLEANUP
Test->>Adapter: cleanup()
Adapter->>Surface: exposure.cleanup() (bounded by EVAL_EXPOSURE_CLEANUP_TIMEOUT_MS)
Adapter->>Adapter: Remove per-surface temp dir
Adapter-->>Test: Cleanup complete
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
b3a408c to
4415d1d
Compare
4415d1d to
934dc33
Compare
934dc33 to
4f4a5c2
Compare
1f71e95 to
e15f1ec
Compare
e15f1ec to
5d3e260
Compare
There was a problem hiding this comment.
Review completed against the latest diff
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
5d3e260 to
34b0311
Compare
34b0311 to
151893c
Compare
151893c to
bb002d3
Compare
bb002d3 to
5a1a4ea
Compare
The agent-facing half of the stagehand_code code-mode surface: prepareLLMExposure initializes a v4 Stagehand client via initStagehand and declares a code_handles agent mount — stagehand/page/z in the snippet scope, surface-owned prompt instructions and run-tool copy, final-state evidence capture (screenshot + URL + aria tree), and cleanup that closes the browser as well as the client (stagehand.close() alone leaves the browser running). Nothing consumes the mount here; the claude_code adapter does in #2596 and codex in #2609. Bottom of the nondeterministic-evals stack (#2591 → #2611, with the merge-readiness fixes in #2649 and the MCP tool surfaces in #2650 stacked on top).⚠️ **Base housekeeping before merge**: this PR still targets `evals-v4-root`, which has since merged (via #2570 → #2494) into `v4-spike`. Rebase onto current `v4-spike` and retarget. One known reconciliation: v4-spike removed the `EVAL_VERIFIER_MODEL` override from `verifierAdapter` (2af557b) as redundant with V3Evaluator's own constructor options; this stack's later PRs still carry it — drop it during the rebase rather than reintroducing it. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds the `stagehand_code` code-mode tool and registers it in the core tool registry, wiring a v4 `@browserbasehq/stagehand` client with scoped handles, run-tool execution, artifact capture, and full teardown. Enables the v4 code-mode surface for STG-2671 with a fixed SDK model and local/Browserbase startup profiles. - New Features - New `StagehandCodeTool` (`id: stagehand_code`) with session, navigation, evaluation, screenshot, viewport, wait, click, hover, scroll, type, press, tabs, and representation. - Targets: `selector`, `coords`, `focused`. - Agent mount via handles: `stagehand`, `page`, and `z`; scoped prompt instructions; run-tool description, code param description, and deny message. Snippets also get `startUrl`, `task`, and `console` in scope. - Captures screenshot, URL, and ARIA tree; cleanup closes both the Stagehand client and the browser. - Profiles: `tool_launch_local` and `tool_create_browserbase`; connection mode derived; model fixed to `openai/gpt-4.1-mini`. - Registered in `listCoreTools`/`getCoreTool`; tests assert `stagehand_code` is retrievable and that prompt guidance includes awaited locator actions. <sup>Written for commit e579140. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/browserbase/stagehand/pull/2591?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
The surface now owns its agent mount: prompt instructions (carried over verbatim from the per-surface block inside the claude_code tool adapter), a code_handles declaration, and captureEvidence() returning the terminal screenshot, URL, and aria tree. Behavior is unchanged until the adapter consumes mounts generically in #2596. Part of the nondeterministic-evals stack (#2591 → #2611). <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Make `playwright_code` agent-mountable so the v4 harness can consume it generically, with handle exposure, prompt wiring, runTool config, and best-effort evidence capture. No behavior change; supports STG-2671’s non-deterministic suite. - **New Features** - Added `agentMount` with handle access (`page`, `context`, `browser`), prompt instructions (incl. first-action guidance), and `runTool` config (async snippet scope: `page`, `context`, `browser`, `startUrl`, `task`, `console`; return JSON-serializable values; deny message references `AGENT_RUN_TOOL_NAME`). - Added `captureEvidence` typed as `ProbeEvidence` (screenshot, URL, `ariaTree` via `page.represent({ includeIframes: true })` with best-effort per modality); track active page on `"page"` events; ensured initial page exists; unified cleanup. <sup>Written for commit 9cf16fb. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/browserbase/stagehand/pull/2592?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
Same shape as #2592 for the CDP surface: prompt instructions carried over verbatim, code_handles declaration, captureEvidence() for the terminal screenshot, URL, and aria tree. Behavior is unchanged until the adapter consumes mounts generically in #2596. Part of the nondeterministic-evals stack (#2591 → #2611). <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Expose `cdp_code` as an `LLMExposure` with an agent-mountable `cdp` runtime, clearer prompt instructions, and richer final-state evidence. Linked to Linear STG-2671 (part 5/6). Requires the `LLMExposure` contract (1/6). - **New Features** - Agent mount: `handles.cdp`; prompt includes `AGENT_RUN_TOOL_NAME`, a first navigate/load recipe, run-tool description and code param, and a deny message; `captureEvidence` collects screenshot, URL, and `ariaTree`. - Runtime: `send`/`browser` plus `on`/`off`/`once`/`waitForEvent`/`wait` with session scoping, timeouts, safe teardown, and unhandled-rejection guards; exposes `targetId`/`sessionId`; `createAgentRuntime(logger)` initializes it. - Representation: adds `representation` capability; `page.represent()` returns the accessibility tree with metadata; evidence includes `ariaTree`. - Page management: `syncPages` keeps session pages current before `listPages`/`activePage`; bootstrap only creates a target if none exist. <sup>Written for commit e641edf. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/browserbase/stagehand/pull/2595?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
Replaces the per-surface logic inside the adapter with one generic
mount consumer: any surface declaring an agent mount gets its handles
mounted as the single local-MCP run tool, with the surface's own prompt
instructions. Net deletion — the bespoke playwright_code/cdp_code blocks
move behind the contract, and adding a surface no longer means editing
the adapter.
Part of the nondeterministic-evals stack (#2591 → #2611). Requires the
three mount declarations below it.
Verified across the stack: tsc and oxlint per part, evals vitest, live
core runs on Browserbase for --tool stagehand_code, playwright_code, and
cdp_code (3/3 each, prompt exit), one long-horizon row (webvoyager x
claude_code x stagehand_code, 3/3), and the paired webvoyager acceptance
run (stagehand_code 2/3 vs playwright_code 3/3, both cells traced to
Braintrust).
Summary by cubic
Consume LLM exposure mounts generically in the
claude_codeadapter so all code surfaces expose their handles as a single MCP run tool. This aligns with STG-2671 and adds optional evidence capture while removing surface-specific logic.New Features
playwright_code,cdp_code, andstagehand_code; prompt text, run-tool copy/deny messages, andtask/consolebindings come from the mount.captureEvidence()for grading (timeoutEVAL_CAPTURE_EVIDENCE_TIMEOUT_MS); standardized identifiers viaAGENT_RUN_TOOL_NAMEandAGENT_RUN_TOOL_SERVER.Refactors
startUrl/task/console. Re-exportswaitForCdpEvent.startAgentToolRuntimewith idempotent cleanup (timeoutEVAL_AGENT_MOUNT_CLEANUP_TIMEOUT_MS); startup profiles:browse_cli/stagehand_codeown the browser,playwright_code/cdp_codeexpect runner-provided CDP. Improvedbrowse_clibuild-artifacts error.Written for commit 5a1a4ea. Summary will update on new commits.