[STG-1852] feat: support hosted model.providerOptions for bedrock and vertex#2031
[STG-1852] feat: support hosted model.providerOptions for bedrock and vertex#2031
Conversation
🦋 Changeset detectedLatest commit: 6f62d1f The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
2 issues found across 10 files
Confidence score: 3/5
- There is moderate merge risk: two medium-severity issues (6/10) with high confidence suggest concrete user-facing behavior problems rather than pure housekeeping.
- In
packages/core/lib/v3/types/public/api.ts, validation issues raised fromSessionStartRequestSchemacan be attached to incorrect paths because nested helpers use object-scopedctx; this can mislead clients/UI about which fields actually failed. - In
packages/core/lib/v3/modelProviderOptions.ts, error text interpolates unsanitizedmodelName, which can leak raw input into user-facing messages and reduce safety/consistency of error handling. - Pay close attention to
packages/core/lib/v3/types/public/api.tsandpackages/core/lib/v3/modelProviderOptions.ts- incorrect validation paths and unsanitized error-message interpolation are the main regression risks.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/core/lib/v3/types/public/api.ts">
<violation number="1" location="packages/core/lib/v3/types/public/api.ts:524">
P2: Validation error paths are incorrect when triggered from `SessionStartRequestSchema`. The `ctx` is scoped to the `SessionStartRequest` object, but `addBedrockAuthIssues` and `getProviderConfigMismatchMessage` add issues with paths like `["providerConfig", "options", "region"]`. Since the data lives at `modelClientOptions.providerConfig.options.region`, error consumers won't be able to locate the offending field.
Consider prefixing the paths with `"modelClientOptions"` when calling from `SessionStartRequestSchema`, or having `validateProviderConfig` accept a path prefix parameter.</violation>
</file>
<file name="packages/core/lib/v3/modelProviderOptions.ts">
<violation number="1" location="packages/core/lib/v3/modelProviderOptions.ts:156">
P2: Custom agent: **Exception and error message sanitization**
User-facing error message reflects unsanitized raw `modelName` input via string interpolation.</violation>
</file>
Architecture diagram
sequenceDiagram
participant User
participant SDK as Stagehand SDK (V3)
participant Lib as modelProviderOptions
participant API as Stagehand API Client
participant Hosted as Stagehand Hosted API
Note over User,Hosted: Session Initialization Flow
User->>SDK: new Stagehand({ model: { providerOptions, ... } })
SDK->>Lib: normalizeClientOptionsForModel()
Note right of Lib: NEW: Normalizes Bedrock/Vertex auth<br/>into runtime options
Lib-->>SDK: normalizedOptions
SDK->>API: init({ modelClientOptions: normalizedOptions })
API->>Lib: toApiModelClientOptions()
Note right of Lib: NEW: Serializes SDK options to<br/>API "providerConfig" wire format
Lib-->>API: apiModelClientOptions
API->>API: CHANGED: Store sessionModelConfig
Note right of API: Retains provider-native auth for<br/>subsequent hosted actions
alt NEW: Bedrock/Vertex with provider auth
API->>Hosted: POST /session/start (body: { modelClientOptions })
Note left of Hosted: Request sent WITHOUT x-model-api-key header
else Standard API Key Auth
API->>Hosted: POST /session/start (header: x-model-api-key)
end
Hosted-->>API: 200 OK (sessionId)
Note over User,Hosted: Execution Flow (e.g., act / extract / observe)
User->>SDK: act({ input })
SDK->>API: act({ input })
API->>API: NEW: ensureModelConfig()
Note right of API: Injects stored sessionModelConfig if<br/>no per-call model override exists
API->>Hosted: POST /act (body: { model: sessionModelConfig, ... })
Note left of Hosted: Ensures provider-native auth persists<br/>on every hosted action
Hosted-->>API: Action Results
API-->>SDK: Results
SDK-->>User: Results
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
There was a problem hiding this comment.
2 issues found across 8 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/core/lib/v3/llm/LLMProvider.ts">
<violation number="1" location="packages/core/lib/v3/llm/LLMProvider.ts:111">
P2: `isStringRecord({})` returns `true` due to vacuous truth on `Array.prototype.every`, so `headers: {}` alone will bypass the Vertex experimental-mode gate. Add an `Object.keys(value).length > 0` check (as you already do for `googleAuthOptions`) to ensure the headers object is non-empty.</violation>
</file>
<file name="packages/core/lib/v3/types/public/api.ts">
<violation number="1" location="packages/core/lib/v3/types/public/api.ts:1240">
P2: Inconsistent `model` field type: every other `model` field in this file accepts `z.union([ModelConfigSchema, z.string()])`, allowing users to pass a plain string model name (e.g. `'openai/gpt-5-nano'`). This field only accepts the object form, so callers who pass a string will get a validation error. It also lacks the `.meta()` description present on all sibling fields.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
|
Re: cubics review summaries and (#2031 (review)) — addressed the valid inline findings in 47826d5a: SessionStartRequest providerConfig issues now use the correct modelClientOptions-prefixed paths, empty Vertex headers no longer satisfy the hosted-provider gate, and NavigateOptionsSchema.model now accepts the same string-or-object contract as the sibling schemas. I left the raw modelName error-message note as-is for the reason in the inline reply: it is a plain-text invalid-argument message, not an HTML/rendering sink, and keeping the quoted model identifier is useful for debugging invalid inputs. |
Linear: https://linear.app/browserbase/issue/STG-1852/support-hosted-provideroptions-for-bedrock-and-vertex-models
Summary
model.providerOptionssupport for Bedrock and Vertex while keeping legacy top-level Vertex fields workingproviderConfigpayloads for Stagehand APIinit()Testing
pnpm --dir packages/core run buildpnpm --dir packages/core run lintpnpm --dir packages/core exec vitest run dist/esm/tests/unit/model-provider-options.test.js dist/esm/tests/unit/api-client-model-config.test.js dist/esm/tests/unit/api-provider-config-schema.test.js dist/esm/tests/unit/public-api/llm-and-agents.test.js dist/esm/tests/unit/llm-middleware.test.jsset -a && source /Users/shrey/Developer/scratchpad/.stagehand-bedrock-local.env && set +a && BROWSERBASE_CONFIG_DIR='' pnpm run reproin/Users/shrey/Developer/scratchpad/stagehand-provideroptions-localStagehandconstructor:The ‘Make America Healthy Again’ Movement Is Cooling on Trump and RepublicansRelated
Summary by cubic
Adds
model.providerOptionsforbedrock/...andvertex/..., serializes provider auth into hostedmodelClientOptions.providerConfig, re-sends the session model config on all hosted actions (includingnavigate), and normalizes hosted model config on the server. Docs include Bedrock/Vertex examples and drop the Vertex experimental requirement when using hosted client options. Meets Linear STG-1852.New Features
model.providerOptionsto hostedmodelClientOptions.providerConfigwith new API schemas (ProviderConfig,ModelClientOptions) and validation.region,accessKeyId,secretAccessKey,sessionToken; promote to local runtime; start sessions withoutx-model-api-keywhen auth is provided.project/location/headersandproviderOptions; normalize headers (includingHeaders); allow serializablegoogleAuthOptions; allow hosted Vertex configs in API mode when client options are provided.act/extract/observe/navigatewhen no per-call model is given;navigateoptions now accept amodel.packages/server-v3): normalize hostedmodeland agent configs vianormalizeApiModelConfig, mappingproviderConfigto SDKproviderOptionsand accepting string models.Bug Fixes
providerConfig.providervsmodelName.region; enforce AWS key pairs (accessKeyIdwithsecretAccessKey);sessionTokenrequires both; headers must be string maps.googleAuthOptionsmust be an object with supported keys only; credential fields must be strings;scopesmust be string or string[]; empty headers are not treated as hosted config.Written for commit 6f62d1f. Summary will update on new commits. Review in cubic