Skip to content

Add support for passing custom headers in clientOptions#1817

Merged
tkattkat merged 1 commit intomainfrom
Add-support-for-passing-custom-headers-in-clientOptions
Mar 12, 2026
Merged

Add support for passing custom headers in clientOptions#1817
tkattkat merged 1 commit intomainfrom
Add-support-for-passing-custom-headers-in-clientOptions

Conversation

@tkattkat
Copy link
Collaborator

@tkattkat tkattkat commented Mar 12, 2026

why

Allow users to pass custom headers in their LLM calls

what changed

Add headers to the model.ts types

test plan


Summary by cubic

Adds headers support to ClientOptions so clients can send custom HTTP headers with every provider request. Useful for auth tokens or routing hints without changing global config.

  • New Features
    • Added headers?: Record<string, string> to ClientOptions in packages/core/lib/v3/types/public/model.ts; headers are sent with each request.
    • No breaking changes; default behavior is unchanged.

Written for commit 424dc1a. Summary will update on new commits. Review in cubic

@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: 424dc1a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@browserbasehq/stagehand Patch
@browserbasehq/browse-cli Patch
@browserbasehq/stagehand-evals Patch
@browserbasehq/stagehand-server-v3 Patch
@browserbasehq/stagehand-server-v4 Patch

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

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 12, 2026

Greptile Summary

This PR exposes a new headers?: Record<string, string> field on the public ClientOptions type, allowing users to inject custom HTTP headers into LLM provider calls. The change is type-only — the actual forwarding relies on existing client constructors already passing clientOptions through to their underlying SDK instances.

Key observations:

  • Works as expected for OpenAI, Anthropic, Cerebras, and Groq clients, which either pass the full clientOptions object or spread it into their SDK constructors (which natively support a headers field).
  • Also works for the AI SDK path (models using the provider/model format), where the full clientOptions is forwarded to the relevant SDK factory function.
  • Silent failure for legacy gemini-* models: GoogleClient.ts constructs GoogleGenAI by extracting only apiKey from clientOptions, discarding all other fields including headers. No error is raised, so users have no indication their headers are being dropped.
  • The changeset correctly marks this as a patch release.

Confidence Score: 3/5

  • Safe to merge for most providers, but headers are silently dropped for legacy Google models without any runtime indication.
  • The type addition itself is correct and the feature works end-to-end for OpenAI, Anthropic, Cerebras, Groq, and AI SDK paths. However, GoogleClient.ts does not forward the new headers field to its underlying GoogleGenAI constructor, creating a silent behavioral mismatch between what the public API advertises and what the Google path actually delivers. This is a logic gap that would confuse users targeting Gemini models.
  • packages/core/lib/v3/llm/GoogleClient.ts — needs to forward clientOptions.headers to the GoogleGenAI constructor to match the behavior of all other provider clients.

Important Files Changed

Filename Overview
packages/core/lib/v3/types/public/model.ts Adds headers?: Record<string, string> to ClientOptions. Works correctly for OpenAI/Anthropic/Cerebras/Groq and the AI SDK path, but GoogleClient.ts only passes apiKey to GoogleGenAI, silently dropping headers for legacy gemini-* models.
.changeset/yellow-cups-swim.md Standard patch-level changeset entry for the new headers support in clientOptions; no issues.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["User sets clientOptions.headers"] --> B{Model path}
    B -->|"provider/model format"| C["getAISDKLanguageModel\ncreator(clientOptions)"]
    C --> D["AI SDK provider factory\n✅ headers forwarded"]
    B -->|"Legacy model name"| E{Provider}
    E -->|"openai / o1 / o3 / gpt-*"| F["new OpenAI(clientOptions)\n✅ headers forwarded"]
    E -->|"anthropic/claude-*"| G["new Anthropic(clientOptions)\n✅ headers forwarded"]
    E -->|"cerebras-*"| H["new OpenAI({...clientOptions})\n✅ headers forwarded"]
    E -->|"groq-*"| I["new OpenAI({...clientOptions})\n✅ headers forwarded"]
    E -->|"gemini-*"| J["new GoogleGenAI({apiKey only})\n❌ headers silently dropped"]
Loading

Last reviewed commit: 424dc1a

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.
Architecture diagram
sequenceDiagram
    participant User as Client Application
    participant SDK as Stagehand SDK
    participant API as LLM Provider (OpenAI/Anthropic)

    Note over User,SDK: Model Initialization / Execution

    User->>SDK: execute(prompt, clientOptions)
    Note right of User: NEW: clientOptions now contains <br/>headers: Record<string, string>

    SDK->>SDK: Prepare request context
    SDK->>SDK: NEW: Merge base headers with custom clientOptions.headers

    SDK->>API: HTTP POST (Completion Request)
    Note right of SDK: Request includes:<br/>1. Standard Auth/Content-Type<br/>2. NEW: Custom User-defined Headers

    alt Successful Request
        API-->>SDK: 200 OK (Response Data)
        SDK-->>User: Model Output
    else Provider Error
        API-->>SDK: 4xx/5xx Error
        SDK-->>User: Error Exception
    end
Loading

@tkattkat tkattkat merged commit 2402a3c into main Mar 12, 2026
186 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants