Agents as a First-Class Abstraction

AI SDK 6 introduces the Agent abstraction, built for defining a reusable agent once—model, instructions, and tools—and then deploying it across chat UIs, background jobs, and API endpoints. The functional generateText/streamText approach remains for low-level control, but the new abstraction eliminates the repetition of passing identical configuration objects through every layer of an application.

The Agent type is an interface, with ToolLoopAgent as the default production-ready implementation. It manages the full tool execution cycle: call the model, execute requested tools, feed results back, and repeat up to 20 steps by default via stopWhen: stepCountIs(20). For custom needs, you can implement the Agent interface directly—as demonstrated by Workflow DevKit's DurableAgent, which makes each tool execution a retryable, observable workflow step.

Typed Call Options and UI Integration

Call options let you pass type-safe arguments per invocation of generate or stream. This supports patterns like injecting retrieved documents for RAG, selecting models based on request complexity, or adjusting tool behavior for a particular request.

The abstraction also encourages clean code organization: define tools in separate files, compose them into agents, expose them via API routes, and let types flow to the client automatically. Message types imported from the agent file enable typed rendering of tool components in the UI by switching on part type.

Tooling Upgrades for Production Agents

Reliable agents depend on four things: valid tool inputs, alignment with developer intent, efficient token usage for tool results, and safe execution. AI SDK 6 addresses each with tool execution approval, strict mode, input examples, and toModelOutput.

Human Approval for Tool Execution

A single needsApproval flag adds human-in-the-loop control without custom infrastructure. Set it to true to require review before any tool runs, or pass a function to decide based on the input—for instance, auto-approving ls but flagging rm -rf for review. User preferences can be stored to remember approved patterns for future calls.

In the UI, useChat makes approval handling straightforward: check the tool invocation state, prompt the user, and respond with addToolApprovalResponse.

Strict Mode Per Tool

Strict mode guarantees model tool inputs match your schema exactly, but some providers only support subsets of JSON Schema in strict mode—and one incompatible tool used to fail the entire request. AI SDK 6 makes strict mode opt-in per tool, so compatible schemas get the guarantee while others run in regular mode within the same call.

Input Examples and Custom Model Output

Complex schemas with nested objects or domain-specific patterns are hard to convey through descriptions alone. Input examples provide the model with concrete, correctly-structured instances. Native support currently exists only with Anthropic; for other providers, addToolInputExamplesMiddleware appends examples to the tool description, and unsupported cases quietly ignore them.

The toModelOutput function separates application data from what the model sees. Return full results from execute for your logic, then control exactly which tokens go back to the model—avoiding thousands of unnecessary tokens for large file contents or awkward base64 encoding of images.

Full MCP Support

MCP support in @ai-sdk/mcp is now stable and extended to cover OAuth authentication, resources, prompts, and elicitation. Remote servers connect via HTTP transport with URL and auth headers. The package handles the complete OAuth flow—PKCE challenges, token refresh, dynamic client registration, and retry on mid-session expiry.

Applications can discover and read server-exposed resources (files, database records, API responses) and use reusable prompt templates with runtime parameters. Elicitation support lets servers request user input mid-operation—confirmations, choices, or additional context—while your application manages gathering it.

Unified Tool Calling with Structured Output

Previously, combining tool calling with structured output meant chaining generateText and generateObject. AI SDK 6 unifies them, enabling multi-step tool loops that end in structured output generation.

The Output object specifies the result shape:

  • Output.object(): structured objects
  • Output.array(): arrays of structured objects
  • Output.choice(): selection from specific options
  • Output.json(): unstructured JSON
  • Output.text(): plain text, the default

Debugging Agent Runs

Multi-step agent flows are notoriously difficult to trace. A single token change in one step's input can cascade into completely different downstream behavior, forcing developers to manually log and reconstruct each step by hand. The DevTools viewer in AI SDK 6 tackles this by providing full visibility into LLM calls and agent execution. You can inspect each step—input, output, model configuration, token usage, timing, and raw provider request/response payloads—in a single interface.

Setup is minimal: wrap your model with devToolsMiddleware and use it with any AI SDK function.

import { wrapLanguageModel, gateway } from 'ai';

import { devToolsMiddleware } from '@ai-sdk/devtools';

const devToolsEnabledModel = wrapLanguageModel({

model: gateway('anthropic/claude-sonnet-4.5'),

middleware: devToolsMiddleware(),

});

import { generateText } from 'ai';

const result = await generateText({

model: devToolsEnabledModel,

prompt: 'What is love?',

});

Launch the viewer with npx @ai-sdk/devtools and open http://localhost:4983. The interface exposes:

  • Input parameters and prompts: the complete input sent to the model
  • Output content and tool calls: generated text and tool invocations
  • Token usage and timing: resource consumption and performance metrics
  • Raw provider data: full request and response payloads

Reranking for Better Context

Language models perform better with focused context than with everything a retrieval step might surface. AI SDK 6 adds native reranking support via the rerank function, which reorders search results by relevance to a specific query so you can pass only the most relevant documents to the model.

import { rerank } from 'ai';

import { cohere } from '@ai-sdk/cohere';

const documents = [

'sunny day at the beach',

'rainy afternoon in the city',

'snowy night in the mountains',

];

const { ranking } = await rerank({

model: cohere.reranking('rerank-v3.5'),

documents,

query: 'talk about rain',

topN: 2,

});

console.log(ranking);

// [

// { originalIndex: 1, score: 0.9, document: 'rainy afternoon in the city' },

// { originalIndex: 0, score: 0.3, document: 'sunny day at the beach' }

// ]

The function also handles structured documents, which is useful for searching databases, emails, and similar content:

import { rerank } from 'ai';

import { cohere } from '@ai-sdk/cohere';

const documents = [

{ from: 'Paul Doe', subject: 'Follow-up', text: '20% discount offer...' },

{

from: 'John McGill',

subject: 'Missing Info',

text: 'Oracle pricing: $5000/month',

},

];

const { rerankedDocuments } = await rerank({

model: cohere.reranking('rerank-v3.5'),

documents,

query: 'Which pricing did we get from Oracle?',

topN: 1,

});

Reranking works with Cohere, Amazon Bedrock, and Together.ai providers.

Broader Schema and Tool Support

AI SDK 6 no longer requires built-in converters for every schema library. Any library implementing the Standard JSON Schema V1 interface is now supported automatically; there's no SDK-level change needed for Arktype, Valibot, or others that follow the spec.

import { generateText, Output } from 'ai';

import { type } from 'arktype';

const result = await generateText({

model: 'anthropic/claude-sonnet-4.5',

output: Output.object({

schema: type({

recipe: {

name: 'string',

ingredients: type({ name: 'string', amount: 'string' }).array(),

steps: 'string[]',

},

}),

}),

prompt: 'Generate a lasagna recipe.',

});

Provider-specific tools also get expanded coverage. These tools leverage platform capabilities or model-trained functionality such as web search, code execution, and memory management.

Anthropic

  • Memory Tool: store and retrieve information across conversations via a memory file directory
  • Tool Search (Regex): find and select tools dynamically using regex patterns
  • Tool Search (BM25): find tools via natural language queries
  • Code Execution Tool: run code in a sandboxed environment with bash and file operations

import { anthropic } from "@ai-sdk/anthropic";

// Memory Tool - store and retrieve information

const memory = anthropic.tools.memory_20250818({

execute: async (action) => {

// Implement memory storage logic

// Supports: view, create, str_replace, insert, delete, rename

},

});

// Tool Search (Regex) - find tools by pattern

const toolSearchRegex = anthropic.tools.toolSearchRegex_20251119();

// Tool Search (BM25) - find tools with natural language

const toolSearchBm25 = anthropic.tools.toolSearchBm25_20251119();

// Code Execution Tool - run code in sandbox

const codeExecution = anthropic.tools.codeExecution_20250825();

Anthropic programmatic tool calling is also supported—Claude can invoke your tools from a code execution environment, which keeps intermediate results out of the context window. Mark callable tools with allowedCallers, and preserve containers across steps with prepareStep:

import {

anthropic,

forwardAnthropicContainerIdFromLastStep,

} from "@ai-sdk/anthropic";

const getWeather = tool({

description: "Get weather for a city.",

inputSchema: z.object({ city: z.string() }),

execute: async ({ city }) => ({ temp: 22 }),

providerOptions: {

anthropic: { allowedCallers: ["code_execution_20250825"] },

},

});

const result = await generateText({

model: anthropic("claude-sonnet-4-5"),

tools: {

code_execution: anthropic.tools.codeExecution_20250825(),

getWeather,

},

prepareStep: forwardAnthropicContainerIdFromLastStep,

});

OpenAI

  • Shell Tool: execute shell commands with timeout and output limits
  • Apply Patch Tool: create, update, and delete files via structured diffs
  • MCP Tool: connect to remote Model Context Protocol servers

import { openai } from "@ai-sdk/openai";

// Shell Tool - execute shell commands

const shell = openai.tools.shell({

execute: async ({ action }) => {

// action.commands: string[] - commands to execute

// action.timeoutMs: optional timeout

// action.maxOutputLength: optional max chars to return

},

});

// Apply Patch Tool - file operations with diffs

const applyPatch = openai.tools.applyPatch({

execute: async ({ callId, operation }) => {

// operation.type: 'create_file' | 'update_file' | 'delete_file'

// operation.path: file path

// operation.diff: diff content (for create/update)

},

});

// MCP Tool - connect to MCP servers

const mcp = openai.tools.mcp({

serverLabel: "my-mcp-server",

serverUrl: "[https://mcp.example.com](https://mcp.example.com/)",

allowedTools: ["tool1", "tool2"],

});

Google

  • Google Maps Tool: location-aware responses with Maps grounding (Gemini 2.0+)
  • Vertex RAG Store Tool: retrieve context from Vertex AI RAG Engine corpora (Gemini 2.0+)
  • File Search Tool: semantic and keyword search in file stores (Gemini 2.5+)

import { google } from "@ai-sdk/google";

// Google Maps Tool - location-aware grounding

const googleMaps = google.tools.googleMaps();

// Vertex RAG Store Tool - retrieve from RAG corpora

const vertexRagStore = google.tools.vertexRagStore({

ragCorpus: "projects/{project}/locations/{location}/ragCorpora/{rag_corpus}",

topK: 5, // optional: number of contexts to retrieve

});

// File Search Tool - search in file stores

const fileSearch = google.tools.fileSearch({

fileSearchStoreNames: ["fileSearchStores/my-store-123"],

topK: 10, // optional: number of chunks to retrieve

metadataFilter: "author=John Doe", // optional: AIP-160 filter

});

xAI

  • Web Search: search the web with domain filtering and image understanding
  • X Search: search X posts with handle and date filtering
  • Code Execution: run code in a sandboxed environment
  • View Image: analyze and describe images
  • View X Video: analyze X video content

import { xai } from "@ai-sdk/xai";

// Web Search Tool - search the web

const webSearch = xai.tools.webSearch({

allowedDomains: [

"[wikipedia.org](http://wikipedia.org/)",

"[github.com](http://github.com/)",

], // optional: max 5

excludedDomains: ["[example.com](http://example.com/)"], // optional: max 5

enableImageUnderstanding: true, // optional

});

// X Search Tool - search X posts

const xSearch = xai.tools.xSearch({

allowedXHandles: ["elonmusk", "xai"], // optional: max 10

fromDate: "2025-01-01", // optional

toDate: "2025-12-31", // optional

enableImageUnderstanding: true, // optional

enableVideoUnderstanding: true, // optional

});

// Code Execution Tool - run code

const codeExecution = xai.tools.codeExecution();

// View Image Tool - analyze images

const viewImage = xai.tools.viewImage();

// View X Video Tool - analyze X videos

const viewXVideo = xai.tools.viewXVideo();

Image Editing and Better Response Metadata

The generateImage function—promoted to stable and renamed from experimental_generateImage—now supports image-to-image operations. Pass reference images alongside your prompt for inpainting, outpainting, style transfer, and similar workflows:

import { generateImage } from "ai";

import { blackForestLabs } from "@ai-sdk/black-forest-labs";

const { images } = await generateImage({

model: blackForestLabs.image("flux-2-pro"),

prompt: {

text: "Edit this to make it two tanukis on a date",

images: ["https://www.example.com/tanuki.png"],

},

});

"Edit this to make it two tanukis on a date"

Reference images can be URL strings, base64-encoded strings, Uint8Array, ArrayBuffer, or Buffer.

Response visibility also improves. When providers emit finish reasons the SDK doesn't recognize, they now surface via rawFinishReason instead of being collapsed into 'other'. This is useful when a provider maps multiple reasons to a single SDK value, or when you need to branch on provider-specific behavior.

const { finishReason, rawFinishReason } = await generateText({

model: 'anthropic/claude-sonnet-4.5',

prompt: 'What is love?',

});

// finishReason: 'other' (mapped)

// rawFinishReason: 'end_turn' (provider-specific)

Usage reporting gains detailed input and output token breakdowns, helping with cost optimization and cross-provider debugging:

const { usage } = await generateText({

model: 'anthropic/claude-sonnet-4.5',

prompt: 'What is love?',

});

// Input token details

usage.inputTokenDetails.noCacheTokens; // Non-cached input tokens

usage.inputTokenDetails.cacheReadTokens; // Tokens read from cache

usage.inputTokenDetails.cacheWriteTokens; // Tokens written to cache

// Output token details

usage.outputTokenDetails.textTokens; // Text generation tokens

usage.outputTokenDetails.reasoningTokens; // Reasoning tokens (where supported)

// Raw provider usage

usage.raw; // Complete provider-specific usage object

LangChain Adapter Rewrite

The @ai-sdk/langchain package has been rewritten to support modern LangChain and LangGraph features. New APIs include toBaseMessages() to convert UI messages to LangChain format, toUIMessageStream() to transform LangGraph event streams, and LangSmithDeploymentTransport for browser-side connections to LangSmith deployments. The adapter also supports tool calling with partial input streaming, reasoning blocks, and Human-in-the-Loop workflows via LangGraph interrupts.

import { toBaseMessages, toUIMessageStream } from '@ai-sdk/langchain';

import { createUIMessageStreamResponse } from 'ai';

const langchainMessages = await toBaseMessages(messages);

const stream = await graph.stream({ messages: langchainMessages });

return createUIMessageStreamResponse({

stream: toUIMessageStream(stream),

});

The rewrite is fully backwards compatible.

Migration

AI SDK 6 is a major version bump because of the v3 Language Model Specification, which powers agents and tool approval. Unlike AI SDK 5, this release is not expected to cause major breakage for most users—the bump reflects spec improvements rather than a redesign. Migration from v5 should require minimal code changes.

npx @ai-sdk/codemod upgrade v6

The migration guide covers all changes with step-by-step instructions and examples. An automated codemod is also available for smoother transitions. For those starting fresh, the release is a good entry point: it bundles composable agents, human-in-the-loop tool approval, stable structured outputs with tool calling, and DevTools for debugging, all in one SDK.

Built With the Community

AI SDK 6 is the product of close collaboration between Vercel's core team — Gregor, Lars, Aayush, Josh, and Nico — and a broad community of external contributors. The release incorporates feedback, bug reports, and pull requests from dozens of developers, spanning everything from core logic improvements to documentation and edge-case fixes.

The full list of external contributors includes viktorlarsson, shaper, AVtheking, SamyPesse, firemoonai, seldo, R-Taneja, ZiuChen, gaspar09, christian-bromann, jeremyphilemon, DaniAkash, a-tokyo, rohrz4nge, EwanTauran, codicecustode, shubham-021, kkawamu1, mclenhard, gdaybrice, dyh-sjtu, blurrah, EurFelux, AryanBagade, Omcodes23, jeffcarbs, codeyogi911, zirkelc, qkdreyer, tsuzaki430, qchuchu, karthikscale3, alex-deneuvillers, kesku, yorkeccak, guy-hartstein, Und3rf10w, siwachabhi, homanp, tengis617, SalvatoreAmoroso, ericciarla, baturyilmaz, chentsulin, kovereduard, yaonyan, mwln, IdoBouskila, wangyedev, rubnogueira, Emmaccen, priyanshusaini105, dpmishler, yilinjuang, JulioPeixoto, DeJeune, BangDori, shadowssdt, efantasia, kevinjosethomas, lukehrucker, Mohammedsinanpk, danielamitay, davidsonsns, teeverc, MQ37, jephal, TimPietrusky, theishangoswami, juliettech13, shelleypham, tconley1428, goyalshivansh2805, KirschX, neallseth, jltimm, rahulbhadja, tayyab3245, cwtuan, titouv, dylan-duan-aai, bel0v, josh-williams, amyegan, samjbobb, teunlao, dylanmoz, 0xlakshan, patelvivekdev, nvie, nlaz, drew-foxall, dannyroosevelt, Diluka, AlexKer, YosefLm, YutoKitano13, SarityS, jonaslalin, tobiasbueschel, dhofheinz, ethshea, ellis-driscoll, marcbouchenoire, shin-sakata, ellispinsky, DDU1222, ci, tomsseisums, kpman, juanuicich, A404coder, tamarshe-dev, crishoj, kevint-cerebras, arjunkmrm, Barbapapazes, nimeshnayaju, lewwolfe, sergical, tomerigal, huanshenyi, horita-yuya, rbadillap, syeddhasnainn, Dhravya, jagreehal, Mintnoii, mhodgson, amardeeplakshkar, aron, TooTallNate, Junyi-99, princejoogie, iiio2, MonkeyLeeT, joshualipman123, andrewdoro, fveiraswww, HugoRCD, and rockingrohit9639.