Bring Your Own Model / Bring Your Own Browser
Scrape's engine depends on interfaces, not concrete model or browser packages. Bring your own model by implementing ScrapeAiBridge. Bring your own browser by implementing BrowserSession.
Custom AI Bridge
The bridge plans, extracts, chooses actions, and heals selectors.
import { runScrape } from "@cuitty/scrape/engine";
import type { ScrapeAiBridge } from "@cuitty/scrape/ai";
import { createMockBrowserSession } from "@cuitty/scrape/driver";
import { createMockCredentialProvider } from "@cuitty/scrape/auth";
const bridge: ScrapeAiBridge = {
async plan() {
return { classification: "content", output: "answer", outline: ["navigate", "extract"] };
},
async extract({ intent }) {
return { answer: { intent, source: "custom-bridge" }, tokens: 0 };
},
async decide() {
return { verb: "assert", done: true };
},
async heal({ failedSelector }) {
return failedSelector;
},
};
const result = await runScrape(
{ url: "https://example.com", intent: "Summarize the page" },
{
bridge,
session: createMockBrowserSession(),
credentials: createMockCredentialProvider(),
},
);
console.log(result.answer);
Using a Different Model
For OpenAI, local Ollama, or another provider, keep provider-specific code inside your bridge. The engine only needs the four bridge methods. If you use the Vercel AI SDK, mirror the Claude bridge pattern and lazy-load optional model packages inside method calls.
Custom Browser Session
The current BrowserSession interface contains navigation, bifurcation, signals, click, fill, storage-state capture/hydration, and close. Screenshots can be returned as part of bifurcate().
import type { BrowserSession, PageBifurcation } from "@cuitty/scrape/driver";
const session: BrowserSession = {
async navigate(url: string) {
console.log("navigate", url);
},
async bifurcate(): Promise<PageBifurcation> {
return {
markdown: "# Example\n\nHello from a custom browser.",
html: "<main><h1>Example</h1></main>",
elements: [],
};
},
async signals() {
return { url: "https://example.com" };
},
async click() {},
async fill() {},
async storageState() {
return JSON.stringify({ cookies: [], origins: [] });
},
async hydrate() {},
async close() {},
};
console.log((await session.bifurcate()).markdown);
Firefox, WebKit, and Headed Browsers
The shipped createPlaywrightBrowserSession() currently launches Chromium through playwright-core and defaults to system Chrome. To use Firefox or WebKit today, inject a custom BrowserSession that wraps the Playwright browser type you need.
For Chromium live sessions, configure headed/headless behavior through the live server or direct Playwright session options:
import { createPlaywrightBrowserSession } from "@cuitty/scrape/driver/playwright";
const headedChrome = createPlaywrightBrowserSession({
headless: false,
channel: "chrome",
});
await headedChrome.navigate("https://example.com");
await headedChrome.close();
Stealth and Patchright
Patchright/stealth support is not part of the current shipped factory. Keep stealth-specific browser code behind a custom BrowserSession until the engine track exposes a first-class option.