/** * Stagehand configuration for the AcadeDoc semantic smoke suite — R4.8. * * Stagehand (Browserbase, MIT) wraps Playwright with an LLM-driven action * planner. Instead of hardcoded selectors (Playwright pure), we describe the * intent in natural language and the LLM resolves the right element at runtime. * That makes the suite resilient to UI label/markup churn — the same test still * works after a Mantine version bump or a French/English label rename. * * This config is consumed both by tests/acadenice-smoke-stagehand.spec.ts and * by any direct script that imports `buildStagehand()` to drive a session. * * Env vars (read from e2e/.env.smoke): * ANTHROPIC_API_KEY — required, the LLM that powers act/observe/extract * STAGEHAND_MODEL — optional, defaults to anthropic/claude-haiku-4-5-20251001 * (haiku = fast + cheap, sufficient for UI navigation) * STAGEHAND_HEADED — "true" to run with a visible browser, default false * STAGEHAND_VERBOSE — "0" | "1" | "2", default "1" */ import { Stagehand } from "@browserbasehq/stagehand"; import * as dotenv from "dotenv"; import * as path from "path"; dotenv.config({ path: path.resolve(__dirname, ".env.smoke") }); export interface StagehandConfig { modelName: string; apiKey: string; headless: boolean; verbose: 0 | 1 | 2; } export function readConfig(): StagehandConfig { const apiKey = process.env.ANTHROPIC_API_KEY ?? ""; const modelName = process.env.STAGEHAND_MODEL ?? "anthropic/claude-haiku-4-5-20251001"; const headed = (process.env.STAGEHAND_HEADED ?? "").toLowerCase() === "true"; const verboseRaw = process.env.STAGEHAND_VERBOSE ?? "1"; const verbose = (["0", "1", "2"].includes(verboseRaw) ? Number(verboseRaw) : 1) as 0 | 1 | 2; return { modelName, apiKey, headless: !headed, verbose }; } /** * Build a Stagehand instance pointed at a local Chromium with Anthropic Claude * as the planning model. Caller is responsible for `await stagehand.init()` and * `await stagehand.close()`. */ export function buildStagehand(): Stagehand { const cfg = readConfig(); if (!cfg.apiKey) { throw new Error( "ANTHROPIC_API_KEY missing in e2e/.env.smoke — cannot build Stagehand instance", ); } return new Stagehand({ env: "LOCAL", verbose: cfg.verbose, model: { modelName: cfg.modelName, apiKey: cfg.apiKey, }, localBrowserLaunchOptions: { headless: cfg.headless, viewport: { width: 1440, height: 900 }, }, }); }