Using Vercel AI SDK
Mastra integrates with Vercel’s AI SDK to support model routing, React Hooks, and data streaming methods.
AI SDK v5 (beta)
Mastra also supports AI SDK v5 (beta) see the following section for v5 specific methods: Vercel AI SDK v5
The code examples contained with this page assume you’re using the Next.js App Router at the root of your
project, e.g., app
rather than src/app
.
Model routing
When creating agents in Mastra, you can specify any AI SDK-supported model.
import { openai } from "@ai-sdk/openai";
import { Agent } from "@mastra/core/agent";
export const weatherAgent = new Agent({
name: "Weather Agent",
instructions: "Instructions for the agent...",
model: openai("gpt-4-turbo"),
});
See Model Providers and Model Capabilities for more information.
React Hooks
Mastra supports AI SDK hooks for connecting frontend components directly to agents using HTTP streams.
Install the required AI SDK React package:
npm
npm install @ai-sdk/react
Using the useChat()
Hook
The useChat
hook handles real-time chat interactions between your frontend and a Mastra agent, enabling you to send prompts and receive streaming responses over HTTP.
"use client";
import { useChat } from "@ai-sdk/react";
export function Chat() {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: "api/chat"
});
return (
<div>
<pre>{JSON.stringify(messages, null, 2)}</pre>
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleInputChange} placeholder="Name of city" />
</form>
</div>
);
}
Requests sent using the useChat
hook are handled by a standard server route. This example shows how to define a POST route using a Next.js Route Handler.
import { mastra } from "../../mastra";
export async function POST(req: Request) {
const { messages } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const stream = await myAgent.stream(messages);
return stream.toDataStreamResponse();
}
When using
useChat
with agent memory, refer to the Agent Memory section for key implementation details.
Using the useCompletion()
Hook
The useCompletion
hook handles single-turn completions between your frontend and a Mastra agent, allowing you to send a prompt and receive a streamed response over HTTP.
"use client";
import { useCompletion } from "@ai-sdk/react";
export function Completion() {
const { completion, input, handleInputChange, handleSubmit } = useCompletion({
api: "api/completion"
});
return (
<div>
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleInputChange} placeholder="Name of city" />
</form>
<p>Completion result: {completion}</p>
</div>
);
}
Requests sent using the useCompletion
hook are handled by a standard server route. This example shows how to define a POST route using a Next.js Route Handler.
import { mastra } from "../../../mastra";
export async function POST(req: Request) {
const { prompt } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const stream = await myAgent.stream([{ role: "user", content: prompt }]);
return stream.toDataStreamResponse();
}
Using the useObject()
Hook
The useObject
hook consumes streamed text from a Mastra agent and parses it into a structured JSON object based on a defined schema.
"use client";
import { experimental_useObject as useObject } from "@ai-sdk/react";
import { z } from "zod";
export function Object() {
const { object, submit } = useObject({
api: "api/object",
schema: z.object({
weather: z.string()
})
});
return (
<div>
<button onClick={() => submit("London")}>Generate</button>
{object ? <pre>{JSON.stringify(object, null, 2)}</pre> : null}
</div>
);
}
Requests sent using the useObject
hook are handled by a standard server route. This example shows how to define a POST route using a Next.js Route Handler.
import { mastra } from "../../../mastra";
import { z } from "zod";
export async function POST(req: Request) {
const body = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const stream = await myAgent.stream(body, {
output: z.object({
weather: z.string()
})
});
return stream.toTextStreamResponse();
}
Passing additional data with sendExtraMessageFields
The sendExtraMessageFields
option allows you to pass additional data from the frontend to Mastra. This data is available on the server as RuntimeContext
.
"use client";
import { useChat } from "@ai-sdk/react";
export function ChatExtra() {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: "/api/chat-extra",
sendExtraMessageFields: true
});
const handleFormSubmit = (e: React.FormEvent) => {
e.preventDefault();
handleSubmit(e, {
data: {
userId: "user123",
preferences: {
language: "en",
temperature: "celsius"
}
}
});
};
return (
<div>
<pre>{JSON.stringify(messages, null, 2)}</pre>
<form onSubmit={handleFormSubmit}>
<input value={input} onChange={handleInputChange} placeholder="Name of city" />
</form>
</div>
);
}
Requests sent using sendExtraMessageFields
are handled by a standard server route. This example shows how to extract the custom data and populate a RuntimeContext
instance.
import { mastra } from "../../../mastra";
import { RuntimeContext } from "@mastra/core/runtime-context";
export async function POST(req: Request) {
const { messages, data } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const runtimeContext = new RuntimeContext();
if (data) {
for (const [key, value] of Object.entries(data)) {
runtimeContext.set(key, value);
}
}
const stream = await myAgent.stream(messages, { runtimeContext });
return stream.toDataStreamResponse();
}
Handling runtimeContext
with server.middleware
You can also populate the RuntimeContext
by reading custom data in a server middleware:
import { Mastra } from "@mastra/core/mastra";
export const mastra = new Mastra({
agents: { weatherAgent },
server: {
middleware: [
async (c, next) => {
const runtimeContext = c.get("runtimeContext");
if (c.req.method === "POST") {
try {
const clonedReq = c.req.raw.clone();
const body = await clonedReq.json();
if (body?.data) {
for (const [key, value] of Object.entries(body.data)) {
runtimeContext.set(key, value);
}
}
} catch {
}
}
await next();
},
],
},
});
You can then access this data in your tools via the
runtimeContext
parameter. See the Runtime Context documentation for more details.
Streaming data
The ai
package provides utilities for managing custom data streams. In some cases, you may want to send structured updates or annotations to the client using an agent’s dataStream
.
Install the required package:
npm
npm install ai
Using createDataStream()
The createDataStream
function allows you to stream additional data to the client.
import { createDataStream } from "ai";
import { Agent } from "@mastra/core/agent";
export const weatherAgent = new Agent({...});
createDataStream({
async execute(dataStream) {
dataStream.writeData({ value: "Hello" });
dataStream.writeMessageAnnotation({ type: "status", value: "processing" });
const agentStream = await weatherAgent.stream("What is the weather");
agentStream.mergeIntoDataStream(dataStream);
},
onError: (error) => `Custom error: ${error}`
});
Using createDataStreamResponse()
The createDataStreamResponse
function creates a response object that streams data to the client.
import { mastra } from "../../../mastra";
import { createDataStreamResponse } from "ai";
export async function POST(req: Request) {
const { messages } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const agentStream = await myAgent.stream(messages);
const response = createDataStreamResponse({
status: 200,
statusText: "OK",
headers: {
"Custom-Header": "value"
},
async execute(dataStream) {
dataStream.writeData({ value: "Hello" });
dataStream.writeMessageAnnotation({
type: "status",
value: "processing"
});
agentStream.mergeIntoDataStream(dataStream);
},
onError: (error) => `Custom error: ${error}`
});
return response;
}
Vercel AI SDK v5
This guide covers Mastra-specific considerations when migrating from AI SDK v4 to v5 beta.
Please add any feedback or bug reports to the AI SDK v5 mega issue in Github.
Official migration guide
Follow the official AI SDK v5 Migration Guide for all AI SDK core breaking changes, package updates, and API changes.
This guide covers only the Mastra-specific aspects of the migration.
- Data compatibility: New data stored in v5 format will no longer work if you downgrade from the beta
- Backup recommendation: Keep DB backups from before you upgrade to v5 beta
- Production use: Wait for the AI SDK v5 stable release before using in production applications
- Prerelease status: The Mastra
ai-v5
tag is a prerelease version and may have bugs
Memory and Storage
Mastra automatically handles AI SDK v4 data using its internal MessageList
class, which manages format conversion—including v4 to v5. No database migrations are required; your existing messages are translated on the fly and continue working after you upgrade.
Migration strategy
Migrating to AI SDK v5 with Mastra involves updating both your backend (Mastra server) and frontend. We provide a compatibility mode to handle stream format conversion during the transition.
Upgrade dependencies
Install the @ai-v5
prerelease version of all Mastra packages:
npm
npm install mastra@ai-v5 @mastra/core@ai-v5 @mastra/memory@ai-v5
Configure your Mastra instance with v4
compatibility so your frontend, and the Mastra Playground will continue to work:
import { Mastra } from "@mastra/core/mastra";
import { weatherAgent } from "./agents/weather-agent";
export const mastra = new Mastra({
agents: { weatherAgent },
aiSdkCompat: 'v4',
});
Enabling stream compatibility
If your frontend calls a Mastra agent using a custom API route, wrap the toUIMessageStreamResponse()
result with createV4CompatibleResponse
to maintain AI SDK v4
compatibility.
import { mastra } from "../../../mastra";
import { createV4CompatibleResponse } from "@mastra/core/agent";
export async function POST(req: Request) {
const { messages } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const stream = await myAgent.stream(messages);
return createV4CompatibleResponse(stream.toUIMessageStreamResponse().body!);
}
Frontend upgrade
When you’re ready, remove the compatibility flag and upgrade your frontend:
- Remove
aiSdkCompat: 'v4'
from your Mastra configuration - Follow the AI SDK guide on upgrading your frontend dependencies
- Update your frontend code for v5 breaking changes