Skip to main content
Recipes

Calling Agents

VoltAgent 3 accepts AI SDK models and tools directly. Use Node.js 22 or newer with ESM. During the v3 prerelease, install VoltAgent packages from the next channel; see the migration guide.

Programmatic calls​

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

export const agent = new Agent({
id: "assistant",
name: "Assistant",
instructions: "You are a helpful assistant.",
model: openai("gpt-4o-mini"),
});

const result = await agent.generateText({
prompt: "What is the capital of France?",
maxOutputTokens: 500,
temperature: 0.7,
});
console.log(result.text);

The positional form, agent.generateText("Hello", options), also works. In the object form, provide either prompt or messages. A prompt may be a string or an array of model messages. Caller-supplied system messages require allowSystemInMessages: true; prefer instructions for call-level instructions.

Pass AI SDK settings at the top level and framework settings under voltagent:

const result = await agent.generateText({
prompt: "Remember that my name is John",
voltagent: {
userId: "user-123",
conversationId: "conversation-456",
context: { language: "en" },
},
});

Configure memory on the agent to persist conversation history. Add contextSchema to infer and validate context values in dynamic instructions, models, and tools.

A call-level model overrides the agent's model and fallback list for that invocation:

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

await agent.generateText({
model: openai("gpt-4o"),
instructions: "Answer in one sentence.",
prompt: "Explain photosynthesis.",
});

The agent's configured instructions remain additive. Future calls still use its configured model.

Streaming​

const result = await agent.streamText({
prompt: "Write a short story about a robot.",
onChunk: ({ chunk }) => {
if (chunk.type === "text-delta") console.log(chunk.text);
},
});

for await (const text of result.textStream) {
process.stdout.write(text);
}
console.log(await result.text);

Use result.stream for detailed events or result.toUIMessageStreamResponse() for an AI SDK UI response. These streams also support Web Stream methods. Stream-only callbacks belong on streamText.

Structured output​

import { Output } from "ai";
import { z } from "zod";

const profileSchema = z.object({
name: z.string(),
interests: z.array(z.string()),
});

const result = await agent.generateText({
prompt: "Create a fictional user profile",
output: Output.object({ schema: profileSchema }),
});
console.log(result.output.name);

const stream = await agent.streamText({
prompt: "Create another fictional user profile",
output: Output.object({ schema: profileSchema }),
});
for await (const partial of stream.partialOutputStream) {
console.log(partial);
}
console.log(await stream.output);

generateObject and streamObject remain deprecated compatibility wrappers. Use the output-based methods for new code.

HTTP endpoints​

Register the agent with a server:

import { VoltAgent } from "@voltagent/core";
import { honoServer } from "@voltagent/server-hono";
import { agent } from "./agent.js";

new VoltAgent({ agents: { assistant: agent }, server: honoServer() });

The default agent endpoint prefix is /agents, without /api:

curl -X POST http://localhost:3141/agents/assistant/text \
-H 'Content-Type: application/json' \
-d '{"input":"Hello","options":{"maxOutputTokens":500,"userId":"user-123","conversationId":"conversation-456"}}'

Use /agents/assistant/stream for detailed SSE events and /agents/assistant/chat for the AI SDK UI protocol. HTTP requests use input or messages plus JSON-serializable options; JavaScript callbacks and provider model objects belong in application code. See the agent endpoint reference for request and response schemas.

Next.js and AI SDK UI​

Convert UI messages to model messages in your route:

// app/api/chat/route.ts
import { convertToModelMessages, type UIMessage } from "ai";
import { agent } from "@/lib/agent";

export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = await agent.streamText({
messages: await convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse();
}

Use a transport and local input state on the client:

"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 (
<div>
{messages.map((message) => (
<div key={message.id}>
{message.parts.map((part, index) =>
part.type === "text" ? <span key={index}>{part.text}</span> : null
)}
</div>
))}
<form
onSubmit={(event) => {
event.preventDefault();
if (!input.trim()) return;
void sendMessage({ text: input });
setInput("");
}}
>
<input value={input} onChange={(event) => setInput(event.target.value)} />
<button type="submit" disabled={status === "submitted" || status === "streaming"}>
Send
</button>
</form>
</div>
);
}

Calling from workflows​

import { createWorkflowChain } from "@voltagent/core";
import { z } from "zod";
import { agent } from "./agent.js";

const workflow = createWorkflowChain({
id: "research",
name: "Research workflow",
input: z.object({ topic: z.string() }),
result: z.object({ summary: z.string() }),
}).andAgent(async ({ data }) => `Write a short overview of ${data.topic}`, agent, {
schema: z.object({ summary: z.string() }),
});

const result = await workflow.run({ topic: "AI agents" });
console.log(result);

Calling from tools​

Use the agent's tool adapter when one agent should consult another:

import { Agent } from "@voltagent/core";

const expert = new Agent({
name: "Expert",
instructions: "Explain technical concepts accurately.",
model: "openai/gpt-4o-mini",
});

const coordinator = new Agent({
name: "Coordinator",
instructions: "Consult the expert for technical questions.",
model: "openai/gpt-4o-mini",
tools: [expert.toTool()],
});

See agent tools and subagents for delegation and shared context behavior.

Table of Contents