ctx.memory
Distributed memory with automatic scoping, vectors, and real-time events
The ctx.memory interface provides distributed state management across agents with automatic scoping to workflow, session, actor, or global contexts.
Memory is automatically shared between agents in the same workflow. When Agent A
calls Agent B via ctx.call(), both agents access the same workflow memory.
Basic Operations
agent.reasoner('example', async (ctx) => {
// Set a value
await ctx.memory.set('user_preference', { theme: 'dark' });
// Get a value
const pref = await ctx.memory.get('user_preference');
// Check existence
const exists = await ctx.memory.exists('user_preference');
// Delete a value
await ctx.memory.delete('user_preference');
// List keys in current scope
const keys = await ctx.memory.listKeys();
return { pref, exists, keys };
});Core Methods
Prop
Type
Memory Scopes
Default scope. Shared across all agents in the same workflow execution.
// Automatic workflow scope
await ctx.memory.set('step_result', data);
const result = await ctx.memory.get('step_result');
// Explicit workflow scope
const workflowMem = ctx.memory.workflow('wf-123');
await workflowMem.set('key', value);Use for: Task coordination, intermediate results, cross-agent data sharing.
User session data. Persists across multiple workflow executions.
const sessionMem = ctx.memory.session('user-123');
// Store user preferences
await sessionMem.set('preferences', { theme: 'dark' });
// Get conversation history
const history = await sessionMem.get('history') || [];Use for: User preferences, conversation history, shopping carts.
Agent-private state. Not shared with other agents.
const actorMem = ctx.memory.actor('my-agent');
// Store agent-specific cache
await actorMem.set('api_cache', cachedData);
// Track rate limits
await actorMem.set('rate_limit_remaining', 950);Use for: Caching, rate limit tracking, agent configuration.
System-wide data. Shared across all agents and workflows.
const globalMem = ctx.memory.globalScope;
// Store feature flags
await globalMem.set('feature_flags', {
newUI: true,
betaFeatures: false
});
// Get global config
const config = await globalMem.get('app_config');Use for: Feature flags, system configuration, shared reference data.
Vector Operations
Store and search embeddings for semantic similarity.
setVector()
await ctx.memory.setVector('doc_1', embedding, {
title: 'Introduction',
content: 'Document content...'
});Prop
Type
searchVector()
const results = await ctx.memory.searchVector(queryEmbedding, {
limit: 10,
minScore: 0.7
});
// results: Array<{ key, scope, scopeId, score, metadata }>Prop
Type
deleteVector() / deleteVectors()
await ctx.memory.deleteVector('doc_1');
await ctx.memory.deleteVectors(['doc_1', 'doc_2', 'doc_3']);Embedding Helpers
Generate embeddings using the AI client.
// Embed single text
const embedding = await ctx.memory.embedText('Hello world');
// Embed multiple texts
const embeddings = await ctx.memory.embedTexts([
'First document',
'Second document'
]);
// Embed and store in one call
const embedding = await ctx.memory.embedAndSet(
'doc_key',
'Document content to embed',
{ title: 'My Document' }
);Memory Watch
Watch for memory changes with pattern matching.
// On the agent (not in reasoner)
agent.watchMemory('user_*', async (event) => {
console.log(`Key ${event.key} changed:`, event.data);
}, { scope: 'session' });
// Multiple patterns
agent.watchMemory(['order_*', 'cart_*'], async (event) => {
await processOrderUpdate(event);
});Event Object
Prop
Type
Examples
Cross-Agent State Sharing
// Agent A: Support Agent
agent.reasoner('analyze_ticket', async (ctx) => {
const analysis = await ctx.ai(`Analyze: ${ctx.input.ticket}`);
// Store in workflow memory
await ctx.memory.set('ticket_analysis', {
priority: analysis.priority,
category: analysis.category
});
// Call specialist agent
return await ctx.call('specialist-agent.handle', {
ticketId: ctx.input.ticketId
});
});
// Agent B: Specialist Agent
agent.reasoner('handle', async (ctx) => {
// Access same workflow memory
const analysis = await ctx.memory.get('ticket_analysis');
// analysis.priority and analysis.category are available
return { handled: true, priority: analysis.priority };
});Session-Based Chat History
agent.reasoner('chat', async (ctx) => {
const { userId, message } = ctx.input;
const sessionMem = ctx.memory.session(userId);
// Get history
const history = await sessionMem.get('history') || [];
// Generate response with context
const response = await ctx.ai(
`History: ${JSON.stringify(history.slice(-5))}\nUser: ${message}`,
{ system: 'You are a helpful assistant.' }
);
// Update history
history.push(
{ role: 'user', content: message },
{ role: 'assistant', content: response }
);
await sessionMem.set('history', history);
return { response };
});Semantic Search
agent.reasoner('search_docs', async (ctx) => {
const { query } = ctx.input;
// Embed the query
const queryEmbedding = await ctx.memory.embedText(query);
// Search for similar documents
const results = await ctx.memory.searchVector(queryEmbedding, {
limit: 5,
minScore: 0.7
});
return {
query,
results: results.map(r => ({
key: r.key,
score: r.score,
title: r.metadata?.title
}))
};
});Document Indexing
agent.reasoner('index_document', async (ctx) => {
const { docId, title, content } = ctx.input;
// Embed and store
await ctx.memory.embedAndSet(
`doc_${docId}`,
content,
{ title, docId, indexedAt: new Date().toISOString() },
'global' // Store globally for cross-workflow search
);
return { indexed: true, docId };
});Related
- ReasonerContext - Full context reference
- Configuration - MemoryConfig options
- Memory Events - Event system deep dive