AI SDK 5
Vercel AI SDK 5 patterns. Trigger: When building AI chat features - breaking changes from v4.
MCP get_skill({ skillId: "ai-sdk-5-0d63d95e" })Use this skill with your agent
Create a free account and connect via MCP
## Breaking Changes from AI SDK 4
```typescript
// ❌ AI SDK 4 (OLD)
import { useChat } from "ai";
const { messages, handleSubmit, input, handleInputChange } = useChat({
api: "/api/chat",
});
// ✅ AI SDK 5 (NEW)
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
});
```
## Client Setup
```typescript
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { useState } from "react";
export function Chat() {
const [input, setInput] = useState("");
const { messages, sendMessage, isLoading, error } = useChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!input.trim()) return;
sendMessage({ text: input });
setInput("");
};
return (
<div>
<div>
{messages.map((message) => (
<Message key={message.id} message={message} />
))}
</div>
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type a message..."
disabled={isLoading}
/>
<button type="submit" disabled={isLoading}>
Send
</button>
</form>
{error && <div>Error: {error.message}</div>}
</div>
);
}
```
## UIMessage Structure (v5)
```typescript
// ❌ Old: message.content was a string
// ✅ New: message.parts is an array
interface UIMessage {
id: string;
role: "user" | "assistant" | "system";
parts: MessagePart[];
}
type MessagePart =
| { type: "text"; text: string }
| { type: "image"; image: string }
| { type: "tool-call"; toolCallId: string; toolName: string; args: unknown }
| { type: "tool-result"; toolCallId: string; result: unknown };
// Extract text from parts
function getMessageText(message: UIMessage): string {
return message.parts
.filter((part): part is { type: "text"; text: string } => part.type === "text")
.map((part) => part.text)
.join("");
}
// Render message
function Message({ message }: { message: UIMessage }) {
return (
<div className={message.role === "user" ? "user" : "assistant"}>
{message.parts.map((part, index) => {
if (part.type === "text") {
return <p key={index}>{part.text}</p>;
}
if (part.type === "image") {
return <img key={index} src={part.image} alt="" />;
}
return null;
})}
</div>
);
}
```
## Server-Side (Route Handler)
```typescript
// app/api/chat/route.ts
import { openai } from "@ai-sdk/openai";
import { streamText } from "ai";
export async function POST(req: Request) {
const { messages } = await req.json();
const result = await streamText({
model: openai("gpt-4o"),
messages,
system: "You are a helpful assistant.",
});
return result.toDataStreamResponse();
}
```
## With LangChain
```typescript
// app/api/chat/route.ts
import { toUIMessageStream } from "@ai-sdk/langchain";
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, AIMessage } from "@langchain/core/messages";
export async function POST(req: Request) {
const { messages } = await req.json();
const model = new ChatOpenAI({
modelName: "gpt-4o",
streaming: true,
});
// Convert UI messages to LangChain format
const langchainMessages = messages.map((m) => {
const text = m.parts
.filter((p) => p.type === "text")
.map((p) => p.text)
.join("");
return m.role === "user"
? new HumanMessage(text)
: new AIMessage(text);
});
const stream = await model.stream(langchainMessages);
return toUIMessageStream(stream).toDataStreamResponse();
}
```
## Streaming with Tools
```typescript
import { openai } from "@ai-sdk/openai";
import { streamText, tool } from "ai";
import { z } from "zod";
const result = await streamText({
model: openai("gpt-4o"),
messages,
tools: {
getWeather: tool({
description: "Get weather for a location",
parameters: z.object({
location: z.string().describe("City name"),
}),
execute: async ({ location }) => {
// Fetch weather data
return { temperature: 72, condition: "sunny" };
},
}),
},
});
```
## useCompletion (Text Generation)
```typescript
import { useCompletion } from "@ai-sdk/react";
import { DefaultCompletionTransport } from "ai";
const { completion, complete, isLoading } = useCompletion({
transport: new DefaultCompletionTransport({ api: "/api/complete" }),
});
// Trigger completion
await complete("Write a haiku about");
```
## Error Handling
```typescript
const { error, messages, sendMessage } = useChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
onError: (error) => {
console.error("Chat error:", error);
toast.error("Failed to send message");
},
});
// Display error
{error && (
<div className="error">
{error.message}
<button onClick={() => sendMessage({ text: lastInput })}>
Retry
</button>
</div>
)}
```
## Keywords
ai sdk, vercel ai, chat, streaming, langchain, openai, llmRelated Skills
More skills in Data, AI & Research
Ablation Planner
Use when main results pass result-to-claim (`claim_supported = yes` or `partial`) and ablation studies are needed for paper submission. A secondary Codex agent designs ablations from a reviewer's perspective; the local executor reviews feasibility and implements.
Ablation Planner
Use when main results pass result-to-claim (claim_supported=yes or partial) and ablation studies are needed for paper submission.
About
Provides information about the bitwize-music plugin, its version, and its creator. Use when the user asks about the plugin, its purpose, version, or capabilities.
Ab Test Analysis
Analyze A/B test results with statistical significance, sample size validation, confidence intervals, and ship/extend/stop recommendations. Use when evaluating experiment results, checking if a test reached significance, interpreting split test data, or deciding whether to ship a variant.
Academic Search
Search and analyze academic literature. Find papers, understand research methodologies, and synthesize academic findings for research projects.
Adaptyv
How to use the Adaptyv Bio Foundry API and Python SDK for protein experiment design, submission, and results retrieval. Use this skill whenever the user mentions Adaptyv, Foundry API, protein binding assays, protein screening experiments, BLI/SPR assays, thermostability assays, or wants to submit protein sequences for experimental characterization. Also trigger when code imports `adaptyv`, `adaptyv_sdk`, or `FoundryClient`, or references `foundry-api-public.adaptyvbio.com`.
Explore Other Categories
Skills from other categories with shared topics
Angular Architecture
Angular architecture: Scope Rule, project structure, file naming, style guide. Trigger: When structuring Angular projects or deciding where to place components.
Angular Core
Angular core patterns: standalone components, signals, inject, control flow, zoneless. Trigger: When creating Angular components, using signals, or setting up zoneless.
Angular Forms
Angular forms: Signal Forms (experimental) and Reactive Forms. Trigger: When working with forms, validation, or form state in Angular.