agents
Version:
A home for your AI agents
148 lines (147 loc) • 5.52 kB
JavaScript
import { n as browserScreenshotOutput, t as browserExecuteModelOutput } from "../../tool-helpers-F3_Wy2YX.js";
import { createBrowserRuntime } from "../ai.js";
import { t as createBrowserToolCore } from "../../browser-tool-DOqT1oSD.js";
import { z } from "zod";
import { toolDefinition } from "@tanstack/ai";
//#region src/browser/tanstack-ai.ts
/**
* The legacy TanStack AI `createBrowserTools`. `agents/browser/tanstack-ai`
* (`tools/tanstack-ai.ts`) re-exports it until it's retired.
*/
/**
* Create TanStack AI tools for browser automation via CDP code mode.
*
* Returns an array with a single durable `browser_execute` `ServerTool`
* backed by the same codemode runtime as `agents/browser/ai` — the model
* writes TypeScript against the `cdp` connector and browser sessions
* survive pauses.
*
* The stateless Quick Action tools are not surfaced through this TanStack
* wrapper (it exposes only `browser_execute`); use `createQuickActionTools`
* from `agents/browser/ai` if you want them.
*
* @example
* ```ts
* import { createBrowserTools } from "agents/browser/tanstack-ai";
* import { chat } from "@tanstack/ai";
*
* // inside a Durable Object / Agent:
* const browserTools = createBrowserTools({
* ctx: this.ctx,
* browser: this.env.BROWSER,
* loader: this.env.LOADER,
* });
*
* const stream = chat({
* adapter: openaiText("gpt-4o"),
* tools: [...browserTools, ...otherTools],
* messages,
* });
* ```
*
* @deprecated Use `browserTool` from `agents/browser/ai-sdk`,
* `agents/browser/tanstack-ai` or `agents/browser/pi`. See
* https://github.com/cloudflare/agents/blob/main/docs/agents/browse-the-web.md#persistent-browser
*/
function createBrowserTools(options) {
const { tools } = createBrowserRuntime({
...options,
quickActions: false
});
const executeTool = tools.browser_execute;
return [toolDefinition({
name: "browser_execute",
description: typeof executeTool.description === "function" ? "" : executeTool.description ?? "",
inputSchema: z.object({ code: z.string().meta({ description: "TypeScript async arrow function that uses the cdp connector" }) })
}).server(async ({ code }) => {
if (!executeTool.execute) throw new Error("browser_execute tool is not executable");
const result = await executeTool.execute({ code }, {
toolCallId: crypto.randomUUID(),
messages: [],
context: {}
});
const modelOutput = await executeTool.toModelOutput?.({
toolCallId: crypto.randomUUID(),
input: { code },
output: result
});
if (modelOutput?.type === "error-text") throw new Error(modelOutput.value);
if (modelOutput?.type === "text") return {
...result,
result: modelOutput.value
};
if (modelOutput?.type === "json") return modelOutput.value;
return result;
})];
}
//#endregion
//#region src/browser/tools/tanstack-ai.ts
/**
* `agents/browser/tanstack-ai` — the TanStack AI tool for a persistent
* `Browser`.
*
* The older `createBrowserTools` lives in `../tanstack-ai.ts` and is
* re-exported here until it's retired.
*/
/**
* What the model sees from one run. TanStack AI has one return channel, so
* the host gets this too: no `calls` log, bounded `logs`, and a screenshot
* replaced by a sentence saying it was left out.
*/
function browserToolModelResult(output) {
const screenshot = browserScreenshotOutput(output);
if (!screenshot) return browserExecuteModelOutput(output).value;
const bytes = Math.floor(screenshot.data.length * 3 / 4);
return browserExecuteModelOutput({
...output,
result: `Screenshot captured (${screenshot.mediaType}, approximately ${bytes.toLocaleString()} bytes), but this tool can't return images, so neither you nor the user can see it. Read the page with Runtime.evaluate instead.`
}).value;
}
/**
* Create a TanStack AI tool that lets the model drive a persistent browser
* with JavaScript and the Chrome DevTools Protocol.
*
* Works like `browserTool` in `agents/browser/ai-sdk`: tabs, cookies, and
* logins carry over between runs, `sessionId: "active"` addresses the tab the
* model last worked in, and a replaced browser is reported in the
* result's `notice`. The tool is named `browser` unless you pass `name`.
*
* Unlike the AI SDK tool, the host gets the same output as the model, and
* screenshots aren't supported: a returned screenshot is replaced by a
* sentence saying it was left out.
*
* @example
* ```ts
* import { Browser, browserRun } from "agents/browser";
* import { browserTool } from "agents/browser/tanstack-ai";
* import { chat } from "@tanstack/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);
* }
*
* async onChatMessage() {
* const stream = chat({
* adapter,
* tools: [browserTool({ browser: this.browser, loader: this.env.LOADER })],
* messages
* });
* }
* }
* ```
*/
function browserTool(options) {
const core = createBrowserToolCore(options, { screenshotHint: "This tool can't return images, so don't take screenshots; read the page with Runtime.evaluate (for example document.body.innerText) instead." });
return toolDefinition({
name: options.name ?? "browser",
description: core.description,
inputSchema: core.inputSchema
}).server(async (input, context) => browserToolModelResult(await core.execute(input, { signal: context?.abortSignal })));
}
//#endregion
export { browserTool, createBrowserTools };
//# sourceMappingURL=tanstack-ai.js.map