Skip to content

Commit d3d485c

Browse files
authored
fix: use zod instead of zod/v4 for tool type compatibility (#130)
## Summary - Fixes type incompatibility when users define tools with plain `zod` imports - The SDK was importing types from `zod/v4`, but users typically import from `zod`, causing TypeScript errors due to internal type metadata differences ## Changes - Import `ZodType`, `ZodObject`, `ZodRawShape` from `zod` instead of `zod/v4` in `tool-types.ts`, `tool.ts`, and `tool-executor.ts` - Keep runtime imports (`toJSONSchema`, `ZodError`) from `zod/v4` as they're only available there - Use type assertion in `convertZodToJsonSchema` to bridge the type gap between `zod` and `zod/v4` - Update `toJSONSchema` target from `openapi-3.0` to `draft-7` (former isn't supported in current Zod version) - Update tests to use `draft-7` target ## Error Before Fix ``` No overload matches this call. Type ZodObject<{ channel: ZodString; timestamp: ZodString; name: ZodString; }, strip> is not assignable to type ZodObject<Readonly<{ [k: string]: ZodType<unknown, unknown, ZodTypeInternals<unknown, unknown>>; }>, strip>. The types of '_zod.version.minor' are incompatible between these types. Type 1 is not assignable to type 0. ``` ## Test plan - [x] Build passes (`pnpm run build`) - [x] All tests pass (`npx vitest --run`) - [x] Verified tool definition works with plain `zod` imports
1 parent a96ad34 commit d3d485c

File tree

11 files changed

+369
-25
lines changed

11 files changed

+369
-25
lines changed

.speakeasy/gen.lock

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ management:
55
docVersion: 1.0.0
66
speakeasyVersion: 1.680.0
77
generationVersion: 2.788.4
8-
releaseVersion: 0.3.10
9-
configChecksum: 29a887b679dad847b37964d7d8c2d87d
8+
releaseVersion: 0.3.11
9+
configChecksum: cef53c8d1317cb3ef7f140d2e53bd7a0
1010
repoURL: https://github.com/OpenRouterTeam/typescript-sdk.git
1111
installationURL: https://github.com/OpenRouterTeam/typescript-sdk
1212
published: true
1313
persistentEdits:
14-
generation_id: cf2761d3-02ae-4b5c-b54f-2627801d3677
15-
pristine_commit_hash: 1ba3d6fe317aee62716df18c2f461b29c7d0e8e3
16-
pristine_tree_hash: 4f92002bb977564791b1296c0a552d5ae8f5b351
14+
generation_id: a2ada765-9f3b-4659-b8b6-ed40269ea430
15+
pristine_commit_hash: 984a52fad729045bce58eef97270470afb744196
16+
pristine_tree_hash: 5e4ab5e188946409ef6e4571fe523f276fe7105f
1717
features:
1818
typescript:
1919
acceptHeaders: 2.81.2
@@ -1960,12 +1960,12 @@ trackedFiles:
19601960
pristine_git_object: 410efafd6a7f50d91ccb87131fedbe0c3d47e15a
19611961
jsr.json:
19621962
id: 7f6ab7767282
1963-
last_write_checksum: sha1:077495983e847ab761e9361a4c0b11546b91d315
1964-
pristine_git_object: 803816ad090244d157c67480c8b7141b4bce3a96
1963+
last_write_checksum: sha1:f1ea0044f9cd1074d554da2a6f1d66366d57215b
1964+
pristine_git_object: cacd2f7942fa4dad0f007c80aa05e57f8af49b7c
19651965
package.json:
19661966
id: 7030d0b2f71b
1967-
last_write_checksum: sha1:86e4d4968cdb2ffe2e89ec4f7a22c4d04c0ea024
1968-
pristine_git_object: 24f4ce534eb0c48a8354aba89c465afccace2710
1967+
last_write_checksum: sha1:b2c8f1a9776d2997b4404711ee9aa80b79a065da
1968+
pristine_git_object: 0c7924af3d3a92ddf8286d18b5845d2ca0de020c
19691969
src/core.ts:
19701970
id: f431fdbcd144
19711971
last_write_checksum: sha1:5aa66b0b6a5964f3eea7f3098c2eb3c0ee9c0131
@@ -2088,8 +2088,8 @@ trackedFiles:
20882088
pristine_git_object: a187e58707bdb726ca2aff74941efe7493422d4e
20892089
src/lib/config.ts:
20902090
id: 320761608fb3
2091-
last_write_checksum: sha1:5608ed9fc6a1751b332d7a876a6d7a6a78670793
2092-
pristine_git_object: c0bd2f341c2a834bc7bfd30d06213087cc7884e3
2091+
last_write_checksum: sha1:351edbf3be387f1947550fa5d5eb5dedb4a41d9a
2092+
pristine_git_object: cde57f6466fbde060f4e4601264df4c9153dc794
20932093
src/lib/dlv.ts:
20942094
id: b1988214835a
20952095
last_write_checksum: sha1:eaac763b22717206a6199104e0403ed17a4e2711

.speakeasy/gen.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ generation:
3333
skipResponseBodyAssertions: false
3434
preApplyUnionDiscriminators: true
3535
typescript:
36-
version: 0.3.10
36+
version: 0.3.11
3737
acceptHeaderEnum: false
3838
additionalDependencies:
3939
dependencies: {}

jsr.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
{
44
"name": "@openrouter/sdk",
5-
"version": "0.3.10",
5+
"version": "0.3.11",
66
"exports": {
77
".": "./src/index.ts",
88
"./models/errors": "./src/models/errors/index.ts",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openrouter/sdk",
3-
"version": "0.3.10",
3+
"version": "0.3.11",
44
"author": "OpenRouter",
55
"description": "The OpenRouter TypeScript SDK is a type-safe toolkit for building AI applications with access to 300+ language models through a unified API.",
66
"keywords": [

src/lib/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
7272
export const SDK_METADATA = {
7373
language: "typescript",
7474
openapiDocVersion: "1.0.0",
75-
sdkVersion: "0.3.10",
75+
sdkVersion: "0.3.11",
7676
genVersion: "2.788.4",
77-
userAgent: "speakeasy-sdk/typescript 0.3.10 2.788.4 1.0.0 @openrouter/sdk",
77+
userAgent: "speakeasy-sdk/typescript 0.3.11 2.788.4 1.0.0 @openrouter/sdk",
7878
} as const;

src/lib/tool-executor.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ZodType } from 'zod/v4';
1+
import type { ZodType } from 'zod';
22
import type {
33
APITool,
44
Tool,
@@ -12,10 +12,12 @@ import { hasExecuteFunction, isGeneratorTool, isRegularExecuteTool } from './too
1212

1313
/**
1414
* Convert a Zod schema to JSON Schema using Zod v4's toJSONSchema function
15+
* Uses type assertion to bridge zod (user schemas) and zod/v4 (toJSONSchema)
1516
*/
1617
export function convertZodToJsonSchema(zodSchema: ZodType): Record<string, unknown> {
17-
const jsonSchema = toJSONSchema(zodSchema, {
18-
target: 'openapi-3.0',
18+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
19+
const jsonSchema = toJSONSchema(zodSchema as any, {
20+
target: 'draft-7',
1921
});
2022
return jsonSchema;
2123
}

src/lib/tool-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ZodObject, ZodRawShape, ZodType, z } from 'zod/v4';
1+
import type { ZodObject, ZodRawShape, ZodType, z } from 'zod';
22
import type * as models from '../models/index.js';
33
import type { OpenResponsesStreamEvent } from '../models/index.js';
44
import type { ModelResult } from './model-result.js';

src/lib/tool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ZodObject, ZodRawShape, ZodType, z } from "zod/v4";
1+
import type { ZodObject, ZodRawShape, ZodType, z } from "zod";
22
import {
33
ToolType,
44
type TurnContext,

tests/e2e/call-model-tools.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('Enhanced Tool Support for callModel', () => {
2626
});
2727

2828
const jsonSchema = toJSONSchema(schema, {
29-
target: 'openapi-3.0',
29+
target: 'draft-7',
3030
});
3131

3232
expect(jsonSchema).toHaveProperty('type', 'object');
@@ -48,7 +48,7 @@ describe('Enhanced Tool Support for callModel', () => {
4848
});
4949

5050
const jsonSchema = toJSONSchema(schema, {
51-
target: 'openapi-3.0',
51+
target: 'draft-7',
5252
});
5353

5454
expect(jsonSchema.properties?.user).toBeDefined();
@@ -61,7 +61,7 @@ describe('Enhanced Tool Support for callModel', () => {
6161
});
6262

6363
const jsonSchema = toJSONSchema(schema, {
64-
target: 'openapi-3.0',
64+
target: 'draft-7',
6565
});
6666

6767
expect(jsonSchema.properties?.location?.['description']).toBe(

tests/e2e/call-model.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ describe('callModel E2E Tests', () => {
160160

161161
it('should work with chat-style messages and chat-style tools together', async () => {
162162
const response = client.callModel({
163-
model: 'meta-llama/llama-3.1-8b-instruct',
163+
model: 'anthropic/claude-sonnet-4',
164164
input: fromChatMessages([
165165
{
166166
role: 'system',

0 commit comments

Comments
 (0)