Skip to content

feat(zod): support schema definitions#1993

Merged
HAYDEN-OAI merged 4 commits into
mainfrom
dev/hayden/issue-1285-dedupe-zod-schema-refs
Jul 22, 2026
Merged

feat(zod): support schema definitions#1993
HAYDEN-OAI merged 4 commits into
mainfrom
dev/hayden/issue-1285-dedupe-zod-schema-refs

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown
Contributor
  • I understand that this repository is auto-generated and my pull request may not be merged

Changes being requested

Fixes #1285.

zodResponseFormat() now accepts an optional schemaDefinitions map in its existing third argument. Callers can name shared Zod schemas that should be extracted into JSON Schema definitions, allowing repeated large schemas such as enums to be referenced instead of copied at every use site.

The helper previously forwarded response-format props but had no way to pass definitions into schema conversion. Reusing two 200-value enums could therefore emit more than the API's 500-enum limit even though the logical schema only contained 400 unique values.

The implementation keeps the same public option for both supported Zod paths:

  • Zod v3 forwards the supplied map to the vendored zod-to-json-schema definitions option.
  • Zod v4 registers the supplied schemas with their definition names before native JSON Schema conversion.

schemaDefinitions is removed from the outgoing response-format object after conversion, and callers who do not provide it keep the existing generated schema shape.

The regression test mirrors the issue's two reused 200-value enums for both Zod v3 and v4. It verifies that only 400 enum values are emitted and that every generated reference resolves.

Additional context & links

@HAYDEN-OAI
HAYDEN-OAI marked this pull request as ready for review July 13, 2026 21:13
@HAYDEN-OAI
HAYDEN-OAI requested a review from a team as a code owner July 13, 2026 21:13
@openai-sdks

openai-sdks Bot commented Jul 13, 2026

Copy link
Copy Markdown

OkTest Summary

237/237 SDK tests passed in 8.513s for Node SDK PR #1993.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 169ms
tests/chat-completions-create.test.ts ✅ Passed 158ms
tests/chat-completions-stream.test.ts ✅ Passed 132ms
tests/files-content-binary.test.ts ✅ Passed 100ms
tests/files-create-multipart.test.ts ✅ Passed 108ms
tests/files-list-pagination.test.ts ✅ Passed 111ms
tests/initialize-config.test.ts ✅ Passed 127ms
tests/instance-isolation.test.ts ✅ Passed 102ms
tests/models-list.test.ts ✅ Passed 124ms
tests/responses-background-lifecycle.test.ts ✅ Passed 164ms
tests/responses-body-method-errors.test.ts ✅ Passed 238ms
tests/responses-cancel-timeout.test.ts ✅ Passed 179ms
tests/responses-cancel.test.ts ✅ Passed 156ms
tests/responses-compact-retries.test.ts ✅ Passed 203ms
tests/responses-compact.test.ts ✅ Passed 167ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 82ms
tests/responses-create-advanced.test.ts ✅ Passed 143ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.075s
tests/responses-create-errors.test.ts ✅ Passed 155ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 108ms
tests/responses-create-retries.test.ts ✅ Passed 145ms
tests/responses-create-stream-failures.test.ts ✅ Passed 173ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.124s
tests/responses-create-stream-wire.test.ts ✅ Passed 1.999s
tests/responses-create-stream.test.ts ✅ Passed 64ms
tests/responses-create-terminal-states.test.ts ✅ Passed 176ms
tests/responses-create-timeout.test.ts ✅ Passed 180ms
tests/responses-create.test.ts ✅ Passed 106ms
tests/responses-delete.test.ts ✅ Passed 101ms
tests/responses-input-items-errors.test.ts ✅ Passed 141ms
tests/responses-input-items-list.test.ts ✅ Passed 141ms
tests/responses-input-items-options.test.ts ✅ Passed 79ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 197ms
tests/responses-input-tokens-count.test.ts ✅ Passed 219ms
tests/responses-malformed-inputs.test.ts ✅ Passed 1.631s
tests/responses-not-found-errors.test.ts ✅ Passed 182ms
tests/responses-parse.test.ts ✅ Passed 160ms
tests/responses-retrieve-retries.test.ts ✅ Passed 191ms
tests/responses-retrieve.test.ts ✅ Passed 161ms
tests/responses-stored-method-errors.test.ts ✅ Passed 444ms
tests/retry-behavior.test.ts ✅ Passed 2.919s
tests/sdk-error-shape.test.ts ✅ Passed 197ms

View OkTest run #29952237957

SDK merge (232b5167b727) · head (3305aa5218c7) · base (39a15b412fc1) · OkTest (d2b5921fc22a)

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main implementation is focused and the intended enum-deduplication case works for both Zod v3 and v4. I’m requesting changes for two definition-name edge cases in the new public map that currently generate invalid schemas.

Validated locally at 16b870f0:

  • pnpm test --runInBand tests/helpers/zod.test.ts — 28/28 passed
  • pnpm lint — passed, including build, types, package checks, and JSR dry run
  • additional Zod v3/v4/v4-mini runtime probes

The ordinary PR checks are green. OkTest is red for an unrelated generated fixture mismatch (InputTokensDetails.cache_write_tokens), before its compatibility suite runs.

Comment thread src/helpers/zod.ts
Comment thread src/helpers/zod.ts

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core approach is sound and the normal v3/v4 cases are well covered, but I found two correctness gaps in the newly accepted schemaDefinitions names that can produce invalid or semantically wrong schemas. Please address these before merge.

Validation performed:

  • focused Zod helper suite: 28/28 passed
  • full repository suite: 1,189 passed (1 skipped)
  • pnpm lint and pnpm build: passed, including type checks, publint, package loading, and JSR dry-run
  • GitHub build/lint/tests/ecosystem/examples/breaking-change checks: passed

The separate OkTest failure is unrelated: its Node bridge fixtures are missing the newly required cache_write_tokens field, and the run fails before exercising this change.

Comment thread src/helpers/zod.ts
Comment thread src/helpers/zod.ts
@jbeckwith-oai
jbeckwith-oai dismissed their stale review July 13, 2026 21:21

Duplicate review submitted during a concurrent review; the earlier review contains the same blocking findings.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two previously reported name issues are fixed, and the normal enum-deduplication path is sound. However, the public map still accepts arbitrary string keys that produce dangling $refs in two reproducible cases on both Zod v3 and v4. Please either encode/preserve these keys correctly or reject them explicitly, with regression coverage for both converter paths.

Validation at bbd5c857: focused Zod suite 32/32 passed; all full-suite Jest assertions passed (1,201 passed, 1 skipped), although the command exited nonzero afterward because the existing mock-server cleanup passed multiple newline-separated PIDs to kill; full pnpm lint passed (format, ESLint, CJS/ESM and Deno builds, TypeScript, ATTW, publint, JSR dry-run). Current CI and OkTest 237/237 are green.

Comment thread src/helpers/zod.ts Outdated
Comment thread src/helpers/zod.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for supplying named shared Zod schemas to zodResponseFormat() so they can be emitted as JSON Schema definitions and referenced via $ref, reducing duplicated schema output (notably large enums) and helping stay within API schema limits.

Changes:

  • Extend zodResponseFormat()’s third argument to accept an optional schemaDefinitions map and ensure it is not forwarded as an API response-format field.
  • Implement definition registration/extraction for both Zod v3 (zod-to-json-schema definitions option) and Zod v4 (registry metadata), including JSON Pointer + URI escaping for generated $refs.
  • Add regression tests covering enum deduplication, name collision behavior, JSON Pointer escaping, URI encoding, and __proto__ rejection.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/helpers/zod.ts Adds schemaDefinitions support for both Zod v3 and v4 schema conversion paths and sanitizes/escapes generated $refs.
tests/helpers/zod.test.ts Adds tests validating definition extraction/deduplication and correct $ref escaping/validation behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the exact current head (3305aa52) after the prior change request. Both dangling-reference findings are fixed: URI-fragment tokens are now JSON Pointer-escaped and URI-encoded (foo%2Fbar emits foo%252Fbar and resolves to the literal key), and an own __proto__ definition key is rejected before either converter runs. The thread-aware review state shows both prior threads resolved.

I verified the fixes on Zod v3, v4, and v4-mini, including adjacent /, ~, #, spaces, Unicode, constructor, and prototype names. Local validation passed: focused Zod suite 36/36 and full pnpm lint (Prettier, ESLint, CJS/ESM and Deno builds, TypeScript, ATTW, publint, JSR dry-run). Current CI is green across Node 20/22/24/26.2, ecosystem tests, Agents SDK regressions, breaking-change detection, examples, and CodeQL; OkTest is 237/237. No substantive issues remain.

@HAYDEN-OAI
HAYDEN-OAI merged commit eb04567 into main Jul 22, 2026
20 checks passed
@HAYDEN-OAI
HAYDEN-OAI deleted the dev/hayden/issue-1285-dedupe-zod-schema-refs branch July 22, 2026 19:51
@stainless-app stainless-app Bot mentioned this pull request Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow specifying definitions as a zodResponseFormat param

3 participants