);
}
```
```
--------------------------------
### Install @tanstack/ai-vue
Source: https://tanstack.com/ai/latest/docs/api/ai-vue.md
Install the @tanstack/ai-vue package using npm.
```bash
npm install @tanstack/ai-vue
```
--------------------------------
### Install React AI Devtools
Source: https://tanstack.com/ai/latest/docs/getting-started/devtools.md
Install the necessary packages for React AI Devtools.
```bash
npm install -D @tanstack/react-ai-devtools @tanstack/react-devtools
```
--------------------------------
### Complete Example: Tree-Shakeable Chat Implementation
Source: https://tanstack.com/ai/latest/docs/advanced/tree-shaking.md
This example demonstrates importing only the 'chat' activity and the 'openaiText' adapter. Bundlers will exclude all other activities and adapters, optimizing the final bundle size.
```typescript
// Only import what you need
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
// Chat generation - returns AsyncIterable
const chatResult = chat({
adapter: openaiText('gpt-5.2'),
messages: [{ role: 'user', content: 'Hello!' }],
})
for await (const chunk of chatResult) {
console.log(chunk)
}
```
--------------------------------
### Install TanStack AI and Adapters
Source: https://tanstack.com/ai/latest/docs/getting-started/agent-skills.md
Install the core TanStack AI package and any necessary adapter packages, such as the OpenAI adapter, using pnpm.
```bash
pnpm add @tanstack/ai @tanstack/ai-openai
```
--------------------------------
### Install TanStack AI
Source: https://tanstack.com/ai/latest/docs/migration/migration-from-vercel-ai.md
Install TanStack AI and its corresponding adapters for model providers and framework integration.
```bash
npm install @tanstack/ai @tanstack/ai-react @tanstack/ai-openai @tanstack/ai-anthropic
```
--------------------------------
### Install Anthropic Adapter
Source: https://tanstack.com/ai/latest/docs/adapters/anthropic.md
Install the Anthropic adapter package using npm.
```bash
npm install @tanstack/ai-anthropic
```
--------------------------------
### Install OpenTelemetry API
Source: https://tanstack.com/ai/latest/docs/advanced/otel.md
Install the OpenTelemetry API as an optional peer dependency for `@tanstack/ai`.
```bash
pnpm add @opentelemetry/api
```
--------------------------------
### Install TanStack AI and OpenAI Adapter
Source: https://tanstack.com/ai/latest/docs/getting-started/quick-start-server.md
Install the necessary packages for TanStack AI and the OpenAI adapter using npm, pnpm, or yarn.
```bash
npm install @tanstack/ai @tanstack/ai-openai
# or
pnpm add @tanstack/ai @tanstack/ai-openai
# or
yarn add @tanstack/ai @tanstack/ai-openai
```
--------------------------------
### Example: Basic Chat
Source: https://tanstack.com/ai/latest/docs/api/ai-react.md
A simple example demonstrating how to use the `useChat` hook to create a basic chat interface.
```APIDOC
## Example: Basic Chat
```typescript
import { useState } from "react";
import { useChat, fetchServerSentEvents } from "@tanstack/ai-react";
export function Chat() {
const [input, setInput] = useState("");
const { messages, sendMessage, isLoading } = useChat({
connection: fetchServerSentEvents("/api/chat"),
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (input.trim() && !isLoading) {
sendMessage(input);
setInput("");
}
};
return (
);
}
```
```
--------------------------------
### Install Code Mode Skills Package
Source: https://tanstack.com/ai/latest/docs/code-mode/code-mode-with-skills.md
Install the necessary package for using code mode with skills.
```bash
pnpm add @tanstack/ai-code-mode-skills
```
--------------------------------
### Start Ollama Server
Source: https://tanstack.com/ai/latest/docs/adapters/ollama.md
Start the Ollama server process. It defaults to running on http://localhost:11434.
```bash
ollama serve
```
--------------------------------
### Install Mynth Adapter and TanStack AI
Source: https://tanstack.com/ai/latest/docs/community-adapters/mynth.md
Install the necessary packages for the Mynth adapter and TanStack AI using your preferred package manager.
```sh
# bun
bun add @mynthio/tanstack-ai-adapter @tanstack/ai
# pnpm
pnpm add @mynthio/tanstack-ai-adapter @tanstack/ai
# npm
npm install @mynthio/tanstack-ai-adapter @tanstack/ai
```
--------------------------------
### Example SSE Output
Source: https://tanstack.com/ai/latest/docs/protocol/sse-protocol.md
An example of the Server-Sent Events format, showing data chunks and a final `[DONE]` marker.
```text
data: {"type":"content","id":"msg_1","model":"gpt-5.2","timestamp":1701234567890,"delta":"Hello","content":"Hello"}
data: {"type":"content","id":"msg_1","model":"gpt-5.2","timestamp":1701234567891,"delta":" there","content":"Hello there"}
data: {"type":"done","id":"msg_1","model":"gpt-5.2","timestamp":1701234567892,"finishReason":"stop"}
data: [DONE]
```
--------------------------------
### Install OpenAI Adapter
Source: https://tanstack.com/ai/latest/docs/adapters/openai.md
Install the OpenAI adapter using npm. This package provides the necessary tools to connect with OpenAI's services.
```bash
npm install @tanstack/ai-openai
```
--------------------------------
### Install Decart AI Adapter
Source: https://tanstack.com/ai/latest/docs/community-adapters/decart.md
Install the Decart AI adapter package using npm.
```bash
npm install @decartai/tanstack-ai-adapter
```
--------------------------------
### Run Intent Install CLI
Source: https://tanstack.com/ai/latest/docs/getting-started/agent-skills.md
Execute the `intent install` command from your project's root to automatically discover and configure agent skills. This command scans for packages with skills and generates task-to-skill mappings.
```bash
npx @tanstack/intent@latest install
```
--------------------------------
### Install Soniox TanStack AI Adapter
Source: https://tanstack.com/ai/latest/docs/community-adapters/soniox.md
Install the Soniox adapter using npm. This command is used to add the necessary package to your project.
```bash
npm install @soniox/tanstack-ai-adapter
```
--------------------------------
### Install QuickJS Isolate Driver
Source: https://tanstack.com/ai/latest/docs/code-mode/code-mode-isolates.md
Install the QuickJS isolate driver using pnpm. This driver has no native dependencies and runs anywhere JavaScript runs.
```bash
pnpm add @tanstack/ai-isolate-quickjs
```
--------------------------------
### Ollama Chat Completion API Example
Source: https://tanstack.com/ai/latest/docs/adapters/ollama.md
Example of setting up a POST endpoint to handle chat completions using the Ollama adapter.
```typescript
import { chat, toServerSentEventsResponse } from "@tanstack/ai";
import { ollamaText } from "@tanstack/ai-ollama";
export async function POST(request: Request) {
const { messages } = await request.json();
const stream = chat({
adapter: ollamaText("llama3"),
messages,
});
return toServerSentEventsResponse(stream);
}
```
--------------------------------
### Server: Generate Realtime Token (TanStack Start)
Source: https://tanstack.com/ai/latest/docs/media/realtime-chat.md
Generates a short-lived token on the server for client authentication. This example uses TanStack Start but can be adapted for other server frameworks.
```typescript
import { realtimeToken } from '@tanstack/ai'
import { openaiRealtimeToken } from '@tanstack/ai-openai'
import { createServerFn } from '@tanstack/react-start'
const getRealtimeToken = createServerFn({ method: 'POST' })
.handler(async () => {
return realtimeToken({
adapter: openaiRealtimeToken({
model: 'gpt-4o-realtime-preview',
}),
})
})
```
--------------------------------
### Example with Tools
Source: https://tanstack.com/ai/latest/docs/adapters/anthropic.md
Integrate tools for the Anthropic adapter to use during chat.
```typescript
import { chat, toolDefinition } from "@tanstack/ai"
import { anthropicText } from "@tanstack/ai-anthropic"
import { z } from "zod"
const searchDatabaseDef = toolDefinition({
name: "search_database",
description: "Search the database",
inputSchema: z.object({
query: z.string(),
}),
});
const searchDatabase = searchDatabaseDef.server(async ({ query }) => {
// Search database
return { results: [] };
});
const stream = chat({
adapter: anthropicText("claude-sonnet-4-5"),
messages,
tools: [searchDatabase],
});
```
--------------------------------
### Example: Chat Completion with Tools
Source: https://tanstack.com/ai/latest/docs/adapters/openai.md
Integrate tools with the chat completion process using the `openaiText` adapter. This example defines a `getWeather` tool with Zod schema validation and demonstrates how to pass it to the `chat` function.
```typescript
import { chat, toolDefinition } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
import { z } from "zod";
const getWeatherDef = toolDefinition({
name: "get_weather",
description: "Get the current weather",
inputSchema: z.object({
location: z.string(),
}),
});
const getWeather = getWeatherDef.server(async ({ location }) => {
// Fetch weather data
return { temperature: 72, conditions: "sunny" };
});
const stream = chat({
adapter: openaiText("gpt-5.2"),
messages,
tools: [getWeather],
});
```
--------------------------------
### SSE Content Chunk Example
Source: https://tanstack.com/ai/latest/docs/protocol/sse-protocol.md
An example of a Server-Sent Event (SSE) formatted chunk containing content data. Each event starts with 'data: ', followed by the JSON-encoded chunk, and ends with a double newline.
```text
data: {"type":"content","id":"chatcmpl-abc123","model":"gpt-5.2","timestamp":1701234567890,"delta":"Hello","content":"Hello","role":"assistant"}\n\n
```
--------------------------------
### Example: With Tools
Source: https://tanstack.com/ai/latest/docs/adapters/grok.md
Demonstrates how to integrate custom tools with the Grok adapter for advanced chat interactions.
```APIDOC
## Example: With Tools
```typescript
import { chat, toolDefinition } from "@tanstack/ai";
import { grokText } from "@tanstack/ai-grok";
import { z } from "zod";
const getWeatherDef = toolDefinition({
name: "get_weather",
description: "Get the current weather",
inputSchema: z.object({
location: z.string(),
}),
});
const getWeather = getWeatherDef.server(async ({ location }) => {
// Fetch weather data
return { temperature: 72, conditions: "sunny" };
});
const stream = chat({
adapter: grokText("grok-4-1-fast-reasoning"),
messages,
tools: [getWeather],
});
```
```
--------------------------------
### Quick Start: Generate Image with Mynth Adapter
Source: https://tanstack.com/ai/latest/docs/community-adapters/mynth.md
A basic example demonstrating how to generate an image using the Mynth adapter with a specified model and prompt.
```ts
import { generateImage } from "@tanstack/ai";
import { mynthImage } from "@mynthio/tanstack-ai-adapter";
const result = await generateImage({
adapter: mynthImage("black-forest-labs/flux.2-dev"),
prompt: "Editorial product photo of a ceramic mug on a linen tablecloth",
numberOfImages: 1,
size: "1024x1024",
});
console.log(result.id);
console.log(result.model);
console.log(result.images[0]?.url);
```
--------------------------------
### Initialize Code Mode and Load Skills
Source: https://tanstack.com/ai/latest/docs/code-mode/code-mode-with-skills.md
This snippet demonstrates the manual setup of Code Mode, including initializing the driver, storage, and trust strategy. It shows how to load all available skills and convert them into tools for the LLM, bypassing the automatic skill selection process. This is useful when you need explicit control over which skills are available.
```typescript
import { chat, maxIterations } from '@tanstack/ai'
import { createCodeMode } from '@tanstack/ai-code-mode'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import {
createAlwaysTrustedStrategy,
createSkillManagementTools,
createSkillsSystemPrompt,
skillsToTools,
} from '@tanstack/ai-code-mode-skills'
import {createFileSkillStorage} from '@tanstack/ai-code-mode-skills/storage'
const trustStrategy = createAlwaysTrustedStrategy()
const storage = createFileSkillStorage({
directory: './.skills',
trustStrategy,
})
const driver = createNodeIsolateDriver()
// 1. Create Code Mode tool + prompt
const { tool: codeModeTool, systemPrompt: codeModePrompt } =
createCodeMode({
driver,
tools: [myTool1, myTool2],
timeout: 60_000,
memoryLimit: 128,
})
// 2. Load all skills and convert to tools
const allSkills = await storage.loadAll()
const skillIndex = await storage.loadIndex()
const skillTools = allSkills.length > 0
? skillsToTools({
skills: allSkills,
driver,
tools: [myTool1, myTool2],
storage,
timeout: 60_000,
memoryLimit: 128,
})
: []
// 3. Create management tools
const managementTools = createSkillManagementTools({
storage,
trustStrategy,
})
// 4. Generate skill library prompt
const skillsPrompt = createSkillsSystemPrompt({
selectedSkills: allSkills,
totalSkillCount: skillIndex.length,
skillsAsTools: true,
})
// 5. Assemble and call chat()
const stream = chat({
adapter: openaiText('gpt-4o'),
tools: [codeModeTool, ...managementTools, ...skillTools],
messages,
systemPrompts: [BASE_PROMPT, codeModePrompt, skillsPrompt],
agentLoopStrategy: maxIterations(15),
})
```
--------------------------------
### Next.js Server Setup for Chat API
Source: https://tanstack.com/ai/latest/docs/getting-started/quick-start.md
Set up a Next.js API route to handle chat requests. This example shows integration with OpenAI and streaming responses.
```typescript
import { chat, toServerSentEventsResponse } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
export async function POST(request: Request) {
// Check for API key
if (!process.env.OPENAI_API_KEY) {
return new Response(
JSON.stringify({
error: "OPENAI_API_KEY not configured",
}),
{
status: 500,
headers: { "Content-Type": "application/json" },
}
);
}
const body = await request.json();
try {
// Create a streaming chat response. `chat()` reads the AG-UI
// `threadId` for devtools correlation when available.
const stream = chat({
adapter: openaiText("gpt-5.2"),
messages: body.messages,
});
// Convert stream to HTTP response
return toServerSentEventsResponse(stream);
} catch (error) {
return new Response(
JSON.stringify({
error: error instanceof Error ? error.message : "An error occurred",
}),
{
status: 500,
headers: { "Content-Type": "application/json" },
}
);
}
}
```
--------------------------------
### Setup Server Event Bus in Next.js
Source: https://tanstack.com/ai/latest/docs/getting-started/devtools.md
Manually start the ServerEventBus in Next.js by implementing the instrumentation hook to enable server-side devtools middleware to emit events.
```ts
export async function register() {
if (
process.env["NEXT_RUNTIME"] === "nodejs" &&
process.env.NODE_ENV === "development"
) {
const { ServerEventBus } = await import(
"@tanstack/devtools-event-bus/server"
);
const bus = new ServerEventBus();
await bus.start();
}
}
```
--------------------------------
### Base Generation Composable Setup
Source: https://tanstack.com/ai/latest/docs/api/ai-vue.md
Illustrates the basic setup for the `useGeneration` composable in Vue.js for custom AI generation tasks. It shows how to initialize the composable with a server-sent events connection.
```typescript
import { useGeneration } from "@tanstack/ai-vue";
import { fetchServerSentEvents } from "@tanstack/ai-client";
const { generate, result, isLoading, error, status, stop, reset } =
useGeneration({
connection: fetchServerSentEvents("/api/generate/custom"),
});
```
--------------------------------
### Basic Chat Example with useChat
Source: https://tanstack.com/ai/latest/docs/api/ai-preact.md
A fundamental example of using the `useChat` hook to build a chat interface. It manages user input, sends messages, and displays chat history.
```typescript
import { useState } from "preact/hooks";
import { useChat, fetchServerSentEvents } from "@tanstack/ai-preact";
export function Chat() {
const [input, setInput] = useState("");
const { messages, sendMessage, isLoading } = useChat({
connection: fetchServerSentEvents("/api/chat"),
});
const handleSubmit = (e) => {
e.preventDefault();
if (input.trim() && !isLoading) {
sendMessage(input);
setInput("");
}
};
return (
);
}
```
--------------------------------
### Tool Calling with Cencori
Source: https://tanstack.com/ai/latest/docs/community-adapters/cencori.md
Implement tool calling by defining available tools with their schemas. This example shows how to handle a tool call for getting weather information.
```typescript
import { chat } from "@tanstack/ai";
import { cencori } from "@cencori/ai-sdk/tanstack";
const adapter = cencori("gpt-4o");
for await (const chunk of chat({
adapter,
messages: [{ role: "user", content: "What's the weather in NYC?" }],
tools: {
getWeather: {
name: "getWeather",
description: "Get weather for a location",
inputSchema: {
type: "object",
properties: { location: { type: "string" } },
},
},
},
})) {
if (chunk.type === "tool_call") {
console.log("Tool call:", chunk.toolCall);
}
}
```
--------------------------------
### RUN_STARTED Event Definition and Example
Source: https://tanstack.com/ai/latest/docs/protocol/chunk-definitions.md
Emitted when a run begins. Includes a unique runId and optional threadId. Use this event to track the start of a new AI interaction.
```typescript
interface RunStartedEvent extends BaseAGUIEvent {
type: 'RUN_STARTED';
runId: string; // Unique identifier for this run
threadId?: string; // Optional thread/conversation ID
}
```
```json
{
"type": "RUN_STARTED",
"runId": "run_abc123",
"model": "gpt-4o",
"timestamp": 1701234567890
}
```
--------------------------------
### Parallel Tool Execution Example
Source: https://tanstack.com/ai/latest/docs/tools/tool-architecture.md
Illustrates how an LLM can call multiple tools simultaneously for improved efficiency. The example shows a user request triggering parallel calls to a 'get_weather' tool for different cities, with results collected for comparison.
```text
User: "Compare the weather in NYC, SF, and LA"
LLM calls:
- get_weather({city: "NYC"}) [index: 0]
- get_weather({city: "SF"}) [index: 1]
- get_weather({city: "LA"}) [index: 2]
All execute simultaneously, then LLM generates comparison.
```
--------------------------------
### TanStack Router Server Setup for Chat API
Source: https://tanstack.com/ai/latest/docs/getting-started/quick-start.md
Set up an API route using TanStack Router to handle chat requests. This example demonstrates how to integrate with OpenAI and stream responses.
```typescript
import { chat, toServerSentEventsResponse } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/api/chat")({
server: {
handlers: {
POST: async ({ request }) => {
// Check for API key
if (!process.env.OPENAI_API_KEY) {
return new Response(
JSON.stringify({
error: "OPENAI_API_KEY not configured",
}),
{
status: 500,
headers: { "Content-Type": "application/json" },
},
);
}
const body = await request.json();
try {
// Create a streaming chat response. `chat()` reads the AG-UI
// `threadId` for devtools correlation when available.
const stream = chat({
adapter: openaiText("gpt-5.2"),
messages: body.messages,
});
// Convert stream to HTTP response
return toServerSentEventsResponse(stream);
} catch (error) {
return new Response(
JSON.stringify({
error:
error instanceof Error ? error.message : "An error occurred",
}),
{
status: 500,
headers: { "Content-Type": "application/json" },
},
);
}
},
},
},
});
```
--------------------------------
### ImmediateStrategy Constructor
Source: https://tanstack.com/ai/latest/docs/reference/classes/ImmediateStrategy.md
Initializes a new instance of the ImmediateStrategy class.
```APIDOC
## Constructor
### `new ImmediateStrategy()`
Initializes a new instance of the `ImmediateStrategy` class.
#### Returns
- `ImmediateStrategy`: An instance of the `ImmediateStrategy` class.
```
--------------------------------
### TanStack AI Server API Setup
Source: https://tanstack.com/ai/latest/docs/migration/migration-from-vercel-ai.md
Set up a server-side API endpoint using TanStack AI to handle chat requests. This example defines a tool for fetching weather and integrates it with the chat model.
```typescript
// server/api/chat.ts
import { chat, toServerSentEventsResponse, toolDefinition } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import { z } from 'zod'
const getWeatherDef = toolDefinition({
name: 'getWeather',
description: 'Get weather',
inputSchema: z.object({ city: z.string() }),
outputSchema: z.object({ temp: z.number(), conditions: z.string() }),
})
const getWeather = getWeatherDef.server(async ({ city }) => fetchWeather(city))
export async function POST(request: Request) {
const { messages } = await request.json()
const stream = chat({
adapter: openaiText('gpt-4o'),
systemPrompts: ['You are a helpful assistant.'],
messages,
temperature: 0.7,
tools: [getWeather],
})
return toServerSentEventsResponse(stream)
}
```
--------------------------------
### Vue Chat: Client Tools with Type Safety
Source: https://tanstack.com/ai/latest/docs/api/ai-vue.md
Example of integrating type-safe client-side tools with the `useChat` composable in Vue.js. This setup ensures that tool inputs and outputs are correctly typed, enhancing development safety.
```vue
Tool executed: {{ part.name }}
```
--------------------------------
### Configuration
Source: https://tanstack.com/ai/latest/docs/community-adapters/cencori.md
Shows how to create a custom Cencori adapter using `createCencori` with an API key and optional base URL.
```typescript
import { createCencori } from "@cencori/ai-sdk/tanstack";
const cencori = createCencori({
apiKey: process.env.CENCORI_API_KEY!,
baseUrl: "https://cencori.com", // Optional
});
const adapter = cencori("gpt-4o");
```
--------------------------------
### Configuration
Source: https://tanstack.com/ai/latest/docs/adapters/grok.md
Illustrates how to configure the Grok adapter with options like baseURL.
```APIDOC
## Configuration
```typescript
import { createGrokText, type GrokTextConfig } from "@tanstack/ai-grok";
const config: Omit = {
baseURL: "https://api.x.ai/v1", // Optional, this is the default
};
const adapter = createGrokText("grok-4", process.env.XAI_API_KEY!, config);
```
```
--------------------------------
### Initialize Code Mode with Skills (High-Level API)
Source: https://tanstack.com/ai/latest/docs/code-mode/code-mode-with-skills.md
Set up and initialize `codeModeWithSkills` with a storage driver, tools, and LLM adapters for skill selection and main chat. This is the high-level approach for turnkey setup.
```typescript
import {
chat,
maxIterations,
toServerSentEventsStream,
} from '@tanstack/ai'
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
import { codeModeWithSkills } from '@tanstack/ai-code-mode-skills'
import { createFileSkillStorage } from '@tanstack/ai-code-mode-skills/storage'
import { openaiText } from '@tanstack/ai-openai'
const storage = createFileSkillStorage({ directory: './.skills' })
const driver = createNodeIsolateDriver()
const { toolsRegistry, systemPrompt, selectedSkills } = await codeModeWithSkills({
config: {
driver,
tools: [myTool1, myTool2],
timeout: 60_000,
memoryLimit: 128,
},
adapter: openaiText('gpt-4o-mini'), // cheap model for skill selection
skills: {
storage,
maxSkillsInContext: 5,
},
messages, // current conversation
})
const stream = chat({
adapter: openaiText('gpt-4o'), // strong model for reasoning
toolRegistry: toolsRegistry,
messages,
systemPrompts: ['You are a helpful assistant.', systemPrompt],
agentLoopStrategy: maxIterations(15),
})
```
--------------------------------
### Complete Video Generation Workflow
Source: https://tanstack.com/ai/latest/docs/community-adapters/decart.md
A comprehensive example demonstrating video job creation, polling for status, and returning the video URL upon successful completion.
```typescript
import { generateVideo, getVideoJobStatus } from "@tanstack/ai";
import { decartVideo } from "@decartai/tanstack-ai-adapter";
async function createVideo(prompt: string) {
const adapter = decartVideo("lucy-pro-t2v");
// Create the job
const { jobId } = await generateVideo({ adapter, prompt });
console.log("Job created:", jobId);
// Poll for completion
let status = "pending";
while (status !== "completed" && status !== "failed") {
await new Promise((resolve) => setTimeout(resolve, 5000));
const result = await getVideoJobStatus({ adapter, jobId });
status = result.status;
console.log(`Status: ${status}`);
if (result.status === "failed") {
throw new Error("Video generation failed");
}
if (result.status === "completed" && result.url) {
return result.url;
}
}
}
const videoUrl = await createVideo("A drone shot over a tropical beach");
```
--------------------------------
### Install Ollama on macOS
Source: https://tanstack.com/ai/latest/docs/adapters/ollama.md
Install Ollama using Homebrew on macOS.
```bash
# macOS
brew install ollama
```
--------------------------------
### Define and Implement Server Tools
Source: https://tanstack.com/ai/latest/docs/tools/server-tools.md
Demonstrates defining multiple server tools, including one for user data and another for searching products via an external API. The product search tool includes server-only API key access.
```typescript
import { toolDefinition } from "@tanstack/ai";
import { z } from "zod";
// Step 1: Define the tool schema
const getUserDataDef = toolDefinition({
name: "get_user_data",
description: "Get user information from the database",
inputSchema: z.object({
userId: z.string().meta({ description: "The user ID to look up" }),
}),
outputSchema: z.object({
name: z.string(),
email: z.string().email(),
createdAt: z.string(),
}),
});
// Step 2: Create server implementation
const getUserData = getUserDataDef.server(async ({ userId }) => {
// This runs on the server - can access database, APIs, etc.
const user = await db.users.findUnique({ where: { id: userId } });
return {
name: user.name,
email: user.email,
createdAt: user.createdAt.toISOString(),
};
});
// Example: API call tool
const searchProductsDef = toolDefinition({
name: "search_products",
description: "Search for products in the catalog",
inputSchema: z.object({
query: z.string().meta({ description: "Search query" }),
limit: z.number().optional().meta({ description: "Maximum number of results" }),
}),
});
const searchProducts = searchProductsDef.server(async ({ query, limit = 10 }) => {
const response = await fetch(
`https://api.example.com/products?q=${query}&limit=${limit}`,
{
headers: {
Authorization: `Bearer ${process.env.API_KEY}`, // Server-only access
},
}
);
return await response.json();
});
```
--------------------------------
### Basic Usage
Source: https://tanstack.com/ai/latest/docs/adapters/grok.md
Demonstrates the basic setup for using the Grok adapter with the chat function.
```APIDOC
## Basic Usage
```typescript
import { chat } from "@tanstack/ai";
import { grokText } from "@tanstack/ai-grok";
const stream = chat({
adapter: grokText("grok-4"),
messages: [{ role: "user", content: "Hello!" }],
});
```
```
--------------------------------
### Environment Variables for API Keys
Source: https://tanstack.com/ai/latest/docs/getting-started/quick-start-server.md
Example of setting API keys in a `.env` file for different providers like OpenRouter or OpenAI. The adapter reads these at runtime.
```bash
# OpenRouter (recommended — access 300+ models with one key)
OPENROUTER_API_KEY=sk-or-...
# OpenAI
OPENAI_API_KEY=your-openai-api-key
```
--------------------------------
### Chat Completion Example
Source: https://tanstack.com/ai/latest/docs/adapters/anthropic.md
Example of handling chat completions and streaming responses.
```typescript
import { chat, toServerSentEventsResponse } from "@tanstack/ai"
import { anthropicText } from "@tanstack/ai-anthropic"
export async function POST(request: Request) {
const { messages } = await request.json();
const stream = chat({
adapter: anthropicText("claude-sonnet-4-5"),
messages,
});
return toServerSentEventsResponse(stream);
}
```
--------------------------------
### Dynamic Configuration with Middleware
Source: https://tanstack.com/ai/latest/docs/advanced/middleware.md
Shows how to dynamically adjust chat configuration using middleware. This example adds a system prompt during initialization and increases the temperature on retries.
```typescript
const dynamicTemperature: ChatMiddleware = {
name: "dynamic-temperature",
onConfig: (ctx, config) => {
if (ctx.phase === "init") {
// Add a system prompt at startup — only systemPrompts is overwritten
return {
systemPrompts: [
...config.systemPrompts,
"You are a helpful assistant.",
],
};
}
if (ctx.phase === "beforeModel" && ctx.iteration > 0) {
// Increase temperature on retries — other fields stay unchanged
return {
temperature: Math.min((config.temperature ?? 0.7) + 0.1, 1.0),
};
}
},
};
```
--------------------------------
### Example: Tool Approval
Source: https://tanstack.com/ai/latest/docs/api/ai-react.md
Demonstrates how to handle tool calls that require user approval in a React chat interface. It shows how to request approval and then send the response back to the server.
```APIDOC
## Example: Tool Approval
```typescript
import { useChat, fetchServerSentEvents } from "@tanstack/ai-react";
export function ChatWithApproval() {
const { messages, sendMessage, addToolApprovalResponse } = useChat({
connection: fetchServerSentEvents("/api/chat"),
});
return (