zod.mjs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import * as z4 from 'zod/v4';
  2. import { makeParseableResponseFormat, makeParseableTextFormat, makeParseableTool, } from "../lib/parser.mjs";
  3. import { zodToJsonSchema as _zodToJsonSchema } from "../_vendor/zod-to-json-schema/index.mjs";
  4. import { makeParseableResponseTool } from "../lib/ResponsesParser.mjs";
  5. import { toStrictJsonSchema } from "../lib/transform.mjs";
  6. function zodV3ToJsonSchema(schema, options) {
  7. return _zodToJsonSchema(schema, {
  8. openaiStrictMode: true,
  9. name: options.name,
  10. nameStrategy: 'duplicate-ref',
  11. $refStrategy: 'extract-to-root',
  12. nullableStrategy: 'property',
  13. });
  14. }
  15. function zodV4ToJsonSchema(schema) {
  16. return toStrictJsonSchema(z4.toJSONSchema(schema, {
  17. target: 'draft-7',
  18. }));
  19. }
  20. function isZodV4(zodObject) {
  21. return '_zod' in zodObject;
  22. }
  23. /**
  24. * Creates a chat completion `JSONSchema` response format object from
  25. * the given Zod schema.
  26. *
  27. * If this is passed to the `.parse()`, `.stream()` or `.runTools()`
  28. * chat completion methods then the response message will contain a
  29. * `.parsed` property that is the result of parsing the content with
  30. * the given Zod object.
  31. *
  32. * ```ts
  33. * const completion = await client.chat.completions.parse({
  34. * model: 'gpt-4o-2024-08-06',
  35. * messages: [
  36. * { role: 'system', content: 'You are a helpful math tutor.' },
  37. * { role: 'user', content: 'solve 8x + 31 = 2' },
  38. * ],
  39. * response_format: zodResponseFormat(
  40. * z.object({
  41. * steps: z.array(z.object({
  42. * explanation: z.string(),
  43. * answer: z.string(),
  44. * })),
  45. * final_answer: z.string(),
  46. * }),
  47. * 'math_answer',
  48. * ),
  49. * });
  50. * const message = completion.choices[0]?.message;
  51. * if (message?.parsed) {
  52. * console.log(message.parsed);
  53. * console.log(message.parsed.final_answer);
  54. * }
  55. * ```
  56. *
  57. * This can be passed directly to the `.create()` method but will not
  58. * result in any automatic parsing, you'll have to parse the response yourself.
  59. */
  60. export function zodResponseFormat(zodObject, name, props) {
  61. return makeParseableResponseFormat({
  62. type: 'json_schema',
  63. json_schema: {
  64. ...props,
  65. name,
  66. strict: true,
  67. schema: isZodV4(zodObject) ? zodV4ToJsonSchema(zodObject) : zodV3ToJsonSchema(zodObject, { name }),
  68. },
  69. }, (content) => zodObject.parse(JSON.parse(content)));
  70. }
  71. export function zodTextFormat(zodObject, name, props) {
  72. return makeParseableTextFormat({
  73. type: 'json_schema',
  74. ...props,
  75. name,
  76. strict: true,
  77. schema: isZodV4(zodObject) ? zodV4ToJsonSchema(zodObject) : zodV3ToJsonSchema(zodObject, { name }),
  78. }, (content) => zodObject.parse(JSON.parse(content)));
  79. }
  80. /**
  81. * Creates a chat completion `function` tool that can be invoked
  82. * automatically by the chat completion `.runTools()` method or automatically
  83. * parsed by `.parse()` / `.stream()`.
  84. */
  85. export function zodFunction(options) {
  86. // @ts-expect-error TODO
  87. return makeParseableTool({
  88. type: 'function',
  89. function: {
  90. name: options.name,
  91. parameters: isZodV4(options.parameters) ?
  92. zodV4ToJsonSchema(options.parameters)
  93. : zodV3ToJsonSchema(options.parameters, { name: options.name }),
  94. strict: true,
  95. ...(options.description ? { description: options.description } : undefined),
  96. },
  97. }, {
  98. callback: options.function,
  99. parser: (args) => options.parameters.parse(JSON.parse(args)),
  100. });
  101. }
  102. export function zodResponsesFunction(options) {
  103. return makeParseableResponseTool({
  104. type: 'function',
  105. name: options.name,
  106. parameters: isZodV4(options.parameters) ?
  107. zodV4ToJsonSchema(options.parameters)
  108. : zodV3ToJsonSchema(options.parameters, { name: options.name }),
  109. strict: true,
  110. ...(options.description ? { description: options.description } : undefined),
  111. }, {
  112. callback: options.function,
  113. parser: (args) => options.parameters.parse(JSON.parse(args)),
  114. });
  115. }
  116. //# sourceMappingURL=zod.mjs.map