Repository navigation
fix(v3): set additionalProperties false on nullable act action schema - #3150
Open
miguelg719 wants to merge 2 commits into
Open
miguelg719 wants to merge 2 commits into
miguelg719 wants to merge 2 commits into
Conversation
OpenAI strict structured outputs require additionalProperties: false on every object. The AI SDK converter used by generateObject omits it for the object inside the nullable action's anyOf, so act requests through AI SDK OpenAI models fail with invalid_json_schema. Set it via .meta() so only the JSON schema changes; parsing still strips unknown keys.
🦋 Changeset detectedLatest commit: 8c3658a 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 |
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Architecture diagram
sequenceDiagram
participant C as Client
participant A as act() (inference.ts)
participant S as Zod Schema
participant AI as AI SDK converter
participant O as OpenAI API
Note over C,O: Act Tool Schema Generation Flow
C->>A: call act() with instruction
A->>A: Build Zod schema with nullable action
A->>S: Apply .meta() with additionalProperties: false
Note over A,S: Only affects JSON schema output,<br/>not runtime parsing
alt AI SDK client (strictJsonSchema: true)
A->>AI: Convert schema
AI->>S: Generate JSON schema
S-->>AI: Schema with additionalProperties: false
AI->>O: Send request
Note over O: OpenAI validates schema
alt Valid schema
O-->>AI: 200 OK with generated content
AI->>A: Return content
A->>A: Parse with original Zod schema
Note over A: Parsing strips unknown keys<br/>(does not reject them)
A-->>C: Return parsed action
end
else Direct provider client
A->>S: Convert with toJsonSchema
S-->>A: Schema with additionalProperties: false
Note over A: Schema already includes the flag
end
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
zod is a peer dependency (^3.25 || ^4). Under Zod 3 the root import has no .meta(), so act() threw while building its schema. The Zod 3 converter already emits additionalProperties: false, so skip .meta() there.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
actfails on OpenAI models routed through the AI SDK client (for exampleopenai/gpt-4.1-nano) with:AISdkClientsends OpenAI requests withstrictJsonSchema: true, and OpenAI strict mode requiresadditionalProperties: falseon every object.generateObjectconverts the Zod schema with the AI SDK's own converter, which leaves that field off the object inside the nullableaction'sanyOf. The direct provider clients usetoJsonSchemaand already emit it.This is what fails
server/v3/integration/v3/actandserver/v3/integration/v3/agentExecute(the variables tests return an empty field because the agent'sacttool call 400s). See #3114.What changed
.meta({ additionalProperties: false })when running on Zod 4.zodis a peer dependency (^3.25 || ^4) and Zod 3 has no.meta(); its converter already emits the field, so the call is skipped there. This changes only the generated JSON schema. Parsing still strips unknown keys, so clients that validate locally (Google, AI SDK providers without strict mode, custom clients) keep accepting responses with extra fields..strict()was considered and rejected because it would make those responses fail validation.act()builds its schema under a Zod 3 peer.Test plan
act-response-schemaunit tests pass; the AI SDK converter test fails without the fix.act-response-schema-zod3(mockszodwithzod/v3) passes; without the guard it fails withactionSchema.meta is not a function.inference-temperatureunit tests pass.generateObjectcall with@ai-sdk/openaigpt-4.1-nanoandstrictJsonSchema: true: without the fix it returns the 400 above; with the fix it returns a valid action.Summary by cubic
Fixes
actcalls failing on OpenAI models routed through the AI SDK client. OpenAI strict mode requiresadditionalProperties: falseon every object, and the AI SDK schema converter omitted it inside the nullableaction'sanyOf, producing aninvalid_json_schema400.additionalProperties: falsevia.meta()so only the generated JSON schema changes; parsing still strips unknown keys, so clients that validate locally keep accepting responses with extra fields..meta()only under Zod 4 sincezodis a peer dependency (^3.25 || ^4) and its Zod 3 import lacks the method; the Zod 3 converter already emits the field.toJsonSchemaconverters, including the Zod 3 path.Written for commit 8c3658a. Summary will update on new commits.