export { Sandbox } from "../../worker/sandbox"; import runtime, { PersonalAgent as FixturePersonalAgent, Conversation as FixtureConversation, } from "./think-worker"; import type { Env } from "../../worker/personal-agent"; import type { BrowserBinding } from "agents/browser"; import { createBrowserSession } from "agents/browser"; import { getAgentByName } from "agents"; import { browserRace } from "./browser-races"; const sessions: { id: string; deleted: boolean }[] = []; const requests: string[] = []; let failDeletes = 0; let delayCreate = 0; const dynamicHtml = `Initial title
Loading
`; const originalFetch = globalThis.fetch; globalThis.fetch = ((input: RequestInfo | URL, init?: RequestInit) => { const url = new URL( typeof input === "string" ? input : input instanceof URL ? input.href : input.url, ); return url.hostname === "browser.fixture.example.com" ? Promise.resolve( new Response(dynamicHtml, { headers: { "content-type": "text/html" } }), ) : originalFetch(input, init); }) as typeof fetch; function fixtureBrowser(browser: BrowserBinding): BrowserBinding { return { async fetch(input, init) { if (init?.method === "DELETE" && failDeletes-- > 0) return new Response(null, { status: 503 }); const response = await browser.fetch(input, init); if (init?.method === "POST") { const { sessionId } = (await response.clone().json()) as { sessionId: string; }; sessions.push({ id: sessionId, deleted: false }); if (delayCreate) await new Promise((resolve) => setTimeout(resolve, delayCreate)); } if (init?.method === "DELETE") { const found = sessions.find( (session) => session.id === String(input).split("/").at(-1), ); if (found && (response.ok || response.status === 404)) found.deleted = true; } if (response.webSocket) { const socket = response.webSocket; const send = socket.send.bind(socket); const paused = new Map(); socket.addEventListener("message", (message) => { const event = JSON.parse(String(message.data)); if (event.method === "Fetch.requestPaused") { paused.set(event.params.requestId, event.params.request.url); requests.push(event.params.request.url); } }); socket.send = (message) => { const command = JSON.parse(String(message)); if (command.method === "Fetch.continueRequest") { const url = new URL(paused.get(command.params.requestId)!); if (url.hostname === "browser.fixture.example.com") { const path = url.pathname; const body = path === "/follow" ? "Followed source
Follow-up evidence
" : path === "/large" ? "
" + "🐟".repeat(12_000) + "
" : path === "/slow" ? "
Waiting
" : dynamicHtml; command.method = "Fetch.fulfillRequest"; command.params = { requestId: command.params.requestId, responseCode: path === "/private" ? 302 : path === "/error" ? 429 : 200, responseHeaders: [ { name: "content-type", value: "text/html; charset=utf-8" }, ...(path === "/private" ? [{ name: "location", value: "http://127.0.0.1/secret" }] : []), ], body: btoa( String.fromCharCode(...new TextEncoder().encode(body)), ), }; } } send(JSON.stringify(command)); }; } return response; }, }; } export class PersonalAgent extends FixturePersonalAgent { constructor(ctx: DurableObjectState, env: Env) { super(ctx, { ...env, BROWSER: fixtureBrowser(env.BROWSER) as Fetcher }); } inspectBrowsers() { return this.sql`SELECT * FROM flarebot_browser_leases`; } async seedBrowser(conversationId: string, ms: number) { const { sessionId } = await createBrowserSession(this.env.BROWSER, { keepAliveMs: 60_000, }); await this.registerResearchBrowser( conversationId, sessionId, Date.now() + ms, ); return sessionId; } } export class Conversation extends FixtureConversation { constructor(ctx: DurableObjectState, env: Env) { super(ctx, { ...env, BROWSER: fixtureBrowser(env.BROWSER) as Fetcher }); } } export default { async fetch( request: Request, env: Env, ctx: ExecutionContext, ) { const url = new URL(request.url); if (url.pathname === "/__fixture/browser-probe") { const response = await env.BROWSER.fetch( `https://localhost/v1/devtools/browser/${url.searchParams.get("id")}/json/list`, ); return Response.json({ status: response.status }); } if (url.pathname === "/__fixture/browser-status") { const parent = await getAgentByName(env.PersonalAgent, "personal"); return Response.json({ sessions, requests, leases: await (parent as unknown as PersonalAgent).inspectBrowsers(), }); } if (url.pathname === "/__fixture/browser-fault") { failDeletes = Number(url.searchParams.get("deletes") ?? 0); delayCreate = Number(url.searchParams.get("create") ?? 0); return new Response("ok"); } if (url.pathname === "/__fixture/browser-seed") { const parent = await getAgentByName(env.PersonalAgent, "personal"); return Response.json( await (parent as unknown as PersonalAgent).seedBrowser( url.searchParams.get("id")!, Number(url.searchParams.get("ms")), ), ); } if (url.pathname === "/__fixture/browser-race") return Response.json( await browserRace(url.searchParams.get("scenario")!), ); return runtime.fetch(request, env, ctx); }, };