Skip to content

evals: consume agent mounts generically in the claude_code tool adapter - #2596

Merged
miguelg719 merged 1 commit into
stg-2671-cdp-code-exposurefrom
stg-2671-exposure-adapter
Aug 9, 2026
Merged

evals: consume agent mounts generically in the claude_code tool adapter#2596
miguelg719 merged 1 commit into
stg-2671-cdp-code-exposurefrom
stg-2671-exposure-adapter

Conversation

@shriyatheunicorn

@shriyatheunicorn shriyatheunicorn commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

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_code adapter 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

    • Generic agent mount consumption across playwright_code, cdp_code, and stagehand_code; prompt text, run-tool copy/deny messages, and task/console bindings come from the mount.
    • Optional captureEvidence() for grading (timeout EVAL_CAPTURE_EVIDENCE_TIMEOUT_MS); standardized identifiers via AGENT_RUN_TOOL_NAME and AGENT_RUN_TOOL_SERVER.
  • Refactors

    • One mount consumer replaces bespoke surface code; snippets run with handle names plus startUrl/task/console. Re-exports waitForCdpEvent.
    • Shared tool/target lifecycle via startAgentToolRuntime with idempotent cleanup (timeout EVAL_AGENT_MOUNT_CLEANUP_TIMEOUT_MS); startup profiles: browse_cli/stagehand_code own the browser, playwright_code/cdp_code expect runner-provided CDP. Improved browse_cli build-artifacts error.

Written for commit 5a1a4ea. Summary will update on new commits.

Review in cubic

@changeset-bot

changeset-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 5a1a4ea

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/evals/framework/claudeCodeToolAdapter.ts Outdated
Comment thread packages/evals/framework/claudeCodeToolAdapter.ts Outdated
Comment thread packages/evals/framework/claudeCodeToolAdapter.ts Outdated
Comment thread packages/evals/framework/claudeCodeToolAdapter.ts
Comment thread packages/evals/framework/claudeCodeToolAdapter.ts
@shriyatheunicorn
shriyatheunicorn force-pushed the stg-2671-exposure-adapter branch from b3a408c to 4415d1d Compare August 5, 2026 07:14
@shriyatheunicorn
shriyatheunicorn force-pushed the stg-2671-exposure-adapter branch from 4415d1d to 934dc33 Compare August 5, 2026 08:13
@shriyatheunicorn
shriyatheunicorn force-pushed the stg-2671-exposure-adapter branch from 934dc33 to 4f4a5c2 Compare August 5, 2026 08:28
@shriyatheunicorn
shriyatheunicorn force-pushed the stg-2671-exposure-adapter branch 2 times, most recently from 1f71e95 to e15f1ec Compare August 5, 2026 19:06
@shriyatheunicorn
shriyatheunicorn force-pushed the stg-2671-exposure-adapter branch from e15f1ec to 5d3e260 Compare August 5, 2026 22:40

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed against the latest diff

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/evals/framework/claudeCodeToolAdapter.ts Outdated
Comment thread packages/evals/framework/claudeCodeToolAdapter.ts Outdated
@shriyatheunicorn
shriyatheunicorn force-pushed the stg-2671-exposure-adapter branch from 5d3e260 to 34b0311 Compare August 6, 2026 02:16
@shriyatheunicorn
shriyatheunicorn force-pushed the stg-2671-exposure-adapter branch from 34b0311 to 151893c Compare August 6, 2026 02:46
@miguelg719
miguelg719 force-pushed the stg-2671-exposure-adapter branch from 151893c to bb002d3 Compare August 6, 2026 23:27
@shriyatheunicorn
shriyatheunicorn force-pushed the stg-2671-exposure-adapter branch from bb002d3 to 5a1a4ea Compare August 8, 2026 04:49
@miguelg719 miguelg719 changed the title evals: consume LLMExposures generically in the claude_code tool adapter evals: consume agent mounts generically in the claude_code tool adapter Aug 9, 2026
@miguelg719
miguelg719 merged commit b8c9628 into v4-spike Aug 9, 2026
26 of 39 checks passed
miguelg719 added a commit that referenced this pull request Aug 9, 2026
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. -->
miguelg719 added a commit that referenced this pull request Aug 9, 2026
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. -->
miguelg719 added a commit that referenced this pull request Aug 9, 2026
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. -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants