Skip to content

[STG-1473] Replace hardcoded provider enum with z.string()#1760

Open
shrey150 wants to merge 1 commit intomainfrom
shrey/stg-1473-replace-provider-enum-with-string
Open

[STG-1473] Replace hardcoded provider enum with z.string()#1760
shrey150 wants to merge 1 commit intomainfrom
shrey/stg-1473-replace-provider-enum-with-string

Conversation

@shrey150
Copy link
Contributor

@shrey150 shrey150 commented Feb 26, 2026

Summary

  • Replaces the hardcoded z.enum(["openai", "anthropic", "google", "microsoft", "bedrock"]) with z.string() in ModelConfigObjectSchema and AgentConfigSchema
  • Widens AgentType from a union literal to string to match
  • Regenerates OpenAPI spec (removes enum constraints from provider fields)

Why

The provider field enum was:

  • Out of sync — 5 providers in the enum vs 14 in AISDK_PROVIDERS (and microsoft was in the enum but not in AISDK_PROVIDERS)
  • Not validated server-side — the server only checks the provider prefix from modelName, never the provider field
  • RedundantLLMProvider.getClient() already rejects unknown providers at runtime
  • A maintenance burden — every new provider required updating the Zod enum, AgentType, AISDK_PROVIDERS, and the AISDKProviders map separately

What doesn't change

  • Server-side validation of modelName prefix against AISDK_PROVIDERS (unchanged)
  • Runtime provider validation in LLMProvider (unchanged)
  • The provider field remains optional — users typically specify provider via modelName prefix

Linear: https://linear.app/browserbase/issue/STG-1473

🤖 Generated with Claude Code


Summary by cubic

Replaced hardcoded provider enums with strings in public schemas to prevent drift and reduce maintenance (STG-1473). No behavior change; runtime and server-side validation remain the same.

  • Refactors
    • provider in ModelConfigObjectSchema and AgentConfigSchema: enum -> string (still optional)
    • AgentType: union literal -> string
    • Regenerated OpenAPI to remove provider enum lists

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

The provider field enum in ModelConfigObjectSchema and AgentConfigSchema
was hardcoded and out of sync with AISDK_PROVIDERS (5 vs 14 providers).
The field is optional, never validated server-side (the server only
checks the modelName prefix), and runtime validation in LLMProvider
already rejects unknown providers.

Switching to z.string() eliminates the need to update schemas every time
a new provider is added.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Feb 26, 2026

🦋 Changeset detected

Latest commit: c18e86b

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

This PR includes changesets to release 3 packages
Name Type
@browserbasehq/stagehand Patch
@browserbasehq/stagehand-server Patch
@browserbasehq/stagehand-evals 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

@github-actions
Copy link
Contributor

github-actions bot commented Feb 26, 2026

✱ Stainless preview builds

This PR will update the stagehand SDKs with the following commit message.

feat: [STG-1473] Replace hardcoded provider enum with z.string()

Edit this comment to update it. It will appear in the SDK's changelogs.

stagehand-openapi studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅

stagehand-kotlin studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅build ✅lint ✅test ✅

stagehand-typescript studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅build ✅lint ✅test ✅

npm install https://pkg.stainless.com/s/stagehand-typescript/d6a69947c60cd9c58b1ccbd789bbf623117852b0/dist.tar.gz
stagehand-ruby studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅lint ✅test ✅

stagehand-python studio · code · diff

generate ✅build ⏳lint ✅test ✅

stagehand-java studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅build ✅lint ✅test ✅

Add the following URL as a Maven source: 'https://pkg.stainless.com/s/stagehand-java/be8de9d84a8c240b3953fff447ec05e808de6705/mvn'
stagehand-go studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅lint ✅test ✅

go get github.com/stainless-sdks/stagehand-go@93ce55c5852fa565bc0915de170e454583e3faee
stagehand-php studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅lint ✅test ✅

stagehand-csharp studio · code · diff

Your SDK build had at least one "warning" diagnostic, but this did not represent a regression.
generate ⚠️build ✅lint ❗test ✅

New diagnostics (1 note)
💡 Name/Renamed: 28 names were renamed due to language constraints, so fallback names will be used instead.

⏳ These are partial results; builds are still running.


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-02-26 01:14:17 UTC

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Removes the hardcoded provider enum (z.enum(["openai", "anthropic", "google", "microsoft", "bedrock"])) from Zod schemas and replaces it with z.string(). This eliminates the maintenance burden of keeping the enum in sync with the 16 providers in AISDK_PROVIDERS and removes redundant validation (runtime validation already occurs in LLMProvider.getClient()).

Key changes:

  • Replaced enum with z.string() in ModelConfigObjectSchema and AgentConfigSchema
  • Widened AgentType from union literal to string
  • Regenerated OpenAPI spec to remove enum constraints from 4 provider field locations
  • Added changeset documenting the patch release

What doesn't change:

  • Server-side validation of modelName prefix against AISDK_PROVIDERS remains unchanged
  • Runtime provider validation in LLMProvider remains unchanged
  • The provider field remains optional

This is a clean refactoring that eliminates an out-of-sync enum (5 providers vs 16 in AISDK_PROVIDERS, plus microsoft was in the enum but not in AISDK_PROVIDERS) and simplifies adding new providers in the future.

Confidence Score: 5/5

  • This PR is safe to merge with no risk
  • The changes are a clean refactoring that removes redundant client-side validation while preserving all runtime validation. The enum was already out of sync (5 providers in enum vs 16 in AISDK_PROVIDERS) and the provider field is optional and not validated server-side. All changes are consistent across Zod schemas and the regenerated OpenAPI spec. No functionality changes or breaking changes.
  • No files require special attention

Important Files Changed

Filename Overview
.changeset/replace-provider-enum-with-string.md Adds changeset documenting the removal of hardcoded provider enum
packages/core/lib/v3/types/public/agent.ts Changes AgentType from union literal to string, removing hardcoded provider restrictions
packages/core/lib/v3/types/public/api.ts Replaces z.enum([...]) with z.string() for provider fields in ModelConfigObjectSchema and AgentConfigSchema
packages/server/openapi.v3.yaml Removes enum constraints from provider fields in 4 locations, regenerated from updated Zod schemas

Last reviewed commit: c18e86b

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

4 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

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.

cubic analysis

1 issue found across 4 files

Confidence score: 3/5

  • Schema change to the provider field in packages/core/lib/v3/types/public/api.ts could be a breaking change to the Stagehand REST API and lacks the required integration test coverage, creating regression risk for clients/servers.
  • Score reflects a medium-severity, user-facing contract change without mandated tests, so there is some risk even if the change is intentional.
  • Pay close attention to packages/core/lib/v3/types/public/api.ts - API schema change needs integration test coverage under packages/server/test.
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:54">
P1: Custom agent: **Any breaking changes to Stagehand REST API client / server implementation must be covered by an integration test under packages/server/test**

This PR changes the `provider` field schema from a strict enum to `z.string()` in both `ModelConfigObjectSchema` and `AgentConfigSchema`, which modifies the public API contract (the OpenAPI spec removes enum constraints). Per the project rule, any breaking changes to shared request/response shapes in `packages/core/**/types/public/api.ts` must be covered by at least one integration test under `packages/server/test/**`. No such test was added or exists.

Consider adding an integration test that exercises the provider field with a value outside the old enum (e.g., `"xai"` or `"deepseek"`) to confirm it is accepted end-to-end.</violation>
</file>

Linked issue analysis

Linked issue: STG-1473: Replace hardcoded provider enum with z.string() in Zod schemas

Status Acceptance criteria Notes
Replace z.enum([...]) with z.string() in ModelConfigObjectSchema provider field (optional) Replaced z.enum with z.string().optional() in ModelConfigObjectSchema
Replace z.enum([...]) with z.string() in AgentConfigSchema provider field (optional) AgentConfigSchema provider changed to .string().optional()
Widen AgentType from union literal to string AgentType changed from union literals to string
Regenerate OpenAPI spec to remove enum constraints from provider fields OpenAPI enum entries removed for provider fields
Ensure provider field remains optional in schemas Provider fields still marked .optional() in both schemas
Add changelog/changeset documenting the change Added .changeset file describing the patch
Do not change server-side validation of modelName prefix or runtime LLMProvider validation No diffs touching server-side validation or LLMProvider
Architecture diagram
sequenceDiagram
    participant Client as Public API / SDK User
    participant Schema as Zod Schema (ModelConfig)
    participant Server as Server Logic
    participant Provider as LLMProvider Utility

    Note over Client,Provider: Request Handling Flow

    Client->>Schema: POST /execute with { provider, modelName }
    
    rect rgb(23, 37, 84)
    Note right of Schema: CHANGED: Schema no longer<br/>restricts provider to<br/>hardcoded enum list.
    Schema->>Schema: Validate provider as z.string().optional()
    end
    
    Schema-->>Server: Validated Config Object
    
    Server->>Server: Extract provider prefix from modelName
    Note over Server: e.g. "anthropic" from "anthropic/claude-3"

    Server->>Provider: getClient(extractedProvider)
    
    alt Provider exists in AISDK_PROVIDERS
        Provider->>Provider: Initialize specific AI SDK client
        Provider-->>Server: Client Instance
        Server-->>Client: 200 OK (Execution Result)
    else Provider not supported at runtime
        Provider-->>Server: Throw "Unsupported Provider" Error
        Server-->>Client: 400 Bad Request
    end

    Note over Server,Provider: Maintenance Flow (Internal)
    Note right of Provider: NEW: Adding a provider now only<br/>requires updating AISDK_PROVIDERS<br/>map (no schema/OpenAPI changes).
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

"AI provider for the model (or provide a baseURL endpoint instead)",
example: "openai",
}),
provider: z.string().optional().meta({
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 26, 2026

Choose a reason for hiding this comment

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

P1: Custom agent: Any breaking changes to Stagehand REST API client / server implementation must be covered by an integration test under packages/server/test

This PR changes the provider field schema from a strict enum to z.string() in both ModelConfigObjectSchema and AgentConfigSchema, which modifies the public API contract (the OpenAPI spec removes enum constraints). Per the project rule, any breaking changes to shared request/response shapes in packages/core/**/types/public/api.ts must be covered by at least one integration test under packages/server/test/**. No such test was added or exists.

Consider adding an integration test that exercises the provider field with a value outside the old enum (e.g., "xai" or "deepseek") to confirm it is accepted end-to-end.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/lib/v3/types/public/api.ts, line 54:

<comment>This PR changes the `provider` field schema from a strict enum to `z.string()` in both `ModelConfigObjectSchema` and `AgentConfigSchema`, which modifies the public API contract (the OpenAPI spec removes enum constraints). Per the project rule, any breaking changes to shared request/response shapes in `packages/core/**/types/public/api.ts` must be covered by at least one integration test under `packages/server/test/**`. No such test was added or exists.

Consider adding an integration test that exercises the provider field with a value outside the old enum (e.g., `"xai"` or `"deepseek"`) to confirm it is accepted end-to-end.</comment>

<file context>
@@ -51,14 +51,11 @@ export const LocalBrowserLaunchOptionsSchema = z
-          "AI provider for the model (or provide a baseURL endpoint instead)",
-        example: "openai",
-      }),
+    provider: z.string().optional().meta({
+      description:
+        "AI provider for the model (or provide a baseURL endpoint instead)",
</file context>
Fix with Cubic

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.

1 participant