Skip to content

feat(provider/google): support JSON Schema for structured outputs via useResponseJsonSchema - #18325

Open
onatozmenn wants to merge 1 commit into
vercel:mainfrom
onatozmenn:feat/google-response-json-schema
Open

feat(provider/google): support JSON Schema for structured outputs via useResponseJsonSchema#18325
onatozmenn wants to merge 1 commit into
vercel:mainfrom
onatozmenn:feat/google-response-json-schema

Conversation

@onatozmenn

Copy link
Copy Markdown

Background

Fixes #6494.

Gemini structured outputs currently go out as generationConfig.responseSchema, which is a subset of the OpenAPI 3.0 spec rather than JSON Schema. That subset does not cover unions or records, so z.union / z.record schemas either fail with errors like response_schema.properties[occupation].type: must be specified or force users to disable structured outputs entirely (structuredOutputs: false), losing constrained decoding.

Gemini 2.5 and later support submitting JSON Schema through generationConfig.responseJsonSchema, which is mutually exclusive with responseSchema and requires responseMimeType (API reference, guide).

Summary

Adds a useResponseJsonSchema provider option to @ai-sdk/google:

  • when true, the response format schema is sent unchanged as generationConfig.responseJsonSchema instead of being converted to the OpenAPI subset for generationConfig.responseSchema
  • the two fields are never sent together, and responseMimeType keeps being set as before
  • defaults to false, so existing requests are unchanged
  • structuredOutputs: false still wins and suppresses both fields

This unblocks unions, records and recursive schemas for object generation on Gemini 2.5+ without giving up structured outputs.

const { output } = await generateText({
  model: google('gemini-2.5-flash'),
  providerOptions: {
    google: {
      useResponseJsonSchema: true,
    } satisfies GoogleLanguageModelOptions,
  },
  output: Output.object({
    schema: z.object({
      name: z.string(),
      contact: z.union([
        z.object({ type: z.literal('email'), value: z.string() }),
        z.object({ type: z.literal('phone'), value: z.string() }),
      ]),
    }),
  }),
  prompt: 'Generate an example person for testing.',
});

The schema is forwarded as-is (including $schema), matching how the official js-genai SDK routes JSON Schema payloads to this field.

Contributor Credit

End-to-End Verification

Verified through the provider request-body tests, which assert the exact JSON sent to :generateContent:

  • useResponseJsonSchema: true produces generationConfig.responseJsonSchema with the untouched anyOf union schema and no responseSchema
  • useResponseJsonSchema: true combined with structuredOutputs: false sends neither schema field
  • all pre-existing structured-output snapshots are unchanged, confirming the default path is untouched

pnpm --filter @ai-sdk/google exec vitest --config vitest.node.config.js --run src/google-language-model.test.ts → 177 passed. Type check and oxlint on the touched files are clean.

Checklist

  • All commits are signed (PRs with unsigned commits cannot be merged)
  • Tests have been added / updated (for bug fixes / features)
  • Documentation has been added / updated (for bug fixes / features)
  • A patch changeset for relevant packages has been added (for bug fixes / features - run pnpm changeset in the project root)
  • I have reviewed this pull request (self-review)

Future Work

The Gemini API exposes the same escape hatch for tool inputs via FunctionDeclaration.parametersJsonSchema. Wiring that up would let tool input schemas use unions and records too; it was left out here to keep this change focused on structured outputs.

Send structured output schemas via generationConfig.responseJsonSchema instead of the OpenAPI 3.0 subset, enabling unions, records and recursive schemas on Gemini 2.5+.
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.

Support JSON schema for Gemini 2.5

1 participant