import { toFile } from "@browserbasehq/sdk" import * as z from "zod" import { defineAction } from "../../automation/actions" import { getBrowserbaseClient, requestBrowserbaseText } from "./lib" import { BROWSERBASE_ID_SCHEMA, BROWSERBASE_RECORDING_DOWNLOADS_SCHEMA, BROWSERBASE_SESSION_CREATE_RESPONSE_SCHEMA, BROWSERBASE_SESSION_CREATE_SCHEMA, BROWSERBASE_SESSION_LIVE_URLS_SCHEMA, BROWSERBASE_SESSION_LOG_SCHEMA, BROWSERBASE_SESSION_REPLAY_SCHEMA, BROWSERBASE_SESSION_RESPONSE_SCHEMA, BROWSERBASE_SESSION_SCHEMA, } from "./schemas" /** Creates a Browserbase cloud browser session. */ export const createBrowserbaseSession = defineAction( "Create Browserbase session", ) .describe( "Creates a configurable cloud browser session and returns connection URLs.", ) .account("browserbase") .input(BROWSERBASE_SESSION_CREATE_SCHEMA) .output(BROWSERBASE_SESSION_CREATE_RESPONSE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input: { timeout, ...input } }) => BROWSERBASE_SESSION_CREATE_RESPONSE_SCHEMA.parse( await getBrowserbaseClient(account.secret).sessions.create({ ...input, ...(timeout !== undefined && { api_timeout: timeout }), }), ), ) /** Lists Browserbase sessions by status or metadata query. */ export const listBrowserbaseSessions = defineAction("List Browserbase sessions") .describe( "Lists sessions filtered by lifecycle status or user metadata query.", ) .account("browserbase") .input( z.object({ q: z.string().min(1).optional(), status: z .enum(["PENDING", "RUNNING", "ERROR", "TIMED_OUT", "COMPLETED"]) .optional(), }), ) .output(BROWSERBASE_SESSION_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => BROWSERBASE_SESSION_SCHEMA.array().parse( await getBrowserbaseClient(account.secret).sessions.list(input), ), ) /** Gets one Browserbase session. */ export const getBrowserbaseSession = defineAction("Get Browserbase session") .describe( "Gets current lifecycle, usage, metadata, and connection details for one session.", ) .account("browserbase") .input(z.object({ sessionId: BROWSERBASE_ID_SCHEMA })) .output(BROWSERBASE_SESSION_RESPONSE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => BROWSERBASE_SESSION_RESPONSE_SCHEMA.parse( await getBrowserbaseClient(account.secret).sessions.retrieve( input.sessionId, ), ), ) /** Requests early release of a Browserbase session. */ export const endBrowserbaseSession = defineAction("End Browserbase session") .describe( "Requests that a running session complete before its configured timeout.", ) .account("browserbase") .input(z.object({ sessionId: BROWSERBASE_ID_SCHEMA })) .output(BROWSERBASE_SESSION_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => BROWSERBASE_SESSION_SCHEMA.parse( await getBrowserbaseClient(account.secret).sessions.update( input.sessionId, { status: "REQUEST_RELEASE" }, ), ), ) /** Gets live debugger URLs for a Browserbase session. */ export const getBrowserbaseSessionLiveUrls = defineAction( "Get Browserbase session live URLs", ) .describe( "Gets session-level and page-level debugger URLs for live inspection.", ) .account("browserbase") .input(z.object({ sessionId: BROWSERBASE_ID_SCHEMA })) .output(BROWSERBASE_SESSION_LIVE_URLS_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => BROWSERBASE_SESSION_LIVE_URLS_SCHEMA.parse( await getBrowserbaseClient(account.secret).sessions.debug( input.sessionId, ), ), ) /** Lists Chrome DevTools Protocol logs for a Browserbase session. */ export const listBrowserbaseSessionLogs = defineAction( "List Browserbase session logs", ) .describe("Lists captured Chrome DevTools Protocol requests and responses.") .account("browserbase") .input(z.object({ sessionId: BROWSERBASE_ID_SCHEMA })) .output(BROWSERBASE_SESSION_LOG_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => BROWSERBASE_SESSION_LOG_SCHEMA.array().parse( await getBrowserbaseClient(account.secret).sessions.logs.list( input.sessionId, ), ), ) /** Starts MP4 assembly for each recorded page in a completed session. */ export const requestBrowserbaseSessionRecordingDownloads = defineAction( "Request Browserbase session recording downloads", ) .describe("Enqueues one MP4 recording download per recorded page.") .account("browserbase") .input(z.object({ sessionId: BROWSERBASE_ID_SCHEMA })) .output(BROWSERBASE_RECORDING_DOWNLOADS_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => BROWSERBASE_RECORDING_DOWNLOADS_SCHEMA.parse( await getBrowserbaseClient( account.secret, ).sessions.recording.downloads.create(input.sessionId), ), ) /** Lists per-page MP4 assembly status and completed download URLs. */ export const listBrowserbaseSessionRecordingDownloads = defineAction( "List Browserbase session recording downloads", ) .describe( "Lists MP4 assembly state and short-lived URLs for completed pages.", ) .account("browserbase") .input(z.object({ sessionId: BROWSERBASE_ID_SCHEMA })) .output(BROWSERBASE_RECORDING_DOWNLOADS_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => BROWSERBASE_RECORDING_DOWNLOADS_SCHEMA.parse( await getBrowserbaseClient( account.secret, ).sessions.recording.downloads.list(input.sessionId), ), ) /** Gets replay page metadata for a Browserbase session. */ export const getBrowserbaseSessionReplay = defineAction( "Get Browserbase session replay", ) .describe("Gets every recorded page and its HLS replay timing metadata.") .account("browserbase") .input(z.object({ sessionId: BROWSERBASE_ID_SCHEMA })) .output(BROWSERBASE_SESSION_REPLAY_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => BROWSERBASE_SESSION_REPLAY_SCHEMA.parse( await getBrowserbaseClient(account.secret).sessions.replays.retrieve( input.sessionId, ), ), ) /** Gets one HLS replay playlist for a Browserbase session page. */ export const getBrowserbaseSessionReplayPage = defineAction( "Get Browserbase session replay page", ) .describe("Gets the HLS media playlist for one recorded page.") .account("browserbase") .input( z.object({ pageId: z.string().regex(/^\d{1,3}$/), sessionId: BROWSERBASE_ID_SCHEMA, }), ) .output(z.object({ playlist: z.string() })) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => ({ playlist: await requestBrowserbaseText( account.secret, `/v1/sessions/${encodeURIComponent(input.sessionId)}/replays/${encodeURIComponent(input.pageId)}`, ), })) /** Uploads a file into a running Browserbase session. */ export const uploadBrowserbaseSessionFile = defineAction( "Upload Browserbase session file", ) .describe( "Uploads a file for use by browser file inputs in a running session.", ) .account("browserbase") .input( z.object({ file: z.instanceof(Blob), filename: z.string().min(1).max(255), sessionId: BROWSERBASE_ID_SCHEMA, }), ) .output(z.object({ message: z.string() })) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { return z.object({ message: z.string() }).parse( await getBrowserbaseClient(account.secret).sessions.uploads.create( input.sessionId, { file: await toFile(await input.file.arrayBuffer(), input.filename, { type: input.file.type, }), }, ), ) })