-
Notifications
You must be signed in to change notification settings - Fork 1.6k
2/2 Implement explicit model gateway #2440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
monadoid
wants to merge
5
commits into
add-explicit-model-gateway-protocol
from
implement-model-gateway
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
a749a31
Add model routing protocol
monadoid e916922
Implement model gateway
monadoid 63fbb89
Accept open provider model names at runtime
monadoid 3f40429
Merge model gateway protocol updates
monadoid 5800c9e
Fix model gateway routing and coverage
monadoid File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import type { BrowserbaseRegion } from "../../protocol/types.js"; | ||
|
|
||
| /** Stagehand API base URL per Browserbase region. */ | ||
| const REGION_API_URLS: Record<BrowserbaseRegion, string> = { | ||
| "us-west-2": "https://api.stagehand.browserbase.com", | ||
| "us-east-1": "https://api.use1.stagehand.browserbase.com", | ||
| "eu-central-1": "https://api.euc1.stagehand.browserbase.com", | ||
| "ap-southeast-1": "https://api.apse1.stagehand.browserbase.com", | ||
| }; | ||
|
|
||
| const DEFAULT_REGION: BrowserbaseRegion = "us-west-2"; | ||
|
|
||
| /** Resolves the regional Stagehand API endpoint for a Browserbase session. */ | ||
| export function apiUrlForRegion(region: BrowserbaseRegion | undefined): string { | ||
|
monadoid marked this conversation as resolved.
|
||
| return `${REGION_API_URLS[region ?? DEFAULT_REGION]}/v1`; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { createOpenAI } from "@ai-sdk/openai"; | ||
| import type { LanguageModel } from "ai"; | ||
| import type { StagehandInitParams } from "../../protocol/types.js"; | ||
| import { apiUrlForRegion } from "../clients/stagehandApi.js"; | ||
| import type { BrowserbaseModelTarget } from "./modelTarget.js"; | ||
|
|
||
| export type GatewayContext = { | ||
| apiUrl: string; | ||
| apiKey: string; | ||
| sessionId: string; | ||
| }; | ||
|
|
||
| /** Builds the Browserbase gateway context for a Browserbase-backed session. */ | ||
| export function buildGatewayContext(initParams: StagehandInitParams): GatewayContext | undefined { | ||
| const sessionId = initParams.browser?.sessionId; | ||
| if (!initParams.apiKey || !sessionId) return undefined; | ||
| return { | ||
| apiUrl: apiUrlForRegion(initParams.browser?.region), | ||
| apiKey: initParams.apiKey, | ||
| sessionId, | ||
| }; | ||
| } | ||
|
|
||
| /** Creates an AI SDK Responses model backed by Browserbase Model Gateway. */ | ||
| export function createGatewayLanguageModel( | ||
|
monadoid marked this conversation as resolved.
|
||
| target: BrowserbaseModelTarget, | ||
| gateway: GatewayContext, | ||
| ): LanguageModel { | ||
| return createOpenAI({ | ||
| apiKey: gateway.apiKey, | ||
| baseURL: `${gateway.apiUrl}/llm`, | ||
|
monadoid marked this conversation as resolved.
|
||
| headers: { | ||
| "x-bb-api-key": gateway.apiKey, | ||
| "x-bb-session-id": gateway.sessionId, | ||
| }, | ||
| }).responses(target.modelName); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| import type { | ||
| BrowserbaseModelConfig, | ||
| CustomModelConfig, | ||
| DirectModelConfig, | ||
| ModelConfig, | ||
| } from "../../protocol/types.js"; | ||
|
|
||
| export type DirectModelTarget = { | ||
| type: "direct"; | ||
| modelName: string; | ||
| apiKey: string; | ||
| headers?: Record<string, string>; | ||
| }; | ||
|
|
||
| export type BrowserbaseModelTarget = { | ||
| type: "browserbase"; | ||
| modelName: string; | ||
| }; | ||
|
|
||
| export type OpenAICompatibleModelTarget = { | ||
| type: "openai-compatible"; | ||
| modelName: string; | ||
| baseURL: string; | ||
| apiKey?: string; | ||
| headers?: Record<string, string>; | ||
| }; | ||
|
|
||
| export type ModelTarget = DirectModelTarget | BrowserbaseModelTarget | OpenAICompatibleModelTarget; | ||
|
|
||
| function isBrowserbaseModel(config: ModelConfig): config is BrowserbaseModelConfig { | ||
| return config.modelName.startsWith("browserbase/"); | ||
| } | ||
|
|
||
| function isOpenAICompatibleModel(config: ModelConfig): config is CustomModelConfig { | ||
| return "baseURL" in config; | ||
| } | ||
|
|
||
| function isDirectModel(config: ModelConfig): config is DirectModelConfig { | ||
| return "apiKey" in config && !isOpenAICompatibleModel(config); | ||
| } | ||
|
|
||
| /** Resolves the public model-name namespace into the server's execution target. */ | ||
| export function resolveModelTarget(config: ModelConfig): ModelTarget { | ||
| if (isOpenAICompatibleModel(config)) { | ||
| return { | ||
| type: "openai-compatible", | ||
| modelName: config.modelName, | ||
| baseURL: config.baseURL, | ||
| apiKey: config.apiKey, | ||
| headers: config.headers, | ||
| }; | ||
| } | ||
|
|
||
| if (isBrowserbaseModel(config)) { | ||
| return { | ||
| type: "browserbase", | ||
| modelName: config.modelName.slice("browserbase/".length), | ||
| }; | ||
| } | ||
|
|
||
| if (isDirectModel(config)) { | ||
| return { | ||
| type: "direct", | ||
| modelName: config.modelName, | ||
| apiKey: config.apiKey, | ||
| headers: config.headers, | ||
| }; | ||
| } | ||
|
|
||
| throw new Error("Model configuration did not resolve to a supported inference target"); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { createOpenAICompatible } from "@ai-sdk/openai-compatible"; | ||
| import type { LanguageModel } from "ai"; | ||
| import type { OpenAICompatibleModelTarget } from "./modelTarget.js"; | ||
|
|
||
| /** Creates an OpenAI Chat Completions-compatible model for a caller-controlled endpoint. */ | ||
| export function createOpenAICompatibleLanguageModel( | ||
|
monadoid marked this conversation as resolved.
|
||
| target: OpenAICompatibleModelTarget, | ||
| ): LanguageModel { | ||
| return createOpenAICompatible({ | ||
| name: "openai-compatible", | ||
| apiKey: target.apiKey, | ||
| baseURL: target.baseURL, | ||
| headers: target.headers, | ||
| }).chatModel(target.modelName); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3: Constructing
Stagehand(model="browserbase/...", model_api_key=...)or passingmodel_headersnow raises a raw Pydantic extra-field validation error. Browserbase gateway models have no per-model connection fields; reject those options explicitly with the SDK's argument-validation path (or otherwise handle them) before expandingconnection.Prompt for AI agents