Skip to content

Commit 4fe9a72

Browse files
bbclankershrey150claudeci-testmonadoid
authored
[STG-1573] Add providerOptions for extensible model auth (#1822)
## Summary - Add `providerOptions` bag to model config schema for provider-specific auth (Bedrock, Vertex, future providers) without polluting the shared schema with vendor-specific fields - Make `modelApiKey` optional so providers with non-API-key auth (e.g. AWS SigV4) can work without it - Server stores `modelClientOptions` from session start and reuses them on subsequent act/observe/extract/execute calls — SDKs don't need to reimplement this logic - Send `modelClientOptions` (including `providerOptions`) in the session start request body; server merges stored + per-request config ## What this enables - **Bedrock**: pass `region`, `accessKeyId`, `secretAccessKey`, `sessionToken` via `providerOptions` - **Vertex**: pass `project`, `location`, `googleAuthOptions` via `providerOptions` - **Future providers**: any provider with non-standard auth just adds fields to `providerOptions` — zero schema or server changes needed ## Architecture ``` SDK Server AI SDK ───────────────────────── ───────────────────────── ────────────── modelClientOptions: { Stores in session, createAmazonBedrock({ apiKey?, merges on each request, apiKey, providerOptions: { ──► passes to V3 constructor ──► region, region, accessKeyId, accessKeyId, Server is vendor-agnostic: secretAccessKey, ... just passes providerOptions ... } through unchanged }) } ``` ## Linked PRs - core: browserbase/core#8004 ## Testing <img width="694" height="945" alt="image" src="https://github.com/user-attachments/assets/39dc4bd2-4008-4776-bcdb-cf3b5eefc726" /> <img width="748" height="641" alt="image" src="https://github.com/user-attachments/assets/ab1c6bcf-322b-4e78-9a96-9dbc5045ba02" /> --------- Co-authored-by: Shrey Pandya <shrey@browserbase.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: ci-test <ci-test@example.com> Co-authored-by: monadoid <sam.finton@gmail.com>
1 parent d39fe98 commit 4fe9a72

33 files changed

Lines changed: 2646 additions & 175 deletions

.changeset/green-mugs-explain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@browserbasehq/stagehand": patch
3+
---
4+
5+
Restore public variable schema support and align Bedrock provider config validation coverage after the main-branch rebase.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* This example shows how to run Stagehand with Amazon Bedrock using
3+
* a short-term Bedrock API key.
4+
*
5+
* Required env vars:
6+
* - AWS_REGION
7+
* - BEDROCK_API_KEY
8+
*
9+
* Optional env vars:
10+
* - BEDROCK_MODEL_ID (defaults to amazon.nova-pro-v1:0)
11+
*
12+
* Example command:
13+
* AWS_REGION=us-east-1 BEDROCK_API_KEY=... pnpm --filter @browserbasehq/stagehand example -- bedrock_api_key
14+
*/
15+
import { Stagehand } from "../lib/v3/index.js";
16+
import { z } from "zod";
17+
18+
const region = process.env.AWS_REGION;
19+
const apiKey = process.env.BEDROCK_API_KEY;
20+
const modelId = process.env.BEDROCK_MODEL_ID ?? "amazon.nova-pro-v1:0";
21+
const modelName = `bedrock/${modelId}`;
22+
23+
if (!region) {
24+
throw new Error("Set AWS_REGION before running the Bedrock API key example.");
25+
}
26+
27+
if (!apiKey) {
28+
throw new Error(
29+
"Set BEDROCK_API_KEY before running the Bedrock API key example.",
30+
);
31+
}
32+
33+
async function main() {
34+
const stagehand = new Stagehand({
35+
env: "LOCAL",
36+
verbose: 2,
37+
model: {
38+
modelName,
39+
apiKey,
40+
providerOptions: {
41+
region,
42+
},
43+
},
44+
});
45+
46+
try {
47+
await stagehand.init();
48+
49+
const page = stagehand.context.pages()[0];
50+
await page.goto("https://example.com");
51+
52+
const extraction = await stagehand.extract(
53+
"Extract the page heading and the visible link text.",
54+
z.object({
55+
heading: z.string(),
56+
linkText: z.string(),
57+
}),
58+
);
59+
60+
console.log(
61+
JSON.stringify(
62+
{
63+
authMode: "bedrock-api-key",
64+
modelName,
65+
region,
66+
extraction,
67+
},
68+
null,
69+
2,
70+
),
71+
);
72+
} finally {
73+
await stagehand.close();
74+
}
75+
}
76+
77+
void main();
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* This example shows how to run Stagehand with Amazon Bedrock using
3+
* AWS credentials.
4+
*
5+
* Required env vars:
6+
* - AWS_REGION
7+
* - AWS_ACCESS_KEY_ID
8+
* - AWS_SECRET_ACCESS_KEY
9+
*
10+
* Optional env vars:
11+
* - AWS_SESSION_TOKEN
12+
* - BEDROCK_MODEL_ID (defaults to amazon.nova-pro-v1:0)
13+
*
14+
* Example command:
15+
* AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... pnpm --filter @browserbasehq/stagehand example -- bedrock_aws_credentials
16+
*/
17+
import { Stagehand } from "../lib/v3/index.js";
18+
import { z } from "zod";
19+
20+
const region = process.env.AWS_REGION;
21+
const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
22+
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
23+
const sessionToken = process.env.AWS_SESSION_TOKEN;
24+
const modelId = process.env.BEDROCK_MODEL_ID ?? "amazon.nova-pro-v1:0";
25+
const modelName = `bedrock/${modelId}`;
26+
27+
if (!region) {
28+
throw new Error(
29+
"Set AWS_REGION before running the Bedrock AWS credentials example.",
30+
);
31+
}
32+
33+
if (!accessKeyId || !secretAccessKey) {
34+
throw new Error(
35+
"Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY before running the Bedrock AWS credentials example.",
36+
);
37+
}
38+
39+
async function main() {
40+
const stagehand = new Stagehand({
41+
env: "LOCAL",
42+
verbose: 2,
43+
model: {
44+
modelName,
45+
providerOptions: {
46+
region,
47+
accessKeyId,
48+
secretAccessKey,
49+
...(sessionToken ? { sessionToken } : {}),
50+
},
51+
},
52+
});
53+
54+
try {
55+
await stagehand.init();
56+
57+
const page = stagehand.context.pages()[0];
58+
await page.goto("https://example.com");
59+
60+
const extraction = await stagehand.extract(
61+
"Extract the page heading and the visible link text.",
62+
z.object({
63+
heading: z.string(),
64+
linkText: z.string(),
65+
}),
66+
);
67+
68+
console.log(
69+
JSON.stringify(
70+
{
71+
authMode: "aws-credentials",
72+
modelName,
73+
region,
74+
extraction,
75+
},
76+
null,
77+
2,
78+
),
79+
);
80+
} finally {
81+
await stagehand.close();
82+
}
83+
}
84+
85+
void main();

0 commit comments

Comments
 (0)