- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1.2k
azure/bedrock api integration #1048
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
base: main
Are you sure you want to change the base?
azure/bedrock api integration #1048
Conversation
| 
 | 
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.
Greptile Summary
This PR refactors the LLM client architecture to support Azure OpenAI and AWS Bedrock API integrations. The changes focus on standardizing client option handling across different AI providers while maintaining backwards compatibility.
The core changes include:
- Type System Refactoring: Modified ClientOptionstype to include a genericRecord<string, string>union alongside existingOpenAIClientOptionsandAnthropicClientOptions, enabling support for diverse provider-specific configurations
- Client Architecture Updates: Made clientOptionsproperty optional across all LLM client implementations (OpenAIClient,AnthropicClient,CerebrasClient) and removed it from the abstractLLMClientbase class
- Provider System Enhancement: Updated LLMProvider.getAISDKLanguageModel()to accept unifiedClientOptionsparameter instead of separateapiKeyandbaseURLparameters, allowing more flexible provider configuration
- Import Organization: Standardized import ordering across LLM client files, moving error type imports to the top for consistency
- API Key Handling: Simplified API key resolution in the main Stagehand constructor to rely exclusively on environment variables for legacy providers (OpenAI, Anthropic, Google)
These changes integrate with the existing AI SDK framework that supports multiple providers through factory functions, enabling the codebase to accommodate cloud-based AI services that require additional configuration beyond simple API keys (such as regions, resource names, and custom endpoints).
PR Description Notes:
- The PR description is empty and lacks the required "Why", "What Changed", and "Test Plan" sections as outlined in the repository's pull request template
Confidence score: 3/5
- This PR introduces significant architectural changes that could impact existing integrations and require careful testing
- Score reflects the complexity of the type system changes and potential for runtime issues with the loosened type constraints
- Pay close attention to types/model.ts,lib/llm/LLMProvider.ts, andlib/index.tsas they contain the most critical changes
Context used:
Context - We enforce linting and prettier at the CI level, so no code style comments that aren't obvious. (link)
8 files reviewed, 4 comments
        
          
                lib/llm/CerebrasClient.ts
              
                Outdated
          
        
      | @@ -1,5 +1,6 @@ | |||
| import OpenAI from "openai"; | |||
| import { CreateChatCompletionResponseError } from "@/types/stagehandErrors"; | |||
| import type { ClientOptions } from "openai"; | |||
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.
style: Import ClientOptions from openai but use OpenAI.ClientOptions in constructor parameter - consider using consistent type reference
| import type { ClientOptions } from "openai"; | |
| clientOptions?: ClientOptions; | 
        
          
                lib/llm/LLMProvider.ts
              
                Outdated
          
        
      | } | ||
| const provider = creator(providerConfig); | ||
| // Create the provider instance with the custom configuration options | ||
| const provider = creator(modelClientOptions); | 
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.
logic: Type safety concern: ClientOptions is a union type that may not match what the creator function expects, potentially causing runtime errors
# why solves #1060 patch regression of playwright arguments being removed from agent execute response # what changed agent.execute now returns playwright arguments in its response # test plan tested locally
…ms to docs (#1065) # why reflect project id changes in docs # what changed advanced configuration comments # test plan reviewed via mintlify on localhost
# why Easier to use for Custom LLM Clients and keep users up to date with our aisdk file # what changed added export of aisdk to lib/index.ts # test plan build local stagehand, import local AISdkClient, run Azure Stagehand session
…onfigu… (#1073) …ration settings # why Updated docs to match the new fingerprint params in the Browserbase docs here: https://docs.browserbase.com/guides/stealth-customization#customization-options # what changed Update browser configuration docs to reflect the docs changes. # test plan
# why Updating docs to reflect aisdk can be imported directly # what changed The model page # test plan Reviewed page with mintlify dev locally
        
          
                lib/api.ts
              
                Outdated
          
        
      | // Add modelClientOptions as a header if provided | ||
| if (modelClientOptions) { | ||
| defaultHeaders["x-model-client-options"] = | ||
| JSON.stringify(modelClientOptions); | 
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.
why send it as a header? modelClientOptions already gets sent in the payload. A stringified json in a header is probably not the move
# why # what changed # test plan
# why Currently, we do not support stagehand agent within the api # what changed When api is enabled, stagehand agent now routes through the api # test plan Tested locally
# why Currently, using playwright screenshot command is not available when the execution environment is Stagehand. A customer has indicated they would prefer to use Playwright's native screenshot command instead of CDP when using Browserbase as CDP screenshot causes unexpected behavior for their target site. # what changed - added a StagehandScreenshotOptions type with useCDP argument added - extended page type to accept custom stagehand screeenshot options - update screenshot proxy to default useCDP to true if the env is browserbase and use playwright screenshot if false - added eval for screenshot with and without cdp # test plan - tested and confirmed functionality with eval and external example script (not committed)
…1057) # why We want to build a best in class agent in stagehand. Therefore, we need more eval benchmarks. # what changed - Added Web-bench evals dataset - Added a subset of OS World evals - those that can be run in a chrome browser (desktop-based tasks omitted) - added LICENSE noticed to the copied evals tasks - Added ground truth / expected result to some WebVoyager tasks using reference_answer.json from Browser Use public evals repo. Improvements to `pnpm run evals -man` to better describe how to run evals. # test plan Evals should run locally and bb for these new benchmarks.
# why Initial instructions didn't mention uv or pip prerequisites and also didn't mention venv. Fix reduces friction on first timers. # what changed - added link to install uv - added details for initializing venv - adjusted code example respectively # test plan docs change
# why - webpage structure changed, needed to update the xpath in the expected locator
… with LanguageModelV1 + LiteLLM works for python (#1086) # why 1. aisdk not yet available through npm package 2. customLLM provider only works with LanguageModelV1 3. LiteLLM compatible providers are supported in python # what changed 1. change docs to install stagehand from git repo 2. pin versions that use LanguageModelV1 # test plan local test
# why currently we pass stagehand page to agent, this results in our page management having issues when facing new tabs # what changed the stagehand object is now passed instead of stagehandPage # test plan tested locally
# why Our existing screenshot service is a dummy time-based triggered service. It also does not trigger based on any actions of the agent. # what changed Added img hash diff algo (quick check with MSE, verify with SSIM algo) to see if there was an actual UI change and only store ss in the buffer if that is so. Added ss interceptor which copies each screenshot the agent is taking to a buffer (if different enough from the previous ss) to be later used for evals. - There's also a small refactor of the agent initialization config to enable the screenshot collector service to be attached # test plan Tests pass locally --------- Co-authored-by: Miguel <36487034+miguelg719@users.noreply.github.com> Co-authored-by: miguel <miguelg71921@gmail.com>
fc0c9e5    to
    8eccd56      
    Compare
  
    # why To help make sense of eval test cases and results # what changed Added metadata to eval runs, cleaned deprecated code # test plan
# why # what changed # test plan
# why anthropic released a new sota computer use model # what changed added claude-sonnet-4-5-20250929 as a model to the list # test plan ran evals
        
          
                lib/api.ts
              
                Outdated
          
        
      | this.logger({ | ||
| category: "execute", | ||
| message: `Executing ${method} with args: ${JSON.stringify(args)}`, | ||
| level: 1, | 
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.
maybe level 2
| const result = await this.api.act({ | ||
| ...observeResult, | ||
| frameId: this.rootFrameId, | ||
| modelClientOptions: this.stagehand["modelClientOptions"], | 
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.
is this required?
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.
We will need this once we add self-healing
| result = await this.api.extract<T>({ frameId: this.rootFrameId }); | ||
| result = await this.api.extract<T>({ | ||
| frameId: this.rootFrameId, | ||
| modelClientOptions: this.stagehand["modelClientOptions"], | 
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.
is this required?
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.
Yes because otherwise it doesn't get sent to the API. We need this param on all api calls now
| message: | ||
| "No Amazon Bedrock authentication credentials found. Please provide credentials via modelClientOptions (accessKeyId/secretAccessKey or bearerToken) or environment variables (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY or AWS_BEARER_TOKEN_BEDROCK)", | ||
| level: 0, | ||
| }); | 
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.
should we throw here
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.
It would throw once they make an LLM call. We let people use stagehand without an LLM so I figured we just print a warning for now. Down to change it tho
Why
Custom AI SDK tools and MCP integrations weren't working properly with
Anthropic CUA - parameters were empty {} and tools weren't tracked.
What Changed
- Convert Zod schemas to JSON Schema before sending to Anthropic (using
zodToJsonSchema)
- Track custom tool calls in the actions array
- Silence "Unknown tool name" warnings for custom tools
Test Plan
Tested with examples file. 
Parameters passed correctly ({"city":"San Francisco"} instead of {})
Custom tools execute and appear in actions array
No warnings
    # why To improve context # what changed Added current page and url to the system prompt # test plan
# why To inform the user throughout the agent execution process # what changed Added logs to tool calls, and on the stagehand agent handler # test plan - [x] tested locally
# why # what changed # test plan
# why anthropic released a new sota computer use model # what changed added claude-sonnet-4-5-20250929 as a model to the list # test plan ran evals
Why
Custom AI SDK tools and MCP integrations weren't working properly with
Anthropic CUA - parameters were empty {} and tools weren't tracked.
What Changed
- Convert Zod schemas to JSON Schema before sending to Anthropic (using
zodToJsonSchema)
- Track custom tool calls in the actions array
- Silence "Unknown tool name" warnings for custom tools
Test Plan
Tested with examples file. 
Parameters passed correctly ({"city":"San Francisco"} instead of {})
Custom tools execute and appear in actions array
No warnings
    # why To improve context # what changed Added current page and url to the system prompt # test plan
# why To inform the user throughout the agent execution process # what changed Added logs to tool calls, and on the stagehand agent handler # test plan - [x] tested locally
why
Need to support Azure/Bedrock and all other AI SDK providers that have more than just an
apiKeyparameter.what changed
Allowed free input of
modelClientOptionsand added logic for authenticating with AWS for Bedrock usage.test plan