Get a daily random issue suggestion from any GitHub repository
This PR adds comprehensive support for propertyOrdering
in the Google provider, allowing developers to control the order of properties in JSON responses from Gemini models. The implementation supports both a simple array format for basic use cases and a nested object format for complex structures.
For basic root-level property ordering, you can use a simple array:
import { google } from '@ai-sdk/google';
import { generateObject } from 'ai';
import { z } from 'zod';
const result = await generateObject({
model: google('gemini-2.0-flash'),
providerOptions: {
google: {
propertyOrdering: ['name', 'age', 'email'], // Clean and simple!
},
},
schema: z.object({
name: z.string(),
age: z.number(),
email: z.string(),
}),
prompt: 'Generate a person profile',
});
// Output will have properties in the specified order:
// { "name": "...", "age": ..., "email": "..." }
For nested structures, use the object format with dot notation:
const result = await generateObject({
model: google('gemini-2.0-flash'),
providerOptions: {
google: {
propertyOrdering: {
'': ['name', 'profile', 'preferences'], // Empty string for root
'profile': ['bio', 'settings', 'contacts'],
'profile.settings': ['theme', 'notifications'], // dot-notation for nested obejcts
'profile.settings.notifications': ['email', 'push'],
'profile.contacts': ['address', 'phone'],
'profile.contacts.address': ['street', 'city'],
'preferences': ['language', 'timezone'],
},
},
},
schema: z.object({
name: z.string(),
profile: z.object({
bio: z.string(),
settings: z.object({
theme: z.string(),
notifications: z.object({
email: z.boolean(),
push: z.boolean(),
}),
}),
contacts: z.object({
address: z.object({
street: z.string(),
city: z.string(),
}),
phone: z.string(),
}),
}),
preferences: z.object({
language: z.string(),
timezone: z.string(),
}),
}),
prompt: 'Generate a comprehensive user profile',
});
Enhanced Type System:
// Supports both formats:
propertyOrdering: z.union([
z.array(z.string()), // Simple: ['name', 'age', 'email']
z.record(z.string(), z.array(z.string())), // Nested: { '': [...], 'profile': [...] }
]).optional();
Smart Format Normalization:
Enhanced convertJSONSchemaToOpenAPISchema
function:
Record<string, string[]>
and string[]
formats
string[]
for simple root-level property ordering and Record<string, string[]>
for nested property ordering.'parent.child'
)OpenAPI Schema Generation: The function converts property ordering definitions into OpenAPI-compliant schemas:
// Input
{ '': ['name', 'profile'], 'profile': ['bio', 'settings'] }
// Generated OpenAPI Schema
{
"type": "object",
"properties": { /* ... */ },
"propertyOrdering": ["name", "profile"] // ← Automatically included
}
The implementation supports:
''
(empty string) or simple array format'parent.child'
dot notationshould add propertyOrdering when provided
- Complex nested object testshould work without propertyOrdering
- Backward compatibility testshould support simple array format for root-level property ordering
- Simple array format testThe API provides excellent developer experience with progressive complexity:
// ✅ Simple case - clean and intuitive
propertyOrdering: ['name', 'age', 'email']
// ✅ Complex case - full control over nested structures
propertyOrdering: {
'': ['name', 'profile'],
'profile': ['bio', 'settings'],
'profile.settings': ['theme', 'notifications']
}
None. This is a purely additive feature with full backward compatibility.
This implementation enables developers to leverage Google's property ordering feature for more consistent, reliable, and high-quality structured outputs from Gemini models, with an API that scales from simple to complex use cases.