fix: enable structured outputs for all providers that support it#1944
fix: enable structured outputs for all providers that support it#1944monadoid merged 1 commit intoeconnrefusedfixfrom
Conversation
🦋 Changeset detectedLatest commit: 256bafd The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 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 |
There was a problem hiding this comment.
1 issue found across 13 files
Confidence score: 4/5
- This PR looks safe to merge overall, with a focused moderate-risk issue in a test file rather than production runtime code.
- In
packages/core/tests/unit/element-id-regression.test.ts, thevi.mockspecifier missing.jsmay not match the ESM import, which can cause the mock to silently not apply and weaken regression protection. - Given severity 5/10 (with high confidence), this is a real correctness concern for test behavior, but it appears limited in scope and not strongly merge-blocking.
- Pay close attention to
packages/core/tests/unit/element-id-regression.test.ts- align mock/import specifiers (including.js) so ESM mocking applies reliably.
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/tests/unit/element-id-regression.test.ts">
<violation number="1" location="packages/core/tests/unit/element-id-regression.test.ts:10">
P2: The `vi.mock` path is missing the `.js` extension, inconsistent with the actual import on line 7 and the other `vi.mock` on line 15. In ESM mode, mismatched specifiers can cause the mock to silently not apply.
(Based on your team's feedback about requiring explicit .js extensions on all relative ESM import specifiers.) [FEEDBACK_USED]</violation>
</file>
Architecture diagram
sequenceDiagram
participant Handler as Act/Observe Handler
participant Inf as Inference Layer
participant LLM as LLM Client (OpenAI/AISDK)
participant External as External LLM API
participant Resolver as NEW: Model Action Resolver
participant Snap as Snapshot Storage
Note over Handler,Snap: Runtime Flow for Element Interaction
Handler->>Snap: captureHybridSnapshot()
Snap-->>Handler: combinedTree, xpathMap (encoded keys)
Handler->>Inf: act() / observe()
Note over Inf,LLM: Uses modelActResponseSchema / modelActionSchema
Inf->>LLM: createChatCompletion(schema)
LLM->>External: POST /completions (Strict JSON Mode)
Note right of External: CHANGED: Returns structured target<br/>{frameOrdinal, backendNodeId}
External-->>LLM: JSON Response
LLM-->>Inf: Typed ModelAction
Inf-->>Handler: Typed ModelAction
Handler->>Resolver: NEW: resolveModelAction(action, xpathMap)
rect rgb(240, 240, 240)
Note over Resolver: Internal Mapping Logic
Resolver->>Resolver: NEW: Encode target ref to "frame-node" string
Resolver->>Resolver: Lookup XPath in map via encoded string
alt method is dragAndDrop
Resolver->>Resolver: NEW: Resolve destination ref to XPath
end
end
Resolver-->>Handler: Resolved Action (with XPath selector)
alt Action valid
Handler->>Handler: performUnderstudyMethod(selector)
else Element/XPath not found
Handler-->>Handler: Handle missing element (Self-heal/Retry)
end
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
There was a problem hiding this comment.
1 issue found across 18 files (changes from recent commits).
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/external_clients/aisdk.ts">
<violation number="1" location="packages/core/lib/v3/external_clients/aisdk.ts:140">
P1: `response.output` can be `undefined` when `Output.object()` parsing fails, but it's returned directly as `data` without a null check. Unlike `generateObject` (which throws on schema mismatch), `generateText` with `Output.object` returns `undefined` on parse failure. This silently passes `undefined` to callers that expect a valid object, undermining the PR's goal of stricter schema enforcement.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
There was a problem hiding this comment.
3 issues found across 18 files (changes from recent commits).
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/external_clients/aisdk.ts">
<violation number="1">
P2: Generation parameters (`temperature`, `maxOutputTokens`, `topP`, `frequencyPenalty`, `presencePenalty`) are no longer forwarded to `generateObject`. Any caller-specified values for these options will be silently ignored, potentially producing non-deterministic or unexpectedly long outputs.</violation>
<violation number="2">
P1: Removed null safety on `options.tools`. Since `tools` is optional in `ChatCompletionOptions`, this will throw `TypeError: options.tools is not iterable` when no tools are provided.</violation>
</file>
<file name="packages/core/lib/v3/llm/aisdk.ts">
<violation number="1" location="packages/core/lib/v3/llm/aisdk.ts:167">
P1: Regression: `azure`, `vertex`, and `cerebras` provider options were dropped when replacing `buildStructuredProviderOptions` with the inline switch. These three providers will no longer receive their structured-output flags (`strictJsonSchema`/`structuredOutputs`), which can cause `generateObject` to fail for users on those providers.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
|
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 rerun pls |
@monadoid I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 4 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Architecture diagram
sequenceDiagram
participant Core as Stagehand / Core
participant Client as AISdkClient
participant AISDK as Vercel AI SDK
participant API as LLM Provider API
Note over Core,API: Structured Output Request Flow
Core->>Client: createChatCompletion(options)
Client->>Client: NEW: inferProviderName(modelId)
Note over Client: NEW: Map provider-specific <br/>structured output flags
alt provider is openai | azure | cerebras
Client->>Client: Set strictJsonSchema: true
else provider is google | vertex | groq
Client->>Client: Set structuredOutputs: true
else provider is mistral
Client->>Client: Set structuredOutputs: true & strictJsonSchema: true
else provider is anthropic
Client->>Client: Set structuredOutputMode: "auto"
end
opt provider is openai
Client->>Client: CHANGED: Merge reasoningEffort & textVerbosity <br/>into providerOptions.openai
end
Client->>AISDK: CHANGED: generateObject() with providerOptions
AISDK->>API: Request with native structured output parameters
alt Provider Success
API-->>AISDK: Valid JSON response
AISDK-->>Client: Typed Object
Client-->>Core: Chat Completion Result
else Provider Error / Validation Failure
API-->>AISDK: Error response
AISDK-->>Client: Error
Client-->>Core: Throw Error / Fallback
end
Why
This PR is meant to add structured-output support across the provider paths we use, while preserving the existing model-facing act/observe identifier shape.
What Changed
elementId/ encoded ID format for act and observe, including the existing^\\d+-\\d+$validation.Test Plan
Added passing tests