Memory SDK

AI memory SDK with semantic search, knowledge graphs, and context management.

Installation

Install the Memory SDK using your preferred package manager:

npm install @usetransactional/memory
pnpm add @usetransactional/memory
yarn add @usetransactional/memory

Quick Start

import { MemoryClient } from '@usetransactional/memory';
 
const client = new MemoryClient({
  apiKey: 'your-api-key',
});
 
// Add a memory
await client.add({
  content: 'User prefers dark mode and compact layouts.',
  userId: 'user-123',
  type: 'preference',
});
 
// Search memories
const results = await client.search({
  query: 'UI preferences',
  userId: 'user-123',
  strategy: 'semantic',
});
 
// Get context for an LLM prompt
const context = await client.getContext({
  userId: 'user-123',
  query: 'Help the user customize their dashboard',
  maxTokens: 2000,
  includeProfile: true,
  includeFacts: true,
  includePreferences: true,
});

Configuration

Create a client instance with your API key and optional configuration:

import { MemoryClient } from '@usetransactional/memory';
 
const client = new MemoryClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.usetransactional.com',
  timeout: 30000,
  maxRetries: 3,
  headers: {
    'X-Custom-Header': 'value',
  },
});
OptionTypeRequiredDefaultDescription
apiKeystringYes-Your Transactional API key
baseUrlstringNohttps://api.usetransactional.comAPI base URL
timeoutnumberNo30000Request timeout in milliseconds
maxRetriesnumberNo3Maximum number of retry attempts for failed requests
headersRecord<string, string>No-Additional HTTP headers to include in every request

Memory Operations

add()

Store a new memory associated with a user:

const memory = await client.add({
  content: 'User mentioned they work at Acme Corp as a senior engineer.',
  userId: 'user-123',
  sessionId: 'session-abc',
  type: 'fact',
  metadata: {
    source: 'chat',
    confidence: 0.95,
  },
});
 
console.log(memory.id); // 'mem_abc123'
ParameterTypeRequiredDescription
contentstringYesThe memory content to store
userIdstringYesUser ID to associate the memory with
sessionIdstringNoSession ID for grouping related memories
typestringNoMemory type (e.g., 'fact', 'preference', 'event')
metadataRecord<string, unknown>NoArbitrary metadata to attach

Search memories using keyword, semantic, or hybrid strategies:

const results = await client.search({
  query: 'work experience and company',
  userId: 'user-123',
  types: ['fact', 'entity'],
  strategy: 'hybrid',
  threshold: 0.7,
  limit: 10,
  includeRelated: true,
});
 
for (const result of results) {
  console.log(result.content, result.score);
}
ParameterTypeRequiredDescription
querystringYesSearch query
userIdstringYesUser ID to search within
typesstring[]NoFilter by memory types
strategy'auto' | 'keyword' | 'semantic' | 'hybrid'NoSearch strategy. Defaults to 'auto'
thresholdnumberNoMinimum relevance score (0 to 1)
limitnumberNoMaximum number of results
includeRelatedbooleanNoInclude related memories via knowledge graph connections

Search strategies:

StrategyDescription
autoAutomatically selects the best strategy based on the query
keywordTraditional keyword matching, best for exact terms
semanticVector similarity search, best for conceptual queries
hybridCombines keyword and semantic search for balanced results

get()

Retrieve a specific memory by session and memory ID:

const memory = await client.get('session-abc', 'mem_abc123');
console.log(memory.content);

update()

Update an existing memory's name or properties:

await client.update('session-abc', 'mem_abc123', {
  name: 'Work Info',
  properties: {
    verified: true,
    lastConfirmed: '2025-01-15',
  },
});

delete()

Delete a specific memory:

await client.delete('session-abc', 'mem_abc123');

getContext()

Generate a formatted context string optimized for LLM system prompts. This method aggregates relevant memories, profile data, facts, and preferences into a single context block:

const context = await client.getContext({
  userId: 'user-123',
  sessionId: 'session-abc',
  query: 'Help the user with their project settings',
  maxTokens: 2000,
  includeProfile: true,
  includeFacts: true,
  includePreferences: true,
});
 
// Use the context in an LLM system prompt
const systemPrompt = `You are a helpful assistant. Here is what you know about the user:
 
${context.text}
 
Use this context to personalize your responses.`;
ParameterTypeRequiredDescription
userIdstringYesUser ID to generate context for
sessionIdstringNoLimit context to a specific session
querystringNoRelevance query to prioritize related memories
maxTokensnumberNoMaximum token budget for the context
includeProfilebooleanNoInclude user profile information
includeFactsbooleanNoInclude stored facts about the user
includePreferencesbooleanNoInclude user preferences

getJobStatus()

Check the status of an asynchronous job (e.g., content ingestion):

const status = await client.getJobStatus('job_xyz789');
console.log(status.state); // 'pending' | 'processing' | 'completed' | 'failed'

Sessions

Sessions group related memories and conversations together. They support auto-extraction and auto-summarization of memories from conversation messages.

sessions.create()

const session = await client.sessions.create({
  userId: 'user-123',
  agentId: 'support-bot',
  ttl: 86400, // 24 hours in seconds
  config: {
    autoExtract: true,
    autoSummarize: true,
  },
});
 
console.log(session.id); // 'ses_abc123'
ParameterTypeRequiredDescription
userIdstringYesUser ID to associate the session with
agentIdstringNoAgent or bot identifier
ttlnumberNoTime-to-live in seconds before the session expires
config.autoExtractbooleanNoAutomatically extract memories from messages
config.autoSummarizebooleanNoAutomatically generate session summaries

sessions.get()

const session = await client.sessions.get('ses_abc123');

sessions.list()

import { MemorySessionStatus } from '@usetransactional/memory';
 
const sessions = await client.sessions.list({
  userId: 'user-123',
  status: MemorySessionStatus.ACTIVE,
  page: 1,
  limit: 20,
});
ParameterTypeRequiredDescription
userIdstringNoFilter sessions by user ID
statusMemorySessionStatusNoFilter by session status
pagenumberNoPage number for pagination
limitnumberNoResults per page

sessions.update()

await client.sessions.update('ses_abc123', {
  ttl: 172800, // Extend to 48 hours
});

sessions.delete()

await client.sessions.delete('ses_abc123');

Profiles

Profiles store persistent facts and preferences about a user that span across sessions.

profiles.get()

const profile = await client.profiles.get('user-123');
console.log(profile.staticFacts);  // e.g., { name: 'Jane', role: 'Engineer' }
console.log(profile.dynamicFacts); // e.g., { currentProject: 'Dashboard Redesign' }

profiles.upsert()

Create or update a user profile with static and dynamic facts:

await client.profiles.upsert('user-123', {
  staticFacts: {
    name: 'Jane Doe',
    company: 'Acme Corp',
    role: 'Senior Engineer',
  },
  dynamicFacts: {
    currentProject: 'Dashboard Redesign',
    preferredLanguage: 'TypeScript',
    timezone: 'America/New_York',
  },
});

Static facts are permanent attributes that rarely change (name, company, role). Dynamic facts are contextual information that may change over time (current project, recent activity).

profiles.delete()

await client.profiles.delete('user-123');

Knowledge Graph

The knowledge graph connects memories through entity relationships, enabling traversal and discovery of related information.

graph.get()

Retrieve the knowledge graph for a session:

const graph = await client.graph.get({
  sessionId: 'ses_abc123',
  depth: 2,
  entityTypes: ['entity', 'topic', 'relationship'],
  limit: 50,
});
 
for (const node of graph.nodes) {
  console.log(node.name, node.type, node.properties);
}
 
for (const edge of graph.edges) {
  console.log(edge.source, '->', edge.target, `[${edge.label}]`);
}
ParameterTypeRequiredDescription
sessionIdstringYesSession to retrieve the graph for
depthnumberNoMaximum traversal depth from root nodes
entityTypesstring[]NoFilter by entity types
limitnumberNoMaximum number of nodes to return

graph.traverse()

Traverse the graph starting from a specific entity:

const subgraph = await client.graph.traverse({
  startEntityId: 'ent_abc123',
  depth: 3,
  direction: 'outbound',
});
ParameterTypeRequiredDescription
startEntityIdstringYesEntity ID to start traversal from
depthnumberNoMaximum traversal depth
direction'outbound' | 'inbound' | 'both'NoTraversal direction. Defaults to 'both'

Content Ingestion

Ingest external content to automatically extract memories, entities, and embeddings.

ingest.url()

Ingest content from a URL:

const job = await client.ingest.url({
  url: 'https://example.com/docs/getting-started',
  userId: 'user-123',
  sessionId: 'ses_abc123',
  options: {
    extractEntities: true,
    generateEmbeddings: true,
  },
});
 
// Check ingestion progress
const status = await client.getJobStatus(job.jobId);

ingest.pdf()

Ingest content from a PDF file:

import { readFileSync } from 'fs';
 
const pdfBuffer = readFileSync('/path/to/document.pdf');
 
const job = await client.ingest.pdf({
  file: pdfBuffer,
  filename: 'document.pdf',
  userId: 'user-123',
  options: {
    extractEntities: true,
    generateEmbeddings: true,
  },
});
ParameterTypeRequiredDescription
fileBufferYesPDF file contents as a Buffer
filenamestringYesOriginal filename
userIdstringYesUser ID to associate extracted memories with
options.extractEntitiesbooleanNoExtract named entities from the document
options.generateEmbeddingsbooleanNoGenerate vector embeddings for semantic search

ingest.text()

Ingest raw text content:

const job = await client.ingest.text({
  content: '# Project Notes\n\nThe dashboard redesign uses React 19...',
  contentType: 'markdown',
  sessionId: 'ses_abc123',
});
ParameterTypeRequiredDescription
contentstringYesText content to ingest
contentType'markdown' | 'text' | 'code'YesContent format for optimal parsing
sessionIdstringNoSession to associate the content with

Enums

The SDK exports enums for type-safe usage across all operations:

import {
  MemoryEntityType,
  MemorySessionStatus,
  MemoryMessageRole,
} from '@usetransactional/memory';

MemoryEntityType

ValueDescription
USERA user identity
FACTA verified piece of information
TOPICA subject or theme
PREFERENCEA user preference or setting
EVENTA time-bound occurrence
MESSAGEA conversation message
SUMMARYAn auto-generated summary
ORGANIZATIONAn organization or group

MemorySessionStatus

ValueDescription
ACTIVESession is currently active
EXPIREDSession has expired based on TTL
DELETEDSession has been deleted

MemoryMessageRole

ValueDescription
USERMessage from the user
ASSISTANTMessage from the AI assistant
SYSTEMSystem-level message

Error Handling

The SDK throws typed errors for different failure scenarios. All errors extend the base MemoryError class:

import {
  MemoryError,
  AuthenticationError,
  ValidationError,
  NotFoundError,
  RateLimitError,
} from '@usetransactional/memory';
 
try {
  const results = await client.search({
    query: 'user preferences',
    userId: 'user-123',
  });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key. Check your credentials.');
  } else if (error instanceof ValidationError) {
    console.error('Invalid request parameters:', error.message);
  } else if (error instanceof NotFoundError) {
    console.error('Resource not found:', error.message);
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter} seconds.`);
  } else if (error instanceof MemoryError) {
    console.error('Memory API error:', error.message);
  }
}
Error ClassDescription
MemoryErrorBase error class for all SDK errors
AuthenticationErrorInvalid or missing API key
ValidationErrorInvalid request parameters
NotFoundErrorRequested resource does not exist
RateLimitErrorToo many requests. Includes retryAfter property (seconds until retry is safe)

TypeScript Types

The SDK exports all types for full type safety:

import type {
  Memory,
  Session,
  SearchResult,
  ContextResult,
  MemoryEntityType,
} from '@usetransactional/memory';
TypeDescription
MemoryA stored memory with id, content, type, userId, metadata, createdAt, and updatedAt
SessionA session with id, userId, status, config, ttl, createdAt, and updatedAt
SearchResultA search result with memory, score, and highlights
ContextResultGenerated context with text, tokenCount, memoryCount, and sources
MemoryEntityTypeEnum of all memory entity types