Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions js/core/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ import { GenkitError } from './error.js';
import type { Registry } from './registry.js';
const ajv = new Ajv();
addFormats(ajv);
// Gemini structured output uses the non-standard `propertyOrdering` keyword as a
// field-order hint. Register it so Ajv strict mode does not reject those schemas.
// See https://ai.google.dev/gemini-api/docs/structured-output#property-ordering
ajv.addVocabulary(['propertyOrdering']);

export { z }; // provide a consistent zod to use throughout genkit

Expand Down
53 changes: 53 additions & 0 deletions js/core/tests/schema_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,38 @@ describe('validate()', () => {
{ path: '(root)', message: "must have required property 'foo'" },
],
},
{
it: 'should allow Gemini propertyOrdering keyword in json schema',
jsonSchema: {
type: 'object',
properties: {
answer: { type: 'number' },
x: { type: 'number' },
y: { type: 'number' },
},
required: ['x', 'y', 'answer'],
propertyOrdering: ['x', 'y', 'answer'],
additionalProperties: false,
},
data: { x: 1, y: 2, answer: 3 },
valid: true,
},
{
it: 'should still validate data when propertyOrdering is present',
jsonSchema: {
type: 'object',
properties: {
x: { type: 'number' },
y: { type: 'number' },
},
required: ['x', 'y'],
propertyOrdering: ['x', 'y'],
additionalProperties: false,
},
data: { x: 'nope', y: 2 },
valid: false,
errors: [{ path: 'x', message: 'must be number' }],
},
];
for (const test of tests) {
it(test.it, () => {
Expand Down Expand Up @@ -375,6 +407,27 @@ describe('disableSchemaCodeGeneration()', () => {
assert.strictEqual(result.valid, true);
});

it('should allow Gemini propertyOrdering keyword in interpret mode', () => {
disableSchemaCodeGeneration();
const result = validateSchema(
{ x: 1, y: 2, answer: 3 },
{
jsonSchema: {
type: 'object',
properties: {
answer: { type: 'number' },
x: { type: 'number' },
y: { type: 'number' },
},
required: ['x', 'y', 'answer'],
propertyOrdering: ['x', 'y', 'answer'],
additionalProperties: false,
},
}
);
assert.strictEqual(result.valid, true);
});

it('should strip undefined values recursively', () => {
disableSchemaCodeGeneration();
const result = validateSchema(
Expand Down
Loading