Skip to content

STG-1758 Migrate AI SDK to v6#1949

Open
monadoid wants to merge 8 commits intomainfrom
STG-1758
Open

STG-1758 Migrate AI SDK to v6#1949
monadoid wants to merge 8 commits intomainfrom
STG-1758

Conversation

@monadoid
Copy link
Copy Markdown
Contributor

@monadoid monadoid commented Apr 2, 2026

Why

We want to use AI SDK v6 so that we can better enforce that the LLMs return data in the correct schema.
This upgrades us to AI SDK v6 so our structured-output paths use the current provider/runtime contract and so Stagehand-owned schemas can take advantage of strict structured outputs where the schema is under our control.

What Changed

I believe this PR does not introduce any breaking changes to our public interface (tests confirm this).

One important note: When a user passes in a zod schema, it is not necessarily compatible with openai structured outputs. Thus, we can't enforce strict mode yet for these calls (future PR for this incoming, but requires breaking changes to our API).

  • migrated the AI-SDK-backed LLM clients from deprecated object-generation flows to AI SDK v6 generateText(..., output: Output.object(...)) while preserving Stagehand's existing LLMParsedResponse and usage shapes
  • kept act, observe, extract metadata, and agent done-tool paths strict
  • preserved compatibility mode for user-supplied extract schemas
  • updated AI SDK token usage handling to read the v6 usage fields and continue returning the legacy snake_case usage payloads Stagehand already exposes
  • had to update ollama-ai-provider-v2 to latest version (which allows it to be a v3 provider, despite the name)
  • added focused regression coverage for extract compatibility, agent usage payload compatibility, and Ollama provider behaviour

Testing

  • wrote regression tests against the old main branch first, verified they passed there, then ran the same assertions again on this branch to confirm there were no behavioural regressions

Summary by cubic

Migrates Stagehand’s LLM integration to AI SDK v6 with strict structured outputs for Stagehand-owned schemas. Preserves the public API, legacy usage shape, and the agent.execute error contract; satisfies STG-1758 and removes custom Ollama shims.

  • Migration

    • Switch to v6 models (LanguageModelV3) and use Output.object via generateText; keep LLMParsedResponse unchanged.
    • Add strictSchema to extraction (default strict for Stagehand-controlled paths); bubble NoObjectGeneratedError from strict paths (act, extract, fillform, done tool).
    • Preserve agent.execute behavior by returning { success: false, error } on tool failures while surfacing strict-output violations.
    • Map v6 usage to legacy snake_case (incl. reasoning and cached tokens); update FlowLogger middleware to spec v3 and guard missing token totals.
    • Only send tools when present and honor tool choice; adapt tools to read { output }; expose a tool wrapper that accepts the legacy toModelOutput(result) signature.
    • Accept LanguageModelV2 via asLanguageModelV3Compat; update provider/middleware types to v3 and preserve requested model id/spec version; export additional public types.
    • Update packages/evals to v6 and keep legacy usage mapping; add regression tests for compat and structured-output error propagation.
  • Dependencies

    • Upgrade ai to v6 and @ai-sdk/provider to ^3.0.8; bump optional providers to their v3/v4 lines.
    • Upgrade Ollama provider to ^3.5.0 and wire it through LLMProvider; refresh pnpm-lock.yaml.

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

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 2, 2026

🦋 Changeset detected

Latest commit: 3f09171

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

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

@monadoid monadoid changed the title STG-1758 Migrate Stagehand AI SDK integration to v6 STG-1758 Migrate AI SDK to v6 Apr 2, 2026
@monadoid monadoid marked this pull request as ready for review April 2, 2026 16:01
Copy link
Copy Markdown
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 33 files

Confidence score: 3/5

  • Potential runtime TypeError in packages/core/lib/v3/flowlogger/FlowLogger.ts when usage lacks v6 sub-objects (inputTokens/outputTokens), which could break logging for some providers
  • Risk is moderate due to a concrete user-facing crash scenario, so this isn’t a trivial merge despite being localized
  • Pay close attention to packages/core/lib/v3/flowlogger/FlowLogger.ts - missing optional chaining may throw when providers return incomplete usage data.
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/flowlogger/FlowLogger.ts">

<violation number="1" location="packages/core/lib/v3/flowlogger/FlowLogger.ts:700">
P1: Missing optional chaining on `inputTokens` / `outputTokens`. If a provider returns `usage` without the expected v6 sub-objects (e.g. `inputTokens` is `undefined`), this will throw `TypeError: Cannot read properties of undefined (reading 'total')`, crashing the LLM call.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant User as User / Stagehand API
    participant V3 as V3 Agent / Handlers
    participant Client as AISdkClient (Adapter)
    participant MW as FlowLogger (Middleware)
    participant AISDK as AI SDK v6 (generateText)
    participant LLM as LLM Provider (OpenAI/Ollama/etc.)

    Note over User,LLM: Structured Output Flow (extract/act/observe)

    User->>V3: extract(instruction, schema)
    
    V3->>V3: NEW: Determine strictSchema flag
    Note right of V3: True for Stagehand schemas<br/>False for user-supplied Zod
    
    V3->>Client: createChatCompletion(options)
    
    Client->>MW: NEW: Intercept call (Spec v3)
    MW->>MW: NEW: logLlmRequest with uuidv7
    
    MW->>AISDK: CHANGED: generateText() with Output.object
    
    AISDK->>LLM: Request with schema
    opt NEW: OpenAI Strict Mode
        AISDK->>LLM: providerOptions: { strictJsonSchema: true }
    end

    alt Success
        LLM-->>AISDK: JSON payload + v6 Usage Data
        AISDK-->>MW: generateText result
        MW-->>Client: Result + v6 Usage
        
        Client->>Client: CHANGED: toLLMUsage()
        Note right of Client: Maps reasoning_tokens &<br/>cached_input_tokens to legacy shape
        
        Client-->>V3: LLMParsedResponse
        V3-->>User: Structured Data + Legacy Usage
    else NEW: NoObjectGeneratedError
        AISDK-->>MW: Error
        MW-->>Client: Error
        Client-->>User: Throw Error (matches legacy behavior)
    end

    Note over User,LLM: Agent Tool Interaction

    V3->>AISDK: execute tool calls
    AISDK->>LLM: tool call request
    LLM-->>AISDK: tool results
    AISDK->>V3: CHANGED: return { output: result }
    Note right of V3: Tool adapters now read<br/>the 'output' property
Loading

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

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai bot commented Apr 6, 2026

You're iterating quickly on this pull request. To help protect your rate limits, cubic has paused automatic reviews on new pushes for now—when you're ready for another review, comment @cubic-dev-ai review.

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