Skip to content

Commit 510c866

Browse files
RobertCraigiestainless-app[bot]
authored andcommitted
fix(helpers/zod): nested union schema extraction (#979)
1 parent 9b7568c commit 510c866

File tree

3 files changed

+378
-56
lines changed

3 files changed

+378
-56
lines changed

src/_vendor/zod-to-json-schema/zodToJsonSchema.ts

+18-18
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,24 @@ const zodToJsonSchema = <Target extends Targets = 'jsonSchema7'>(
4343
main.title = title;
4444
}
4545

46-
const definitions =
47-
!isEmptyObj(refs.definitions) ?
48-
Object.entries(refs.definitions).reduce(
49-
(acc, [name, schema]) => ({
50-
...acc,
51-
[name]:
52-
parseDef(
53-
zodDef(schema),
54-
{
55-
...refs,
56-
currentPath: [...refs.basePath, refs.definitionPath, name],
57-
},
58-
true,
59-
) ?? {},
60-
}),
61-
{},
62-
)
63-
: undefined;
46+
const definitions = (() => {
47+
if (isEmptyObj(refs.definitions)) {
48+
return undefined;
49+
}
50+
51+
const definitions: Record<string, any> = {};
52+
53+
for (const [name, zodSchema] of Object.entries(refs.definitions)) {
54+
definitions[name] =
55+
parseDef(
56+
zodDef(zodSchema),
57+
{ ...refs, currentPath: [...refs.basePath, refs.definitionPath, name] },
58+
true,
59+
) ?? {};
60+
}
61+
62+
return definitions;
63+
})();
6464

6565
const combined: ReturnType<typeof zodToJsonSchema<Target>> =
6666
name === undefined ?

tests/lib/__snapshots__/parser.test.ts.snap

+40-12
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
exports[`.parse() zod deserialises response_format 1`] = `
44
"{
5-
"id": "chatcmpl-9tZXFjiGKgtrHZeIxvkklWe51DYZp",
5+
"id": "chatcmpl-9uLhvwLPvKOZoJ7hwaa666fYuxYif",
66
"object": "chat.completion",
7-
"created": 1723031665,
7+
"created": 1723216839,
88
"model": "gpt-4o-2024-08-06",
99
"choices": [
1010
{
1111
"index": 0,
1212
"message": {
1313
"role": "assistant",
14-
"content": "{\\"city\\":\\"San Francisco\\",\\"units\\":\\"f\\"}",
14+
"content": "{\\"city\\":\\"San Francisco\\",\\"units\\":\\"c\\"}",
1515
"refusal": null
1616
},
1717
"logprobs": null,
@@ -30,16 +30,16 @@ exports[`.parse() zod deserialises response_format 1`] = `
3030

3131
exports[`.parse() zod merged schemas 2`] = `
3232
"{
33-
"id": "chatcmpl-9tyPgktyF5JgREIZd0XZI4XgrBAD2",
33+
"id": "chatcmpl-9uLi0HJ6HYH0FM1VI1N6XCREiGvX1",
3434
"object": "chat.completion",
35-
"created": 1723127296,
35+
"created": 1723216844,
3636
"model": "gpt-4o-2024-08-06",
3737
"choices": [
3838
{
3939
"index": 0,
4040
"message": {
4141
"role": "assistant",
42-
"content": "{\\"person1\\":{\\"name\\":\\"Jane Doe\\",\\"phone_number\\":\\"+1234567890\\",\\"roles\\":[\\"other\\"],\\"description\\":\\"Engineer at OpenAI. Email: jane@openai.com\\"},\\"person2\\":{\\"name\\":\\"John Smith\\",\\"phone_number\\":\\"+0987654321\\",\\"differentField\\":\\"Engineer at OpenAI. Email: john@openai.com\\"}}",
42+
"content": "{\\"person1\\":{\\"name\\":\\"Jane Doe\\",\\"phone_number\\":\\".\\",\\"roles\\":[\\"other\\"],\\"description\\":\\"Engineer at OpenAI, born Nov 16, contact email: jane@openai.com\\"},\\"person2\\":{\\"name\\":\\"John Smith\\",\\"phone_number\\":\\"john@openai.com\\",\\"differentField\\":\\"Engineer at OpenAI, born March 1.\\"}}",
4343
"refusal": null
4444
},
4545
"logprobs": null,
@@ -51,23 +51,51 @@ exports[`.parse() zod merged schemas 2`] = `
5151
"completion_tokens": 72,
5252
"total_tokens": 133
5353
},
54-
"system_fingerprint": "fp_845eaabc1f"
54+
"system_fingerprint": "fp_2a322c9ffc"
55+
}
56+
"
57+
`;
58+
59+
exports[`.parse() zod nested schema extraction 2`] = `
60+
"{
61+
"id": "chatcmpl-9uLi6hkH6VcoaYiNEzy3h56QRAyns",
62+
"object": "chat.completion",
63+
"created": 1723216850,
64+
"model": "gpt-4o-2024-08-06",
65+
"choices": [
66+
{
67+
"index": 0,
68+
"message": {
69+
"role": "assistant",
70+
"content": "{\\"name\\":\\"TodoApp\\",\\"fields\\":[{\\"type\\":\\"string\\",\\"name\\":\\"taskId\\",\\"metadata\\":{\\"foo\\":\\"unique identifier for each task\\"}},{\\"type\\":\\"string\\",\\"name\\":\\"title\\",\\"metadata\\":{\\"foo\\":\\"title of the task\\"}},{\\"type\\":\\"string\\",\\"name\\":\\"description\\",\\"metadata\\":{\\"foo\\":\\"detailed description of the task. This is optional.\\"}},{\\"type\\":\\"string\\",\\"name\\":\\"status\\",\\"metadata\\":{\\"foo\\":\\"status of the task, e.g., pending, completed, etc.\\"}},{\\"type\\":\\"string\\",\\"name\\":\\"dueDate\\",\\"metadata\\":null},{\\"type\\":\\"string\\",\\"name\\":\\"priority\\",\\"metadata\\":{\\"foo\\":\\"priority level of the task, e.g., low, medium, high\\"}},{\\"type\\":\\"string\\",\\"name\\":\\"creationDate\\",\\"metadata\\":{\\"foo\\":\\"date when the task was created\\"}},{\\"type\\":\\"string\\",\\"name\\":\\"lastModifiedDate\\",\\"metadata\\":{\\"foo\\":\\"date when the task was last modified\\"}},{\\"type\\":\\"string\\",\\"name\\":\\"tags\\",\\"metadata\\":{\\"foo\\":\\"tags associated with the task, for categorization\\"}}]}",
71+
"refusal": null
72+
},
73+
"logprobs": null,
74+
"finish_reason": "stop"
75+
}
76+
],
77+
"usage": {
78+
"prompt_tokens": 36,
79+
"completion_tokens": 208,
80+
"total_tokens": 244
81+
},
82+
"system_fingerprint": "fp_2a322c9ffc"
5583
}
5684
"
5785
`;
5886

5987
exports[`.parse() zod top-level recursive schemas 1`] = `
6088
"{
61-
"id": "chatcmpl-9taiMDrRVRIkk1Xg1yE82UjnYuZjt",
89+
"id": "chatcmpl-9uLhw79ArBF4KsQQOlsoE68m6vh6v",
6290
"object": "chat.completion",
63-
"created": 1723036198,
91+
"created": 1723216840,
6492
"model": "gpt-4o-2024-08-06",
6593
"choices": [
6694
{
6795
"index": 0,
6896
"message": {
6997
"role": "assistant",
70-
"content": "{\\"type\\":\\"form\\",\\"label\\":\\"User Profile Form\\",\\"children\\":[{\\"type\\":\\"field\\",\\"label\\":\\"Full Name\\",\\"children\\":[],\\"attributes\\":[{\\"name\\":\\"type\\",\\"value\\":\\"text\\"},{\\"name\\":\\"placeholder\\",\\"value\\":\\"Enter your full name\\"}]},{\\"type\\":\\"field\\",\\"label\\":\\"Email Address\\",\\"children\\":[],\\"attributes\\":[{\\"name\\":\\"type\\",\\"value\\":\\"email\\"},{\\"name\\":\\"placeholder\\",\\"value\\":\\"Enter your email address\\"}]},{\\"type\\":\\"field\\",\\"label\\":\\"Phone Number\\",\\"children\\":[],\\"attributes\\":[{\\"name\\":\\"type\\",\\"value\\":\\"tel\\"},{\\"name\\":\\"placeholder\\",\\"value\\":\\"Enter your phone number\\"}]},{\\"type\\":\\"button\\",\\"label\\":\\"Submit\\",\\"children\\":[],\\"attributes\\":[{\\"name\\":\\"type\\",\\"value\\":\\"submit\\"}]}],\\"attributes\\":[{\\"name\\":\\"method\\",\\"value\\":\\"post\\"},{\\"name\\":\\"action\\",\\"value\\":\\"/submit-profile\\"}]}",
98+
"content": "{\\"type\\":\\"form\\",\\"label\\":\\"User Profile Form\\",\\"children\\":[{\\"type\\":\\"field\\",\\"label\\":\\"First Name\\",\\"children\\":[],\\"attributes\\":[{\\"name\\":\\"type\\",\\"value\\":\\"text\\"},{\\"name\\":\\"name\\",\\"value\\":\\"firstName\\"},{\\"name\\":\\"placeholder\\",\\"value\\":\\"Enter your first name\\"}]},{\\"type\\":\\"field\\",\\"label\\":\\"Last Name\\",\\"children\\":[],\\"attributes\\":[{\\"name\\":\\"type\\",\\"value\\":\\"text\\"},{\\"name\\":\\"name\\",\\"value\\":\\"lastName\\"},{\\"name\\":\\"placeholder\\",\\"value\\":\\"Enter your last name\\"}]},{\\"type\\":\\"field\\",\\"label\\":\\"Email Address\\",\\"children\\":[],\\"attributes\\":[{\\"name\\":\\"type\\",\\"value\\":\\"email\\"},{\\"name\\":\\"name\\",\\"value\\":\\"email\\"},{\\"name\\":\\"placeholder\\",\\"value\\":\\"Enter your email address\\"}]},{\\"type\\":\\"button\\",\\"label\\":\\"Submit\\",\\"children\\":[],\\"attributes\\":[{\\"name\\":\\"type\\",\\"value\\":\\"submit\\"}]}],\\"attributes\\":[]}",
7199
"refusal": null
72100
},
73101
"logprobs": null,
@@ -76,8 +104,8 @@ exports[`.parse() zod top-level recursive schemas 1`] = `
76104
],
77105
"usage": {
78106
"prompt_tokens": 38,
79-
"completion_tokens": 168,
80-
"total_tokens": 206
107+
"completion_tokens": 175,
108+
"total_tokens": 213
81109
},
82110
"system_fingerprint": "fp_845eaabc1f"
83111
}

0 commit comments

Comments
 (0)