Skip to content

feat(browser): run browserTool on a BrowserSession, without codemode - #2667

Merged
ben-reitz merged 16 commits into
browser-tool/deprecatefrom
browser-tool/session
Oct 26, 2026
Merged

ben-reitz merged 16 commits into
browser-tool/deprecatefrom
browser-tool/session

Conversation

@ben-reitz

@ben-reitz ben-reitz commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

browserTool runs the model's code in its own Dynamic Worker on a new BrowserSession, instead of on @cloudflare/codemode.

 browserTool(code)
-  codemode executor
-    BrowserSessionConnector (cdp.*)
+  runBrowserCode            # sandbox.ts: Dynamic Worker, globalOutbound: null, host-side deadline
+    cdp.* → BrowserSession  # session.ts: one run's connection to the browser
+  session.close() → report  # restarted, newTabs, tabClosed, tabShared
  • browser.session({ scope }) is public, so your own code gets the same sessionId: "active" handling, validation and error hints.
  • browserTool no longer needs ctx or a CodemodeRuntime export, and its output drops the calls log. @cloudflare/codemode must stay installed while agents/browser still exports the deprecated codemode APIs.
  • Model code can't close or crash the browser, mint a Live View link (Cloudflare.getLiveView, Cloudflare.handoff), or tunnel commands past that check (Target.sendMessageToTarget, Target.exposeDevToolsProtocol).
  • The host enforces the run timeout too, so code that cancels the sandbox's timer can't hold the scope's queue.
  • A returned browser_screenshot is kept whole only if it's a png, jpeg or webp of base64 data under 1 MB; anything else is cut down like any result. Console logs are capped at 100 lines.
  • session-connector.ts is gone; truncate.ts keeps results under the token budget.

Ported from #2612 by @mattzcarey (co-authored). Computer ws:browser mentions are removed here; that comes later in its own PR. This stack supersedes #2612.

@ben-reitz
ben-reitz added this pull request to stack #2675 October 22, 2026 15:10
@ben-reitz
ben-reitz force-pushed the browser-tool/session branch from b0877b3 to f3ab829 Compare October 22, 2026 15:40
@changeset-bot

changeset-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cf57109

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 Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

🔴 agents import sizes: 1 entry point over threshold

Entry point Exports Largest gzip change Size now
🔴 agents/browser 1 resized, 2 new +6.4 KiB (+15.53%) 47.8 KiB
🟡 agents/browser/ai 2 resized up to +1.2 KiB (+0.79%) 149 KiB
🟢 agents/browser/pi 1 resized -43 KiB (-55.53%) 34.4 KiB
🟢 agents/browser/ai-sdk 1 resized -8.7 KiB (-6.13%) 133.9 KiB
🟢 agents/browser/tanstack-ai 1 resized -8.7 KiB (-5.52%) 149.5 KiB
Changed exports (8)
Import Gzip change Size now
🔴 agents/browser#Browser +6.4 KiB (+15.53%) 47.8 KiB
🟡 agents/browser/ai#createBrowserTools +1.2 KiB (+0.79%) 149 KiB
🟡 agents/browser/ai#createBrowserRuntime +1.2 KiB (+0.79%) 149 KiB
🆕 agents/browser#BrowserSession — 42.8 KiB
🆕 agents/browser#ACTIVE_PAGE_SESSION — 35.9 KiB
🟢 agents/browser/pi#browserTool -43 KiB (-55.53%) 34.4 KiB
🟢 agents/browser/ai-sdk#browserTool -8.7 KiB (-6.13%) 133.9 KiB
🟢 agents/browser/tanstack-ai#browserTool -8.7 KiB (-5.52%) 149.5 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 5e7f5515 → cf57109f · workflow run · reported by agent-think[bot]

@pkg-pr-new

pkg-pr-new Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

agents

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

@cloudflare/ai-chat

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

@cloudflare/codemode

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

hono-agents

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

@cloudflare/shell

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

@cloudflare/think

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

@cloudflare/voice

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

@cloudflare/worker-bundler

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

commit: cf57109

@ben-reitz
ben-reitz marked this pull request as ready for review October 22, 2026 21:52
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@ben-reitz
ben-reitz force-pushed the browser-tool/session branch 2 times, most recently from da1c8c2 to db07ae5 Compare October 23, 2026 10:52
devin-ai-integration[bot]

This comment was marked as resolved.

@ben-reitz
ben-reitz force-pushed the browser-tool/session branch 2 times, most recently from 2ef8ad3 to 61e313c Compare October 23, 2026 13:00
@ben-reitz
ben-reitz force-pushed the browser-tool/session branch 2 times, most recently from d6bce55 to 9226d98 Compare October 26, 2026 10:32
ben-reitz and others added 12 commits October 26, 2026 10:51
browserTool's code now runs in a fresh Dynamic Worker from `loader`
(browser/sandbox.ts) with no network access and a frozen `cdp` object as
its only way out, instead of on a codemode facet. It no longer needs
`ctx` (now ignored) or a `CodemodeRuntime` export, and its output drops
the `calls` log.

The per-run CDP logic moves from session-connector.ts into
BrowserSession (browser/session.ts), returned by `browser.session()`:
the "active" tab, attach handles, error hints, refusing Browser.close,
and the end-of-run report. truncate.ts is a copy of codemode's
truncateResult. BrowserConnector is marked deprecated.

Ported from #2612, keeping the browserTool name.

Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
- Statements with no return get a notice instead of a silent undefined.
- Rule and docs say only screenshots over 1 MB fail, and why the limit stays.
- Pi docs drop the CodemodeRuntime export.
- Design record: browserTool first, codemode connector under Deprecated.

Co-authored-by: Matt Carey <77928207+mattzcarey@users.noreply.github.com>
…every empty body run

A `return` inside a string no longer hides the statements notice.

Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
…precated part

Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
…lled

Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Model code could mint a Live View link with Cloudflare.getLiveView, or
wrap a refused command in Target.sendMessageToTarget.

Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Model code could cancel the sandbox's timer and hold the scope's queue.

Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
A returned browser_screenshot must be a png, jpeg or webp of base64 data
within the 1 MB limit; anything else is cut down like any other result.

Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
ben-reitz and others added 4 commits October 26, 2026 10:51
Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
…lled

Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
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