diff --git a/.changeset/orcarouter-provider.md b/.changeset/orcarouter-provider.md
new file mode 100644
index 0000000000..ce056bdffc
--- /dev/null
+++ b/.changeset/orcarouter-provider.md
@@ -0,0 +1,9 @@
+---
+"@browserbasehq/stagehand": minor
+"@browserbasehq/stagehand-extension": minor
+"@browserbasehq/stagehand-protocol": minor
+"@browserbasehq/stagehand-python": minor
+"@browserbasehq/stagehand-go": minor
+---
+
+feat(providers): add OrcaRouter as a first-class model provider
diff --git a/.env.example b/.env.example
index a402c75d66..edcd0c2461 100644
--- a/.env.example
+++ b/.env.example
@@ -1,5 +1,9 @@
OPENAI_API_KEY=""
BROWSERBASE_API_KEY=""
+# OrcaRouter (OpenAI-compatible gateway): https://www.orcarouter.ai
+# Use model names like "orcarouter/auto" with an ORCAROUTER_API_KEY.
+# ORCAROUTER_API_KEY="sk-orca-..."
+
# Optional: set this only if Chrome cannot be detected automatically.
# CHROME_PATH=""
diff --git a/packages/docs/v4/configuration/models.mdx b/packages/docs/v4/configuration/models.mdx
index 4a6cb4bb82..79348ddf7c 100644
--- a/packages/docs/v4/configuration/models.mdx
+++ b/packages/docs/v4/configuration/models.mdx
@@ -328,7 +328,7 @@ defer func() { err = errors.Join(err, client.Close(ctx)) }()
-Model names for the providers below carry a `provider/` prefix, and the provider must be one of the five. Stagehand ships a list of known model IDs per provider and validates the full name when you call `Stagehand.create()` or pass a per-call override, so a name it does not recognize fails before any request reaches the provider. Upgrade the SDK to pick up newly released models. The prefix is never optional: to reach an Azure OpenAI deployment, a self-hosted model, or anything else outside those five providers, use the [bring-your-own-LLM callback](#custom-models).
+Model names for the providers below carry a `provider/` prefix, and the provider must be one of the first-class providers listed on this page. Stagehand ships a list of known model IDs per provider and validates the full name when you call `Stagehand.create()` or pass a per-call override, so a name it does not recognize fails before any request reaches the provider. Upgrade the SDK to pick up newly released models. The prefix is never optional: to reach an Azure OpenAI deployment, a self-hosted model, or anything else outside those first-class providers, use the [bring-your-own-LLM callback](#custom-models).
@@ -668,6 +668,74 @@ Commonly used: `cerebras/gpt-oss-120b`, `cerebras/qwen-3-235b-a22b-instruct-2507
[View all supported Cerebras models →](https://inference-docs.cerebras.ai/models/overview)
+
+
+
+
+```typescript
+import { browserbase, Stagehand } from "@browserbasehq/stagehand";
+
+const stagehand = await Stagehand.create({
+ browser: await browserbase.launch({ apiKey: process.env.BROWSERBASE_API_KEY }),
+ model: {
+ modelName: "orcarouter/auto",
+ apiKey: process.env.ORCAROUTER_API_KEY,
+ },
+});
+```
+
+
+
+```python
+import os
+
+from stagehand import Stagehand, browserbase
+
+browser = await browserbase.launch(api_key=os.environ["BROWSERBASE_API_KEY"])
+
+stagehand = await Stagehand.create(
+ browser=browser,
+ model="orcarouter/auto",
+ model_api_key=os.environ["ORCAROUTER_API_KEY"],
+)
+```
+
+
+
+```go
+apiKey := os.Getenv("BROWSERBASE_API_KEY")
+modelAPIKey := os.Getenv("ORCAROUTER_API_KEY")
+model := stagehand.ModelConfig{
+ ModelName: "orcarouter/auto",
+ APIKey: &modelAPIKey,
+}
+
+browser, err := stagehand.LaunchBrowserbase(ctx, stagehand.BrowserbaseLaunchOptions{
+ APIKey: apiKey,
+})
+if err != nil {
+ return err
+}
+
+client, err := stagehand.Create(ctx, stagehand.CreateOptions{
+ Browser: browser,
+ Model: &model,
+})
+if err != nil {
+ return err
+}
+defer func() { err = errors.Join(err, client.Close(ctx)) }()
+```
+
+
+
+[OrcaRouter](https://www.orcarouter.ai) is an OpenAI-compatible gateway that fronts hundreds of frontier and open-weight models behind a single `sk-orca-` key. Use a gateway routing alias like `orcarouter/auto` or a vendor-prefixed model like `orcarouter/deepseek/deepseek-v4-pro`. It also runs gateway-level, zero-trust security for AI agents on the same endpoint — screening every prompt/response and governing every tool call on a default-deny basis, with no application code changes.
+
+Commonly used: `orcarouter/auto`, `orcarouter/fusion`, `orcarouter/fusion-flash`, `orcarouter/fusion-mini`, `orcarouter/deepseek/deepseek-v4-pro`.
+
+[View all supported OrcaRouter models →](https://www.orcarouter.ai)
+
+
---
@@ -1570,7 +1638,7 @@ defer func() { err = errors.Join(err, client.Close(ctx)) }()
-There is no base URL option. A model configuration always names one of the five supported providers, so Azure OpenAI deployments, self-hosted models, and any other custom endpoint go through the [bring-your-own-LLM callback](#custom-models) instead, where you own the client, the transport, and the credentials.
+There is no base URL option. A model configuration always names one of the first-class providers, so Azure OpenAI deployments, self-hosted models, and any other custom endpoint go through the [bring-your-own-LLM callback](#custom-models) instead, where you own the client, the transport, and the credentials.
---
@@ -1746,6 +1814,7 @@ You pinned a `model` but gave it no `apiKey`, and the browser is not a Browserba
| OpenAI | `OPENAI_API_KEY` |
| Groq | `GROQ_API_KEY` |
| Cerebras | `CEREBRAS_API_KEY` |
+| OrcaRouter | `ORCAROUTER_API_KEY` |
| Bring your own LLM | None; your callback owns its credentials |
@@ -1756,7 +1825,7 @@ You pinned a `model` but gave it no `apiKey`, and the browser is not a Browserba
**Solutions:**
- Use the `provider/model` format: `openai/gpt-5`. The prefix is required; bare model names are rejected
-- Use one of the five supported providers: `openai`, `anthropic`, `google`, `groq`, `cerebras`
+- Use one of the first-class providers: `openai`, `anthropic`, `google`, `groq`, `cerebras`, `orcarouter`
- Check the model ID against the lists on this page. Stagehand validates the whole name, so a typo fails at `Stagehand.create()` rather than on the first inference
- Upgrade the SDK if the model shipped after your installed version
- For a provider outside that list, use the [bring-your-own-LLM callback](#custom-models)
diff --git a/packages/evals/initStagehand.ts b/packages/evals/initStagehand.ts
index dd7d60faa5..cd143063ff 100644
--- a/packages/evals/initStagehand.ts
+++ b/packages/evals/initStagehand.ts
@@ -35,6 +35,7 @@ const PROVIDER_API_KEY_ENV: Record = {
google: ["GOOGLE_GENERATIVE_AI_API_KEY", "GEMINI_API_KEY"],
groq: ["GROQ_API_KEY"],
cerebras: ["CEREBRAS_API_KEY"],
+ orcarouter: ["ORCAROUTER_API_KEY"],
};
type StagehandLogEvent = Parameters>[0];
diff --git a/packages/evals/tests/tui/welcomeStatus.test.ts b/packages/evals/tests/tui/welcomeStatus.test.ts
index b94a58b328..e8d2f90e55 100644
--- a/packages/evals/tests/tui/welcomeStatus.test.ts
+++ b/packages/evals/tests/tui/welcomeStatus.test.ts
@@ -16,6 +16,7 @@ const PROVIDER_KEYS = [
"BB_API_KEY",
"BB_PROJECT_ID",
"BRAINTRUST_API_KEY",
+ "ORCAROUTER_API_KEY",
];
const savedEnv: Record = {};
@@ -160,6 +161,12 @@ describe("hasZeroProviderKeys", () => {
__resetPackageEnvCacheForTests();
expect(hasZeroProviderKeys(snapshotEnv())).toBe(false);
});
+
+ it("false with only OrcaRouter set", () => {
+ process.env.ORCAROUTER_API_KEY = "sk-orca-test";
+ __resetPackageEnvCacheForTests();
+ expect(hasZeroProviderKeys(snapshotEnv())).toBe(false);
+ });
});
describe("renderInlineWarning", () => {
diff --git a/packages/evals/tui/welcomeStatus.ts b/packages/evals/tui/welcomeStatus.ts
index 1e49466778..16bfad501d 100644
--- a/packages/evals/tui/welcomeStatus.ts
+++ b/packages/evals/tui/welcomeStatus.ts
@@ -45,6 +45,7 @@ export type EnvSnapshot = {
google: GoogleKeyEntry;
browserbase: BrowserbaseKeyEntry;
braintrust: ProviderKeyEntry;
+ orcarouter: ProviderKeyEntry;
};
// ---------------------------------------------------------------------------
@@ -166,6 +167,7 @@ export function snapshotEnv(): EnvSnapshot {
google: googleEntry(),
browserbase: browserbaseEntry(),
braintrust: providerEntry("BRAINTRUST_API_KEY"),
+ orcarouter: providerEntry("ORCAROUTER_API_KEY"),
};
}
@@ -177,7 +179,10 @@ export function snapshotEnv(): EnvSnapshot {
export function hasZeroProviderKeys(s: EnvSnapshot): boolean {
return (
- s.openai.state === "missing" && s.anthropic.state === "missing" && s.google.state === "missing"
+ s.openai.state === "missing" &&
+ s.anthropic.state === "missing" &&
+ s.google.state === "missing" &&
+ s.orcarouter.state === "missing"
);
}
diff --git a/packages/extension/llm/LLMProvider.ts b/packages/extension/llm/LLMProvider.ts
index 34d1214eca..684383f0e3 100644
--- a/packages/extension/llm/LLMProvider.ts
+++ b/packages/extension/llm/LLMProvider.ts
@@ -21,6 +21,15 @@ const AISDKProviderFactories: Record = {
google: createGoogleGenerativeAI as AISDKProviderFactory,
groq: createGroq as AISDKProviderFactory,
cerebras: createCerebras as AISDKProviderFactory,
+ // OrcaRouter is an OpenAI-compatible gateway; the createOpenAI factory talks
+ // to it once baseURL points at the gateway.
+ orcarouter: createOpenAI as AISDKProviderFactory,
+};
+
+// Default base URL for each OpenAI-compatible gateway provider, applied when the
+// caller does not set one explicitly.
+const DEFAULT_BASE_URL: Partial> = {
+ orcarouter: "https://api.orcarouter.ai/v1",
};
type AISDKProviderClientOptions = ClientOptions & Record;
@@ -30,7 +39,7 @@ function parseClientOptions(clientOptions?: ClientOptions): ClientOptions {
}
export function toAISDKClientOptions(
- _subProvider: ModelProvider,
+ subProvider: ModelProvider,
clientOptions?: ClientOptions,
): AISDKProviderClientOptions | undefined {
const { auth, providerOptions: _providerOptions, ...rest } = parseClientOptions(clientOptions);
@@ -41,6 +50,12 @@ export function toAISDKClientOptions(
...apiKeyOption,
};
+ // OpenAI-compatible gateways route through the Responses API; give them a
+ // sensible base URL when the caller did not pin one.
+ if (DEFAULT_BASE_URL[subProvider] && !options.baseURL) {
+ options.baseURL = DEFAULT_BASE_URL[subProvider];
+ }
+
return Object.values(options).some((value) => value !== undefined && value !== null)
? options
: undefined;
@@ -63,7 +78,12 @@ export function getAISDKLanguageModel(
const model =
subProvider === "openai"
? (provider as ReturnType).responses(subModelName)
- : provider(subModelName);
+ : subProvider === "orcarouter"
+ ? // OrcaRouter routes on the full gateway-qualified model name
+ // (`orcarouter/fusion`, `orcarouter/deepseek/deepseek-v4-pro`), so
+ // send the complete model name rather than the stripped suffix.
+ (provider as ReturnType).responses(`orcarouter/${subModelName}`)
+ : provider(subModelName);
if (middleware) {
return wrapLanguageModel({ model: model as never, middleware });
diff --git a/packages/extension/llm/aiSdkClient.ts b/packages/extension/llm/aiSdkClient.ts
index 720884301b..5a6d839b04 100644
--- a/packages/extension/llm/aiSdkClient.ts
+++ b/packages/extension/llm/aiSdkClient.ts
@@ -17,6 +17,7 @@ import {
LLMGenerateResultSchema,
ModelProviderSchema,
OpenAIModelIdSchema,
+ OrcaRouterModelNameSchema,
} from "../../protocol/schemas.js";
import type { LLMGenerateParams, LLMGenerateResult, ModelConfig } from "../../protocol/types.js";
@@ -163,6 +164,18 @@ export function createAiSdkLanguageModel(
return createGroq(connection)(GroqModelIdSchema.parse(modelId));
case "cerebras":
return createCerebras(connection)(CerebrasModelIdSchema.parse(modelId));
+ case "orcarouter": {
+ const orcaRouter = createOpenAI({
+ ...connection,
+ baseURL: "https://api.orcarouter.ai/v1",
+ });
+ // OrcaRouter routes on the full gateway-qualified model name
+ // (`orcarouter/fusion`), so re-attach the provider prefix.
+ const orcaRouterModelName = OrcaRouterModelNameSchema.parse(config.modelName);
+ return params?.stopSequences?.length
+ ? orcaRouter.chat(orcaRouterModelName)
+ : orcaRouter.responses(orcaRouterModelName);
+ }
}
}
diff --git a/packages/extension/llm/aisdk.ts b/packages/extension/llm/aisdk.ts
index 50a78c215e..2f978c0855 100644
--- a/packages/extension/llm/aisdk.ts
+++ b/packages/extension/llm/aisdk.ts
@@ -191,6 +191,14 @@ export class AISdkClient extends LLMClient {
strictJsonSchema: true,
};
break;
+ case "orcarouter":
+ // OrcaRouter is an OpenAI-compatible gateway served through the
+ // createOpenAI factory, so its provider options ride under the openai
+ // key and the Responses API applies strict JSON schema.
+ providerOptions.openai = {
+ strictJsonSchema: true,
+ };
+ break;
case "mistral":
providerOptions.mistral = {
structuredOutputs: true,
diff --git a/packages/extension/tests/ai-sdk-client.test.ts b/packages/extension/tests/ai-sdk-client.test.ts
index b5590d80a4..14a3da7e6b 100644
--- a/packages/extension/tests/ai-sdk-client.test.ts
+++ b/packages/extension/tests/ai-sdk-client.test.ts
@@ -47,6 +47,12 @@ describe("AI SDK language models", () => {
modelId: "gpt-oss-120b",
provider: "cerebras.chat",
},
+ {
+ name: "OrcaRouter",
+ modelName: "orcarouter/auto" as const,
+ modelId: "orcarouter/auto",
+ provider: "openai.responses",
+ },
])("creates a direct $name model from its validated configuration", (testCase) => {
const model = createAiSdkLanguageModel({
modelName: testCase.modelName,
@@ -75,6 +81,21 @@ describe("AI SDK language models", () => {
});
});
+ it("uses Chat Completions for OrcaRouter requests with stop sequences", () => {
+ const model = createAiSdkLanguageModel(
+ {
+ modelName: "orcarouter/fusion",
+ apiKey: "provider-secret",
+ },
+ { stopSequences: ["STOP"] },
+ );
+
+ expect(model).toMatchObject({
+ provider: "openai.chat",
+ modelId: "orcarouter/fusion",
+ });
+ });
+
it("routes a configured provider model through the AI SDK client", async () => {
vi.mocked(generateText).mockResolvedValue({
text: "Four",
diff --git a/packages/extension/tests/model-resolution.test.ts b/packages/extension/tests/model-resolution.test.ts
index 56ae23d69a..ddc8bfb942 100644
--- a/packages/extension/tests/model-resolution.test.ts
+++ b/packages/extension/tests/model-resolution.test.ts
@@ -7,6 +7,7 @@ import {
ModelConfigSchema,
ModelNameSchema,
OpenAIModelIdSchema,
+ OrcaRouterModelIdSchema,
} from "../../protocol/schemas.js";
import type { StagehandInitParams, StagehandResultMetadata } from "../../protocol/types.js";
import { createStagehandController } from "../controllers/stagehandController.js";
@@ -64,6 +65,7 @@ describe("model configuration", () => {
["google", GoogleModelIdSchema.options],
["groq", GroqModelIdSchema.options],
["cerebras", CerebrasModelIdSchema.options],
+ ["orcarouter", OrcaRouterModelIdSchema.options],
] as const;
for (const [provider, modelIds] of providers) {
@@ -77,6 +79,11 @@ describe("model configuration", () => {
expect(ModelNameSchema.safeParse("groq/openai/gpt-oss-120b").success).toBe(true);
});
+ it("accepts an OrcaRouter gateway alias and a vendor-prefixed model", () => {
+ expect(ModelNameSchema.safeParse("orcarouter/auto").success).toBe(true);
+ expect(ModelNameSchema.safeParse("orcarouter/deepseek/deepseek-v4-pro").success).toBe(true);
+ });
+
it("rejects a model from an unsupported provider", () => {
expect(ModelNameSchema.safeParse("bedrock/anthropic.claude-sonnet-v1:0").success).toBe(false);
});
diff --git a/packages/integrations/core/src/facade/config.ts b/packages/integrations/core/src/facade/config.ts
index 14c5ab9a57..d0ba6c5b91 100644
--- a/packages/integrations/core/src/facade/config.ts
+++ b/packages/integrations/core/src/facade/config.ts
@@ -109,6 +109,8 @@ function providerApiKey(provider: string | undefined, env: NodeJS.ProcessEnv): s
return nonEmpty(env.GROQ_API_KEY);
case "cerebras":
return nonEmpty(env.CEREBRAS_API_KEY);
+ case "orcarouter":
+ return nonEmpty(env.ORCAROUTER_API_KEY);
default:
return undefined;
}
diff --git a/packages/integrations/core/tests/facade-contract.test.ts b/packages/integrations/core/tests/facade-contract.test.ts
index 20bc0829db..38df274b33 100644
--- a/packages/integrations/core/tests/facade-contract.test.ts
+++ b/packages/integrations/core/tests/facade-contract.test.ts
@@ -104,4 +104,25 @@ describe("Stagehand facade contract", () => {
}).success,
).toBe(false);
});
+
+ it("resolves an OrcaRouter model key from STAGEHAND_MODEL_NAME", () => {
+ const config = stagehandFacadeConfigFromEnv({
+ BROWSERBASE_API_KEY: "bb-test",
+ STAGEHAND_MODEL_NAME: "orcarouter/auto",
+ ORCAROUTER_API_KEY: "sk-orca-test",
+ });
+ expect(config.stagehand.model).toMatchObject({
+ modelName: "orcarouter/auto",
+ apiKey: "sk-orca-test",
+ });
+ });
+
+ it("rejects an unsupported OrcaRouter model name", () => {
+ expect(() =>
+ stagehandFacadeConfigFromEnv({
+ BROWSERBASE_API_KEY: "bb-test",
+ STAGEHAND_MODEL_NAME: "orcarouter/not-a-real-model",
+ }),
+ ).toThrow(/Unsupported STAGEHAND_MODEL_NAME/);
+ });
});
diff --git a/packages/protocol/schemas.ts b/packages/protocol/schemas.ts
index d528aaf320..a08ac734eb 100644
--- a/packages/protocol/schemas.ts
+++ b/packages/protocol/schemas.ts
@@ -179,8 +179,38 @@ export const CerebrasModelIdSchema = z
])
.meta({ id: "CerebrasModelId" });
+// OrcaRouter is an OpenAI-compatible gateway that fronts hundreds of models
+// (frontier + open weights) behind a single `sk-orca-` key. The gateway's own
+// routing aliases live under the `orcarouter/` prefix; upstream models exposed
+// by https://api.orcarouter.ai/v1/models are addressable by their vendor name.
+// Like Groq, model IDs may themselves contain slashes, so `orcarouter/auto`
+// and `orcarouter/deepseek/deepseek-v4-pro` are both valid full model names.
+export const OrcaRouterModelIdSchema = z
+ .enum([
+ "auto",
+ "free",
+ "fusion",
+ "fusion-flash",
+ "fusion-mini",
+ "open-code",
+ "code-review",
+ "deepseek/deepseek-v4-flash",
+ "deepseek/deepseek-v4-pro",
+ "openai/gpt-5.6-luna",
+ "openai/gpt-5.6-sol",
+ "openai/gpt-5.6-terra",
+ "anthropic/claude-sonnet-5",
+ "anthropic/claude-fable-5",
+ "anthropic/claude-haiku-4.5",
+ "google/gemini-3.1-flash-lite",
+ "google/gemini-3.6-flash",
+ "qwen/qwen3.6-flash",
+ "qwen/qwen3.8-27b",
+ ])
+ .meta({ id: "OrcaRouterModelId" });
+
export const ModelProviderSchema = z
- .enum(["openai", "anthropic", "google", "groq", "cerebras"])
+ .enum(["openai", "anthropic", "google", "groq", "cerebras", "orcarouter"])
.meta({ id: "ModelProvider" });
export const OpenAIModelNameSchema = z
@@ -198,6 +228,9 @@ export const GroqModelNameSchema = z
export const CerebrasModelNameSchema = z
.templateLiteral(["cerebras/", CerebrasModelIdSchema])
.meta({ id: "CerebrasModelName" });
+export const OrcaRouterModelNameSchema = z
+ .templateLiteral(["orcarouter/", OrcaRouterModelIdSchema])
+ .meta({ id: "OrcaRouterModelName" });
export const ModelNameSchema = z
.union([
@@ -206,6 +239,7 @@ export const ModelNameSchema = z
GoogleModelNameSchema,
GroqModelNameSchema,
CerebrasModelNameSchema,
+ OrcaRouterModelNameSchema,
])
.meta({
id: "ModelName",
diff --git a/packages/protocol/stagehand.v4.json b/packages/protocol/stagehand.v4.json
index 277938c331..23d0f8d085 100644
--- a/packages/protocol/stagehand.v4.json
+++ b/packages/protocol/stagehand.v4.json
@@ -1300,6 +1300,10 @@
"type": "string",
"pattern": "^cerebras\\/(llama3\\.1-8b|gpt-oss-120b|qwen-3-235b-a22b-instruct-2507|qwen-3-235b-a22b-thinking-2507|zai-glm-4\\.6|zai-glm-4\\.7)$"
},
+ "OrcaRouterModelName": {
+ "type": "string",
+ "pattern": "^orcarouter\\/(auto|free|fusion|fusion-flash|fusion-mini|open-code|code-review|deepseek\\/deepseek-v4-flash|deepseek\\/deepseek-v4-pro|openai\\/gpt-5\\.6-luna|openai\\/gpt-5\\.6-sol|openai\\/gpt-5\\.6-terra|anthropic\\/claude-sonnet-5|anthropic\\/claude-fable-5|anthropic\\/claude-haiku-4\\.5|google\\/gemini-3\\.1-flash-lite|google\\/gemini-3\\.6-flash|qwen\\/qwen3\\.6-flash|qwen\\/qwen3\\.8-27b)$"
+ },
"ModelName": {
"anyOf": [
{
@@ -1316,6 +1320,9 @@
},
{
"$ref": "#/$defs/CerebrasModelName"
+ },
+ {
+ "$ref": "#/$defs/OrcaRouterModelName"
}
],
"description": "An explicitly supported model name with its provider prefix"
diff --git a/packages/protocol/types.ts b/packages/protocol/types.ts
index a03658f7a2..ac53692926 100644
--- a/packages/protocol/types.ts
+++ b/packages/protocol/types.ts
@@ -218,6 +218,8 @@ import type {
ThinkingEffortSchema,
OpenAIModelIdSchema,
OpenAIModelNameSchema,
+ OrcaRouterModelIdSchema,
+ OrcaRouterModelNameSchema,
VariablePrimitiveSchema,
VariablesSchema,
VariableValueSchema,
@@ -256,11 +258,13 @@ export type AnthropicModelId = z.infer;
export type GoogleModelId = z.infer;
export type GroqModelId = z.infer;
export type CerebrasModelId = z.infer;
+export type OrcaRouterModelId = z.infer;
export type OpenAIModelName = z.infer;
export type AnthropicModelName = z.infer;
export type GoogleModelName = z.infer;
export type GroqModelName = z.infer;
export type CerebrasModelName = z.infer;
+export type OrcaRouterModelName = z.infer;
export type ModelConfig = z.infer;
export type ModelName = z.infer;
export type ModelProvider = z.infer;
diff --git a/packages/sdk-go/internal/extensionassets/stagehand-extension.zip b/packages/sdk-go/internal/extensionassets/stagehand-extension.zip
index c4f5890ddf..4615afc69d 100644
Binary files a/packages/sdk-go/internal/extensionassets/stagehand-extension.zip and b/packages/sdk-go/internal/extensionassets/stagehand-extension.zip differ
diff --git a/packages/sdk-go/models.gen.go b/packages/sdk-go/models.gen.go
index b1996ca9e4..65d2878721 100644
--- a/packages/sdk-go/models.gen.go
+++ b/packages/sdk-go/models.gen.go
@@ -1196,6 +1196,8 @@ type ObserveResult struct {
type OpenAIModelName string
+type OrcaRouterModelName string
+
type PageAddInitScriptParams struct {
// PageID corresponds to the JSON schema field "page_id".
PageID string `json:"page_id"`
@@ -2549,6 +2551,9 @@ type generatedModelCatalog struct {
// OpenAIModelName corresponds to the JSON schema field "OpenAIModelName".
OpenAIModelName *OpenAIModelName `json:"OpenAIModelName,omitempty,omitzero"`
+ // OrcaRouterModelName corresponds to the JSON schema field "OrcaRouterModelName".
+ OrcaRouterModelName *OrcaRouterModelName `json:"OrcaRouterModelName,omitempty,omitzero"`
+
// PageAddInitScriptParams corresponds to the JSON schema field
// "PageAddInitScriptParams".
PageAddInitScriptParams *PageAddInitScriptParams `json:"PageAddInitScriptParams,omitempty,omitzero"`
diff --git a/packages/sdk-python/src/stagehand/_generated/input_types.py b/packages/sdk-python/src/stagehand/_generated/input_types.py
index f3cbb05be2..af273c6a9b 100644
--- a/packages/sdk-python/src/stagehand/_generated/input_types.py
+++ b/packages/sdk-python/src/stagehand/_generated/input_types.py
@@ -652,7 +652,10 @@ class NavigationServerAddr(TypedDict):
OpenAIModelName: TypeAlias = str
-ModelName: TypeAlias = OpenAIModelName | AnthropicModelName | GoogleModelName | GroqModelName | CerebrasModelName
+OrcaRouterModelName: TypeAlias = str
+
+
+ModelName: TypeAlias = OpenAIModelName | AnthropicModelName | GoogleModelName | GroqModelName | CerebrasModelName | OrcaRouterModelName
class ModelConfig(TypedDict):
diff --git a/packages/sdk-python/src/stagehand/_generated/models.py b/packages/sdk-python/src/stagehand/_generated/models.py
index b0a81ef0c2..e4d669ce20 100644
--- a/packages/sdk-python/src/stagehand/_generated/models.py
+++ b/packages/sdk-python/src/stagehand/_generated/models.py
@@ -1446,13 +1446,6 @@ class OpenAIModelName(RootModel[StrictStr]):
]
-class ModelName(
- RootModel[Union[OpenAIModelName, AnthropicModelName, GoogleModelName, GroqModelName, CerebrasModelName]]
-):
- root: Union[OpenAIModelName, AnthropicModelName, GoogleModelName, GroqModelName, CerebrasModelName]
- """An explicitly supported model name with its provider prefix"""
-
-
class OperatingSystem(StrEnum):
android = "android"
ios = "ios"
@@ -1461,6 +1454,22 @@ class OperatingSystem(StrEnum):
windows = "windows"
+class OrcaRouterModelName(RootModel[StrictStr]):
+ root: Annotated[
+ StrictStr,
+ Field(
+ pattern="^orcarouter\\/(auto|free|fusion|fusion-flash|fusion-mini|open-code|code-review|deepseek\\/deepseek-v4-flash|deepseek\\/deepseek-v4-pro|openai\\/gpt-5\\.6-luna|openai\\/gpt-5\\.6-sol|openai\\/gpt-5\\.6-terra|anthropic\\/claude-sonnet-5|anthropic\\/claude-fable-5|anthropic\\/claude-haiku-4\\.5|google\\/gemini-3\\.1-flash-lite|google\\/gemini-3\\.6-flash|qwen\\/qwen3\\.6-flash|qwen\\/qwen3\\.8-27b)$"
+ ),
+ ]
+
+
+class ModelName(
+ RootModel[Union[OpenAIModelName, AnthropicModelName, GoogleModelName, GroqModelName, CerebrasModelName, OrcaRouterModelName]]
+):
+ root: Union[OpenAIModelName, AnthropicModelName, GoogleModelName, GroqModelName, CerebrasModelName, OrcaRouterModelName]
+ """An explicitly supported model name with its provider prefix"""
+
+
class Os(StrEnum):
windows = "windows"
mac = "mac"