fix(ts): support Zod 4 custom tool schemas#3495
Open
jkomyno wants to merge 2 commits into
Open
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
3742ad1 to
2a1d34c
Compare
a511846 to
c9d1997
Compare
c9d1997 to
8e0fb63
Compare
7f3d484 to
04cce60
Compare
04cce60 to
f1fb970
Compare
CryogenicPlanet
approved these changes
Jun 5, 2026
2a1d34c to
4231f31
Compare
df0b120 to
bd3d46f
Compare
4231f31 to
86a8187
Compare
bd3d46f to
a79bcd1
Compare
86a8187 to
ae851c2
Compare
a79bcd1 to
e5e479d
Compare
ae851c2 to
6120cf0
Compare
Make isZodV4Schema a type predicate (schema is z4.ZodType) so both branches of zodSchemaToJsonSchema narrow without casts: the v4 branch to z4.ZodType, the v3 branch to z3.ZodType. Drop the two as-JsonSchemaObject casts on the converter outputs — a concrete object type is already assignable to Record<string, unknown>, so removing them lets the compiler verify the converters return object-shaped values instead of trusting a blind assertion. Remove the now-unused z3 import.
e5e479d to
aa23006
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stacked on #3494.
This PR tightens the SDK's Zod boundary now that the TypeScript packages are moving to the newer Node/toolchain baseline. The main issue was asymmetric Zod support:
@composio/json-schema-to-zodalready supports projects with Zod 3 and Zod 4 by generating schemas throughzod/v3, but custom tools converted schemas in the opposite direction throughzod-to-json-schemaonly. With a bare Zod 4z.object(...), that path degraded to an empty JSON Schema.What changed
zod/v3schemas and Zod 4 schemas viaz.toJSONSchema.createCustomTool(...)and legacycomposio.tools.createCustomTool(...).executeinput type while keeping the session context parameter required for context-using tools.jsonSchemaToZodShapethrough the narrow@composio/core/utils/json-schemasubpath.@composio/json-schema-to-zodor converting to a full Zod object and casting.shapeout of it.@composio/coreand@composio/claude-agent-sdk.Review hardening
Follow-up fixes from a deeper pass over the new conversion boundary:
_def.typebeing defined, but Zod 3 stores the element schema there forz.array()/z.promise()— so a Zod 3 array/promiseoutputParamswas misrouted intoz.toJSONSchemaand crashed withCannot read properties of undefined (reading 'def'). It now discriminates on_def.typebeing a string literal (Zod 4) versus aZodTypeobject (Zod 3), with a regression test.iomode was applied to the Zod 4 converter but dropped on the Zod 3 branch; it now maps ontozod-to-json-schema'spipeStrategy/effectStrategyso.default()/.transform()/.pipe()schemas serialize consistently across both runtimes. Added a v3/v4 input-mode parity test.as nevercasts in the Claude Agent SDK provider with a single concretetool()signature — this sidesteps the SDK's deep-instantiation error while keeping the handler's real argument type.Verification
mise exec -- pnpm --filter @composio/core test(933 passing)mise exec -- pnpm --filter @composio/claude-agent-sdk test -- --runInBand(17 passing)mise exec -- pnpm --filter @composio/core build(publint + attw clean, emits@composio/core/utils/json-schema)mise exec -- pnpm --filter @composio/claude-agent-sdk exec tsc --noEmit --skipLibCheckmise exec -- pnpm --filter @composio/claude-agent-sdk build(publint + attw clean)mise exec -- pnpm install --frozen-lockfilegit diff --checkNote:
mise exec -- pnpm --filter @composio/core typecheckstill fails on the existingsrc/utils/pusher.tsChannelAuthorizationHandlertype mismatch. This PR does not touch that file; the core build and full core unit suite pass.