Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/evil-clubs-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@browserbasehq/stagehand": patch
---

Add support for google vertex provider
2 changes: 0 additions & 2 deletions packages/core/examples/custom_client_langchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import { LangchainClient } from "./external_clients/langchain";
import { ChatOpenAI } from "@langchain/openai";

async function example() {
// @ts-expect-error Type instantiation is excessively deep and possibly infinite
const stagehand = new Stagehand({
env: "BROWSERBASE",
verbose: 1,
// @ts-expect-error Type instantiation is excessively deep and possibly infinite
llmClient: new LangchainClient(
new ChatOpenAI({
model: "gpt-4o",
Expand Down
4 changes: 2 additions & 2 deletions packages/core/lib/modelUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ModelConfiguration } from "./v3/types/public/model";
import { ClientOptions, ModelConfiguration } from "./v3/types/public/model";
import {
AVAILABLE_CUA_MODELS,
AvailableCuaModel,
Expand All @@ -17,7 +17,7 @@ export function splitModelName(model: string): {
export function resolveModel(model: string | ModelConfiguration): {
provider: string;
modelName: string;
clientOptions: Record<string, unknown>;
clientOptions: ClientOptions;
isCua: boolean;
} {
// Extract the model string and client options
Expand Down
1 change: 1 addition & 0 deletions packages/core/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ export const providerEnvVarMap: Partial<
openai: "OPENAI_API_KEY",
anthropic: "ANTHROPIC_API_KEY",
google: ["GEMINI_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"],
vertex: "GOOGLE_VERTEX_AI_API_KEY",
groq: "GROQ_API_KEY",
cerebras: "CEREBRAS_API_KEY",
togetherai: "TOGETHER_AI_API_KEY",
Expand Down
3 changes: 2 additions & 1 deletion packages/core/lib/v3/agent/AgentClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
AgentType,
AgentExecutionOptions,
} from "../types/public/agent";
import { ClientOptions } from "../types/public/model";

/**
* Abstract base class for agent clients
Expand All @@ -12,7 +13,7 @@ import {
export abstract class AgentClient {
public type: AgentType;
public modelName: string;
public clientOptions: Record<string, unknown>;
public clientOptions: ClientOptions;
public userProvidedInstructions?: string;

constructor(
Expand Down
3 changes: 2 additions & 1 deletion packages/core/lib/v3/agent/AgentProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ToolSet } from "ai/dist";
import { AgentProviderType } from "../types/public/agent";
import { LogLine } from "../types/public/logs";
import { ClientOptions } from "../types/public/model";
import {
UnsupportedModelError,
UnsupportedModelProviderError,
Expand Down Expand Up @@ -40,7 +41,7 @@ export class AgentProvider {

getClient(
modelName: string,
clientOptions?: Record<string, unknown>,
clientOptions?: ClientOptions,
userProvidedInstructions?: string,
tools?: ToolSet,
): AgentClient {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/lib/v3/agent/AnthropicCUAClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ToolUseItem,
} from "../types/public/agent";
import { LogLine } from "../types/public/logs";
import { ClientOptions } from "../types/public/model";
import { AgentScreenshotProviderError } from "../types/public/sdkErrors";
import Anthropic from "@anthropic-ai/sdk";
import { ToolSet } from "ai";
Expand Down Expand Up @@ -41,7 +42,7 @@ export class AnthropicCUAClient extends AgentClient {
type: AgentType,
modelName: string,
userProvidedInstructions?: string,
clientOptions?: Record<string, unknown>,
clientOptions?: ClientOptions,
tools?: ToolSet,
) {
super(type, modelName, userProvidedInstructions);
Expand All @@ -65,7 +66,7 @@ export class AnthropicCUAClient extends AgentClient {
};

if (this.baseURL) {
this.clientOptions.baseUrl = this.baseURL;
this.clientOptions.baseURL = this.baseURL;
}

// Initialize the Anthropic client
Expand Down
3 changes: 2 additions & 1 deletion packages/core/lib/v3/agent/GoogleCUAClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
AgentType,
AgentExecutionOptions,
} from "../types/public/agent";
import { ClientOptions } from "../types/public/model";
import { AgentClient } from "./AgentClient";
import {
AgentScreenshotProviderError,
Expand Down Expand Up @@ -51,7 +52,7 @@ export class GoogleCUAClient extends AgentClient {
type: AgentType,
modelName: string,
userProvidedInstructions?: string,
clientOptions?: Record<string, unknown>,
clientOptions?: ClientOptions,
tools?: ToolSet,
) {
super(type, modelName, userProvidedInstructions);
Expand Down
3 changes: 2 additions & 1 deletion packages/core/lib/v3/agent/MicrosoftCUAClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
AgentType,
AgentExecutionOptions,
} from "../types/public/agent";
import { ClientOptions } from "../types/public/model";
import { AgentClient } from "./AgentClient";
import { AgentScreenshotProviderError } from "../types/public/sdkErrors";
import { mapKeyToPlaywright } from "./utils/cuaKeyMapping";
Expand Down Expand Up @@ -75,7 +76,7 @@ export class MicrosoftCUAClient extends AgentClient {
type: AgentType,
modelName: string,
userProvidedInstructions?: string,
clientOptions?: Record<string, unknown>,
clientOptions?: ClientOptions,
) {
super(type, modelName || "fara-7b", userProvidedInstructions);

Expand Down
3 changes: 2 additions & 1 deletion packages/core/lib/v3/agent/OpenAICUAClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ComputerCallItem,
FunctionCallItem,
} from "../types/public/agent";
import { ClientOptions } from "../types/public/model";
import { AgentClient } from "./AgentClient";
import { AgentScreenshotProviderError } from "../types/public/sdkErrors";
import { ToolSet } from "ai";
Expand All @@ -36,7 +37,7 @@ export class OpenAICUAClient extends AgentClient {
type: AgentType,
modelName: string,
userProvidedInstructions?: string,
clientOptions?: Record<string, unknown>,
clientOptions?: ClientOptions,
tools?: ToolSet,
) {
super(type, modelName, userProvidedInstructions);
Expand Down
18 changes: 7 additions & 11 deletions packages/core/lib/v3/llm/LLMProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { GroqClient } from "./GroqClient";
import { LLMClient } from "./LLMClient";
import { OpenAIClient } from "./OpenAIClient";
import { openai, createOpenAI } from "@ai-sdk/openai";
import { vertex, createVertex } from "@ai-sdk/google-vertex";
import { anthropic, createAnthropic } from "@ai-sdk/anthropic";
import { google, createGoogleGenerativeAI } from "@ai-sdk/google";
import { xai, createXai } from "@ai-sdk/xai";
Expand All @@ -43,11 +44,13 @@ const AISDKProviders: Record<string, AISDKProvider> = {
deepseek,
perplexity,
ollama,
vertex,
};
const AISDKProvidersWithAPIKey: Record<string, AISDKCustomProvider> = {
openai: createOpenAI,
anthropic: createAnthropic,
google: createGoogleGenerativeAI,
vertex: createVertex,
xai: createXai,
azure: createAzure,
groq: createGroq,
Expand Down Expand Up @@ -96,23 +99,17 @@ const modelToProviderMap: { [key in AvailableModel]: ModelProvider } = {
export function getAISDKLanguageModel(
subProvider: string,
subModelName: string,
apiKey?: string,
baseURL?: string,
clientOptions?: ClientOptions,
) {
if (apiKey) {
if (clientOptions && Object.keys(clientOptions).length > 0) {
const creator = AISDKProvidersWithAPIKey[subProvider];
if (!creator) {
throw new UnsupportedAISDKModelProviderError(
subProvider,
Object.keys(AISDKProvidersWithAPIKey),
);
}
// Create the provider instance with the API key and baseURL if provided
const providerConfig: { apiKey: string; baseURL?: string } = { apiKey };
if (baseURL) {
providerConfig.baseURL = baseURL;
}
const provider = creator(providerConfig);
const provider = creator(clientOptions);
// Get the specific model from the provider
return provider(subModelName);
} else {
Expand Down Expand Up @@ -146,8 +143,7 @@ export class LLMProvider {
const languageModel = getAISDKLanguageModel(
subProvider,
subModelName,
clientOptions?.apiKey,
clientOptions?.baseURL,
clientOptions,
);

return new AISdkClient({
Expand Down
3 changes: 2 additions & 1 deletion packages/core/lib/v3/types/public/agent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { ToolSet, ModelMessage, wrapLanguageModel, StreamTextResult } from "ai";
import { LogLine } from "./logs";
import { ClientOptions } from "./model";
import { Page as PlaywrightPage } from "playwright-core";
import { Page as PuppeteerPage } from "puppeteer-core";
import { Page as PatchrightPage } from "patchright-core";
Expand Down Expand Up @@ -86,7 +87,7 @@ export interface AgentExecutionOptions<

export interface AgentHandlerOptions {
modelName: string;
clientOptions?: Record<string, unknown>;
clientOptions?: ClientOptions;
userProvidedInstructions?: string;
experimental?: boolean;
}
Expand Down
61 changes: 55 additions & 6 deletions packages/core/lib/v3/types/public/model.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,42 @@
import type { ClientOptions as AnthropicClientOptions } from "@anthropic-ai/sdk";
import type { ClientOptions as AnthropicClientOptionsBase } from "@anthropic-ai/sdk";
import type { GoogleVertexProviderSettings as GoogleVertexProviderSettingsBase } from "@ai-sdk/google-vertex";
import type { LanguageModelV2 } from "@ai-sdk/provider";
import type { ClientOptions as OpenAIClientOptions } from "openai";
import type { ClientOptions as OpenAIClientOptionsBase } from "openai";
import type { AgentProviderType } from "./agent";

export type OpenAIClientOptions = Omit<
OpenAIClientOptionsBase,
"httpAgent" | "fetch" | "defaultHeaders" | "dangerouslyAllowBrowser"
>;

export type AnthropicClientOptions = Omit<
AnthropicClientOptionsBase,
"httpAgent" | "fetch" | "defaultHeaders" | "dangerouslyAllowBrowser"
>;

export interface GoogleServiceAccountCredentials {
type?: string;
project_id?: string;
private_key_id?: string;
private_key?: string;
client_email?: string;
client_id?: string;
auth_uri?: string;
token_uri?: string;
auth_provider_x509_cert_url?: string;
client_x509_cert_url?: string;
universe_domain?: string;
}

export type GoogleVertexProviderSettings = Omit<
GoogleVertexProviderSettingsBase,
"headers" | "fetch" | "googleAuthOptions"
> & {
googleAuthOptions?: {
credentials?: GoogleServiceAccountCredentials;
};
};

export type AnthropicJsonSchemaObject = {
definitions?: {
MySchema?: {
Expand All @@ -23,9 +57,7 @@ export interface LLMTool {

export type AISDKProvider = (modelName: string) => LanguageModelV2;
// Represents a function that takes options (like apiKey) and returns an AISDKProvider
export type AISDKCustomProvider = (options: {
apiKey: string;
}) => AISDKProvider;
export type AISDKCustomProvider = (options: ClientOptions) => AISDKProvider;

export type AvailableModel =
| "gpt-4.1"
Expand Down Expand Up @@ -67,8 +99,25 @@ export type ModelProvider =
| "google"
| "aisdk";

export type ClientOptions = (OpenAIClientOptions | AnthropicClientOptions) & {
export type ClientOptions = (
| OpenAIClientOptions
| AnthropicClientOptions
| GoogleVertexProviderSettings
) & {
apiKey?: string;
provider?: AgentProviderType;
/** OpenAI organization ID */
organization?: string;
/** Delay between agent actions in ms */
waitBetweenActions?: number;
/** Anthropic thinking budget for extended thinking */
thinkingBudget?: number;
/** Environment type for CUA agents (browser, mac, windows, ubuntu) */
environment?: string;
/** Max images for Microsoft FARA agent */
maxImages?: number;
/** Temperature for model inference */
temperature?: number;
};

export type ModelConfiguration =
Expand Down
5 changes: 3 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"peerDependencies": {
"deepmerge": "^4.3.1",
"dotenv": "^16.4.5",
"zod": "3.25.76 || 4.1.8"
"zod": "^3.25.76 || ^4.1.8"
},
"dependencies": {
"@ai-sdk/provider": "^2.0.0",
Expand All @@ -65,6 +65,7 @@
"@ai-sdk/cerebras": "^1.0.25",
"@ai-sdk/deepseek": "^1.0.23",
"@ai-sdk/google": "^2.0.23",
"@ai-sdk/google-vertex": "^3.0.70",
"@ai-sdk/groq": "^2.0.24",
"@ai-sdk/mistral": "^2.0.19",
"@ai-sdk/openai": "^2.0.53",
Expand All @@ -87,7 +88,7 @@
"tsx": "^4.10.5",
"typescript": "^5.2.2",
"vitest": "^4.0.8",
"zod": "3.25.76 || 4.1.8"
"zod": "^3.25.76 || ^4.1.8"
},
"repository": {
"type": "git",
Expand Down
Loading