Skip to content

Conversation

@monadoid
Copy link
Contributor

@monadoid monadoid commented Dec 15, 2025

why

  • Our OpenAPI file was stale and hand-maintained; routes and shapes diverged from reality (e.g., /act and /start payloads).
  • Validation had been disabled; we lacked consistent request/response enforcement and clear error reporting.
  • We were on Zod v3 plus zod-to-json-schema
  • We need generated docs that match the live Zod schemas and a path to stricter, type-safe responses.

what changed

  • Upgraded to zod v4 and removed zod-to-json-schema; we now rely on Zod’s native schemas directly with fastify-zod-openapi.
    • Integrated fastify-zod-openapi + @fastify/swagger/UI
    • Added pnpm gen:openapi (scripts/gen-openapi.ts) to write openapi.v3.yaml from the live app.
    • Added Zod response schemas that mirror our actual envelope ({ success, data: ... }) for start/act/agentExecute/navigate/observe/extract/end so response validation is strict without breaking the API.
    • Improved error handling:
    • Schema formatter + error handler now surface Zod issues (422 for requests, 500 for response serialization) with structured logs

Future stuff:

  • Remove healthz and readiness endpoints
  • Tighten up request / response schemas

test plan

Ran eval suite - passing


Summary by cubic

Generates an OpenAPI 3.1 spec from live Zod v4 schemas with strict request/response validation. /v1/sessions/start now accepts browser.type and can return connectUrl; cdpUrl is removed. Addresses STG-1053.

  • New Features

    • Switched to Zod v4 + fastify-zod-openapi with Swagger UI; OpenAPI is generated from runtime schemas.
    • Added pnpm gen:openapi to write packages/server/openapi.v3.yaml.
    • Centralized API request/response schemas in the client and exported under Stagehand.Api; server routes use these directly.
    • /v1/sessions/start accepts browser.type ("local" | "browserbase") and returns { sessionId, available, connectUrl? }.
    • Standardized { success, data } responses; improved errors (422 on request validation, 500 on response serialization).
    • Health endpoints moved to /healthz and readiness to /readyz.
    • Added /v1/sessions/:id/replay stub.
    • Added SSE streaming via the x-stream-response header.
  • Migration

    • Do not expect cdpUrl from /v1/sessions/start; use connectUrl when present. For Browserbase, pass browserbaseSessionID.
    • Rename localBrowserLaunchOptions.cdpUrl to connectUrl.
    • Expect the { success, data } envelope on all responses.
    • Use /healthz and /readyz instead of the old paths.
    • Run pnpm gen:openapi to refresh the spec.

Written for commit 2ae58ab. Summary will update automatically on new commits.

@changeset-bot
Copy link

changeset-bot bot commented Dec 15, 2025

⚠️ No Changeset found

Latest commit: 2ae58ab

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

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.

1 issue found across 30 files

Prompt for AI agents (all 1 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/core/lib/v3/types/private/api.ts">

<violation number="1" location="packages/core/lib/v3/types/private/api.ts:36">
P2: The `browser` type definition doesn&#39;t match the server schema. In the server, `type` is optional and there are additional fields (`cdpUrl`, `launchOptions`) that the core interface doesn&#39;t expose. Consider aligning the types:
```typescript
browser?: {
  type?: &quot;local&quot; | &quot;browserbase&quot;;
  cdpUrl?: string;
  launchOptions?: Record&lt;string, unknown&gt;;
};
```</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 15, 2025

Greptile Overview

Greptile Summary

This PR modernizes the Stagehand server API by migrating from Zod v3 to v4 and implementing automated OpenAPI spec generation using fastify-zod-openapi. The changes address significant technical debt where the hand-maintained OpenAPI file had become stale and validation was disabled.

Key changes include upgrading the server to use Zod v4 schemas with fastify-zod-openapi for automatic documentation generation, standardizing all API responses to use a { success: true, data: ... } envelope format, and updating the /v1/sessions/start endpoint to return a cdpUrl for direct browser connection. The PR also adds a browser.type parameter to support both local and Browserbase browser selection, moves health endpoints to /healthz and /readyz, and introduces a pnpm gen:openapi script to generate the OpenAPI spec from live schemas.

The migration spans the entire codebase, touching core types, server routes, evaluation systems, and examples to ensure consistency. This enables stricter request/response validation, better error reporting with structured Zod issues, and automatic documentation that stays in sync with the actual API implementation.

Important Files Changed

Filename Score Overview
packages/server/src/server.ts 4/5 Major server refactoring to integrate Zod v4 with fastify-zod-openapi, adds OpenAPI generation and enhanced error handling
packages/server/src/routes/v1/sessions/start.ts 4/5 Significant endpoint redesign to return CDP URLs for direct browser connection and support browser type selection
packages/server/openapi.v3.yaml 5/5 Complete regeneration of OpenAPI spec from live schemas, upgraded to 3.1.0 with standardized response envelopes
packages/core/lib/v3/v3.ts 4/5 Major changes to support API-driven browser connection via CDP URLs instead of local browser launching
packages/server/src/routes/v1/sessions/:id/act.ts 4/5 Migration to Zod v4 with strict validation and standardized response format for the act endpoint
packages/server/src/routes/v1/sessions/:id/extract.ts 4/5 Updated extract route with Zod v4 integration and fastify-zod-openapi schema validation
packages/server/src/routes/v1/sessions/:id/observe.ts 5/5 Clean migration to Zod v4 with proper schema validation and response envelope structure
packages/server/src/routes/v1/sessions/:id/navigate.ts 4/5 Updated navigate route with simplified validation and structured response schema enforcement
packages/server/src/routes/v1/sessions/:id/agentExecute.ts 5/5 Straightforward migration to Zod v4 with standardized response schema validation
packages/server/src/routes/v1/sessions/:id/end.ts 5/5 Simple update to include Zod v4 schema validation for params and response structure
packages/server/src/lib/InMemorySessionStore.ts 5/5 Added validation logic for browserbase sessions with conditional session ID generation
packages/server/scripts/gen-openapi.ts 4/5 New script to automatically generate OpenAPI specs from runtime schemas using fastify-zod-openapi
packages/core/lib/v3/types/private/api.ts 5/5 Added browser type selection and CDP URL support to session management API types
packages/evals/initV3.ts 4/5 Added browser configuration support for evaluation system to work with new API structure
packages/core/lib/v3/api.ts 4/5 Enhanced browser parameter support and improved error handling for API client
packages/server/package.json 4/5 Updated dependencies to support Zod v4, fastify-zod-openapi, and added OpenAPI generation scripts
packages/core/package.json 5/5 Updated Zod dependencies to support both v3 and v4, removed prepare script for better dev workflow

Confidence score: 4/5

  • This PR introduces significant architectural changes but appears well-executed with comprehensive testing and proper migration patterns
  • Score reflects the complexity of the migration across multiple packages and the potential for edge cases in browser connection logic, though the changes follow good practices
  • Pay close attention to packages/server/src/server.ts and packages/core/lib/v3/v3.ts for the new CDP URL connection logic and error handling paths

Sequence Diagram

sequenceDiagram
    participant User
    participant LangchainClient as "Langchain Client"
    participant V3 as "Stagehand V3"
    participant Handler as "Extract Handler"
    participant OpenAI as "OpenAI API"
    participant Page as "Browser Page"
    
    User->>V3: "new Stagehand(config)"
    User->>V3: "init()"
    V3->>Page: "goto('https://news.ycombinator.com')"
    User->>V3: "extract('extract the title of the top story', schema)"
    V3->>Handler: "extract(params)"
    Handler->>Page: "Take screenshot"
    Page-->>Handler: "Screenshot data"
    Handler->>LangchainClient: "Generate completion with schema"
    LangchainClient->>OpenAI: "API call with prompt"
    OpenAI-->>LangchainClient: "Structured response"
    LangchainClient-->>Handler: "Parsed result"
    Handler-->>V3: "Extract result"
    V3-->>User: "{ story: 'top story title' }"
    User->>V3: "act('click the first story')"
    V3->>Handler: "act(instruction)"
    Handler->>Page: "Take screenshot"
    Page-->>Handler: "Screenshot data"
    Handler->>LangchainClient: "Generate action plan"
    LangchainClient->>OpenAI: "API call with instruction"
    OpenAI-->>LangchainClient: "Action response"
    LangchainClient-->>Handler: "Action plan"
    Handler->>Page: "Execute click action"
    Page-->>Handler: "Action result"
    Handler-->>V3: "Act result"
    V3-->>User: "Action completion"
    User->>V3: "close()"
    V3->>Page: "Close browser session"
Loading

greptile-apps[bot]

This comment was marked as resolved.

@monadoid monadoid force-pushed the openapi_spec_generation branch from fd35502 to 5150806 Compare December 15, 2025 21:36
cubic-dev-ai[bot]

This comment was marked as resolved.

cubic-dev-ai[bot]

This comment was marked as resolved.

@pirate
Copy link
Member

pirate commented Dec 19, 2025

I got claude to do a deep-dive review to look for any unintentional changes introduced in api.ts or v3.ts, it caught a few things which I fixed, the final report is:

Screenshot 2025-12-18 at 6 12 21 PM

@pirate pirate requested a review from miguelg719 December 20, 2025 02:00

import { error } from "./response.js";

const INTERNAL_SERVER_ERROR_STATUS_CODE = 500;
Copy link
Collaborator

Choose a reason for hiding this comment

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

not sure if we have the same ts / lints restrictions here, but we should. Would it be useful to use http-status-codes rather than declare these?

verbose?: 0 | 1 | 2;
selfHeal?: boolean;
// V2 compatibility fields - only included because the server imports this type and supports V2
waitForCaptchaSolves?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

waitForCaptchaSolves & actTimeoutMs are both v2 params

@github-actions
Copy link
Contributor

github-actions bot commented Dec 22, 2025

✱ Stainless preview builds

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

feat: [STG-1053] [server] Use fastify-zod-openapi + zod v4 for openapi generation
⚠️ stagehand-csharp studio · conflict

There was a regression in your SDK.

stagehand-php studio · code

Your SDK built successfully.
generate ✅lint ✅test ✅

⚠️ stagehand-python studio · code

There was a regression in your SDK.
generate ✅build ✅lint ❗test ✅

pip install https://pkg.stainless.com/s/stagehand-python/405c6068de29f39d90882b31805cc2785c6b94e0/stagehand-0.0.1-py3-none-any.whl
⚠️ stagehand-ruby studio · code

There was a regression in your SDK.
generate ✅lint ✅test ✅

stagehand-go studio · code

Your SDK built successfully.
generate ✅lint ✅test ✅

go get github.com/stainless-sdks/stagehand-go@00248f34223b4bbb242d76d4f6780d0daeefa467
⚠️ stagehand-kotlin studio · code

There was a regression in your SDK.
generate ⚠️lint ✅test ✅

⚠️ stagehand-typescript studio · code

There was a regression in your SDK.
generate ✅build ✅lint ✅test ❗

npm install https://pkg.stainless.com/s/stagehand-typescript/82de4645275ca6c97c1973ee945fbaa12e74a033/dist.tar.gz
⚠️ stagehand-java studio · code

There was a regression in your SDK.
generate ⚠️lint ✅test ✅

stagehand-cli studio · code

Your SDK built successfully.
generate ✅lint ✅test ⏳


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
Last updated: 2025-12-22 21:59:54 UTC

@monadoid monadoid merged commit cdf946b into main Dec 22, 2025
19 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.

6 participants