Agent Class
The Agent class is the core of the Agent SDK, providing AI-powered message generation, thread management, and context-aware conversations.
Constructor
Create a new Agent instance with configuration options.
import { Agent } from "@convex-dev/agent";
import { openai } from "@ai-sdk/openai";
import { components } from "./convex/_generated/api";
new Agent(component, options)
The Convex agent component from your generated API
Configuration object for the agent
The name for the agent. This will be attributed on each message created by this agent.
The LLM model to use for generating/streaming text and objects.languageModel: openai.chat("gpt-4o-mini")
The default system prompt to put in each request. Override per-prompt by passing the “system” parameter.
Tools that the agent can call out to and get responses from. Can be AI SDK tools or Convex context tools.
stopWhen
StopCondition | StopCondition[]
When generating or streaming text with tools available, this determines when to stop. Defaults to the AI SDK default.
Model for generating embeddings for semantic search.
Options for fetching context messages for RAG.
Example:
const agent = new Agent(components.agent, {
name: "support-bot",
languageModel: openai.chat("gpt-4o"),
instructions: "You are a helpful support assistant for a Discord community.",
tools: {
searchDocs: createTool({
description: "Search documentation",
parameters: z.object({ query: z.string() }),
execute: async ({ query }) => {
// Search implementation
}
})
}
});
Thread Management
createThread
Start a new thread with the agent. This creates a fresh conversation history.
await agent.createThread(ctx, args?)
ctx
ActionCtx | MutationCtx
required
The context of the Convex function. From an action, returns both threadId and thread object. From a mutation, returns only threadId.
Thread metadata
The userId to associate with the thread. If not provided, the thread will be anonymous.
The summary of the thread.
The ID of the newly created thread
Thread object with bound methods (only returned from actions, not mutations)
Example:
export const startConversation = action(async (ctx) => {
const agent = new Agent(components.agent, {
name: "helper",
languageModel: openai.chat("gpt-4o-mini"),
});
const { threadId, thread } = await agent.createThread(ctx, {
userId: "user_123",
title: "Help with API integration"
});
const result = await thread.generateText({
prompt: "How do I authenticate?"
});
return result.text;
});
continueThread
Continues an existing thread with this agent. Returns functions bound to the userId and threadId.
await agent.continueThread(ctx, args)
The ctx object passed to the action handler
The associated thread created by createThread
If supplied, the userId can be used to search across other threads for relevant messages from the same user as context.
Thread object with methods bound to the userId and threadId:
generateText() - Generate text response
streamText() - Stream text response
generateObject() - Generate structured object
streamObject() - Stream structured object
getMetadata() - Get thread metadata
updateMetadata() - Update thread metadata
Example:
export const continueConversation = action(async (ctx, { threadId, message }) => {
const { thread } = await agent.continueThread(ctx, { threadId });
const result = await thread.generateText({
prompt: message
});
return result.text;
});
Get the metadata for a thread.
await agent.getThreadMetadata(ctx, { threadId })
ctx
QueryCtx | MutationCtx | ActionCtx
required
A ctx object from a query, mutation, or action
The thread to get the metadata for
The thread metadata including title, summary, userId, and timestamps
Text Generation
generateText
Behaves like generateText from the “ai” package but adds context based on userId/threadId and saves the input/output messages to the thread.
await agent.generateText(ctx, threadOpts, generateTextArgs, options?)
The context passed from the action function
User to associate the message with
Thread to associate the message with
Show Generate Text Arguments
The prompt text or messages
System prompt (overrides agent instructions)
Previous messages in conversation
Tools to use for this call (overrides agent tools)
Maximum number of tool calling steps
Sampling temperature (0-2)
Options for fetching contextual messages for RAG
Options for saving messages to database
The generated text response
ID of the saved prompt message
Order number in the thread
All messages saved during generation
Example:
const result = await agent.generateText(
ctx,
{ threadId, userId: "user_123" },
{
prompt: "Explain how webhooks work",
maxSteps: 3,
temperature: 0.7
}
);
console.log(result.text);
console.log(`Used ${result.usage.totalTokens} tokens`);
streamText
Streams text generation with the same context and storage features as generateText.
await agent.streamText(ctx, threadOpts, streamTextArgs, options?)
The context passed from the action function
Same as generateText arguments
options
Options & { saveStreamDeltas?: boolean | StreamingOptions }
saveStreamDeltas
boolean | StreamingOptions
Whether to save incremental data (deltas) from streaming responses. Defaults to false.
Stream result with async iterators and methods:
textStream - Async iterator for text chunks
fullStream - Async iterator for all events
text - Promise resolving to full text
usage - Promise resolving to token usage
consumeStream() - Consume the stream
Example:
const result = await agent.streamText(
ctx,
{ threadId },
{ prompt: "Write a tutorial" },
{ saveStreamDeltas: true }
);
for await (const chunk of result.textStream) {
console.log(chunk);
}
const fullText = await result.text;
Structured Generation
generateObject
Generate structured objects using schemas (Zod, JSON Schema, etc.).
await agent.generateObject(ctx, threadOpts, generateObjectArgs, options?)
The context passed from the action function
userId and threadId for context
Show Generate Object Arguments
Zod schema or JSON schema defining the output structure
prompt
string | ModelMessage[]
required
The prompt
How to generate the object (defaults to ‘auto’)
The generated object matching the schema
ID of the saved prompt message
Example:
import { z } from "zod";
const result = await agent.generateObject(
ctx,
{ threadId },
{
schema: z.object({
title: z.string(),
priority: z.enum(["low", "medium", "high"]),
tags: z.array(z.string())
}),
prompt: "Analyze this issue: User can't login after password reset"
}
);
console.log(result.object.priority); // "high"
streamObject
Stream structured object generation.
await agent.streamObject(ctx, threadOpts, streamObjectArgs, options?)
Parameters are the same as generateObject.
partialObjectStream - Async iterator for partial objects
object - Promise resolving to final object
usage - Promise resolving to token usage
Message Management
saveMessage
Save a message to a thread.
await agent.saveMessage(ctx, args)
ctx
MutationCtx | ActionCtx
required
A ctx object from a mutation or action
Thread to save message to
User associated with message
The message content (role, content, etc.)
If true, won’t generate embeddings. Useful in mutations where you can’t run fetch.
Extra metadata to store with the message
The ID of the saved message
The saved message document
Example:
const { messageId } = await agent.saveMessage(ctx, {
threadId,
userId: "user_123",
message: {
role: "user",
content: "Hello, I need help"
}
});
listMessages
List messages from a thread with pagination.
await agent.listMessages(ctx, args)
ctx
QueryCtx | MutationCtx | ActionCtx
required
A ctx object from a query, mutation, or action
Thread to list messages from
Pagination options (e.g. from usePaginatedQuery)
Whether to exclude tool messages. False by default.
What statuses to include. All by default.
Paginated list of MessageDoc objects compatible with usePaginatedQuery
deleteMessage
Delete a single message by ID.
await agent.deleteMessage(ctx, { messageId })
ctx
MutationCtx | ActionCtx
required
The ctx argument to your mutation or action
The id of the message to delete
Search & Context
fetchContextMessages
Fetch context messages for a thread using vector/text search.
await agent.fetchContextMessages(ctx, args)
ctx
QueryCtx | MutationCtx | ActionCtx
required
Either a query, mutation, or action ctx. If not an action context, you can’t do text or vector search.
User to fetch context for
Thread to fetch context for
Text to use for search if targetMessageId not provided
If provided, will use this message for text/vector search
Options for context retrieval (maxMessages, vectorSearch settings, etc.)
Array of context messages relevant to the query
generateAndSaveEmbeddings
Generate embeddings for messages and save them to the database.
await agent.generateAndSaveEmbeddings(ctx, { messageIds })
The ctx parameter to an action
The messageIds to generate embeddings for
It will not generate or save embeddings for messages that already have an embedding.
Types
Message
type Message = {
role: "user" | "assistant" | "system" | "tool";
content: string | Array<TextPart | ImagePart | FilePart>;
name?: string;
toolCallId?: string;
toolCalls?: ToolCall[];
};
MessageDoc
type MessageDoc = {
_id: string;
_creationTime: number;
threadId: string;
userId?: string;
order: number;
stepOrder: number;
message: Message;
status: "streaming" | "success" | "failed" | "pending";
agentName?: string;
};
ThreadDoc
type ThreadDoc = {
_id: string;
_creationTime: number;
userId?: string;
title?: string;
summary?: string;
};
ContextOptions
type ContextOptions = {
maxMessages?: number;
vectorSearch?: {
enabled: boolean;
limit?: number;
similarityThreshold?: number;
};
textSearch?: {
enabled: boolean;
limit?: number;
};
};