diff --git a/.changeset/odd-doodles-shop.md b/.changeset/odd-doodles-shop.md new file mode 100644 index 000000000..972b0b9c0 --- /dev/null +++ b/.changeset/odd-doodles-shop.md @@ -0,0 +1,5 @@ +--- +"@browserbasehq/stagehand": patch +--- + +Add session create metadata when env is BROWSERBASE for model client + name diff --git a/.gitignore b/.gitignore index b34c2f45d..53aede82c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ tmp/ eval-summary.json package-lock.json evals/deterministic/tests/BrowserContext/tmp-test.har +evals/test-results \ No newline at end of file diff --git a/evals/deterministic/tests/browserbase/custom_client_metadata.test.ts b/evals/deterministic/tests/browserbase/custom_client_metadata.test.ts new file mode 100644 index 000000000..80362dd90 --- /dev/null +++ b/evals/deterministic/tests/browserbase/custom_client_metadata.test.ts @@ -0,0 +1,46 @@ +/** + * Just extends sessions.test.ts but with a custom client. + */ +import { test, expect } from "@playwright/test"; +import { Stagehand } from "@browserbasehq/stagehand"; +import StagehandConfig from "@/evals/deterministic/stagehand.config"; +import Browserbase from "@browserbasehq/sdk"; +import { AISdkClient } from "@/examples/external_clients/aisdk"; +import { google } from "@ai-sdk/google/dist"; + +test.describe("Browserbase Sessions with custom client metadata", () => { + let browserbase: Browserbase; + let sessionId: string; + let bigStagehand: Stagehand; + + test.beforeAll(async () => { + browserbase = new Browserbase({ + apiKey: process.env.BROWSERBASE_API_KEY, + }); + bigStagehand = new Stagehand({ + ...StagehandConfig, + env: "BROWSERBASE", + modelName: undefined, + llmClient: new AISdkClient({ + model: google("gemini-2.0-flash"), + }), + }); + await bigStagehand.init(); + await bigStagehand.page.goto( + "https://docs.stagehand.dev/get_started/introduction", + ); + sessionId = bigStagehand.browserbaseSessionID; + if (!sessionId) { + throw new Error("Failed to get browserbase session ID"); + } + }); + test.afterAll(async () => { + await bigStagehand.close(); + }); + test("creates the right session metadata", async () => { + const session = await browserbase.sessions.retrieve(sessionId); + expect(session.userMetadata.stagehand).toBe("true"); + expect(session.userMetadata.modelName).toBe("NO_MODEL_DEFINED"); + expect(session.userMetadata.usingCustomClient).toBe("true"); + }); +}); diff --git a/evals/deterministic/tests/browserbase/sessions.test.ts b/evals/deterministic/tests/browserbase/sessions.test.ts index 76f233d78..79ed6e436 100644 --- a/evals/deterministic/tests/browserbase/sessions.test.ts +++ b/evals/deterministic/tests/browserbase/sessions.test.ts @@ -64,4 +64,10 @@ test.describe("Browserbase Sessions", () => { "https://docs.stagehand.dev/get_started/introduction", ); }); + test("creates the right session metadata", async () => { + const session = await browserbase.sessions.retrieve(sessionId); + expect(session.userMetadata.stagehand).toBe("true"); + expect(session.userMetadata.modelName).toBe("gpt-4o"); + expect(session.userMetadata.usingCustomClient).toBe("false"); + }); }); diff --git a/lib/index.ts b/lib/index.ts index fe93a2df0..d338a2565 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -74,6 +74,8 @@ async function getBrowser( env: "LOCAL" | "BROWSERBASE" = "LOCAL", headless: boolean = false, logger: (message: LogLine) => void, + modelName: string, + usingCustomClient: boolean, browserbaseSessionCreateParams?: Browserbase.Sessions.SessionCreateParams, browserbaseSessionID?: string, localBrowserLaunchOptions?: LocalBrowserLaunchOptions, @@ -165,6 +167,8 @@ async function getBrowser( userMetadata: { ...(browserbaseSessionCreateParams?.userMetadata || {}), stagehand: "true", + modelName: modelName?.replace("/", "_") || "unknown", + usingCustomClient: usingCustomClient.toString(), }, }); @@ -403,6 +407,7 @@ export class Stagehand { private _browser: Browser | undefined; private _isClosed: boolean = false; private _history: Array = []; + private _usingCustomClient: boolean; public get history(): ReadonlyArray { return Object.freeze([...this._history]); } @@ -557,6 +562,7 @@ export class Stagehand { // Update logger verbosity level this.stagehandLogger.setVerbosity(this.verbose); this.modelName = modelName ?? DEFAULT_MODEL_NAME; + this._usingCustomClient = !modelName; let modelApiKey: string | undefined; @@ -640,7 +646,6 @@ export class Stagehand { } this.logInferenceToFile = logInferenceToFile; this.selfHeal = selfHeal; - this.disablePino = disablePino; } private registerSignalHandlers() { @@ -739,6 +744,8 @@ export class Stagehand { this.env, this.headless, this.logger, + this._usingCustomClient ? "NO_MODEL_DEFINED" : this.modelName, + this._usingCustomClient, this.browserbaseSessionCreateParams, this.browserbaseSessionID, this.localBrowserLaunchOptions, diff --git a/package.json b/package.json index f19e9f643..24cd1cce1 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "module": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { - "example": "pnpm --filter @browserbasehq/stagehand-examples run start", + "example": "pnpm run build && pnpm --filter @browserbasehq/stagehand-examples run start", "format": "prettier --write .", "prettier": "prettier --check .", "prettier:fix": "prettier --write .", diff --git a/stagehand.config.ts b/stagehand.config.ts index 4c901799b..4af15f272 100644 --- a/stagehand.config.ts +++ b/stagehand.config.ts @@ -1,4 +1,4 @@ -import type { ConstructorParams } from "@/dist"; +import type { ConstructorParams } from "./dist"; import dotenv from "dotenv"; dotenv.config();