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 };
});
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 };
});