[STG-1473] Replace hardcoded provider enum with z.string()#1760
[STG-1473] Replace hardcoded provider enum with z.string()#1760
Conversation
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 detectedLatest commit: c18e86b The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 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 |
✱ Stainless preview buildsThis PR will update the Edit this comment to update it. It will appear in the SDK's changelogs. ✅ stagehand-openapi studio · code · diff
✅ stagehand-kotlin studio · code · diff
✅ stagehand-typescript studio · code · diff
✅ stagehand-ruby studio · code · diff
✅ stagehand-java studio · code · diff
✅ stagehand-go studio · code · diff
✅ stagehand-php studio · code · diff
✅ stagehand-csharp studio · code · diff
⏳ 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. |
Greptile SummaryRemoves the hardcoded provider enum ( Key changes:
What doesn't change:
This is a clean refactoring that eliminates an out-of-sync enum (5 providers vs 16 in Confidence Score: 5/5
Important Files Changed
Last reviewed commit: c18e86b |
There was a problem hiding this comment.
cubic analysis
1 issue found across 4 files
Confidence score: 3/5
- Schema change to the
providerfield inpackages/core/lib/v3/types/public/api.tscould 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 underpackages/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).
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({ |
There was a problem hiding this comment.
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>
Summary
z.enum(["openai", "anthropic", "google", "microsoft", "bedrock"])withz.string()inModelConfigObjectSchemaandAgentConfigSchemaAgentTypefrom a union literal tostringto matchWhy
The
providerfield enum was:AISDK_PROVIDERS(andmicrosoftwas in the enum but not inAISDK_PROVIDERS)modelName, never theproviderfieldLLMProvider.getClient()already rejects unknown providers at runtimeAgentType,AISDK_PROVIDERS, and theAISDKProvidersmap separatelyWhat doesn't change
modelNameprefix againstAISDK_PROVIDERS(unchanged)LLMProvider(unchanged)providerfield remains optional — users typically specify provider viamodelNameprefixLinear: 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.
Written for commit c18e86b. Summary will update on new commits. Review in cubic