For two years the Vercel AI SDK was the quiet default of TypeScript AI development. If you streamed an LLM response into a React app in 2024 or 2025, you almost certainly used streamText and useChat. It was a toolkit, not a framework — a thin, provider-agnostic layer over model APIs.
AI SDK 6 changes that posture. It keeps the low-level functions but adds a first-class Agent abstraction, stable MCP support, human-in-the-loop tool approval, and unified structured outputs. In other words, the toolkit grew up into something you can build autonomous systems on, without abandoning the primitives that made it popular.
This guide walks through what actually changed and why it matters for teams shipping AI products today.
The two layers: functions and agents
The SDK now offers two altitudes of API, and choosing the right one is the first design decision.
At the low level you still have generateText and streamText. These are unopinionated. You pass a model, a prompt, and a set of tools, and you control the loop yourself with stopWhen:
import { generateText, tool, stepCountIs } from 'ai';
import { z } from 'zod';
const { text } = await generateText({
model: 'openai/gpt-5',
prompt: 'What should I do this weekend in Tunis?',
stopWhen: stepCountIs(5),
tools: { weather, activities },
});The SDK handles the mechanical work on every step: it extracts the tool calls the model wants, validates the arguments against your schema, runs your function, appends the result to the conversation, and asks the model again — until the stop condition is met. One important note for v6: generateObject and generateText are now unified, so you can run a multi-step tool loop and still get a typed structured object at the end.
At the high level sits the new Agent interface. Instead of wiring the loop manually each time, you define an agent once with its model, instructions, and tools, then reuse it everywhere.
Defining a tool
Tools are the heart of any agent, and the definition pattern is unchanged and clean. Every tool has a description for the model, a Zod inputSchema, and an execute function:
import { tool } from 'ai';
import { z } from 'zod';
export const weatherTool = tool({
description: 'Get the current weather in a location',
inputSchema: z.object({
location: z.string().describe('The city to get weather for'),
}),
execute: async ({ location }) => ({
temperature: 72,
}),
});The Zod schema does double duty. It tells the model the exact shape of arguments to produce, and it validates whatever the model returns before your execute function ever runs. Bad arguments never reach your code.
ToolLoopAgent: the production default
The headline addition is ToolLoopAgent, a ready-made implementation of the Agent interface that handles the complete tool execution loop for you:
import { ToolLoopAgent } from 'ai';
import { weatherTool } from '@/tools/weather';
export const weatherAgent = new ToolLoopAgent({
model: 'anthropic/claude-sonnet-4.5',
instructions: 'You are a helpful weather assistant.',
tools: { weather: weatherTool },
});
const result = await weatherAgent.generate({
prompt: 'What is the weather in San Francisco?',
});By default the loop runs for up to 20 steps — stopWhen: stepCountIs(20) — which is enough headroom for most real tasks while still bounding runaway behaviour. Crucially, Agent in v6 is an interface, not a sealed class. ToolLoopAgent is the sensible default, but if your product needs a different control flow you can implement the interface yourself and still plug into the rest of the ecosystem.
Human-in-the-loop tool approval
This is the feature that makes AI SDK 6 viable for sensitive operations. A single needsApproval flag pauses execution until a human confirms. You can set it to true outright, or pass a function that decides based on the arguments:
export const runCommand = tool({
description: 'Run a shell command',
inputSchema: z.object({
command: z.string(),
}),
needsApproval: async ({ command }) => command.includes('rm -rf'),
execute: async ({ command }) => {
// only reached after approval
},
});That conditional pattern is the right altitude for production: routine reads run automatically, and only the genuinely dangerous calls — deleting files, sending money, mutating a database — surface to a person. It is the difference between a demo and something you let touch a real system.
Structured outputs and tools, together
Earlier versions forced a choice: either call tools, or get a structured object back. AI SDK 6 lets an agent do both. You attach an Output.object schema, and the agent calls tools as needed, then returns a validated, typed result at the end:
import { Output, ToolLoopAgent } from 'ai';
import { z } from 'zod';
const agent = new ToolLoopAgent({
model: 'anthropic/claude-sonnet-4.5',
tools: { weather: weatherTool },
output: Output.object({
schema: z.object({
summary: z.string(),
temperature: z.number(),
recommendation: z.string(),
}),
}),
});
const { output } = await agent.generate({
prompt: 'What is the weather in San Francisco and what should I wear?',
});The output you get back is fully typed. No parsing, no defensive checks against malformed JSON — the SDK guarantees the shape.
MCP support, now stable
The Model Context Protocol is how agents reach external tools and data in a standard way. In AI SDK 6 the MCP support graduated to stable and moved into a dedicated @ai-sdk/mcp package. It now covers OAuth authentication, resources, prompts, and elicitation — the pieces you need to connect an agent to real, permissioned systems rather than toy endpoints.
End-to-end type safety to the UI
Because agents are defined objects, the SDK can infer their message types and carry that typing all the way to the frontend:
export type WeatherAgentUIMessage = InferAgentUIMessage<typeof weatherAgent>;That single line means your React components know exactly what parts a streamed message can contain. Tool calls, results, and text are all typed across the network boundary — a rare and genuinely useful guarantee in AI tooling.
Migrating from AI SDK 5
If you are on v5, the upgrade is not a rewrite. Vercel ships a codemod:
npx @ai-sdk/codemod v6It handles the bulk of the mechanical renames automatically. Budget time to test your tool loops and any custom streaming, but the migration is designed to be measured in hours, not weeks.
Why this matters for MENA teams
The most strategic property of the AI SDK has nothing to do with agents — it is that the SDK is provider-agnostic. The same generateText call runs against Claude, GPT, Gemini, or an open model behind a gateway by changing one string. For teams in Tunisia, Saudi Arabia, and the wider region, that is a hedge: against vendor outages, against pricing shifts, and against the data-sovereignty constraints that make a single foreign provider a non-starter for some workloads. Write your agent once, route it to a model that satisfies your latency, cost, and compliance needs, and swap when reality changes.
AI SDK 6 takes that flexible foundation and adds the agent machinery on top — without locking you in. That combination, more than any single feature, is why it is worth adopting now.
Building AI agents or products for your business? Noqta helps MENA teams ship production AI on a provider-agnostic foundation. Get in touch.