Skip to content

Commit af43022

Browse files
committed
fix structured outputs: json schema for gemini models
1 parent 47f030d commit af43022

File tree

3 files changed

+24
-30
lines changed

3 files changed

+24
-30
lines changed

src/providers/google-vertex-ai/transformGenerationConfig.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { Params } from '../../types/requestBody';
2-
import { derefer, recursivelyDeleteUnsupportedParameters } from './utils';
2+
import {
3+
recursivelyDeleteUnsupportedParameters,
4+
transformGeminiToolParameters,
5+
} from './utils';
36
import { GoogleEmbedParams } from './embed';
47
import { EmbedInstancesData } from './types';
58
/**
@@ -39,20 +42,11 @@ export function transformGenerationConfig(params: Params) {
3942
}
4043
if (params?.response_format?.type === 'json_schema') {
4144
generationConfig['responseMimeType'] = 'application/json';
42-
recursivelyDeleteUnsupportedParameters(
43-
params?.response_format?.json_schema?.schema
44-
);
4545
let schema =
4646
params?.response_format?.json_schema?.schema ??
4747
params?.response_format?.json_schema;
48-
if (Object.keys(schema).includes('$defs')) {
49-
schema = derefer(schema);
50-
delete schema['$defs'];
51-
}
52-
if (Object.hasOwn(schema, '$schema')) {
53-
delete schema['$schema'];
54-
}
55-
generationConfig['responseSchema'] = schema;
48+
recursivelyDeleteUnsupportedParameters(schema);
49+
generationConfig['responseSchema'] = transformGeminiToolParameters(schema);
5650
}
5751

5852
if (params?.thinking) {

src/providers/google-vertex-ai/utils.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,25 @@ export const transformGeminiToolParameters = (
267267
if (key === 'enum' && Array.isArray(value)) {
268268
transformed.enum = value;
269269
transformed.format = 'enum';
270-
} else if ((key === 'anyOf' || key === 'oneOf') && Array.isArray(value)) {
270+
continue;
271+
}
272+
273+
if ((key === 'anyOf' || key === 'oneOf') && Array.isArray(value)) {
271274
const nonNullItems = value.filter((item) => !isNullTypeNode(item));
272-
if (nonNullItems.length < value.length) {
273-
// remove `null` type in schema and set nullable: true
274-
transformed[key] = transformNode(nonNullItems);
275-
transformed.nullable = true;
276-
} else {
277-
transformed[key] = transformNode(value);
275+
const hadNull = nonNullItems.length < value.length;
276+
if (nonNullItems.length === 1 && hadNull) {
277+
// Flatten to single schema: get rid of anyOf/oneOf and set nullable: true
278+
const single = transformNode(nonNullItems[0]);
279+
if (single && typeof single === 'object') single.nullable = true;
280+
return single;
278281
}
279-
} else {
280-
transformed[key] = transformNode(value);
282+
283+
transformed[key] = transformNode(hadNull ? nonNullItems : value);
284+
if (hadNull) transformed.nullable = true;
285+
continue;
281286
}
287+
288+
transformed[key] = transformNode(value);
282289
}
283290
return transformed;
284291
};

src/providers/google/chatComplete.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
} from '../../types/requestBody';
1212
import { buildGoogleSearchRetrievalTool } from '../google-vertex-ai/chatComplete';
1313
import {
14-
derefer,
1514
getMimeType,
1615
recursivelyDeleteUnsupportedParameters,
1716
transformGeminiToolParameters,
@@ -63,17 +62,11 @@ const transformGenerationConfig = (params: Params) => {
6362
}
6463
if (params?.response_format?.type === 'json_schema') {
6564
generationConfig['responseMimeType'] = 'application/json';
66-
recursivelyDeleteUnsupportedParameters(
67-
params?.response_format?.json_schema?.schema
68-
);
6965
let schema =
7066
params?.response_format?.json_schema?.schema ??
7167
params?.response_format?.json_schema;
72-
if (Object.keys(schema).includes('$defs')) {
73-
schema = derefer(schema);
74-
delete schema['$defs'];
75-
}
76-
generationConfig['responseSchema'] = schema;
68+
recursivelyDeleteUnsupportedParameters(schema);
69+
generationConfig['responseSchema'] = transformGeminiToolParameters(schema);
7770
}
7871
if (params?.thinking) {
7972
const thinkingConfig: Record<string, any> = {};

0 commit comments

Comments
 (0)