agents 0.16.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/{agent-tool-types-NofdbL9X.d.ts → agent-tool-types-CTw3UJUP.d.ts} +9 -1
  2. package/dist/agent-tool-types.d.ts +1 -1
  3. package/dist/{agent-tools-DLquv-dp.d.ts → agent-tools-DZhI5F6Q.d.ts} +2 -2
  4. package/dist/agent-tools.d.ts +1 -1
  5. package/dist/browser/ai.d.ts +91 -6
  6. package/dist/browser/ai.js +174 -7
  7. package/dist/browser/ai.js.map +1 -1
  8. package/dist/browser/index.d.ts +74 -22
  9. package/dist/browser/index.js +2 -2
  10. package/dist/browser/tanstack-ai.d.ts +4 -0
  11. package/dist/browser/tanstack-ai.js +8 -1
  12. package/dist/browser/tanstack-ai.js.map +1 -1
  13. package/dist/chat/index.d.ts +7 -6
  14. package/dist/chat/index.js +35 -14
  15. package/dist/chat/index.js.map +1 -1
  16. package/dist/chat-sdk/index.d.ts +1 -1
  17. package/dist/{client-FUizKzj2.js → client-BXJ9n2f7.js} +18 -2
  18. package/dist/client-BXJ9n2f7.js.map +1 -0
  19. package/dist/client.d.ts +1 -1
  20. package/dist/{compaction-helpers-DVcu5lPN.d.ts → compaction-helpers-wUz6M3us.d.ts} +20 -1
  21. package/dist/{connector-D6yYzYHg.js → connector-CrKhowfD.js} +216 -5
  22. package/dist/connector-CrKhowfD.js.map +1 -0
  23. package/dist/connector-v2M1zlZp.d.ts +659 -0
  24. package/dist/experimental/memory/session/index.d.ts +1 -1
  25. package/dist/experimental/memory/session/index.js +20 -2
  26. package/dist/experimental/memory/session/index.js.map +1 -1
  27. package/dist/experimental/memory/utils/index.d.ts +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +4 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/mcp/client.d.ts +1 -1
  32. package/dist/mcp/client.js +1 -1
  33. package/dist/mcp/index.d.ts +1 -1
  34. package/dist/mcp/index.js +1 -1
  35. package/dist/react.d.ts +1 -1
  36. package/dist/serializable.d.ts +1 -1
  37. package/dist/sub-routing.d.ts +1 -1
  38. package/dist/workflows.d.ts +1 -1
  39. package/package.json +9 -4
  40. package/dist/client-FUizKzj2.js.map +0 -1
  41. package/dist/connector-D6yYzYHg.js.map +0 -1
  42. package/dist/connector-DXursxV5.d.ts +0 -340
@@ -821,6 +821,14 @@ declare class MCPClientConnection {
821
821
  instructions?: string;
822
822
  tools: Tool$1[];
823
823
  private _transport?;
824
+ /**
825
+ * Transport that received the 401 during the initial connect attempt.
826
+ * Kept so finishAuth() runs on the transport that captured the resource
827
+ * metadata URL from the WWW-Authenticate header — a fresh transport would
828
+ * rediscover from defaults and exchange the code at the wrong token
829
+ * endpoint when the authorization server is not at the default location.
830
+ */
831
+ private _pendingAuthTransport?;
824
832
  prompts: Prompt[];
825
833
  resources: Resource[];
826
834
  resourceTemplates: ResourceTemplate[];
@@ -4847,4 +4855,4 @@ export {
4847
4855
  MCPServer as z,
4848
4856
  WorkerTransport as zt
4849
4857
  };
4850
- //# sourceMappingURL=agent-tool-types-NofdbL9X.d.ts.map
4858
+ //# sourceMappingURL=agent-tool-types-CTw3UJUP.d.ts.map
@@ -16,7 +16,7 @@ import {
16
16
  s as AgentToolInterruptedReason,
17
17
  t as AgentToolChildAdapter,
18
18
  u as AgentToolRunInspection
19
- } from "./agent-tool-types-NofdbL9X.js";
19
+ } from "./agent-tool-types-CTw3UJUP.js";
20
20
  export {
21
21
  AgentToolChildAdapter,
22
22
  AgentToolDisplayMetadata,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  a as AgentToolEventState,
3
3
  i as AgentToolEventMessage
4
- } from "./agent-tool-types-NofdbL9X.js";
4
+ } from "./agent-tool-types-CTw3UJUP.js";
5
5
 
6
6
  //#region src/chat/agent-tools.d.ts
7
7
  declare function createAgentToolEventState(): AgentToolEventState;
@@ -11,4 +11,4 @@ declare function applyAgentToolEvent(
11
11
  ): AgentToolEventState;
12
12
  //#endregion
13
13
  export { createAgentToolEventState as n, applyAgentToolEvent as t };
14
- //# sourceMappingURL=agent-tools-DLquv-dp.d.ts.map
14
+ //# sourceMappingURL=agent-tools-DZhI5F6Q.d.ts.map
@@ -16,7 +16,7 @@ import {
16
16
  s as AgentToolInterruptedReason,
17
17
  t as AgentToolChildAdapter,
18
18
  u as AgentToolRunInspection
19
- } from "./agent-tool-types-NofdbL9X.js";
19
+ } from "./agent-tool-types-CTw3UJUP.js";
20
20
  import { Tool } from "ai";
21
21
 
22
22
  //#region src/agent-tools.d.ts
@@ -1,9 +1,11 @@
1
1
  import {
2
- c as BrowserSessionStore,
3
- f as BrowserBinding,
2
+ I as BrowserBinding,
3
+ f as BrowserSessionStore,
4
4
  r as BrowserConnectorSessionOptions,
5
- t as BrowserConnector
6
- } from "../connector-DXursxV5.js";
5
+ t as BrowserConnector,
6
+ v as QuickActionBinding,
7
+ y as QuickActionCommonOptions
8
+ } from "../connector-v2M1zlZp.js";
7
9
  import { ToolSet } from "ai";
8
10
  import { CodemodeRuntimeHandle } from "@cloudflare/codemode";
9
11
 
@@ -15,11 +17,15 @@ interface CreateBrowserToolsOptions {
15
17
  * storage — so the tool must be created from inside a Durable Object
16
18
  * (e.g. an Agent).
17
19
  *
20
+ * Optional: when omitted, it is resolved from the current Agent via
21
+ * `getCurrentAgent()`, so inside an Agent method you can just pass `browser`
22
+ * and `loader`. Pass it explicitly outside an Agent context.
23
+ *
18
24
  * The worker must export the `CodemodeRuntime` class (the
19
25
  * `@cloudflare/codemode/vite` plugin does this automatically, or add
20
26
  * `export { CodemodeRuntime } from "@cloudflare/codemode"` to your entry).
21
27
  */
22
- ctx: DurableObjectState;
28
+ ctx?: DurableObjectState;
23
29
  /**
24
30
  * WorkerLoader binding for sandboxed code execution.
25
31
  *
@@ -68,6 +74,26 @@ interface CreateBrowserToolsOptions {
68
74
  * and snippets. Defaults to `"browser"`.
69
75
  */
70
76
  name?: string;
77
+ /**
78
+ * Also expose stateless {@link createQuickActionTools | Quick Action} tools
79
+ * (`browser_markdown`, `browser_extract`, …) alongside the durable
80
+ * `browser_execute` tool.
81
+ *
82
+ * Enabled by default whenever a Browser Run `browser` binding is available
83
+ * (they share it). Pass an object to configure them, or `false` to disable.
84
+ * The Quick Action binding defaults to `browser`; override it via
85
+ * `quickActions.browser`. When only `cdpUrl` is set (no binding), the
86
+ * defaults are skipped silently — pass `quickActions: { browser }` to force
87
+ * them.
88
+ */
89
+ quickActions?:
90
+ | boolean
91
+ | {
92
+ browser?: QuickActionBinding;
93
+ actions?: QuickActionToolName[];
94
+ maxChars?: number;
95
+ options?: QuickActionCommonOptions;
96
+ };
71
97
  }
72
98
  /**
73
99
  * The browser tool's moving parts, for hosts that need more than the tools:
@@ -140,11 +166,70 @@ declare function createBrowserRuntime(
140
166
  declare function createBrowserTools(
141
167
  options: CreateBrowserToolsOptions
142
168
  ): ToolSet;
169
+ /** A Quick Action exposed as an AI SDK tool. */
170
+ type QuickActionToolName =
171
+ | "markdown"
172
+ | "extract"
173
+ | "links"
174
+ | "scrape"
175
+ | "content";
176
+ interface CreateQuickActionToolsOptions {
177
+ /**
178
+ * Browser Run binding with Quick Actions support (`env.BROWSER`). Requires a
179
+ * Worker `compatibility_date` of `2026-03-24`+ and `remote: true` for local
180
+ * `wrangler dev`.
181
+ */
182
+ browser: QuickActionBinding;
183
+ /**
184
+ * Which tools to expose. Defaults to the text-returning, model-friendly set
185
+ * (`markdown`, `extract`, `links`, `scrape`). `content` (raw HTML) is opt-in
186
+ * since it is large and rarely what a model wants.
187
+ */
188
+ actions?: QuickActionToolName[];
189
+ /**
190
+ * Bound every result to roughly this many characters before returning it to
191
+ * the model, to protect the context window, preserving each result's shape:
192
+ * text (markdown/content) is truncated to a string, oversized arrays
193
+ * (links/scrape) are trimmed but stay arrays, and only an opaque oversized
194
+ * object degrades to a truncated-preview summary. Set to `0` to disable.
195
+ * Defaults to 50000.
196
+ */
197
+ maxChars?: number;
198
+ /**
199
+ * Common Browser Run options merged into every request — e.g. `cookies`,
200
+ * `authenticate`, or `setExtraHTTPHeaders` for authenticated pages, and
201
+ * `gotoOptions` / `viewport` for JavaScript-heavy pages. The model only ever
202
+ * supplies the page (`url`/`html`) and action-specific fields; these
203
+ * host-supplied options are never exposed to it.
204
+ */
205
+ options?: QuickActionCommonOptions;
206
+ }
207
+ /**
208
+ * Create AI SDK tools for Browser Run [Quick Actions](https://developers.cloudflare.com/browser-run/quick-actions/):
209
+ * stateless one-shot browsing (read a page as Markdown, extract structured
210
+ * data with AI, list links, scrape elements). Unlike `createBrowserTools`,
211
+ * these need only the `browser` binding — no Durable Object, loader, or
212
+ * sandbox — so they work from any Worker.
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * import { createQuickActionTools } from "agents/browser/ai";
217
+ *
218
+ * const tools = createQuickActionTools({ browser: this.env.BROWSER });
219
+ * const result = await generateText({ model, tools, messages });
220
+ * ```
221
+ */
222
+ declare function createQuickActionTools(
223
+ options: CreateQuickActionToolsOptions
224
+ ): ToolSet;
143
225
  //#endregion
144
226
  export {
145
227
  BrowserRuntime,
146
228
  CreateBrowserToolsOptions,
229
+ CreateQuickActionToolsOptions,
230
+ QuickActionToolName,
147
231
  createBrowserRuntime,
148
- createBrowserTools
232
+ createBrowserTools,
233
+ createQuickActionTools
149
234
  };
150
235
  //# sourceMappingURL=ai.d.ts.map
@@ -1,8 +1,22 @@
1
- import { i as DurableBrowserSessionStore, t as BrowserConnector } from "../connector-D6yYzYHg.js";
1
+ import { __DO_NOT_USE_WILL_BREAK__agentContext } from "../internal_context.js";
2
+ import { c as browserLinks, d as browserScrape, i as DurableBrowserSessionStore, l as browserMarkdown, o as browserContent, s as browserExtract, t as BrowserConnector } from "../connector-CrKhowfD.js";
3
+ import { tool } from "ai";
4
+ import { z } from "zod";
2
5
  import { DynamicWorkerExecutor, createCodemodeRuntime, truncateResult } from "@cloudflare/codemode";
3
6
  //#region src/browser/ai.ts
4
7
  let didWarnExperimental = false;
5
- function connectorOptions(options) {
8
+ let didDebugQuickActionSkip = false;
9
+ /**
10
+ * The Durable Object state to build the runtime in: the explicit `ctx` if
11
+ * given, otherwise the current Agent's `ctx` (via `getCurrentAgent()`), so
12
+ * `createBrowserRuntime` can be called from an Agent method without threading
13
+ * `this.ctx` through.
14
+ */
15
+ function resolveCtx(options) {
16
+ if (options.ctx) return options.ctx;
17
+ return (__DO_NOT_USE_WILL_BREAK__agentContext.getStore()?.agent)?.ctx;
18
+ }
19
+ function connectorOptions(options, ctx) {
6
20
  if (options.cdpUrl) return {
7
21
  cdpUrl: options.cdpUrl,
8
22
  cdpHeaders: options.cdpHeaders,
@@ -11,7 +25,7 @@ function connectorOptions(options) {
11
25
  if (!options.browser) throw new Error("Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided");
12
26
  return {
13
27
  browser: options.browser,
14
- store: options.store ?? new DurableBrowserSessionStore(options.ctx.storage),
28
+ store: options.store ?? new DurableBrowserSessionStore(ctx.storage),
15
29
  session: options.session,
16
30
  timeout: options.timeout
17
31
  };
@@ -45,9 +59,11 @@ function createBrowserRuntime(options) {
45
59
  didWarnExperimental = true;
46
60
  console.warn("[agents/browser] Browser tools are experimental and may change in a future release.");
47
61
  }
48
- const connector = new BrowserConnector(options.ctx, connectorOptions(options));
62
+ const ctx = resolveCtx(options);
63
+ if (!ctx) throw new Error("createBrowserRuntime requires a Durable Object 'ctx' — pass it explicitly, or call from within an Agent so it can be resolved via getCurrentAgent()");
64
+ const connector = new BrowserConnector(ctx, connectorOptions(options, ctx));
49
65
  const runtime = createCodemodeRuntime({
50
- ctx: options.ctx,
66
+ ctx,
51
67
  executor: new DynamicWorkerExecutor({
52
68
  loader: options.loader,
53
69
  timeout: options.timeout
@@ -56,10 +72,26 @@ function createBrowserRuntime(options) {
56
72
  name: options.name ?? "browser",
57
73
  transformResult: truncateResult
58
74
  });
75
+ const tools = { browser_execute: runtime.tool() };
76
+ if (options.quickActions !== false) {
77
+ const qa = options.quickActions == null || options.quickActions === true ? {} : options.quickActions;
78
+ const quickActionBrowser = qa.browser ?? options.browser;
79
+ if (quickActionBrowser) Object.assign(tools, createQuickActionTools({
80
+ browser: quickActionBrowser,
81
+ actions: qa.actions,
82
+ maxChars: qa.maxChars,
83
+ options: qa.options
84
+ }));
85
+ else if (options.quickActions) throw new Error("quickActions requires a Browser Run binding — set 'browser' (env.BROWSER) or 'quickActions.browser'");
86
+ else if (!didDebugQuickActionSkip) {
87
+ didDebugQuickActionSkip = true;
88
+ console.debug("[agents/browser] Quick Action tools skipped — no Browser Run binding (only 'cdpUrl' is set). Pass 'browser' or 'quickActions.browser' to enable them.");
89
+ }
90
+ }
59
91
  return {
60
92
  runtime,
61
93
  connector,
62
- tools: { browser_execute: runtime.tool() }
94
+ tools
63
95
  };
64
96
  }
65
97
  /**
@@ -92,7 +124,142 @@ function createBrowserRuntime(options) {
92
124
  function createBrowserTools(options) {
93
125
  return createBrowserRuntime(options).tools;
94
126
  }
127
+ const DEFAULT_QUICK_ACTION_TOOLS = [
128
+ "markdown",
129
+ "extract",
130
+ "links",
131
+ "scrape"
132
+ ];
133
+ const DEFAULT_QUICK_ACTION_MAX_CHARS = 5e4;
134
+ const pageInputSchema = z.object({
135
+ url: z.string().url().optional().describe("URL of the page to load"),
136
+ html: z.string().optional().describe("Raw HTML to render instead of loading a URL")
137
+ }).refine((value) => Boolean(value.url) || Boolean(value.html), { message: "Provide either 'url' or 'html'" });
138
+ function toPage(input, options) {
139
+ const page = input.url ? { url: input.url } : { html: input.html };
140
+ return {
141
+ ...options,
142
+ ...page
143
+ };
144
+ }
145
+ function truncate(text, maxChars) {
146
+ if (maxChars <= 0 || text.length <= maxChars) return text;
147
+ return `${text.slice(0, maxChars)}\n\n[truncated ${text.length - maxChars} characters]`;
148
+ }
149
+ /**
150
+ * Keep a tool result within a rough character budget so a single browse cannot
151
+ * blow the model's context window — while preserving the result's shape so the
152
+ * model sees a consistent type across calls:
153
+ *
154
+ * - strings (markdown/content) are truncated to a string;
155
+ * - arrays (links/scrape) are trimmed from the end but stay arrays;
156
+ * - only an opaque oversized object (e.g. a sprawling `extract`) degrades to a
157
+ * `{ truncated, note, preview }` summary, since it cannot be trimmed safely.
158
+ */
159
+ function boundResult(value, maxChars) {
160
+ if (maxChars <= 0) return value;
161
+ if (typeof value === "string") return truncate(value, maxChars);
162
+ let json;
163
+ try {
164
+ json = JSON.stringify(value);
165
+ } catch {
166
+ return value;
167
+ }
168
+ if (json.length <= maxChars) return value;
169
+ if (Array.isArray(value)) {
170
+ const trimmed = boundArray(value, maxChars);
171
+ if (trimmed.length > 0) return trimmed;
172
+ }
173
+ return {
174
+ truncated: true,
175
+ note: `Result is too large (${json.length} characters); narrow the request.`,
176
+ preview: `${json.slice(0, maxChars)}…`
177
+ };
178
+ }
179
+ /**
180
+ * Take as many leading items as fit within `maxChars` (measured against their
181
+ * JSON length), returning a trimmed array of the same element type. Silent by
182
+ * design: the model gets fewer, valid items rather than a reshaped result.
183
+ */
184
+ function boundArray(value, maxChars) {
185
+ const out = [];
186
+ let size = 2;
187
+ for (const item of value) {
188
+ const itemSize = JSON.stringify(item).length + 1;
189
+ if (size + itemSize > maxChars) break;
190
+ out.push(item);
191
+ size += itemSize;
192
+ }
193
+ return out;
194
+ }
195
+ /**
196
+ * Create AI SDK tools for Browser Run [Quick Actions](https://developers.cloudflare.com/browser-run/quick-actions/):
197
+ * stateless one-shot browsing (read a page as Markdown, extract structured
198
+ * data with AI, list links, scrape elements). Unlike `createBrowserTools`,
199
+ * these need only the `browser` binding — no Durable Object, loader, or
200
+ * sandbox — so they work from any Worker.
201
+ *
202
+ * @example
203
+ * ```ts
204
+ * import { createQuickActionTools } from "agents/browser/ai";
205
+ *
206
+ * const tools = createQuickActionTools({ browser: this.env.BROWSER });
207
+ * const result = await generateText({ model, tools, messages });
208
+ * ```
209
+ */
210
+ function createQuickActionTools(options) {
211
+ const { browser } = options;
212
+ const requestOptions = options.options;
213
+ const enabled = new Set(options.actions ?? DEFAULT_QUICK_ACTION_TOOLS);
214
+ const maxChars = options.maxChars ?? DEFAULT_QUICK_ACTION_MAX_CHARS;
215
+ const tools = {};
216
+ if (enabled.has("markdown")) tools.browser_markdown = tool({
217
+ description: "Load a web page (or render raw HTML) and return its content as Markdown. Best for reading articles, docs, or any page as text.",
218
+ inputSchema: pageInputSchema,
219
+ execute: async (input) => boundResult(await browserMarkdown(browser, toPage(input, requestOptions)), maxChars)
220
+ });
221
+ if (enabled.has("extract")) tools.browser_extract = tool({
222
+ description: "Extract structured data from a web page using AI. Describe what you want in 'prompt'. Passing a JSON Schema in 'schema' is strongly recommended — without one the extractor often fails to produce JSON.",
223
+ inputSchema: z.object({
224
+ url: z.string().url().optional().describe("URL of the page to load"),
225
+ html: z.string().optional().describe("Raw HTML to render instead of loading a URL"),
226
+ prompt: z.string().optional().describe("What to extract, in natural language"),
227
+ schema: z.unknown().optional().describe("Optional JSON Schema describing the desired output")
228
+ }).refine((value) => Boolean(value.url) || Boolean(value.html), { message: "Provide either 'url' or 'html'" }).refine((value) => Boolean(value.prompt) || Boolean(value.schema), { message: "Provide either 'prompt' or 'schema'" }),
229
+ execute: async (input) => boundResult(await browserExtract(browser, {
230
+ ...toPage(input, requestOptions),
231
+ prompt: input.prompt,
232
+ response_format: input.schema ? {
233
+ type: "json_schema",
234
+ schema: input.schema
235
+ } : void 0
236
+ }), maxChars)
237
+ });
238
+ if (enabled.has("links")) tools.browser_links = tool({
239
+ description: "Return every link found on a web page (including ones not visible). Useful for discovering pages to follow.",
240
+ inputSchema: pageInputSchema,
241
+ execute: async (input) => boundResult(await browserLinks(browser, toPage(input, requestOptions)), maxChars)
242
+ });
243
+ if (enabled.has("scrape")) tools.browser_scrape = tool({
244
+ description: "Scrape specific elements from a web page by CSS selector. Returns the matched elements' text, HTML, and attributes.",
245
+ inputSchema: z.object({
246
+ url: z.string().url().optional().describe("URL of the page to load"),
247
+ html: z.string().optional().describe("Raw HTML to render instead of loading a URL"),
248
+ selectors: z.array(z.string()).min(1).describe("CSS selectors to extract")
249
+ }).refine((value) => Boolean(value.url) || Boolean(value.html), { message: "Provide either 'url' or 'html'" }),
250
+ execute: async (input) => boundResult(await browserScrape(browser, {
251
+ ...toPage(input, requestOptions),
252
+ elements: input.selectors.map((selector) => ({ selector }))
253
+ }), maxChars)
254
+ });
255
+ if (enabled.has("content")) tools.browser_content = tool({
256
+ description: "Load a web page and return its fully rendered HTML (after JavaScript runs). Prefer 'browser_markdown' unless you need the raw HTML.",
257
+ inputSchema: pageInputSchema,
258
+ execute: async (input) => boundResult(await browserContent(browser, toPage(input, requestOptions)), maxChars)
259
+ });
260
+ return tools;
261
+ }
95
262
  //#endregion
96
- export { createBrowserRuntime, createBrowserTools };
263
+ export { createBrowserRuntime, createBrowserTools, createQuickActionTools };
97
264
 
98
265
  //# sourceMappingURL=ai.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","names":[],"sources":["../../src/browser/ai.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport {\n createCodemodeRuntime,\n DynamicWorkerExecutor,\n truncateResult,\n type CodemodeRuntimeHandle\n} from \"@cloudflare/codemode\";\nimport type { BrowserBinding } from \"./browser-run\";\nimport {\n BrowserConnector,\n type BrowserConnectorOptions,\n type BrowserConnectorSessionOptions\n} from \"./connector\";\nimport {\n DurableBrowserSessionStore,\n type BrowserSessionStore\n} from \"./session-manager\";\n\nexport interface CreateBrowserToolsOptions {\n /**\n * Durable Object state. The codemode runtime that backs the browser tool\n * lives in a facet of this DO, and browser session ids are stored in its\n * storage — so the tool must be created from inside a Durable Object\n * (e.g. an Agent).\n *\n * The worker must export the `CodemodeRuntime` class (the\n * `@cloudflare/codemode/vite` plugin does this automatically, or add\n * `export { CodemodeRuntime } from \"@cloudflare/codemode\"` to your entry).\n */\n ctx: DurableObjectState;\n\n /**\n * WorkerLoader binding for sandboxed code execution.\n *\n * Requires `\"worker_loaders\": [{ \"binding\": \"LOADER\" }]` in wrangler.jsonc.\n */\n loader: WorkerLoader;\n\n /**\n * Browser Rendering binding (Fetcher).\n *\n * This is the primary way to connect — works both locally in\n * `wrangler dev` and when deployed to Cloudflare Workers.\n *\n * Requires `\"browser\": { \"binding\": \"BROWSER\" }` in wrangler.jsonc.\n */\n browser?: BrowserBinding;\n\n /**\n * Optional CDP base URL override (e.g. `http://localhost:9222`).\n *\n * Use when connecting to a manually managed Chrome instance or\n * a remote CDP endpoint behind a tunnel.\n */\n cdpUrl?: string;\n\n /**\n * Headers to send with CDP URL discovery requests.\n * Useful when the CDP endpoint requires authentication\n * (e.g. Cloudflare Access headers).\n */\n cdpHeaders?: Record<string, string>;\n\n /**\n * Browser session lifecycle (binding-backed only). Defaults to one fresh\n * session per codemode execution (`one-shot`).\n */\n session?: BrowserConnectorSessionOptions;\n\n /**\n * Durable store for Browser Run session ids. Defaults to a\n * {@link DurableBrowserSessionStore} over `ctx.storage`.\n */\n store?: BrowserSessionStore;\n\n /**\n * Sandbox execution timeout in milliseconds. Defaults to 30000 (30s).\n * Also used as the per-CDP-command timeout.\n */\n timeout?: number;\n\n /**\n * Codemode runtime name — the durable identity of the tool's executions\n * and snippets. Defaults to `\"browser\"`.\n */\n name?: string;\n}\n\n/**\n * The browser tool's moving parts, for hosts that need more than the tools:\n *\n * - `runtime` — the codemode runtime handle (approve/reject paused runs,\n * `expirePaused`, audit via `executions()`, snippets).\n * - `connector` — host-side session helpers: `sessionInfo()`,\n * `closeSession()`, and `sweep()` for a recurring cleanup task.\n * - `tools` — what `createBrowserTools` returns.\n */\nexport interface BrowserRuntime {\n runtime: CodemodeRuntimeHandle;\n connector: BrowserConnector;\n tools: ToolSet;\n}\n\nlet didWarnExperimental = false;\n\nfunction connectorOptions(\n options: CreateBrowserToolsOptions\n): BrowserConnectorOptions {\n if (options.cdpUrl) {\n return {\n cdpUrl: options.cdpUrl,\n cdpHeaders: options.cdpHeaders,\n timeout: options.timeout\n };\n }\n if (!options.browser) {\n throw new Error(\n \"Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided\"\n );\n }\n return {\n browser: options.browser,\n store: options.store ?? new DurableBrowserSessionStore(options.ctx.storage),\n session: options.session,\n timeout: options.timeout\n };\n}\n\n/**\n * Create the browser codemode runtime: the `browser_execute` tool plus the\n * runtime handle and connector for host-side wiring (approvals, session info,\n * sweeps).\n *\n * @example\n * ```ts\n * export class MyAgent extends Agent<Env> {\n * get browser() {\n * return createBrowserRuntime({\n * ctx: this.ctx,\n * browser: this.env.BROWSER,\n * loader: this.env.LOADER,\n * session: { mode: \"dynamic\" }\n * });\n * }\n *\n * @callable()\n * async closeBrowserSession() {\n * await this.browser.connector.closeSession();\n * }\n * }\n * ```\n */\nexport function createBrowserRuntime(\n options: CreateBrowserToolsOptions\n): BrowserRuntime {\n if (!didWarnExperimental) {\n didWarnExperimental = true;\n console.warn(\n \"[agents/browser] Browser tools are experimental and may change in a future release.\"\n );\n }\n\n const connector = new BrowserConnector(\n options.ctx,\n connectorOptions(options)\n );\n const runtime = createCodemodeRuntime({\n ctx: options.ctx,\n executor: new DynamicWorkerExecutor({\n loader: options.loader,\n timeout: options.timeout\n }),\n connectors: [connector],\n name: options.name ?? \"browser\",\n transformResult: truncateResult\n });\n\n return {\n runtime,\n connector,\n tools: { browser_execute: runtime.tool() }\n };\n}\n\n/**\n * Create AI SDK tools for browser automation via CDP code mode.\n *\n * Returns a `ToolSet` with a single durable `browser_execute` tool backed by\n * a codemode runtime: the model writes TypeScript against the `cdp` connector\n * (`cdp.send`, `cdp.attachToTarget`, `cdp.spec`, …), executions are recorded\n * for abort-and-replay, and browser sessions survive pauses.\n *\n * @example\n * ```ts\n * import { createBrowserTools } from \"agents/browser/ai\";\n * import { generateText } from \"ai\";\n *\n * // inside a Durable Object / Agent:\n * const browserTools = createBrowserTools({\n * ctx: this.ctx,\n * browser: this.env.BROWSER,\n * loader: this.env.LOADER,\n * });\n *\n * const result = await generateText({\n * model,\n * tools: { ...browserTools, ...otherTools },\n * messages,\n * });\n * ```\n */\nexport function createBrowserTools(\n options: CreateBrowserToolsOptions\n): ToolSet {\n return createBrowserRuntime(options).tools;\n}\n"],"mappings":";;;AAuGA,IAAI,sBAAsB;AAE1B,SAAS,iBACP,SACyB;CACzB,IAAI,QAAQ,QACV,OAAO;EACL,QAAQ,QAAQ;EAChB,YAAY,QAAQ;EACpB,SAAS,QAAQ;CACnB;CAEF,IAAI,CAAC,QAAQ,SACX,MAAM,IAAI,MACR,iEACF;CAEF,OAAO;EACL,SAAS,QAAQ;EACjB,OAAO,QAAQ,SAAS,IAAI,2BAA2B,QAAQ,IAAI,OAAO;EAC1E,SAAS,QAAQ;EACjB,SAAS,QAAQ;CACnB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,qBACd,SACgB;CAChB,IAAI,CAAC,qBAAqB;EACxB,sBAAsB;EACtB,QAAQ,KACN,qFACF;CACF;CAEA,MAAM,YAAY,IAAI,iBACpB,QAAQ,KACR,iBAAiB,OAAO,CAC1B;CACA,MAAM,UAAU,sBAAsB;EACpC,KAAK,QAAQ;EACb,UAAU,IAAI,sBAAsB;GAClC,QAAQ,QAAQ;GAChB,SAAS,QAAQ;EACnB,CAAC;EACD,YAAY,CAAC,SAAS;EACtB,MAAM,QAAQ,QAAQ;EACtB,iBAAiB;CACnB,CAAC;CAED,OAAO;EACL;EACA;EACA,OAAO,EAAE,iBAAiB,QAAQ,KAAK,EAAE;CAC3C;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,mBACd,SACS;CACT,OAAO,qBAAqB,OAAO,CAAC,CAAC;AACvC"}
1
+ {"version":3,"file":"ai.js","names":["agentContext"],"sources":["../../src/browser/ai.ts"],"sourcesContent":["import { tool, type ToolSet } from \"ai\";\nimport { z } from \"zod\";\nimport {\n createCodemodeRuntime,\n DynamicWorkerExecutor,\n truncateResult,\n type CodemodeRuntimeHandle\n} from \"@cloudflare/codemode\";\nimport { __DO_NOT_USE_WILL_BREAK__agentContext as agentContext } from \"../internal_context\";\nimport type { BrowserBinding } from \"./browser-run\";\nimport {\n browserContent,\n browserExtract,\n browserLinks,\n browserMarkdown,\n browserScrape,\n type QuickActionBinding,\n type QuickActionCommonOptions,\n type QuickActionPage\n} from \"./quick-actions\";\nimport {\n BrowserConnector,\n type BrowserConnectorOptions,\n type BrowserConnectorSessionOptions\n} from \"./connector\";\nimport {\n DurableBrowserSessionStore,\n type BrowserSessionStore\n} from \"./session-manager\";\n\nexport interface CreateBrowserToolsOptions {\n /**\n * Durable Object state. The codemode runtime that backs the browser tool\n * lives in a facet of this DO, and browser session ids are stored in its\n * storage — so the tool must be created from inside a Durable Object\n * (e.g. an Agent).\n *\n * Optional: when omitted, it is resolved from the current Agent via\n * `getCurrentAgent()`, so inside an Agent method you can just pass `browser`\n * and `loader`. Pass it explicitly outside an Agent context.\n *\n * The worker must export the `CodemodeRuntime` class (the\n * `@cloudflare/codemode/vite` plugin does this automatically, or add\n * `export { CodemodeRuntime } from \"@cloudflare/codemode\"` to your entry).\n */\n ctx?: DurableObjectState;\n\n /**\n * WorkerLoader binding for sandboxed code execution.\n *\n * Requires `\"worker_loaders\": [{ \"binding\": \"LOADER\" }]` in wrangler.jsonc.\n */\n loader: WorkerLoader;\n\n /**\n * Browser Rendering binding (Fetcher).\n *\n * This is the primary way to connect — works both locally in\n * `wrangler dev` and when deployed to Cloudflare Workers.\n *\n * Requires `\"browser\": { \"binding\": \"BROWSER\" }` in wrangler.jsonc.\n */\n browser?: BrowserBinding;\n\n /**\n * Optional CDP base URL override (e.g. `http://localhost:9222`).\n *\n * Use when connecting to a manually managed Chrome instance or\n * a remote CDP endpoint behind a tunnel.\n */\n cdpUrl?: string;\n\n /**\n * Headers to send with CDP URL discovery requests.\n * Useful when the CDP endpoint requires authentication\n * (e.g. Cloudflare Access headers).\n */\n cdpHeaders?: Record<string, string>;\n\n /**\n * Browser session lifecycle (binding-backed only). Defaults to one fresh\n * session per codemode execution (`one-shot`).\n */\n session?: BrowserConnectorSessionOptions;\n\n /**\n * Durable store for Browser Run session ids. Defaults to a\n * {@link DurableBrowserSessionStore} over `ctx.storage`.\n */\n store?: BrowserSessionStore;\n\n /**\n * Sandbox execution timeout in milliseconds. Defaults to 30000 (30s).\n * Also used as the per-CDP-command timeout.\n */\n timeout?: number;\n\n /**\n * Codemode runtime name — the durable identity of the tool's executions\n * and snippets. Defaults to `\"browser\"`.\n */\n name?: string;\n\n /**\n * Also expose stateless {@link createQuickActionTools | Quick Action} tools\n * (`browser_markdown`, `browser_extract`, …) alongside the durable\n * `browser_execute` tool.\n *\n * Enabled by default whenever a Browser Run `browser` binding is available\n * (they share it). Pass an object to configure them, or `false` to disable.\n * The Quick Action binding defaults to `browser`; override it via\n * `quickActions.browser`. When only `cdpUrl` is set (no binding), the\n * defaults are skipped silently — pass `quickActions: { browser }` to force\n * them.\n */\n quickActions?:\n | boolean\n | {\n browser?: QuickActionBinding;\n actions?: QuickActionToolName[];\n maxChars?: number;\n options?: QuickActionCommonOptions;\n };\n}\n\n/**\n * The browser tool's moving parts, for hosts that need more than the tools:\n *\n * - `runtime` — the codemode runtime handle (approve/reject paused runs,\n * `expirePaused`, audit via `executions()`, snippets).\n * - `connector` — host-side session helpers: `sessionInfo()`,\n * `closeSession()`, and `sweep()` for a recurring cleanup task.\n * - `tools` — what `createBrowserTools` returns.\n */\nexport interface BrowserRuntime {\n runtime: CodemodeRuntimeHandle;\n connector: BrowserConnector;\n tools: ToolSet;\n}\n\nlet didWarnExperimental = false;\nlet didDebugQuickActionSkip = false;\n\n/**\n * The Durable Object state to build the runtime in: the explicit `ctx` if\n * given, otherwise the current Agent's `ctx` (via `getCurrentAgent()`), so\n * `createBrowserRuntime` can be called from an Agent method without threading\n * `this.ctx` through.\n */\nfunction resolveCtx(\n options: CreateBrowserToolsOptions\n): DurableObjectState | undefined {\n if (options.ctx) return options.ctx;\n const agent = agentContext.getStore()?.agent as\n | { ctx?: DurableObjectState }\n | undefined;\n return agent?.ctx;\n}\n\nfunction connectorOptions(\n options: CreateBrowserToolsOptions,\n ctx: DurableObjectState\n): BrowserConnectorOptions {\n if (options.cdpUrl) {\n return {\n cdpUrl: options.cdpUrl,\n cdpHeaders: options.cdpHeaders,\n timeout: options.timeout\n };\n }\n if (!options.browser) {\n throw new Error(\n \"Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided\"\n );\n }\n return {\n browser: options.browser,\n store: options.store ?? new DurableBrowserSessionStore(ctx.storage),\n session: options.session,\n timeout: options.timeout\n };\n}\n\n/**\n * Create the browser codemode runtime: the `browser_execute` tool plus the\n * runtime handle and connector for host-side wiring (approvals, session info,\n * sweeps).\n *\n * @example\n * ```ts\n * export class MyAgent extends Agent<Env> {\n * get browser() {\n * return createBrowserRuntime({\n * ctx: this.ctx,\n * browser: this.env.BROWSER,\n * loader: this.env.LOADER,\n * session: { mode: \"dynamic\" }\n * });\n * }\n *\n * @callable()\n * async closeBrowserSession() {\n * await this.browser.connector.closeSession();\n * }\n * }\n * ```\n */\nexport function createBrowserRuntime(\n options: CreateBrowserToolsOptions\n): BrowserRuntime {\n if (!didWarnExperimental) {\n didWarnExperimental = true;\n console.warn(\n \"[agents/browser] Browser tools are experimental and may change in a future release.\"\n );\n }\n\n const ctx = resolveCtx(options);\n if (!ctx) {\n throw new Error(\n \"createBrowserRuntime requires a Durable Object 'ctx' — pass it explicitly, or call from within an Agent so it can be resolved via getCurrentAgent()\"\n );\n }\n\n const connector = new BrowserConnector(ctx, connectorOptions(options, ctx));\n const runtime = createCodemodeRuntime({\n ctx,\n executor: new DynamicWorkerExecutor({\n loader: options.loader,\n timeout: options.timeout\n }),\n connectors: [connector],\n name: options.name ?? \"browser\",\n transformResult: truncateResult\n });\n\n const tools: ToolSet = { browser_execute: runtime.tool() };\n\n // Quick Actions ride the same `browser` binding, so they are on by default.\n // `env.BROWSER` satisfies both the CDP `BrowserBinding` (fetch) and the\n // `QuickActionBinding` (quickAction) surfaces; our narrower option type only\n // sees the former, so reuse it here unless an explicit binding wins.\n if (options.quickActions !== false) {\n const qa =\n options.quickActions == null || options.quickActions === true\n ? {}\n : options.quickActions;\n const quickActionBrowser =\n qa.browser ??\n (options.browser as unknown as QuickActionBinding | undefined);\n if (quickActionBrowser) {\n Object.assign(\n tools,\n createQuickActionTools({\n browser: quickActionBrowser,\n actions: qa.actions,\n maxChars: qa.maxChars,\n options: qa.options\n })\n );\n } else if (options.quickActions) {\n // Explicitly requested but no binding to back them.\n throw new Error(\n \"quickActions requires a Browser Run binding — set 'browser' (env.BROWSER) or 'quickActions.browser'\"\n );\n } else if (!didDebugQuickActionSkip) {\n // Defaulted on, but only `cdpUrl` is set: there is no binding to call\n // Quick Actions through, so they are skipped. Surface it once so a user\n // expecting `browser_markdown` et al. isn't left wondering.\n didDebugQuickActionSkip = true;\n console.debug(\n \"[agents/browser] Quick Action tools skipped — no Browser Run binding (only 'cdpUrl' is set). Pass 'browser' or 'quickActions.browser' to enable them.\"\n );\n }\n }\n\n return { runtime, connector, tools };\n}\n\n/**\n * Create AI SDK tools for browser automation via CDP code mode.\n *\n * Returns a `ToolSet` with a single durable `browser_execute` tool backed by\n * a codemode runtime: the model writes TypeScript against the `cdp` connector\n * (`cdp.send`, `cdp.attachToTarget`, `cdp.spec`, …), executions are recorded\n * for abort-and-replay, and browser sessions survive pauses.\n *\n * @example\n * ```ts\n * import { createBrowserTools } from \"agents/browser/ai\";\n * import { generateText } from \"ai\";\n *\n * // inside a Durable Object / Agent:\n * const browserTools = createBrowserTools({\n * ctx: this.ctx,\n * browser: this.env.BROWSER,\n * loader: this.env.LOADER,\n * });\n *\n * const result = await generateText({\n * model,\n * tools: { ...browserTools, ...otherTools },\n * messages,\n * });\n * ```\n */\nexport function createBrowserTools(\n options: CreateBrowserToolsOptions\n): ToolSet {\n return createBrowserRuntime(options).tools;\n}\n\n/** A Quick Action exposed as an AI SDK tool. */\nexport type QuickActionToolName =\n | \"markdown\"\n | \"extract\"\n | \"links\"\n | \"scrape\"\n | \"content\";\n\nexport interface CreateQuickActionToolsOptions {\n /**\n * Browser Run binding with Quick Actions support (`env.BROWSER`). Requires a\n * Worker `compatibility_date` of `2026-03-24`+ and `remote: true` for local\n * `wrangler dev`.\n */\n browser: QuickActionBinding;\n\n /**\n * Which tools to expose. Defaults to the text-returning, model-friendly set\n * (`markdown`, `extract`, `links`, `scrape`). `content` (raw HTML) is opt-in\n * since it is large and rarely what a model wants.\n */\n actions?: QuickActionToolName[];\n\n /**\n * Bound every result to roughly this many characters before returning it to\n * the model, to protect the context window, preserving each result's shape:\n * text (markdown/content) is truncated to a string, oversized arrays\n * (links/scrape) are trimmed but stay arrays, and only an opaque oversized\n * object degrades to a truncated-preview summary. Set to `0` to disable.\n * Defaults to 50000.\n */\n maxChars?: number;\n\n /**\n * Common Browser Run options merged into every request — e.g. `cookies`,\n * `authenticate`, or `setExtraHTTPHeaders` for authenticated pages, and\n * `gotoOptions` / `viewport` for JavaScript-heavy pages. The model only ever\n * supplies the page (`url`/`html`) and action-specific fields; these\n * host-supplied options are never exposed to it.\n */\n options?: QuickActionCommonOptions;\n}\n\nconst DEFAULT_QUICK_ACTION_TOOLS: QuickActionToolName[] = [\n \"markdown\",\n \"extract\",\n \"links\",\n \"scrape\"\n];\n\nconst DEFAULT_QUICK_ACTION_MAX_CHARS = 50_000;\n\nconst pageInputSchema = z\n .object({\n url: z.string().url().optional().describe(\"URL of the page to load\"),\n html: z\n .string()\n .optional()\n .describe(\"Raw HTML to render instead of loading a URL\")\n })\n .refine((value) => Boolean(value.url) || Boolean(value.html), {\n message: \"Provide either 'url' or 'html'\"\n });\n\nfunction toPage(\n input: { url?: string; html?: string },\n options?: QuickActionCommonOptions\n): QuickActionPage {\n const page = input.url ? { url: input.url } : { html: input.html as string };\n return { ...options, ...page } as QuickActionPage;\n}\n\nfunction truncate(text: string, maxChars: number): string {\n if (maxChars <= 0 || text.length <= maxChars) return text;\n return `${text.slice(0, maxChars)}\\n\\n[truncated ${text.length - maxChars} characters]`;\n}\n\n/**\n * Keep a tool result within a rough character budget so a single browse cannot\n * blow the model's context window — while preserving the result's shape so the\n * model sees a consistent type across calls:\n *\n * - strings (markdown/content) are truncated to a string;\n * - arrays (links/scrape) are trimmed from the end but stay arrays;\n * - only an opaque oversized object (e.g. a sprawling `extract`) degrades to a\n * `{ truncated, note, preview }` summary, since it cannot be trimmed safely.\n */\nfunction boundResult(value: unknown, maxChars: number): unknown {\n if (maxChars <= 0) return value;\n if (typeof value === \"string\") return truncate(value, maxChars);\n let json: string;\n try {\n json = JSON.stringify(value);\n } catch {\n return value;\n }\n if (json.length <= maxChars) return value;\n if (Array.isArray(value)) {\n const trimmed = boundArray(value, maxChars);\n // If even the first element overflows the budget, `trimmed` is empty —\n // returning `[]` would read as \"no results\" rather than \"too large\", so\n // fall through to the explicit truncated-preview summary instead.\n if (trimmed.length > 0) return trimmed;\n }\n return {\n truncated: true,\n note: `Result is too large (${json.length} characters); narrow the request.`,\n preview: `${json.slice(0, maxChars)}…`\n };\n}\n\n/**\n * Take as many leading items as fit within `maxChars` (measured against their\n * JSON length), returning a trimmed array of the same element type. Silent by\n * design: the model gets fewer, valid items rather than a reshaped result.\n */\nfunction boundArray(value: unknown[], maxChars: number): unknown[] {\n const out: unknown[] = [];\n let size = 2; // the enclosing \"[]\"\n for (const item of value) {\n const itemSize = JSON.stringify(item).length + 1; // + a separating comma\n if (size + itemSize > maxChars) break;\n out.push(item);\n size += itemSize;\n }\n return out;\n}\n\n/**\n * Create AI SDK tools for Browser Run [Quick Actions](https://developers.cloudflare.com/browser-run/quick-actions/):\n * stateless one-shot browsing (read a page as Markdown, extract structured\n * data with AI, list links, scrape elements). Unlike `createBrowserTools`,\n * these need only the `browser` binding — no Durable Object, loader, or\n * sandbox — so they work from any Worker.\n *\n * @example\n * ```ts\n * import { createQuickActionTools } from \"agents/browser/ai\";\n *\n * const tools = createQuickActionTools({ browser: this.env.BROWSER });\n * const result = await generateText({ model, tools, messages });\n * ```\n */\nexport function createQuickActionTools(\n options: CreateQuickActionToolsOptions\n): ToolSet {\n const { browser } = options;\n const requestOptions = options.options;\n const enabled = new Set(options.actions ?? DEFAULT_QUICK_ACTION_TOOLS);\n const maxChars = options.maxChars ?? DEFAULT_QUICK_ACTION_MAX_CHARS;\n const tools: ToolSet = {};\n\n if (enabled.has(\"markdown\")) {\n tools.browser_markdown = tool({\n description:\n \"Load a web page (or render raw HTML) and return its content as Markdown. Best for reading articles, docs, or any page as text.\",\n inputSchema: pageInputSchema,\n execute: async (input) =>\n boundResult(\n await browserMarkdown(browser, toPage(input, requestOptions)),\n maxChars\n )\n });\n }\n\n if (enabled.has(\"extract\")) {\n tools.browser_extract = tool({\n description:\n \"Extract structured data from a web page using AI. Describe what you want in 'prompt'. Passing a JSON Schema in 'schema' is strongly recommended — without one the extractor often fails to produce JSON.\",\n inputSchema: z\n .object({\n url: z.string().url().optional().describe(\"URL of the page to load\"),\n html: z\n .string()\n .optional()\n .describe(\"Raw HTML to render instead of loading a URL\"),\n prompt: z\n .string()\n .optional()\n .describe(\"What to extract, in natural language\"),\n schema: z\n .unknown()\n .optional()\n .describe(\"Optional JSON Schema describing the desired output\")\n })\n .refine((value) => Boolean(value.url) || Boolean(value.html), {\n message: \"Provide either 'url' or 'html'\"\n })\n .refine((value) => Boolean(value.prompt) || Boolean(value.schema), {\n message: \"Provide either 'prompt' or 'schema'\"\n }),\n execute: async (input) =>\n boundResult(\n await browserExtract(browser, {\n ...toPage(input, requestOptions),\n prompt: input.prompt,\n response_format: input.schema\n ? { type: \"json_schema\", schema: input.schema }\n : undefined\n }),\n maxChars\n )\n });\n }\n\n if (enabled.has(\"links\")) {\n tools.browser_links = tool({\n description:\n \"Return every link found on a web page (including ones not visible). Useful for discovering pages to follow.\",\n inputSchema: pageInputSchema,\n execute: async (input) =>\n boundResult(\n await browserLinks(browser, toPage(input, requestOptions)),\n maxChars\n )\n });\n }\n\n if (enabled.has(\"scrape\")) {\n tools.browser_scrape = tool({\n description:\n \"Scrape specific elements from a web page by CSS selector. Returns the matched elements' text, HTML, and attributes.\",\n inputSchema: z\n .object({\n url: z.string().url().optional().describe(\"URL of the page to load\"),\n html: z\n .string()\n .optional()\n .describe(\"Raw HTML to render instead of loading a URL\"),\n selectors: z\n .array(z.string())\n .min(1)\n .describe(\"CSS selectors to extract\")\n })\n .refine((value) => Boolean(value.url) || Boolean(value.html), {\n message: \"Provide either 'url' or 'html'\"\n }),\n execute: async (input) =>\n boundResult(\n await browserScrape(browser, {\n ...toPage(input, requestOptions),\n elements: input.selectors.map((selector) => ({ selector }))\n }),\n maxChars\n )\n });\n }\n\n if (enabled.has(\"content\")) {\n tools.browser_content = tool({\n description:\n \"Load a web page and return its fully rendered HTML (after JavaScript runs). Prefer 'browser_markdown' unless you need the raw HTML.\",\n inputSchema: pageInputSchema,\n execute: async (input) =>\n boundResult(\n await browserContent(browser, toPage(input, requestOptions)),\n maxChars\n )\n });\n }\n\n return tools;\n}\n"],"mappings":"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"}
@@ -1,30 +1,56 @@
1
1
  import {
2
- C as CdpSendOptions,
3
- S as CdpAttachOptions,
4
- T as connectUrl,
5
- _ as connectBrowser,
2
+ A as browserMarkdown,
3
+ B as BrowserTargetInfo,
4
+ C as QuickActionScrapeInput,
5
+ D as browserContent,
6
+ E as QuickActionSnapshot,
7
+ F as runQuickAction,
8
+ G as deleteBrowserSession,
9
+ H as connectBrowser,
10
+ I as BrowserBinding,
11
+ J as CdpAttachOptions,
12
+ K as getBrowserRecording,
13
+ L as BrowserRecording,
14
+ M as browserScrape,
15
+ N as browserScreenshot,
16
+ O as browserExtract,
17
+ P as browserSnapshot,
18
+ R as BrowserRenderingError,
19
+ S as QuickActionPage,
20
+ T as QuickActionScreenshotInput,
21
+ U as connectBrowserSession,
22
+ V as ConnectBrowserOptions,
23
+ W as createBrowserSession,
24
+ X as CdpSession,
25
+ Y as CdpSendOptions,
26
+ Z as connectUrl,
27
+ _ as QuickActionBinary,
6
28
  a as BrowserConnectorSweepResult,
7
- b as deleteBrowserSession,
8
- c as BrowserSessionStore,
9
- d as StoredBrowserSession,
10
- f as BrowserBinding,
11
- g as ConnectBrowserOptions,
12
- h as BrowserTargetInfo,
29
+ b as QuickActionExtractInput,
30
+ c as BrowserLiveViewUrl,
31
+ d as BrowserSessionLock,
32
+ f as BrowserSessionStore,
33
+ g as QuickAction,
34
+ h as StoredBrowserSession,
13
35
  i as BrowserConnectorSweepOptions,
14
- l as DEFAULT_SWEEP_IDLE_MS,
15
- m as BrowserSessionInfo,
36
+ j as browserPdf,
37
+ k as browserLinks,
38
+ l as DEFAULT_EXEC_SWEEP_IDLE_MS,
39
+ m as DurableBrowserSessionStore,
16
40
  n as BrowserConnectorOptions,
17
- o as DEFAULT_EXEC_SWEEP_IDLE_MS,
18
- p as BrowserRenderingError,
41
+ o as BrowserLiveView,
42
+ p as DEFAULT_SWEEP_IDLE_MS,
43
+ q as listBrowserTargets,
19
44
  r as BrowserConnectorSessionOptions,
20
- s as BrowserSessionLock,
45
+ s as BrowserLiveViewTarget,
21
46
  t as BrowserConnector,
22
- u as DurableBrowserSessionStore,
23
- v as connectBrowserSession,
24
- w as CdpSession,
25
- x as listBrowserTargets,
26
- y as createBrowserSession
27
- } from "../connector-DXursxV5.js";
47
+ u as LiveViewMode,
48
+ v as QuickActionBinding,
49
+ w as QuickActionScrapeResult,
50
+ x as QuickActionInput,
51
+ y as QuickActionCommonOptions,
52
+ z as BrowserSessionInfo
53
+ } from "../connector-v2M1zlZp.js";
28
54
  import { CodemodeRuntime } from "@cloudflare/codemode";
29
55
 
30
56
  //#region src/browser/spec.d.ts
@@ -67,6 +93,10 @@ export {
67
93
  type BrowserConnectorSessionOptions,
68
94
  type BrowserConnectorSweepOptions,
69
95
  type BrowserConnectorSweepResult,
96
+ type BrowserLiveView,
97
+ type BrowserLiveViewTarget,
98
+ type BrowserLiveViewUrl,
99
+ type BrowserRecording,
70
100
  BrowserRenderingError,
71
101
  type BrowserSessionInfo,
72
102
  type BrowserSessionLock,
@@ -81,14 +111,36 @@ export {
81
111
  DEFAULT_EXEC_SWEEP_IDLE_MS,
82
112
  DEFAULT_SWEEP_IDLE_MS,
83
113
  DurableBrowserSessionStore,
114
+ type LiveViewMode,
115
+ type QuickAction,
116
+ type QuickActionBinary,
117
+ type QuickActionBinding,
118
+ type QuickActionCommonOptions,
119
+ type QuickActionExtractInput,
120
+ type QuickActionInput,
121
+ type QuickActionPage,
122
+ type QuickActionScrapeInput,
123
+ type QuickActionScrapeResult,
124
+ type QuickActionScreenshotInput,
125
+ type QuickActionSnapshot,
84
126
  type SearchableCdpSpec,
85
127
  type StoredBrowserSession,
128
+ browserContent,
129
+ browserExtract,
130
+ browserLinks,
131
+ browserMarkdown,
132
+ browserPdf,
133
+ browserScrape,
134
+ browserScreenshot,
135
+ browserSnapshot,
86
136
  connectBrowser,
87
137
  connectBrowserSession,
88
138
  connectUrl,
89
139
  createBrowserSession,
90
140
  deleteBrowserSession,
141
+ getBrowserRecording,
91
142
  listBrowserTargets,
92
- loadCdpSpec
143
+ loadCdpSpec,
144
+ runQuickAction
93
145
  };
94
146
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,3 @@
1
- import { a as loadCdpSpec, c as connectBrowserSession, d as listBrowserTargets, f as CdpSession, i as DurableBrowserSessionStore, l as createBrowserSession, n as DEFAULT_EXEC_SWEEP_IDLE_MS, o as BrowserRenderingError, p as connectUrl, r as DEFAULT_SWEEP_IDLE_MS, s as connectBrowser, t as BrowserConnector, u as deleteBrowserSession } from "../connector-D6yYzYHg.js";
1
+ import { C as connectUrl, S as CdpSession, _ as connectBrowserSession, a as loadCdpSpec, b as getBrowserRecording, c as browserLinks, d as browserScrape, f as browserScreenshot, g as connectBrowser, h as BrowserRenderingError, i as DurableBrowserSessionStore, l as browserMarkdown, m as runQuickAction, n as DEFAULT_EXEC_SWEEP_IDLE_MS, o as browserContent, p as browserSnapshot, r as DEFAULT_SWEEP_IDLE_MS, s as browserExtract, t as BrowserConnector, u as browserPdf, v as createBrowserSession, x as listBrowserTargets, y as deleteBrowserSession } from "../connector-CrKhowfD.js";
2
2
  import { CodemodeRuntime } from "@cloudflare/codemode";
3
- export { BrowserConnector, BrowserRenderingError, CdpSession, CodemodeRuntime, DEFAULT_EXEC_SWEEP_IDLE_MS, DEFAULT_SWEEP_IDLE_MS, DurableBrowserSessionStore, connectBrowser, connectBrowserSession, connectUrl, createBrowserSession, deleteBrowserSession, listBrowserTargets, loadCdpSpec };
3
+ export { BrowserConnector, BrowserRenderingError, CdpSession, CodemodeRuntime, DEFAULT_EXEC_SWEEP_IDLE_MS, DEFAULT_SWEEP_IDLE_MS, DurableBrowserSessionStore, browserContent, browserExtract, browserLinks, browserMarkdown, browserPdf, browserScrape, browserScreenshot, browserSnapshot, connectBrowser, connectBrowserSession, connectUrl, createBrowserSession, deleteBrowserSession, getBrowserRecording, listBrowserTargets, loadCdpSpec, runQuickAction };
@@ -10,6 +10,10 @@ import { ServerTool } from "@tanstack/ai";
10
10
  * writes TypeScript against the `cdp` connector and browser sessions
11
11
  * survive pauses.
12
12
  *
13
+ * The stateless Quick Action tools are not surfaced through this TanStack
14
+ * wrapper (it exposes only `browser_execute`); use `createQuickActionTools`
15
+ * from `agents/browser/ai` if you want them.
16
+ *
13
17
  * @example
14
18
  * ```ts
15
19
  * import { createBrowserTools } from "agents/browser/tanstack-ai";
@@ -10,6 +10,10 @@ import { toolDefinition } from "@tanstack/ai";
10
10
  * writes TypeScript against the `cdp` connector and browser sessions
11
11
  * survive pauses.
12
12
  *
13
+ * The stateless Quick Action tools are not surfaced through this TanStack
14
+ * wrapper (it exposes only `browser_execute`); use `createQuickActionTools`
15
+ * from `agents/browser/ai` if you want them.
16
+ *
13
17
  * @example
14
18
  * ```ts
15
19
  * import { createBrowserTools } from "agents/browser/tanstack-ai";
@@ -30,7 +34,10 @@ import { toolDefinition } from "@tanstack/ai";
30
34
  * ```
31
35
  */
32
36
  function createBrowserTools(options) {
33
- const { tools } = createBrowserRuntime(options);
37
+ const { tools } = createBrowserRuntime({
38
+ ...options,
39
+ quickActions: false
40
+ });
34
41
  const executeTool = tools.browser_execute;
35
42
  return [toolDefinition({
36
43
  name: "browser_execute",