TypeScript toolkit for building AI-powered applications with unified provider access, streaming UI, tool calling, structured outputs, and agent support across Next.js, React, Svelte, Vue, Angular, and Node.js
Use the AI SDK to build AI-powered applications with TypeScript and JavaScript. The SDK provides a unified, provider-agnostic API for working with language models, streaming UI, tool calling, structured outputs, and agent patterns.
```bash
npm install ai
```
For framework-specific UI hooks:
```bash
npm install @ai-sdk/react # or @ai-sdk/svelte, @ai-sdk/vue, etc.
```
The AI SDK supports two approaches for model access:
Use model strings directly - no provider SDK installation required:
```ts
import { generateText } from 'ai';
const result = await generateText({
model: 'anthropic/claude-opus-4.5', // or 'openai/gpt-5.2', 'google/gemini-3-flash'
prompt: 'Your prompt here',
});
```
Install provider packages for direct API access:
```bash
npm install @ai-sdk/openai @ai-sdk/anthropic @ai-sdk/google
```
```ts
import { generateText } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
const result = await generateText({
model: anthropic('claude-opus-4-5-20250414'),
prompt: 'Your prompt here',
});
```
```ts
import { generateText } from 'ai';
const { text } = await generateText({
model: 'openai/gpt-5',
prompt: 'What is an agent?',
});
```
Use `Output.object()` with Zod schemas to enforce structured responses:
```ts
import { generateText, Output } from 'ai';
import { z } from 'zod';
const { output } = await generateText({
model: 'openai/gpt-5',
output: Output.object({
schema: z.object({
recipe: z.object({
name: z.string(),
ingredients: z.array(
z.object({ name: z.string(), amount: z.string() })
),
steps: z.array(z.string()),
}),
}),
}),
prompt: 'Generate a lasagna recipe.',
});
// output.recipe is fully typed from your schema
```
```ts
import { ToolLoopAgent } from 'ai';
import { openai } from '@ai-sdk/openai';
const agent = new ToolLoopAgent({
model: 'openai/gpt-5',
system: 'You are an agent with access to a shell environment.',
tools: {
shell: openai.tools.localShell({
execute: async ({ action }) => {
// Execute shell command in sandbox
const [cmd, ...args] = action.command;
const sandbox = await getSandbox();
const command = await sandbox.runCommand({ cmd, args });
return { output: await command.stdout() };
},
}),
},
});
```
**File:** `@/agent/image-generation-agent.ts`
```ts
import { openai } from '@ai-sdk/openai';
import { ToolLoopAgent, InferAgentUIMessage } from 'ai';
export const imageGenerationAgent = new ToolLoopAgent({
model: openai('gpt-5'),
tools: {
generateImage: openai.tools.imageGeneration({
partialImages: 3,
}),
},
});
export type ImageGenerationAgentMessage = InferAgentUIMessage<
typeof imageGenerationAgent
>;
```
**File:** `@/app/api/chat/route.ts`
```ts
import { imageGenerationAgent } from '@/agent/image-generation-agent';
import { createAgentUIStreamResponse } from 'ai';
export async function POST(req: Request) {
const { messages } = await req.json();
return createAgentUIStreamResponse({
agent: imageGenerationAgent,
messages,
});
}
```
**File:** `@/component/image-generation-view.tsx`
```tsx
import { openai } from '@ai-sdk/openai';
import { UIToolInvocation } from 'ai';
export default function ImageGenerationView({
invocation,
}: {
invocation: UIToolInvocation<ReturnType<typeof openai.tools.imageGeneration>>;
}) {
switch (invocation.state) {
case 'input-available':
return <div>Generating image...</div>;
case 'output-available':
return <img src={`data:image/png;base64,${invocation.output.result}`} />;
}
}
```
**File:** `@/app/page.tsx`
```tsx
'use client';
import { ImageGenerationAgentMessage } from '@/agent/image-generation-agent';
import ImageGenerationView from '@/component/image-generation-view';
import { useChat } from '@ai-sdk/react';
import { useState } from 'react';
export default function Page() {
const { messages, status, sendMessage } =
useChat<ImageGenerationAgentMessage>();
const [input, setInput] = useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
sendMessage({ text: input });
setInput('');
};
return (
<div>
{messages.map(message => (
<div key={message.id}>
<strong>{`${message.role}: `}</strong>
{message.parts.map((part, index) => {
switch (part.type) {
case 'text':
return <div key={index}>{part.text}</div>;
case 'tool-generateImage':
return <ImageGenerationView key={index} invocation={part} />;
}
})}
</div>
))}
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={e => setInput(e.target.value)}
disabled={status !== 'ready'}
/>
</form>
</div>
);
}
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/ai-sdk-by-vercel/raw