Skip to content

Commit 0f0e7e5

Browse files
authored
Merge branch 'TanStack:main' into ts-react-search
2 parents 54621f2 + 049eb8a commit 0f0e7e5

File tree

78 files changed

+1528
-429
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1528
-429
lines changed

.github/workflows/autofix.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ jobs:
2222
- name: Setup Tools
2323
uses: tanstack/config/.github/setup@main
2424
- name: Fix formatting
25-
run: pnpm prettier:write
26-
- name: Generate Docs
27-
run: pnpm generate-docs
25+
run: pnpm format
2826
- name: Apply fixes
2927
uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27
3028
with:

.github/workflows/release.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ jobs:
4040
title: "ci: Version Packages"
4141
env:
4242
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
43+
- name: Generate Docs
44+
if: steps.changesets.outputs.published == 'true'
45+
run: pnpm generate-docs
4446
- name: Commit Generated Docs
4547
if: steps.changesets.outputs.published == 'true'
4648
run: |
@@ -56,3 +58,8 @@ jobs:
5658
fi
5759
env:
5860
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61+
- name: Comment on PRs about release
62+
if: steps.changesets.outputs.published == 'true'
63+
uses: tanstack/config/.github/comment-on-release@main
64+
with:
65+
published-packages: ${{ steps.changesets.outputs.publishedPackages }}

docs/guides/server-tools.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,54 @@ const getUserData = getUserDataDef.server(async ({ userId }) => {
256256
});
257257
```
258258

259+
## Using JSON Schema
260+
261+
If you have existing JSON Schema definitions or prefer not to use Zod, you can define tool schemas using raw JSON Schema objects:
262+
263+
```typescript
264+
import { toolDefinition } from "@tanstack/ai";
265+
import type { JSONSchema } from "@tanstack/ai";
266+
267+
const inputSchema: JSONSchema = {
268+
type: "object",
269+
properties: {
270+
userId: {
271+
type: "string",
272+
description: "The user ID to look up",
273+
},
274+
},
275+
required: ["userId"],
276+
};
277+
278+
const outputSchema: JSONSchema = {
279+
type: "object",
280+
properties: {
281+
name: { type: "string" },
282+
email: { type: "string" },
283+
},
284+
required: ["name", "email"],
285+
};
286+
287+
const getUserDataDef = toolDefinition({
288+
name: "get_user_data",
289+
description: "Get user information from the database",
290+
inputSchema,
291+
outputSchema,
292+
});
293+
294+
// When using JSON Schema, args is typed as `any`
295+
const getUserData = getUserDataDef.server(async (args) => {
296+
const user = await db.users.findUnique({ where: { id: args.userId } });
297+
return { name: user.name, email: user.email };
298+
});
299+
```
300+
301+
> **Note:** JSON Schema tools skip runtime validation. Zod schemas are recommended for full type safety and validation.
302+
259303
## Best Practices
260304

261305
1. **Keep tools focused** - Each tool should do one thing well
262-
2. **Validate inputs** - Use Zod schemas to ensure type safety
306+
2. **Validate inputs** - Use Zod schemas to ensure type safety (JSON Schema skips validation)
263307
3. **Handle errors** - Return meaningful error messages
264308
4. **Use descriptions** - Clear descriptions help the model use tools correctly
265309
5. **Secure sensitive operations** - Never expose API keys or secrets to the client

docs/guides/tools.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,49 @@ This approach provides:
3333
- **Type Safety**: Full TypeScript inference from Zod schemas
3434
- **Code Reuse**: Define schemas once, use everywhere
3535
- **Flexibility**: Tools can execute on server, client, or both
36+
- **Schema Options**: Use Zod schemas or raw JSON Schema objects
3637

38+
## Schema Options
39+
40+
TanStack AI supports two ways to define tool schemas:
41+
42+
### Option 1: Zod Schemas (Recommended)
43+
44+
Zod schemas provide full TypeScript type inference and runtime validation:
45+
46+
```typescript
47+
import { z } from "zod";
48+
49+
const inputSchema = z.object({
50+
location: z.string().describe("City name"),
51+
unit: z.enum(["celsius", "fahrenheit"]).optional(),
52+
});
53+
```
54+
55+
### Option 2: JSON Schema Objects
56+
57+
For cases where you already have JSON Schema definitions or prefer not to use Zod, you can pass raw JSON Schema objects directly:
58+
59+
```typescript
60+
import type { JSONSchema } from "@tanstack/ai";
61+
62+
const inputSchema: JSONSchema = {
63+
type: "object",
64+
properties: {
65+
location: {
66+
type: "string",
67+
description: "City name",
68+
},
69+
unit: {
70+
type: "string",
71+
enum: ["celsius", "fahrenheit"],
72+
},
73+
},
74+
required: ["location"],
75+
};
76+
```
77+
78+
> **Note:** When using JSON Schema, TypeScript will infer `any` for input/output types since JSON Schema cannot provide compile-time type information. Zod schemas are recommended for full type safety.
3779
3880
## Tool Definition
3981

@@ -74,6 +116,58 @@ const getWeatherServer = getWeatherDef.server(async ({ location, unit }) => {
74116
});
75117
```
76118

119+
### Using JSON Schema
120+
121+
If you prefer JSON Schema or have existing schema definitions:
122+
123+
```typescript
124+
import { toolDefinition } from "@tanstack/ai";
125+
import type { JSONSchema } from "@tanstack/ai";
126+
127+
// Define schemas using JSON Schema
128+
const inputSchema: JSONSchema = {
129+
type: "object",
130+
properties: {
131+
location: {
132+
type: "string",
133+
description: "The city and state, e.g. San Francisco, CA",
134+
},
135+
unit: {
136+
type: "string",
137+
enum: ["celsius", "fahrenheit"],
138+
},
139+
},
140+
required: ["location"],
141+
};
142+
143+
const outputSchema: JSONSchema = {
144+
type: "object",
145+
properties: {
146+
temperature: { type: "number" },
147+
conditions: { type: "string" },
148+
location: { type: "string" },
149+
},
150+
required: ["temperature", "conditions", "location"],
151+
};
152+
153+
// Create the tool definition
154+
const getWeatherDef = toolDefinition({
155+
name: "get_weather",
156+
description: "Get the current weather for a location",
157+
inputSchema,
158+
outputSchema,
159+
});
160+
161+
// Create server implementation (args is typed as `any` with JSON Schema)
162+
const getWeatherServer = getWeatherDef.server(async (args) => {
163+
const { location, unit } = args;
164+
const response = await fetch(
165+
`https://api.weather.com/v1/current?location=${location}&unit=${unit || "fahrenheit"}`
166+
);
167+
return await response.json();
168+
});
169+
```
170+
77171
## Using Tools in Chat
78172

79173
### Server-Side

docs/reference/classes/ToolCallManager.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: ToolCallManager
55

66
# Class: ToolCallManager
77

8-
Defined in: [tools/tool-calls.ts:41](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L41)
8+
Defined in: [tools/tool-calls.ts:51](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L51)
99

1010
Manages tool call accumulation and execution for the chat() method's automatic tool execution loop.
1111

@@ -47,7 +47,7 @@ if (manager.hasToolCalls()) {
4747
new ToolCallManager(tools): ToolCallManager;
4848
```
4949

50-
Defined in: [tools/tool-calls.ts:45](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L45)
50+
Defined in: [tools/tool-calls.ts:55](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L55)
5151

5252
#### Parameters
5353

@@ -67,7 +67,7 @@ readonly [`Tool`](../interfaces/Tool.md)\<`ZodType`\<`unknown`, `unknown`, `$Zod
6767
addToolCallChunk(chunk): void;
6868
```
6969

70-
Defined in: [tools/tool-calls.ts:53](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L53)
70+
Defined in: [tools/tool-calls.ts:63](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L63)
7171

7272
Add a tool call chunk to the accumulator
7373
Handles streaming tool calls by accumulating arguments
@@ -126,7 +126,7 @@ Handles streaming tool calls by accumulating arguments
126126
clear(): void;
127127
```
128128

129-
Defined in: [tools/tool-calls.ts:193](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L193)
129+
Defined in: [tools/tool-calls.ts:208](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L208)
130130

131131
Clear the tool calls map for the next iteration
132132

@@ -145,7 +145,7 @@ executeTools(doneChunk): AsyncGenerator<ToolResultStreamChunk, ModelMessage<
145145
| null>[], void>;
146146
```
147147

148-
Defined in: [tools/tool-calls.ts:111](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L111)
148+
Defined in: [tools/tool-calls.ts:121](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L121)
149149

150150
Execute all tool calls and return tool result messages
151151
Also yields tool_result chunks for streaming
@@ -171,7 +171,7 @@ Also yields tool_result chunks for streaming
171171
getToolCalls(): ToolCall[];
172172
```
173173

174-
Defined in: [tools/tool-calls.ts:101](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L101)
174+
Defined in: [tools/tool-calls.ts:111](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L111)
175175

176176
Get all complete tool calls (filtered for valid ID and name)
177177

@@ -187,7 +187,7 @@ Get all complete tool calls (filtered for valid ID and name)
187187
hasToolCalls(): boolean;
188188
```
189189

190-
Defined in: [tools/tool-calls.ts:94](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L94)
190+
Defined in: [tools/tool-calls.ts:104](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L104)
191191

192192
Check if there are any complete tool calls to execute
193193

docs/reference/functions/convertZodToJsonSchema.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@ title: convertZodToJsonSchema
99
function convertZodToJsonSchema(schema): Record<string, any> | undefined;
1010
```
1111

12-
Defined in: [tools/zod-converter.ts:31](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/zod-converter.ts#L31)
12+
Defined in: [tools/zod-converter.ts:57](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/zod-converter.ts#L57)
1313

14-
Converts a Zod schema to JSON Schema format compatible with LLM providers.
14+
Converts a schema (Zod or JSONSchema) to JSON Schema format compatible with LLM providers.
15+
If the input is already a JSONSchema object, it is returned as-is.
16+
If the input is a Zod schema, it is converted to JSON Schema.
1517

1618
## Parameters
1719

1820
### schema
1921

20-
Zod schema to convert
22+
Zod schema or JSONSchema object to convert
2123

22-
`ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\> | `undefined`
24+
[`SchemaInput`](../type-aliases/SchemaInput.md) | `undefined`
2325

2426
## Returns
2527

@@ -32,12 +34,13 @@ JSON Schema object that can be sent to LLM providers
3234
```typescript
3335
import { z } from 'zod';
3436

35-
const schema = z.object({
37+
// Using Zod schema
38+
const zodSchema = z.object({
3639
location: z.string().describe('City name'),
3740
unit: z.enum(['celsius', 'fahrenheit']).optional()
3841
});
3942

40-
const jsonSchema = convertZodToJsonSchema(schema);
43+
const jsonSchema = convertZodToJsonSchema(zodSchema);
4144
// Returns:
4245
// {
4346
// type: 'object',
@@ -47,4 +50,13 @@ const jsonSchema = convertZodToJsonSchema(schema);
4750
// },
4851
// required: ['location']
4952
// }
53+
54+
// Using JSONSchema directly (passes through unchanged)
55+
const rawSchema = {
56+
type: 'object',
57+
properties: { location: { type: 'string' } },
58+
required: ['location']
59+
};
60+
const result = convertZodToJsonSchema(rawSchema);
61+
// Returns the same object
5062
```

docs/reference/functions/toolDefinition.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ title: toolDefinition
99
function toolDefinition<TInput, TOutput, TName>(config): ToolDefinition<TInput, TOutput, TName>;
1010
```
1111

12-
Defined in: [tools/tool-definition.ts:170](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-definition.ts#L170)
12+
Defined in: [tools/tool-definition.ts:174](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-definition.ts#L174)
1313

1414
Create an isomorphic tool definition that can be used directly or instantiated for server/client
1515

@@ -22,11 +22,11 @@ The definition contains all tool metadata (name, description, schemas) and can b
2222

2323
### TInput
2424

25-
`TInput` *extends* `ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\> = `ZodAny`
25+
`TInput` *extends* [`SchemaInput`](../type-aliases/SchemaInput.md) = `ZodAny`
2626

2727
### TOutput
2828

29-
`TOutput` *extends* `ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\> = `ZodAny`
29+
`TOutput` *extends* [`SchemaInput`](../type-aliases/SchemaInput.md) = `ZodAny`
3030

3131
### TName
3232

docs/reference/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ title: "@tanstack/ai"
4141
- [ImagePart](interfaces/ImagePart.md)
4242
- [InternalToolCallState](interfaces/InternalToolCallState.md)
4343
- [JSONParser](interfaces/JSONParser.md)
44+
- [JSONSchema](interfaces/JSONSchema.md)
4445
- [ModelMessage](interfaces/ModelMessage.md)
4546
- [ProcessorResult](interfaces/ProcessorResult.md)
4647
- [ProcessorState](interfaces/ProcessorState.md)
@@ -80,12 +81,14 @@ title: "@tanstack/ai"
8081
- [ContentPartForModalities](type-aliases/ContentPartForModalities.md)
8182
- [ExtractModalitiesForModel](type-aliases/ExtractModalitiesForModel.md)
8283
- [ExtractModelsFromAdapter](type-aliases/ExtractModelsFromAdapter.md)
84+
- [InferSchemaType](type-aliases/InferSchemaType.md)
8385
- [InferToolInput](type-aliases/InferToolInput.md)
8486
- [InferToolName](type-aliases/InferToolName.md)
8587
- [InferToolOutput](type-aliases/InferToolOutput.md)
8688
- [MessagePart](type-aliases/MessagePart.md)
8789
- [ModalitiesArrayToUnion](type-aliases/ModalitiesArrayToUnion.md)
8890
- [Modality](type-aliases/Modality.md)
91+
- [SchemaInput](type-aliases/SchemaInput.md)
8992
- [StreamChunk](type-aliases/StreamChunk.md)
9093
- [StreamChunkType](type-aliases/StreamChunkType.md)
9194
- [ToolCallState](type-aliases/ToolCallState.md)

0 commit comments

Comments
 (0)