Skip to main content

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)
component
AgentComponent
required
The Convex agent component from your generated API
options
Config
required
Configuration object for the agent
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.
args
object
Thread metadata
threadId
string
The ID of the newly created thread
thread
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)
ctx
ActionCtx
required
The ctx object passed to the action handler
args
object
required
thread
Thread
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;
});

getThreadMetadata

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
args.threadId
string
required
The thread to get the metadata for
ThreadDoc
object
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?)
ctx
ActionCtx
required
The context passed from the action function
threadOpts
object
required
generateTextArgs
object
required
options
Options
text
string
The generated text response
promptMessageId
string
ID of the saved prompt message
order
number
Order number in the thread
savedMessages
MessageDoc[]
All messages saved during generation
usage
object
Token usage information
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?)
ctx
ActionCtx
required
The context passed from the action function
threadOpts
object
required
Same as generateText
streamTextArgs
object
required
Same as generateText arguments
options
Options & { saveStreamDeltas?: boolean | StreamingOptions }
StreamTextResult
object
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?)
ctx
ActionCtx
required
The context passed from the action function
threadOpts
object
required
userId and threadId for context
generateObjectArgs
object
required
object
T
The generated object matching the schema
promptMessageId
string
ID of the saved prompt message
savedMessages
MessageDoc[]
All saved messages
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.
StreamObjectResult
object
  • 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
args
SaveMessageArgs
required
messageId
string
The ID of the saved message
message
MessageDoc
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
args
object
required
PaginationResult
object
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
args.messageId
string
required
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.
args
object
required
MessageDoc[]
array
Array of context messages relevant to the query

generateAndSaveEmbeddings

Generate embeddings for messages and save them to the database.
await agent.generateAndSaveEmbeddings(ctx, { messageIds })
ctx
ActionCtx
required
The ctx parameter to an action
args.messageIds
string[]
required
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;
  };
};