Skip to content

evals: codex harness across all code tool surfaces - #2609

Merged
miguelg719 merged 1 commit into
stg-2671-exposure-adapterfrom
codex-adapter
Aug 9, 2026
Merged

evals: codex harness across all code tool surfaces#2609
miguelg719 merged 1 commit into
stg-2671-exposure-adapterfrom
codex-adapter

Conversation

@shriyatheunicorn

@shriyatheunicorn shriyatheunicorn commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Codex joins claude_code as an external harness across all three code tool surfaces (stagehand_code, playwright_code, cdp_code) — recreating #2397 on the LLMExposure architecture.

codex-sdk has no in-process MCP mounting (unlike claude-agent-sdk), and an external MCP process could not share this process's live surface handles. So the codex mount for a code_handles exposure is a loopback HTTP bridge: this process executes snippets against the in-memory handles; the codex workspace gets a tiny browser_run.mjs client that posts a snippet file to the bridge and prints the result. Scope semantics are identical to the claude_code run tool.

  • codexCodeBridge.ts (new): the bridge server + generated workspace client
  • codexToolAdapter.ts: code-surface mounting (exposure selection, bridge lifecycle, tmpdir cwd, prompt rewrite from run-tool to browser_run.mjs invocation)
  • codexRunner.ts / harnesses/codexAdapter.ts: harness-observed terminal artifact anchors the verifier's final observation, mirroring the claude_code runner
  • Tests: bridge round-trip + widened surface resolution

Part of the nondeterministic-evals stack; stacks on the exposure-adapter PR.

Follow-up on top of the stack: #2650 adds the MCP tool surfaces (playwright_mcp / chrome_devtools_mcp) to both external harnesses; MCP tool calls there count against the codex tool-step budget introduced in #2649.


Summary by cubic

Enable Codex on stagehand_code, playwright_code, and cdp_code via a loopback HTTP bridge that runs snippets against in-memory handles, with terminal artifact capture in the runner for grounded grading. browse_cli remains supported with sane startup defaults, and code surfaces now have clear browser_run.mjs guidance.

  • New Features

    • Bridge server/client in codexCodeBridge.ts: browser_run.mjs posts snippet code to /run; executes with handles, startUrl, task, and console; timeout via EVAL_CODEX_RUN_TOOL_TIMEOUT_MS; non-zero exit on failure.
    • Tool adapter and runner: codexToolAdapter.ts mounts browse_cli, stagehand_code, playwright_code, cdp_code; defaults to tool-owned browsers for browse_cli/stagehand_code and runner-provided CDP for playwright_code/cdp_code; writes browser_run.mjs and rewrites AGENT_RUN_TOOL_NAME; captures evidence via captureEvidence and passes it to codexAdapter.ts; robust cleanup.
  • Bug Fixes

    • Final observation is only anchored when a screenshot is present; URL-only artifacts no longer qualify.
    • Redacts credential fragments (e.g., signingKey, sk-*) from snippet error messages before crossing the bridge or hitting logs.

Written for commit a710ed6. 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: a710ed6

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

@shriyatheunicorn
shriyatheunicorn marked this pull request as ready for review August 5, 2026 22:34

@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/harnesses/codexAdapter.ts Outdated
Comment thread packages/evals/framework/codexCodeBridge.ts
Comment thread packages/evals/framework/codexCodeBridge.ts
Comment thread packages/evals/framework/codexRunner.ts Outdated

@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 1 file (changes from recent commits).

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

Re-trigger cubic

Comment thread packages/evals/framework/harnesses/codexAdapter.ts Outdated

@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 6 files

Architecture diagram
sequenceDiagram
    participant CodexAgent as Codex Agent
    participant CodexHarness as Eval Harness
    participant ToolAdapter as Codex Tool Adapter
    participant CodeBridge as Codex Code Bridge
    participant Surface as Tool Surface
    participant Trajectory as Trajectory Adapter

    Note over CodexAgent,Trajectory: NEW: Codex Code Surface Flow (stagehand_code/playwright_code/cdp_code)

    CodexHarness->>ToolAdapter: prepareCodexToolAdapter(surface, plan)
    ToolAdapter->>ToolAdapter: Determine code surface variant
    
    alt browse_cli
        ToolAdapter->>ToolAdapter: Use existing browse CLI adapter
    else code surface (stagehand_code, playwright_code, cdp_code)
        ToolAdapter->>Surface: prepareLLMExposure(plan, environment)
        Surface-->>ToolAdapter: exposure with code_handles
        
        ToolAdapter->>CodeBridge: startCodeBridge(exposure, plan)
        CodeBridge->>CodeBridge: Create HTTP server on random port
        CodeBridge-->>ToolAdapter: bridge instance with port
        
        ToolAdapter->>ToolAdapter: Create temp directory
        ToolAdapter->>ToolAdapter: Write browser_run.mjs client script
        ToolAdapter-->>CodexHarness: adapter with cwd, env, promptInstructions, cleanup
    end

    Note over CodexAgent,CodexHarness: Agent Tool Invocation

    CodexHarness->>ToolAdapter: Get prompt instructions
    ToolAdapter-->>CodexHarness: Rewritten instructions (run-tool → browser_run.mjs)
    
    CodexAgent->>CodexAgent: Write snippet.js file
    CodexAgent->>CodexAgent: Execute: node browser_run.mjs snippet.js
    
    CodexAgent->>CodeBridge: POST /run with snippet code
    CodeBridge->>CodeBridge: Execute snippet with handles, startUrl, task, console
    
    alt Execution succeeds
        CodeBridge-->>CodexAgent: HTTP 200 { ok: true, result: "..." }
    else Execution fails
        CodeBridge-->>CodexAgent: HTTP 200 { ok: false, error: "..." }
    else Timeout (EVAL_CODEX_RUN_TOOL_TIMEOUT_MS)
        CodeBridge-->>CodexAgent: HTTP 200 { ok: false, error: "timed out" }
    end

    Note over CodexHarness,Trajectory: Final Artifact Capture

    CodexHarness->>ToolAdapter: captureFinalState()
    ToolAdapter->>Surface: captureFinalState()
    Surface-->>ToolAdapter: TerminalArtifact { screenshot, url }
    ToolAdapter-->>CodexHarness: terminal state

    CodexHarness->>Trajectory: gradeExternalTrajectory(with terminalArtifact)
    Trajectory->>Trajectory: Build finalObservation from terminal state
    Trajectory-->>CodexHarness: Graded trajectory

    Note over CodexHarness,ToolAdapter: Cleanup

    CodexHarness->>ToolAdapter: cleanup()
    ToolAdapter->>CodeBridge: close bridge server
    ToolAdapter->>Surface: cleanup exposure
    ToolAdapter->>ToolAdapter: Remove temp directory
Loading

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

Re-trigger cubic

Comment thread packages/evals/framework/codexCodeBridge.ts
@miguelg719
miguelg719 merged commit 6086d58 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. -->
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