Skip to content

fix: drop transitive Zod 3 via type-only @ag-ui/core@0.1.0#738

Draft
tombeckenham wants to merge 1 commit into
mainfrom
520-type-conflict-ag-uicore-0049-zod-3-breaks-consumer-zod-4-type-checking
Draft

fix: drop transitive Zod 3 via type-only @ag-ui/core@0.1.0#738
tombeckenham wants to merge 1 commit into
mainfrom
520-type-conflict-ag-uicore-0049-zod-3-breaks-consumer-zod-4-type-checking

Conversation

@tombeckenham

Copy link
Copy Markdown
Contributor

Important

Blocked on the @ag-ui/core@0.1.0 npm release. The upstream extraction of zod from @ag-ui/core is ag-ui-protocol/ag-ui#1637; we resolved its merge conflicts in ag-ui-protocol/ag-ui#1918. Once 0.1.0 is published: regenerate pnpm-lock.yaml, mark ready for review.

🎯 Changes

Fixes #520.

@ag-ui/core@0.0.x infers its public types from Zod 3 schemas and carries zod ^3.22 as a hard runtime dependency, dragging Zod 3 into every consumer's tree and type graph. Apps on Zod 4 (e.g. with @hookform/resolvers@5) hit zod/v4/core version-mismatch errors (TS2769: The types of '_zod.version.minor' are incompatible) when their lockfile resolves the resolver's zod/v4 import to Zod 3.25's shim.

@ag-ui/core@0.1.0 makes the main entry type-only with zero runtime dependencies and moves the zod schemas to an opt-in /schemas subpath (zod ^3.24 || ^4 optional peer). This PR:

  • Bumps @ag-ui/core to ^0.1.0 — Zod 3 disappears from consumer installs entirely
  • Loads RunAgentInputSchema lazily from @ag-ui/core/schemas inside chatParamsFromRequestBody, typed against a local structural interface so zod never appears in this package's compilation or its public .d.ts (the subpath's emitted declarations are pinned to one zod major; ours must not be)
  • Declares zod (^3.24.0 || ^4.0.0) as an optional peer of @tanstack/ai: only server code calling chatParamsFromRequest* needs it; calling without zod rejects with an actionable AGUIError. Wire behavior unchanged.
  • Updates the migration doc, chatParamsFromRequest API doc, and the ag-ui-protocol agent skill

Verification (against packed builds)

Scenario Result
@tanstack/ai@latest (control): zod 4 + @hookform/resolvers@5 consumer npm ls zod shows nested zod@3.25.76 under @ag-ui/core
Patched: same consumer exactly one zod@4.4.3 in the whole tree; tsc --noEmit clean with skipLibCheck: false
Patched: runtime chatParamsFromRequestBody parses valid bodies (incl. parts re-attach) and rejects invalid ones with AGUIError, validated by upstream schemas running on zod 4
Patched: consumer with no zod import '@tanstack/ai' works; calling chatParamsFromRequest* rejects with the install-zod message

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr. (Run with @ag-ui/core pointed at a tarball built from ag-ui#1918, since 0.1.0 isn't published yet — all targets green, incl. unit (1003), types, lint, knip, sherif, docs, publint, build. E2E: 259 passed, 4 flaky multimodal-image retries unrelated to this change.)

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

🤖 Generated with Claude Code

…520)

@ag-ui/core@0.0.x infers its public types from Zod 3 schemas and carries
zod ^3.22 as a hard runtime dependency, dragging Zod 3 into every
consumer's tree and type graph. Apps on Zod 4 (e.g. @hookform/resolvers@5)
hit zod/v4/core version-mismatch errors (TS2769) when their lockfile
resolves the resolver's zod/v4 import to the Zod 3 shim.

@ag-ui/core@0.1.0 makes the main entry type-only with zero runtime deps
and moves schemas to an opt-in /schemas subpath (zod ^3.24 || ^4 optional
peer). This change:

- bumps @ag-ui/core to ^0.1.0
- loads RunAgentInputSchema lazily from @ag-ui/core/schemas inside
  chatParamsFromRequestBody, typed against a local structural interface
  so zod never appears in this package's compilation or public .d.ts
- declares zod (^3.24.0 || ^4.0.0) as an optional peer dependency — only
  server code calling chatParamsFromRequest* needs zod installed; calling
  without it rejects with an actionable AGUIError

Verified against a packed build: a zod-4 + @hookform/resolvers@5 consumer
gets exactly one zod in its tree and tsc --noEmit passes with
skipLibCheck: false; a zod-free consumer imports @tanstack/ai fine.

Blocked on the @ag-ui/core@0.1.0 npm release
(ag-ui-protocol/ag-ui#1637, conflict resolution in
ag-ui-protocol/ag-ui#1918). Lockfile to be regenerated once published.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ff1be6f6-45c4-4a3d-a6a9-4883f141bbca

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 520-type-conflict-ag-uicore-0049-zod-3-breaks-consumer-zod-4-type-checking

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

Type conflict: @ag-ui/core 0.0.49 (Zod 3) breaks consumer Zod 4 type checking

1 participant