ai-sdk-6

Vercel AI SDK v6 development. Use when building AI agents, chatbots, tool integrations, streaming apps, or structured output with the ai package. Covers ToolLoopAgent, useChat, generateText, streamText, tool approval, smoothStream, provider tools, MCP integration, and Output patterns.

laguagu/claude-code-nextjs-skills181 installsMITSynced Aug 26

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: ai-sdk-6
description: Vercel AI SDK v6 development. Use when building AI agents, chatbots, tool integrations, streaming apps, or structured output with the ai package. Covers ToolLoopAgent, useChat, generateText, streamText, tool approval, smoothStream, provider tools, MCP integration, and Output patterns.
license: MIT
---

# Vercel AI SDK v6 Development Guide

Use this skill when developing AI-powered features using Vercel AI SDK v6 (`ai` package).

> **Docs location**: bundled in `node_modules/ai/docs/`. In Bun/pnpm/Yarn workspace monorepos deps aren't hoisted — use `apps/*/node_modules/ai/docs/` or `packages/*/node_modules/ai/docs/` instead.

## Quick Reference

### Installation

```bash
bun add ai @ai-sdk/openai zod    # or @ai-sdk/anthropic, @ai-sdk/google, etc.
```

### Core Functions

| Function       | Purpose                                                           |
| -------------- | ----------------------------------------------------------------- |
| `generateText` | Non-streaming text generation (+ structured output with `Output`) |
| `streamText`   | Streaming text generation (+ structured output with `Output`)     |

> **v6 Note**: `generateObject`/`streamObject` are deprecated.
> Use `generateText`/`streamText` with `output: Output.object({ schema })` instead.

### Structured Output (v6)

```typescript
import { generateText, Output } from "ai";
import { z } from "zod";

const { output } = await generateText({
  model: anthropic("claude-sonnet-5"),
  output: Output.object({
    schema: z.object({
      sentiment: z.enum(["positive", "neutral", "negative"]),
      topics: z.array(z.string()),
    }),
  }),
  prompt: "Analyze this feedback...",
});
```

Output types: `Output.object()`, `Output.array()`, `Output.choice()`, `Output.json()`, `Output.text()` (default)

### Agent Class (v6 Key Feature)

```typescript
import { ToolLoopAgent, tool, stepCountIs } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";

const myAgent = new ToolLoopAgent({
  model: anthropic("claude-sonnet-5"),
  instructions: "You are a helpful assistant.",
  tools: {
    getData: tool({
      description: "Fetch data from API",
      inputSchema: z.object({
        query: z.string(),
      }),
      execute: async ({ query }) => {
        return { result: "data" };
      },
    }),
  },
  stopWhen: stepCountIs(20),
});

// Usage
const { text } = await myAgent.generate({ prompt: "Hello" });
const stream = await myAgent.stream({ prompt: "Hello" });
```

### API Route with Agent

```typescript
// app/api/chat/route.ts
import { createAgentUIStreamResponse } from "ai";
import { myAgent } from "@/agents/my-agent";

export async function POST(request: Request) {
  const { messages } = await request.json();

  return createAgentUIStreamResponse({
    agent: myAgent,
    uiMessages: messages,
  });
}
```

### Smooth Streaming

```typescript
import { createAgentUIStreamResponse, smoothStream } from "ai";

return createAgentUIStreamResponse({
  agent: myAgent,
  uiMessages: messages,
  experimental_transform: smoothStream({
    delayInMs: 15,
    chunking: "word", // "word" | "line" | RegExp | Intl.Segmenter | callback
  }),
});
```

### useChat Hook (Client)

```typescript
"use client";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { useState } from "react";

export function Chat() {
  const [input, setInput] = useState("");
  const { messages, sendMessage, status } = useChat({
    transport: new DefaultChatTransport({
      api: "/api/chat",
    }),
  });

  return (
    <>
      {messages.map((msg) => (
        <div key={msg.id}>
          {msg.parts.map((part, i) =>
            part.type === "text" ? <span key={i}>{part.text}</span> : null
          )}
        </div>
      ))}
      <form
        onSubmit={(e) => {
          e.preventDefault();
          if (input.trim()) {
            sendMessage({ text: input });
            setInput("");
          }
        }}
      >
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          disabled={status !== "ready"}
        />
        <button type="submit" disabled={status !== "ready"}>
          Send
        </button>
      </form>
    </>
  );
}
```

> **v6 Note**: `useChat` no longer manages input state internally. Use `useState` for controlled inputs.

## Reference Documentation

For detailed information, see:

- [agents.md](references/agents.md) - ToolLoopAgent, loop control, workflows
- [core-functions.md](references/core-functions.md) - generateText, streamText, Output patterns
- [tools.md](references/tools.md) - Tool definition with Zod schemas
- [workflows.md](references/workflows.md) - Sequential, parallel, routing, and orchestrator-worker patterns
- [ui-hooks.md](references/ui-hooks.md) - useChat, UIMessage, streaming
- [middleware.md](references/middleware.md) - Custom middleware patterns
- [mcp.md](references/mcp.md) - MCP server integration
- [examples.md](references/examples.md) - Canonical provider × feature examples from vercel/ai repo

## Official Documentation

For the latest information, see [AI SDK docs](https://ai-sdk.dev/docs/agents).

More AI & ML skills

← All AI & ML skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY