Skip to content

feat(integrations): extract Claude Agent SDK harness adapter from evals - #2748

Open
miguelg719 wants to merge 3 commits into
harness/contractfrom
harness/claude-agent-sdk
Open

feat(integrations): extract Claude Agent SDK harness adapter from evals#2748
miguelg719 wants to merge 3 commits into
harness/contractfrom
harness/claude-agent-sdk

Conversation

@miguelg719

@miguelg719 miguelg719 commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #2746 (← #2743). Part 2 of the harness consolidation stack. Reshaped after review feedback: thin session layer only.

What

New thin package @browserbasehq/stagehand-integrations-claude-agent-sdk: loadClaudeAgentSdk + runClaudeAgentSession — the query() streaming loop (abort control, message logging, token usage, status/stop-reason, max-turns classification) with explicit options and no EVAL_* env reads. This is the code the evals claude_code runner and the claude-code facade example were both maintaining; both now call the package.

Deliberately NOT extracted (returned to evals verbatim after the first cut over-reached): the tool-surface mount machinery — AgentMount handling, the in-process run MCP tool over live handles, permission-gate derivation. That code abstracts over evals' surface registry and has no integrations consumer.

Net diff +661/−515 — the positive remainder is package scaffolding (package.json/tsconfig/tsdown/vitest/turbo/CI globs); the logic itself is a move.

Verification

  • Full gates (build/typecheck/test:unit/lint/fmt) ✅; session tests moved with the code
  • Connected smoke (b:webvoyager --harness claude_code --tool stagehand_code -e browserbase) re-run on the reshaped code — results in PR comment
  • The example keeps its original security posture (stagehand-tools-only canUseTool, deny everything else)

@changeset-bot

changeset-bot Bot commented Aug 16, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 5148b8a

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 21 files

Architecture diagram
sequenceDiagram
    participant Evals as Evals Harness
    participant Adapter as Claude Agent SDK Adapter
    participant SDK as Anthropic Claude Agent SDK
    participant Runtime as Agent Tool Runtime
    participant MCP as In-process MCP Server
    participant Logger as Harness Logger
    participant Verifier as Verifier Service

    Note over Evals,Verifier: Claude Agent SDK Integration Flow

    Evals->>Adapter: runClaudeAgentSession(prompt, config)
    Adapter->>SDK: query() with options
    SDK-->>Adapter: Stream messages
    Adapter->>Adapter: Log message & track tool usage

    loop Message stream
        Adapter->>Adapter: Check message type
        alt Assistant message with tool_use
            Adapter->>Adapter: Map tool_use_id to name
        else User message with tool_result
            Adapter->>Evals: onToolResult(toolName)
        else Result message
            Adapter->>Adapter: Extract resultText & token usage
        end
        
        SDK->>MCP: Call run tool (mcp__stagehand__run)
        MCP->>Runtime: Execute snippet with handles
        Runtime->>Runtime: Wrap handles + startUrl + task
        Runtime-->>MCP: Tool result
        MCP-->>SDK: Serialized result
    end

    Adapter->>Adapter: Classify status (completed/max_turns/sdk_error)
    Adapter-->>Evals: Return session result

    alt Verifier configured
        Evals->>Evals: Build trajectory from messages
        Evals->>Verifier: Grade trajectory
        Verifier-->>Evals: Evaluation result
    end

    Evals->>Evals: Build TaskResult with metrics & observations

    Note over Evals,Adapter: Mount Session Prep (parallel path)
    Evals->>Adapter: prepareClaudeMountSession(mount, context)
    Adapter->>Adapter: Create temp cwd
    alt Handle-based mount
        Adapter->>MCP: buildRunMcpServer(handles, runTool)
        MCP->>MCP: Create run tool with executeSnippet
        MCP-->>Adapter: MCP server spec
        Adapter->>Adapter: Allowlist [run_tool_name]
    else MCP-based mount
        Adapter->>Adapter: Pass through mcpServers
        Adapter->>Adapter: Derive mcp__<server> allowlist
    end

    Adapter->>Adapter: Configure canUseTool gate
    alt allowBash option set
        Adapter->>Adapter: Add Bash to allowedTools
    else Deny by default
        Adapter->>Adapter: Bash denied with denyMessage
    end

    Adapter-->>Evals: Prepared session (cwd, env, tools, cleanup)
    Evals->>Adapter: cleanup() on completion
    Adapter->>Adapter: Remove temp cwd (idempotent, timeout-bound)
Loading

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

Re-trigger cubic

Comment thread packages/integrations/claude-agent-sdk/src/run-tool.ts Outdated
Comment thread packages/integrations/claude-agent-sdk/src/session.ts Outdated
Comment thread packages/integrations/claude-code/src/agent.ts Outdated
Comment thread packages/integrations/claude-agent-sdk/src/mount.ts Outdated
Comment thread packages/integrations/claude-agent-sdk/src/index.ts Outdated
Comment thread packages/integrations/claude-agent-sdk/src/run-tool.ts Outdated
Comment thread packages/evals/framework/claudeCodeToolAdapter.ts Outdated
Comment thread packages/integrations/claude-agent-sdk/src/run-tool.ts Outdated
Comment thread packages/integrations/claude-agent-sdk/src/session.ts Outdated
Comment thread packages/integrations/claude-agent-sdk/vitest.config.ts Outdated
New thin package @browserbasehq/stagehand-integrations-claude-agent-sdk:
loadClaudeAgentSdk + runClaudeAgentSession — the query() streaming loop
(abort control, message logging, token usage, status/stop-reason) with
explicit options and no EVAL_* env reads. This is the code the evals
claude_code runner and the claude-code facade example were both
maintaining; both now call the package.

Deliberately NOT extracted: the tool-surface mount machinery
(AgentMount handling, the in-process run MCP tool, permission gate
derivation) stays in evals — it abstracts over evals' surface registry
and has no integrations consumer.
@miguelg719
miguelg719 force-pushed the harness/claude-agent-sdk branch from c0dffa8 to da0bd1b Compare August 16, 2026 23:51
@miguelg719

Copy link
Copy Markdown
Collaborator Author

Connected smoke on the reshaped code (restored evals mount machinery + thin session package): b:webvoyager --harness claude_code --tool stagehand_code -e browserbase3/3 trials passed (100%), all complete in 8–10 steps.

…redaction, drop unused vitest config

- remove the abort forwarder on session completion so long-lived caller
  signals don't accumulate listeners (cubic P2)
- pass iteration errors through sanitizeErrorMessage before they reach
  stop reasons and logs (cubic P1)
- delete the package vitest.config.ts: tests run through the repo-root
  config via --root (cubic P3)

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

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

Re-trigger cubic

Comment thread packages/integrations/claude-agent-sdk/src/session.ts
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.

1 participant