Memory
By default, each agent.run() call starts with a blank conversation. Memory lets agents recall previous interactions so they can handle follow-up questions and maintain context across runs.
ConversationMemory
ConversationMemory stores messages in Redis using Synkro’s TransportManager. No extra infrastructure — it reuses the same Redis connection your Synkro instance already has.
import { ConversationMemory } from "@synkro/agents";import { Synkro } from "@synkro/core";
const synkro = await Synkro.start({ transport: "redis", connectionUrl: "redis://localhost:6379",});
const memory = new ConversationMemory({ transport: synkro.transport, maxMessages: 50, // Keep last 50 messages (default: 100) ttlSeconds: 3600, // Expire after 1 hour (default: 86400 = 24h)});Configuration
| Field | Type | Default | Description |
|---|---|---|---|
transport | TransportManager | required | Synkro transport instance (use synkro.transport). |
maxMessages | number | 100 | Maximum messages to retrieve per conversation. |
ttlSeconds | number | 86400 | TTL in seconds for conversation data. Set to 0 for no expiry. |
How it works
Messages are stored in Redis lists keyed by synkro:agent:memory:{agentName}:{runId}. The requestId option on agent.run() controls which conversation is loaded:
- Same
requestIdacross runs = same conversation thread. - Different or omitted
requestId= fresh conversation.
Example: multi-turn conversation
-
Create an agent with memory
import { createAgent, OpenAIProvider, ConversationMemory } from "@synkro/agents";import { Synkro } from "@synkro/core";const synkro = await Synkro.start({transport: "redis",connectionUrl: "redis://localhost:6379",});const agent = createAgent({name: "tutor",systemPrompt: "You are a patient math tutor.",provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY! }),model: { model: "gpt-4o" },memory: new ConversationMemory({ transport: synkro.transport }),}); -
First message
const sessionId = "student-42";const r1 = await agent.run("What is a derivative?", {requestId: sessionId,});console.log(r1.output);// "A derivative measures the rate of change of a function..." -
Follow-up (agent remembers)
const r2 = await agent.run("Can you give me an example?", {requestId: sessionId,});console.log(r2.output);// "Sure! For f(x) = x², the derivative f'(x) = 2x..."
Custom memory
Implement the AgentMemory interface to use a different storage backend:
import type { AgentMemory, Message } from "@synkro/agents";
class PostgresMemory implements AgentMemory { async addMessage(agentId: string, runId: string, message: Message): Promise<void> { // INSERT INTO agent_messages (agent_id, run_id, role, content) VALUES (...) }
async getMessages(agentId: string, runId: string): Promise<Message[]> { // SELECT * FROM agent_messages WHERE agent_id = $1 AND run_id = $2 ORDER BY created_at return []; }
async clear(agentId: string, runId: string): Promise<void> { // DELETE FROM agent_messages WHERE agent_id = $1 AND run_id = $2 }}AgentMemory interface
interface AgentMemory { addMessage(agentId: string, runId: string, message: Message): Promise<void>; getMessages(agentId: string, runId: string): Promise<Message[]>; clear(agentId: string, runId: string): Promise<void>;}| Method | Description |
|---|---|
addMessage | Store a single message in the conversation identified by agentId + runId. |
getMessages | Retrieve all stored messages for a conversation. Called at the start of agent.run(). |
clear | Delete all messages for a conversation. |