Skip to content

feat(agents): add browserTool and export Browser for a persistent browser - #2372

Merged
ben-reitz merged 4 commits into
feat/browser-session-connectorfrom
feat/browser-execute-tool
Oct 1, 2026
Merged

ben-reitz merged 4 commits into
feat/browser-session-connectorfrom
feat/browser-execute-tool

Conversation

@ben-reitz

@ben-reitz ben-reitz commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

TL;DR: This ships the public API:

  • browserTool for the AI SDK (including Think or your Agent class)
  • Browser is exported, so agents get a browser whose tabs and logins carry over between runs.

Next:

  1. Framework adapters: TanStack AI, Flue, (+ Pi, starting from examples/next/harnesses/pi).
  2. Recipes: raw-CDP how-tos the model can pull up with help(topic) inside the sandbox, plus a skill file.
    • The recipes can also send the model to cdp.spec() for exact parameters.
    • Quick Actions tool descriptions to be updated to say clearly they don't share the browser or its logins.
  3. Release cleanup: mark createBrowserTools as @deprecated, which hasn't been done yet.
  4. Docs: port the docs to cloudflare-docs and update the examples.

This PR

This adds browserTool in agents/browser/ai, plus the Browser and browserRun exports from agents/browser. Both are experimental and ship with a minor changeset.

import { Browser, browserRun } from "agents/browser";
import { browserTool } from "agents/browser/ai";

export class MyAgent extends Agent<Env> {
  browser = new Browser({ provider: browserRun(this.env.BROWSER) });

  constructor(ctx: AgentContext, env: Env) {
    super(ctx, env);
    this.lifecycle.use(this.browser);
  }

  getTools() {
    return {
      browser: browserTool({ browser: this.browser, loader: this.env.LOADER })
    };
  }
}

The host owns the Browser, so a tool rebuilt every turn reaches the same browser. Tabs, cookies, and logins carry over until Browser Run shuts down an idle browser.

browserTool returns one AI SDK tool, not a { browser_execute } object, so the host picks its name (same as agentTool()).

What the model gets back

 { executionId, result, logs, calls }          // calls are persisted, not shown to the model
+  restarted: true, notice: "…navigate again…"  // the browser was replaced before this run
+  newTabs: [{ targetId, url, title }]          // tabs the page opened

Screenshot summaries include the notice and newTabs as well.

Types

The tool is typed: BrowserTool has execute(input: { code }): Promise<BrowserToolOutput> and toModelOutput, and fits in a ToolSet or Tool<{ code: string }, BrowserToolOutput>. BrowserToolOptions, BrowserToolInput, BrowserToolOutput, and BrowserNewTab are exported. The test helper no longer needs casts, and browser-tool.test-d.ts checks the types.

Compared with existing createBrowserTools

createBrowserTools browserTool
Browser lifetime model (session modes) host (Browser)
Backends Browser Run, cdpUrl, Kitesurf Browser Run Chromium only
Quick actions included use createQuickActionTools

createBrowserTools is unchanged. It gets deprecated in a later PR.

Details

  • Separate history per browser. Each Browser gets its own codemode runtime (browser-tool_<name>), so its history never mixes with createBrowserTools or other browsers.
  • ctx is optional. It's resolved from the current Agent when not passed.
  • Worker setup is the same as createBrowserTools. The worker exports CodemodeRuntime, which is re-exported from agents/browser. The test worker gains a facet-only CodemodeRuntime binding.
  • Docs. A short "Persistent browser" section in docs/agents/browse-the-web.md, which the one-line changeset links to. design/browser-sessions.md and design/browser-tools.md are rewritten in plainer language.

Tests

End-to-end on a real Agent and codemode facet (browser-capability.test.ts):

  • model code runs in the persistent browser and the active tab is stored;
  • a tool rebuilt on a later turn reuses the same browser;
  • after the browser is killed, the code runs in a replacement and the model is told.

Not in this PR: Think, TanStack AI, and Flue wrappers; CDP recipes.

Architecture diff

Outlined boxes are components this PR changes, with one green box per change. Green-filled boxes are new. Grey boxes are unchanged.

flowchart TB
  classDef ctx fill:none,stroke:#8c959f,color:#8c959f
  classDef changes fill:#dafbe1,stroke:#1a7f37,color:#1f2328

  Agent["Agent (host Durable Object)"]:::ctx

  subgraph Tool["browserTool · ai.ts (new)"]
    direction TB
    T1["+ one typed AI SDK tool; the host names it"]:::changes
    T2["+ one codemode runtime per browser"]:::changes
    T3["+ adds restarted, notice, newTabs to results"]:::changes
    T1 ~~~ T2 ~~~ T3
  end

  Runtime["codemode runtime + sandbox"]:::ctx
  Conn["BrowserSessionConnector · session-connector.ts"]:::ctx

  subgraph B["Browser · browser.ts"]
    B1["+ exported from agents/browser with browserRun and its types"]:::changes
  end

  BR["Browser Run"]:::ctx

  Agent -->|"getTools()"| Tool
  Agent -->|lifecycle.use| B
  Tool --> Runtime
  Runtime --> Conn
  Conn -->|"connect()"| B
  B --> BR

  style Tool fill:#dafbe1,stroke:#1a7f37,stroke-width:2px,color:#1f2328
  style B stroke:#1a7f37,stroke-width:2px
Loading

@ben-reitz
ben-reitz added this pull request to stack #2373 September 25, 2026 08:21
@changeset-bot

changeset-bot Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f2663c8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
agents Minor
@cloudflare/agent-think Patch

Not sure what this means? Click here to learn what changesets are.

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

@agent-think

agent-think Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

🟡 agents import sizes: 2 entry points grew

Entry point Exports Largest gzip change Size now
🟡 agents/browser/tanstack-ai 1 resized +1 KiB (+0.63%) 164.3 KiB
🟡 agents/browser/ai 1 resized, 1 new +1 KiB (+0.82%) 123.5 KiB
🆕 agents/browser 2 new — 40.5 KiB
Changed exports (5)
Import Gzip change Size now
🟡 agents/browser/tanstack-ai#createBrowserTools +1 KiB (+0.63%) 164.3 KiB
🟡 agents/browser/ai#createQuickActionTools +1 KiB (+0.82%) 123.5 KiB
🆕 agents/browser/ai#browserTool — 141 KiB
🆕 agents/browser#Browser — 40.5 KiB
🆕 agents/browser#browserRun — 36 KiB
How this works

Each runtime export is bundled on its own, minified, and gzipped. Changes smaller than 100 B, or smaller than 1% and 1 KiB, are ignored. Growth over 10% or 5 KiB is marked 🔴. This report is informational and does not fail CI. The workflow artifact contains every measurement.

Compared 084e77f9 → f2663c8c · workflow run · reported by agent-think[bot]

@pkg-pr-new

pkg-pr-new Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@2372

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@2372

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@2372

hono-agents

npm i https://pkg.pr.new/hono-agents@2372

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@2372

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@2372

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@2372

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@2372

commit: f2663c8

@ben-reitz
ben-reitz force-pushed the feat/browser-execute-tool branch from 29b86ec to 41a4c01 Compare September 25, 2026 09:13
@ben-reitz
ben-reitz force-pushed the feat/browser-execute-tool branch 4 times, most recently from 29740e1 to f17efd9 Compare September 25, 2026 13:48
@ben-reitz
ben-reitz force-pushed the feat/browser-execute-tool branch 4 times, most recently from dbbdcd8 to c63d7c3 Compare September 28, 2026 09:40
@ben-reitz
ben-reitz marked this pull request as ready for review September 28, 2026 09:40
devin-ai-integration[bot]

This comment was marked as resolved.

@ben-reitz
ben-reitz force-pushed the feat/browser-execute-tool branch 2 times, most recently from 9edf929 to 24f8940 Compare September 28, 2026 12:29

@aron-cf aron-cf 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.

This looks great, some minor feedback about docs and naming.

Comment thread .changeset/browser-execute-tool.md Outdated
Comment thread .changeset/browser-execute-tool.md Outdated
Comment thread design/browser-sessions.md Outdated
Comment thread design/browser-sessions.md Outdated
Comment thread design/browser-sessions.md Outdated
Comment thread design/browser-sessions.md Outdated
Comment thread design/browser-tools.md Outdated
Comment thread design/browser-tools.md
Comment thread packages/agents/src/browser/ai.ts Outdated
Comment thread packages/agents/src/tests/agents/browser.ts Outdated
@ben-reitz
ben-reitz removed this pull request from stack #2373 September 29, 2026 13:34
@ben-reitz
ben-reitz added this pull request to stack #2412 September 29, 2026 13:36
@ben-reitz
ben-reitz force-pushed the feat/browser-execute-tool branch from 24f8940 to 8bcafa6 Compare September 29, 2026 13:36
devin-ai-integration[bot]

This comment was marked as resolved.

@ben-reitz ben-reitz changed the title feat(agents): add createBrowserExecuteTool and export BrowserSessions feat(agents): add browserTool and export Browser for a persistent browser Sep 29, 2026
@ben-reitz
ben-reitz force-pushed the feat/browser-execute-tool branch from 8bcafa6 to 81df3ad Compare September 30, 2026 09:25

@devin-ai-integration devin-ai-integration 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.

Devin Review found 1 new potential issue.

Devin Review

Comment thread docs/agents/browse-the-web.md
@ben-reitz
ben-reitz force-pushed the feat/browser-execute-tool branch from f00f590 to cd8d15d Compare October 1, 2026 10:08
@ben-reitz
ben-reitz merged commit 6e1c346 into main Oct 1, 2026
16 of 30 checks passed
@ben-reitz
ben-reitz deleted the feat/browser-execute-tool branch October 1, 2026 10:53
@github-actions github-actions Bot mentioned this pull request Oct 2, 2026
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