ai-sdk-ui
General↓ 0 installsUpdated 15h ago
Curatedmajiayu000
|
SKILL.md preview
---
name: ai-sdk-ui
description: |
Build React chat interfaces with Vercel AI SDK v6. Covers useChat/useCompletion/useObject hooks, message parts structure, tool approval workflows, and 18 UI error solutions. Prevents documented issues with React Strict Mode, concurrent requests, stale closures, and tool approval edge cases.
Use when: implementing AI chat UIs, migrating v5→v6, troubleshooting "useChat failed to parse stream", "stale body values", "React maximum update depth", "Cannot read properties of undefined (reading 'state')", or tool approval workflow errors.
user-invocable: true
---
# AI SDK UI - Frontend React Hooks
Frontend React hooks for AI-powered user interfaces with Vercel AI SDK v6.
**Version**: AI SDK v6.0.42 (Stable)
**Framework**: React 18+/19, Next.js 14+/15+
**Last Updated**: 2026-01-20
---
## AI SDK v6 Stable (January 2026)
**Status:** Stable Release
**Latest:** ai@6.0.42, @ai-sdk/react@3.0.44, @ai-sdk/openai@3.0.7
**Migration:** Minimal breaking changes from v5 → v6
### New UI Features in v6
**1. Message Parts Structure (Breaking Change)**
In v6, message content is now accessed via `.parts` array instead of `.content`:
```tsx
// ❌ v5 (OLD)
{messages.map(m => (
<div key={m.id}>{m.content}</div>
))}
// ✅ v6 (NEW)
{messages.map(m => (
<div key={m.id}>
{m.parts.map((part, i) => {
if (part.type === 'text') return <span key={i}>{part.text}</span>;
if (part.type === 'tool-invocation') return <ToolCall key={i} tool={part} />;
if (part.type === 'file') return <FilePreview key={i} file={part} />;
return null;
})}
</div>
))}
```
**Part Types:**
- `text` - Text content with `.text` property
- `tool-invocation` - Tool calls with `.toolName`, `.args`, `.result`
- `file` - File attachments with `.mimeType`, `.data`
- `reasoning` - Model reasoning (when available)
- `source` - Source citations
**3. Agent Integration**
Type-safe messaging with agents using `InferAgentUIMessage<typeof agent>`:
```tsx
import { useChat } from '@ai-sdk/react';
import type { InferAgentUIMessage } from 'ai';
import { myAgent } from './agent';
export default function AgentChat() {
const { messages, sendMessage } = useChat<InferAgentUIMessage<typeof myAgent>>({
api: '/api/chat',
});
// messages are now type-checked against agent schema
}
```
**4. Tool Approval Workflows (Human-in-the-Loop)**
Request user confirmation before executing tools:
```tsx
import { useChat } from '@ai-sdk/react';
import { useState } from 'react';
export default function ChatWithApproval() {
const { messages, sendMessage, addToolApprovalResponse } = useChat({
api: '/api/chat',
});
const handleApprove = (toolCallId: string) => {
addToolApprovalResponse({
toolCallId,
approved: true, // or false to deny
});
};
return (
<div>
{messages.map(message => (
<div key={message.id}>
{message.toolInvocations?.map(tool => (
tool.state === 'awaiting-approval' && (
<div key={tool.toolCallId}>
<p>Approve tool call: {tool.toolName}?</p>
<button onClick={() => handleApprove(tool.toolCallId)}>
Approve
</button>
<button onClick={() => addToolApprovalResponse({
toolCallId: tool.toolCallId,
approved: false
})}>
Deny
</button>
</div>
)
))}
</div>
))}
</div>
);
}
```
**5. Auto-Submit Capability**
Automatically continue conversation after handling approvals:
```tsx
import { useChat, lastAssistantMessageIsCompleteWithApprovalResponses } from '@ai-sdk/react';
export default function AutoSubmitChat() {
const { messages, sendMessage } = useChat({
api: '/api/chat',
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,
// Automatically resubmit after all approval responses provided
});
…