Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/social-waves-film.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@tanstack/ai-anthropic': minor
'@tanstack/ai-gemini': minor
'@tanstack/ai-ollama': minor
'@tanstack/ai-openai': minor
'@tanstack/ai': minor
---

Add in standard schema support instead of zod
3 changes: 3 additions & 0 deletions docs/getting-started/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ TanStack AI lets you define a tool once and provide environment-specific impleme

```typescript
import { toolDefinition } from '@tanstack/ai'
import { convertZodToJsonSchema } from "@tanstack/ai/zod";
import { z } from 'zod'

// Define a tool
const getProductsDef = toolDefinition({
name: 'getProducts',
toJsonSchema: convertZodToJsonSchema,
inputSchema: z.object({ query: z.string() }),
outputSchema: z.array(z.object({ id: z.string(), name: z.string() })),
})
Expand Down
4 changes: 4 additions & 0 deletions docs/getting-started/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,13 @@ Since TanStack AI is framework-agnostic, you can define and use tools in any env

```typescript
import { toolDefinition } from '@tanstack/ai'
import { convertZodToJsonSchema } from "@tanstack/ai/zod";
import { z } from 'zod'


const getProductsDef = toolDefinition({
name: 'getProducts',
toJsonSchema: convertZodToJsonSchema,
inputSchema: z.object({ query: z.string() }),
})

Expand Down
2 changes: 2 additions & 0 deletions docs/guides/agentic-cycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Here's a real-world example of the agentic cycle:
const getWeatherDef = toolDefinition({
name: "get_weather",
description: "Get current weather for a city",
toJsonSchema: convertZodToJsonSchema,
inputSchema: z.object({
city: z.string(),
}),
Expand All @@ -97,6 +98,7 @@ const getWeatherDef = toolDefinition({
const getClothingAdviceDef = toolDefinition({
name: "get_clothing_advice",
description: "Get clothing recommendations based on weather",
toJsonSchema: convertZodToJsonSchema,
inputSchema: z.object({
temperature: z.number(),
conditions: z.string(),
Expand Down
4 changes: 4 additions & 0 deletions docs/guides/client-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Client tools use the same `toolDefinition()` API but with the `.client()` method
```typescript
// tools/definitions.ts - Shared between server and client
import { toolDefinition } from "@tanstack/ai";
import { convertZodToJsonSchema } from "@tanstack/ai/zod";
import { z } from "zod";

export const updateUIDef = toolDefinition({
Expand All @@ -67,6 +68,7 @@ export const updateUIDef = toolDefinition({
message: z.string().describe("Message to display"),
type: z.enum(["success", "error", "info"]).describe("Message type"),
}),
toJsonSchema: convertZodToJsonSchema,
outputSchema: z.object({
success: z.boolean(),
}),
Expand All @@ -79,6 +81,7 @@ export const saveToLocalStorageDef = toolDefinition({
key: z.string().describe("Storage key"),
value: z.string().describe("Value to store"),
}),
toJsonSchema: convertZodToJsonSchema,
outputSchema: z.object({
saved: z.boolean(),
}),
Expand Down Expand Up @@ -274,6 +277,7 @@ const addToCartDef = toolDefinition({
itemId: z.string(),
quantity: z.number(),
}),
toJsonSchema: convertZodToJsonSchema,
outputSchema: z.object({
success: z.boolean(),
cartId: z.string(),
Expand Down
4 changes: 4 additions & 0 deletions docs/guides/server-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ For better organization, define tool schemas and implementations separately:
```typescript
// tools/definitions.ts
import { toolDefinition } from "@tanstack/ai";
import { convertZodToJsonSchema } from "@tanstack/ai/zod";
import { z } from "zod";

export const getUserDataDef = toolDefinition({
Expand All @@ -173,6 +174,7 @@ export const getUserDataDef = toolDefinition({
inputSchema: z.object({
userId: z.string(),
}),
toJsonSchema: convertZodToJsonSchema,
outputSchema: z.object({
name: z.string(),
email: z.string(),
Expand All @@ -182,6 +184,7 @@ export const getUserDataDef = toolDefinition({
export const searchProductsDef = toolDefinition({
name: "search_products",
description: "Search products",
toJsonSchema: convertZodToJsonSchema,
inputSchema: z.object({
query: z.string(),
}),
Expand Down Expand Up @@ -236,6 +239,7 @@ const getUserDataDef = toolDefinition({
inputSchema: z.object({
userId: z.string(),
}),
toJsonSchema: convertZodToJsonSchema,
outputSchema: z.object({
name: z.string().optional(),
email: z.string().optional(),
Expand Down
11 changes: 11 additions & 0 deletions docs/guides/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Tools are defined using `toolDefinition()` from `@tanstack/ai`:

```typescript
import { toolDefinition } from "@tanstack/ai";
import { convertZodToJsonSchema } from "@tanstack/ai/zod";
import { z } from "zod";

// Step 1: Define the tool schema
Expand All @@ -51,6 +52,8 @@ const getWeatherDef = toolDefinition({
location: z.string().describe("The city and state, e.g. San Francisco, CA"),
unit: z.enum(["celsius", "fahrenheit"]).optional(),
}),
// Do not forget to pass in the toJsonSchema function to convert it to JSON Schema
toJsonSchema: convertZodToJsonSchema,
outputSchema: z.object({
temperature: z.number(),
conditions: z.string(),
Expand All @@ -74,6 +77,13 @@ const getWeatherServer = getWeatherDef.server(async ({ location, unit }) => {
});
```

## Tool validation

We support ANY validation library by requiring you to provide a `toJsonSchema` function when defining your tool.
This function converts your input and output schemas to JSON Schema, which is the format used for tool calling with LLMs.
In the example above, we use `convertZodToJsonSchema` from `@tanstack/ai/zod` to convert Zod schemas to JSON Schema.
You can implement similar functions for other validation libraries if needed.

## Using Tools in Chat

### Server-Side
Expand Down Expand Up @@ -158,6 +168,7 @@ const addToCartDef = toolDefinition({
itemId: z.string(),
quantity: z.number(),
}),
toJsonSchema: convertZodToJsonSchema,
outputSchema: z.object({
success: z.boolean(),
cartId: z.string(),
Expand Down
16 changes: 8 additions & 8 deletions docs/reference/classes/ToolCallManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: ToolCallManager

# Class: ToolCallManager

Defined in: [tools/tool-calls.ts:41](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L41)
Defined in: [tools/tool-calls.ts:80](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L80)

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

Expand Down Expand Up @@ -47,13 +47,13 @@ if (manager.hasToolCalls()) {
new ToolCallManager(tools): ToolCallManager;
```

Defined in: [tools/tool-calls.ts:45](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L45)
Defined in: [tools/tool-calls.ts:84](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L84)

#### Parameters

##### tools

readonly [`Tool`](../interfaces/Tool.md)\<`ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\>, `ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\>, `string`\>[]
readonly [`Tool`](../interfaces/Tool.md)\<`StandardSchemaV1`\<`unknown`, `unknown`\>, `StandardSchemaV1`\<`unknown`, `unknown`\>, `string`\>[]

#### Returns

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

Defined in: [tools/tool-calls.ts:53](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L53)
Defined in: [tools/tool-calls.ts:92](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L92)

Add a tool call chunk to the accumulator
Handles streaming tool calls by accumulating arguments
Expand Down Expand Up @@ -126,7 +126,7 @@ Handles streaming tool calls by accumulating arguments
clear(): void;
```

Defined in: [tools/tool-calls.ts:193](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L193)
Defined in: [tools/tool-calls.ts:232](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L232)

Clear the tool calls map for the next iteration

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

Defined in: [tools/tool-calls.ts:111](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L111)
Defined in: [tools/tool-calls.ts:150](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L150)

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

Defined in: [tools/tool-calls.ts:101](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L101)
Defined in: [tools/tool-calls.ts:140](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L140)

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

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

Defined in: [tools/tool-calls.ts:94](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L94)
Defined in: [tools/tool-calls.ts:133](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-calls.ts#L133)

Check if there are any complete tool calls to execute

Expand Down
50 changes: 0 additions & 50 deletions docs/reference/functions/convertZodToJsonSchema.md

This file was deleted.

21 changes: 18 additions & 3 deletions docs/reference/functions/toolDefinition.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: toolDefinition
function toolDefinition<TInput, TOutput, TName>(config): ToolDefinition<TInput, TOutput, TName>;
```

Defined in: [tools/tool-definition.ts:170](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-definition.ts#L170)
Defined in: [tools/tool-definition.ts:193](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/tools/tool-definition.ts#L193)

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

Expand All @@ -18,15 +18,17 @@ The definition contains all tool metadata (name, description, schemas) and can b
2. Instantiated as a server tool with .server()
3. Instantiated as a client tool with .client()

This function supports any Standard Schema compliant library (Zod, Valibot, ArkType, etc.)

## Type Parameters

### TInput

`TInput` *extends* `ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\> = `ZodAny`
`TInput` *extends* `StandardSchemaV1`\<`unknown`, `unknown`\> = `StandardSchemaV1`\<`unknown`, `unknown`\>

### TOutput

`TOutput` *extends* `ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\> = `ZodAny`
`TOutput` *extends* `StandardSchemaV1`\<`unknown`, `unknown`\> = `StandardSchemaV1`\<`unknown`, `unknown`\>

### TName

Expand All @@ -48,6 +50,7 @@ The definition contains all tool metadata (name, description, schemas) and can b
import { toolDefinition } from '@tanstack/ai';
import { z } from 'zod';

// Using Zod (Standard Schema compliant)
const addToCartTool = toolDefinition({
name: 'addToCart',
description: 'Add a guitar to the shopping cart (requires approval)',
Expand All @@ -63,6 +66,18 @@ const addToCartTool = toolDefinition({
}),
});

// Using Valibot (Standard Schema compliant)
import * as v from 'valibot';

const searchTool = toolDefinition({
name: 'search',
description: 'Search the database',
inputSchema: v.object({
query: v.string(),
limit: v.optional(v.number()),
}),
});

// Use directly in chat (server-side, no execute function)
chat({
tools: [addToCartTool],
Expand Down
1 change: 0 additions & 1 deletion docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ title: "@tanstack/ai"
- [chatOptions](functions/chatOptions.md)
- [combineStrategies](functions/combineStrategies.md)
- [convertMessagesToModelMessages](functions/convertMessagesToModelMessages.md)
- [convertZodToJsonSchema](functions/convertZodToJsonSchema.md)
- [createReplayStream](functions/createReplayStream.md)
- [embedding](functions/embedding.md)
- [generateMessageId](functions/generateMessageId.md)
Expand Down
Loading
Loading