evals: add the LLMExposure tool-surface contract - #2590
Merged
Conversation
|
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 1 file
Architecture diagram
sequenceDiagram
participant Harness as Eval Harness (claude_code, codex, …)
participant Surface as Tool Surface (LLMExposure)
participant LLM as LLM / Agent
participant MCP as MCP Runtime (stagehand_browser)
participant CLI as CLI Subprocess
Note over Harness,CLI: Tool-surface mount contract (types only, no runtime)
Harness->>Surface: read .kind, choose mount strategy
alt kind == "code_handles"
Harness->>Surface: read .handles (named scope values)
Harness->>Surface: read .runTool (description, codeParam, task, console)
Harness->>Harness: wrap into single MCP "run" tool
Harness->>MCP: mount tool under server "stagehand_browser"
MCP-->>LLM: expose tool as LLM_RUN_TOOL_NAME
LLM->>MCP: invoke "run" with snippet
MCP->>MCP: execute snippet with bound handles + task + console
MCP-->>LLM: return result (stringified, no raw images)
else kind == "mcp_server"
Harness->>Surface: read .mcpServers (config object)
Harness->>MCP: mount server config directly
MCP-->>LLM: expose surface tools
LLM->>MCP: direct tool calls
else kind == "cli"
Harness->>Surface: read .command (bin + env)
Harness->>CLI: spawn subprocess with env
CLI-->>LLM: expose via stdio / args
end
Note over Harness,Surface: Post-agent-run artifact capture
Harness->>Surface: read .captureFinalState (function or undefined)
alt captureFinalState is defined
Surface->>Surface: capture screenshot + URL from page
alt screenshot fails
Surface->>Surface: swallow error, omit screenshot from result
end
alt URL fetch fails
Surface->>Surface: swallow error, omit URL from result
end
Surface-->>Harness: TerminalArtifact (partial allowed)
else captureFinalState is undefined
Harness->>Harness: no terminal state capture
end
Note over Harness,CLI: Cleanup
Harness->>Surface: read .cleanup (function)
Surface->>Surface: release resources (browser, processes, …)
Note over Harness,LLM: Constants referenced by mounting code
Harness->>Harness: read LLM_RUN_TOOL_SERVER = "stagehand_browser"
Harness->>Harness: read LLM_RUN_TOOL_NAME = "mcp__stagehand_browser__run"
Harness->>LLM: bind tool name in run-tool prompt instructions
LLM->>LLM: use tool name in function-call requests
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Contributor
There was a problem hiding this comment.
No issues found across 1 file
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Architecture diagram
sequenceDiagram
participant Harness as Eval Harness (claude_code, codex, …)
participant Surface as Tool Surface (LLMExposure)
participant LLM as LLM / Agent
participant MCP as MCP Runtime (stagehand_browser)
participant CLI as CLI Subprocess
Note over Harness,CLI: Tool-surface mount contract (types only, no runtime)
Harness->>Surface: read .kind, choose mount strategy
alt kind == "code_handles"
Harness->>Surface: read .handles (named scope values)
Harness->>Surface: read .runTool (description, codeParam, task, console)
Harness->>Harness: wrap into single MCP "run" tool
Harness->>MCP: mount tool under server "stagehand_browser"
MCP-->>LLM: expose tool as LLM_RUN_TOOL_NAME
LLM->>MCP: invoke "run" with snippet
MCP->>MCP: execute snippet with bound handles + task + console
MCP-->>LLM: return result (stringified, no raw images)
else kind == "mcp_server"
Harness->>Surface: read .mcpServers (config object)
Harness->>MCP: mount server config directly
MCP-->>LLM: expose surface tools
LLM->>MCP: direct tool calls
else kind == "cli"
Harness->>Surface: read .command (bin + env)
Harness->>CLI: spawn subprocess with env
CLI-->>LLM: expose via stdio / args
end
Note over Harness,Surface: Post-agent-run artifact capture
Harness->>Surface: read .captureFinalState (function or undefined)
alt captureFinalState is defined
Surface->>Surface: capture screenshot + URL from page
alt screenshot fails
Surface->>Surface: swallow error, omit screenshot from result
end
alt URL fetch fails
Surface->>Surface: swallow error, omit URL from result
end
Surface-->>Harness: TerminalArtifact (partial allowed)
else captureFinalState is undefined
Harness->>Harness: no terminal state capture
end
Note over Harness,CLI: Cleanup
Harness->>Surface: read .cleanup (function)
Surface->>Surface: release resources (browser, processes, …)
Note over Harness,LLM: Constants referenced by mounting code
Harness->>Harness: read LLM_RUN_TOOL_SERVER = "stagehand_browser"
Harness->>Harness: read LLM_RUN_TOOL_NAME = "mcp__stagehand_browser__run"
Harness->>LLM: bind tool name in run-tool prompt instructions
LLM->>LLM: use tool name in function-call requests
shriyatheunicorn
force-pushed
the
stg-2671-llm-exposure-contract
branch
3 times, most recently
from
August 5, 2026 08:28
3316ea4 to
f4a0e3a
Compare
shriyatheunicorn
force-pushed
the
stg-2671-llm-exposure-contract
branch
from
August 5, 2026 17:45
f4a0e3a to
7827ab7
Compare
shriyatheunicorn
force-pushed
the
stg-2671-llm-exposure-contract
branch
from
August 5, 2026 19:06
7827ab7 to
687f432
Compare
shriyatheunicorn
force-pushed
the
stg-2671-llm-exposure-contract
branch
from
August 5, 2026 22:40
687f432 to
daee645
Compare
shriyatheunicorn
force-pushed
the
stg-2671-llm-exposure-contract
branch
from
August 6, 2026 02:16
daee645 to
5cd453d
Compare
A uniform declaration of what a tool surface offers a coding agent: code_handles (in-scope objects the agent writes code against, mounted by the harness as a single local-MCP run tool), mcp_server, or cli — plus the LLM_RUN_TOOL_SERVER/LLM_RUN_TOOL_NAME bindings the mount uses. Types and constants only; no surface or adapter changes. Part 1/4 of the #2473 port onto the current SDK generation.
shriyatheunicorn
force-pushed
the
stg-2671-llm-exposure-contract
branch
from
August 6, 2026 02:46
5cd453d to
449a8a4
Compare
## Summary - keep the existing `CoreTool` abstraction as the canonical tool-surface definition - attach optional agent delivery and final-state capture to `ToolStartResult`, preserving one runtime lifecycle - replace `LLMExposure` with a lifecycle-free `AgentMount` value using the independent `via: handles | mcp | cli` delivery axis - keep native `CoreTool.surface` independent from agent delivery, so a code surface may be wrapped by MCP or CLI - leave task, start URL, and default console binding with the harness - define reserved harness bindings, CLI environment merge semantics, and capture-before-cleanup ordering This is stacked on #2590. The revision deliberately defers broad naming/registry churn so the contract change remains a focused two-file diff. ## Verification - `pnpm --filter @browserbasehq/stagehand-evals typecheck` - `pnpm --filter @browserbasehq/stagehand-evals test:unit` (52 files, 413 tests) - focused formatting check passed - reviewed independently with Claude Opus 5 against the inline repository diff
shriyatheunicorn
added a commit
that referenced
this pull request
Aug 8, 2026
A uniform declaration of what a tool surface offers a coding agent: code_handles (in-scope objects the agent writes code against, mounted by the harness as a single local-MCP run tool), mcp_server, or cli — plus the LLM_RUN_TOOL_SERVER/LLM_RUN_TOOL_NAME bindings the mount uses. Types and constants only; no surface or adapter changes. Part 1/4 of the #2473 port onto the current SDK generation. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Updates the tool-surface contract to include agent delivery (`AgentMount`) and final-state evidence capture, keeping native `CoreTool.surface` independent from how it’s delivered to the agent. Types + tests only; supports STG-2671. - **New Features** - Types: `AgentMount` (`via: handles | mcp | cli` with `promptInstructions`), `AgentRunToolSpec`; `ToolStartResult` gains optional `agentMount` and `captureEvidence(): Promise<ProbeEvidence>`. - Enums: `ToolSurface` adds `stagehand_code`; `CoreTool.family` adds `stagehand`. - Constants: `AGENT_RUN_TOOL_SERVER` ("stagehand_browser"), `AGENT_RUN_TOOL_NAME` (`mcp__stagehand_browser__run`), `AGENT_RUN_TOOL_RESERVED_HANDLES` (`startUrl`, `task`, `console`). - Contract semantics: delivery is independent of native surface; CLI env merges over harness env; reserved harness bindings; capture-before-cleanup ordering. - Tests: `tool-contract.test.ts` validates delivery independence, handle mounts, and evidence capture. <sup>Written for commit d3ba958. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/browserbase/stagehand/pull/2590?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. --> --------- Co-authored-by: Miguel <36487034+miguelg719@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A uniform declaration of what a tool surface offers a coding agent:
code_handles (in-scope objects the agent writes code against, mounted by
the harness as a single local-MCP run tool), mcp_server, or cli — plus
the LLM_RUN_TOOL_SERVER/LLM_RUN_TOOL_NAME bindings the mount uses.
Types and constants only; no surface or adapter changes.
Part 1/4 of the #2473 port onto the current SDK generation.
Summary by cubic
Updates the tool-surface contract to include agent delivery (
AgentMount) and final-state evidence capture, keeping nativeCoreTool.surfaceindependent from how it’s delivered to the agent. Types + tests only; supports STG-2671.AgentMount(via: handles | mcp | cliwithpromptInstructions),AgentRunToolSpec;ToolStartResultgains optionalagentMountandcaptureEvidence(): Promise<ProbeEvidence>.ToolSurfaceaddsstagehand_code;CoreTool.familyaddsstagehand.AGENT_RUN_TOOL_SERVER("stagehand_browser"),AGENT_RUN_TOOL_NAME(mcp__stagehand_browser__run),AGENT_RUN_TOOL_RESERVED_HANDLES(startUrl,task,console).tool-contract.test.tsvalidates delivery independence, handle mounts, and evidence capture.Written for commit d3ba958. Summary will update on new commits.