SmartMemory
This content is for the 0.6.3 version. Switch to the latest version for up-to-date documentation.
SmartMemory provides a memory system for AI agents with four distinct memory layers that work together to create persistent, intelligent applications. The system manages active conversations, historical sessions, structured knowledge, and reusable procedures through a unified interface.
The architecture separates concerns across memory types: working memory handles active sessions, episodic memory stores completed session summaries, semantic memory holds structured knowledge documents, and procedural memory maintains templates and skills. This separation allows AI agents to maintain context while building long-term capabilities.
Key benefits include multi-layered memory architecture, vector-based semantic search, automatic session summarization, and isolated session management with timeline organization.
Creating
Configure SmartMemory in your raindrop.manifest file within an application block:
application "ai-assistant" { smartmemory "agent_memory" {}}
Accessing
Use SmartMemory in your services through the environment interface. All SmartMemory operations are asynchronous and return Promises:
export default class extends Service<Env> { async fetch(request: Request): Promise<Response> { // Get the SmartMemory binding from environment const memory = this.env.AGENT_MEMORY;
// Start a new working memory session const { sessionId, workingMemory } = await memory.startWorkingMemorySession();
return new Response(`Started session: ${sessionId}`); }};
Core Concepts
Main Interfaces
SmartMemory
- Root interface for memory management and session controlSmartWorkingMemory
- Active session memory with timeline organizationSmartProceduralMemory
- Persistent storage for reusable procedures and skills
Core Data Types
SessionId
export type SessionId = string;// Unique identifier for working memory sessions// Used to track and restore conversation contexts
MemoryEntry
export type MemoryEntry = { id: string; // Unique entry identifier in: SessionId; // Session this entry belongs to timeline: string; // Timeline organization (defaults to "*defaultTimeline") by: string; // Entry originator dueTo: string; // Entry cause or trigger content: string; // Actual memory content at: Date; // Timestamp when entry was created key?: string; // Optional metadata for filtering agent?: string; // Optional agent name that created this entry};
NewMemoryEntry
export type NewMemoryEntry = { timeline?: string; // Optional timeline (defaults to "*defaultTimeline") key?: string; // Optional metadata for filtering content: string; // Required memory content agent?: string; // Optional agent name sessionId?: string; // Optional explicit session ID at?: Date; // Optional timestamp (defaults to current time)};
ProcedureEntry
export type ProcedureEntry = { key: string; // Procedure identifier value: string; // Procedure content or template createdAt: Date; // Creation timestamp updatedAt: Date; // Last modification timestamp};
Working Memory Methods
getWorkingMemorySession
sessionId: string
Promise<ActorStub<SmartWorkingMemory>>
Example
Get access to existing working memory session
// Retrieve an existing working memory sessionconst sessionId = "session-123";const workingMemory = await memory.getWorkingMemorySession(sessionId);
// Use the working memory sessionconst entries = await workingMemory.getMemory({ nMostRecent: 10 });
startWorkingMemorySession
// No parameters required
Promise<{ sessionId: SessionId; workingMemory: ActorStub<SmartWorkingMemory>;}>
Example
Create new working memory session for conversation
// Start a new working memory sessionconst { sessionId, workingMemory } = await memory.startWorkingMemorySession();
// Add first memory entry to the sessionawait workingMemory.putMemory({ content: "User started new conversation about project planning", agent: "assistant"});
rehydrateSession
sessionId: stringsummaryOnly?: boolean
Promise<{ sessionId: string; workingMemory: ActorStub<SmartWorkingMemory>; success: boolean; message: string; entriesRestored?: number;}>
Example
Restore previous session from episodic memory
// Restore a previous session with full conversation historyconst result = await memory.rehydrateSession("session-123", false);
if (result.success) { console.log(`Restored ${result.entriesRestored} entries`); // Continue conversation with restored context const workingMemory = result.workingMemory;}
endSession
flush: boolean
Promise<void>
Example
End working memory session with optional flush to long-term storage
// End the session and flush to episodic memoryawait workingMemory.endSession(true);
// Session is now stored in episodic memory for future retrieval
getMemory
entry: WorkingMemoryQuery = { timeline?: string; // defaults to "*defaultTimeline" key?: string; // optional metadata filtering nMostRecent?: number; // defaults to 'all' startTime?: Date; // optional time range start endTime?: Date; // optional time range end}
Promise<MemoryEntry[] | null>
Example
Retrieve exact matching memory entries from working session
// Get recent memories from specific timelineconst memories = await workingMemory.getMemory({ timeline: "user_preferences", nMostRecent: 5});
// Process retrieved memoriesif (memories) { memories.forEach(entry => { console.log(`${entry.at}: ${entry.content}`); });}
searchMemory
terms: WorkingMemorySearchQuery = { timeline?: string; // defaults to "*defaultTimeline" terms: string; // required search terms nMostRecent?: number; // defaults to 'all' startTime?: Date; // optional time range start endTime?: Date; // optional time range end}
Promise<MemoryEntry[] | null>
Example
Search working memory for entries similar to given terms
// Search for memories related to specific topicconst results = await workingMemory.searchMemory({ terms: "user authentication", nMostRecent: 10});
// Review search resultsif (results) { results.forEach(entry => { console.log(`Found: ${entry.content}`); });}
putMemory
entry: NewMemoryEntry = { timeline?: string; // defaults to "*defaultTimeline" key?: string; // optional metadata content: string; // required memory content agent?: string; // optional agent name sessionId?: string; // optional explicit session ID at?: Date; // optional timestamp}
Promise<string>
Example
Add new memory entry to working session
// Add memory entry with metadataconst entryId = await workingMemory.putMemory({ content: "User prefers dark theme and compact layout", key: "ui_preferences", agent: "settings_handler"});
console.log(`Created memory entry: ${entryId}`);
deleteMemory
entryId: string
Promise<void>
Example
Remove specific memory entry by ID
// Delete a specific memory entryawait workingMemory.deleteMemory("entry-789");
console.log("Memory entry deleted");
summarizeMemory
memories: MemoryEntry[]systemPrompt?: string
Promise<{ summary: string; entries: Record<string, MemoryEntry[]>; metadata: { duration: number; timelineCount: number; entryCount: number; agent: string; };}>
Example
Generate summary of memory entries using AI model
// Get recent memories and create summaryconst memories = await workingMemory.getMemory({ nMostRecent: 20 });
if (memories) { const summary = await workingMemory.summarizeMemory(memories);
console.log(`Session summary: ${summary.summary}`); console.log(`Processed ${summary.metadata.entryCount} entries`);}
Episodic Memory Methods
searchEpisodicMemory
terms: stringoptions?: { nMostRecent?: number; // defaults to 'all' startTime?: Date; endTime?: Date;}
Promise<{ results: Array<{ sessionId: string; summary: string; agent: string; entryCount: number; timelineCount: number; duration: number; createdAt: Date; score?: number; }>; pagination: { total: number; page: number; pageSize: number; totalPages: number; hasMore: boolean; };}>
Example
Search historical conversations for relevant context
// Search for previous discussions about specific topicsconst results = await memory.searchEpisodicMemory("database optimization", { nMostRecent: 5});
// Review relevant past sessionsresults.results.forEach(session => { console.log(`Session ${session.sessionId}: ${session.summary}`);});
Semantic Memory Methods
getSemanticMemory
objectId: string
Promise<{ success: boolean; document?: Record<string, unknown>; error?: string;}>
Example
Retrieve specific knowledge document
// Get a specific knowledge document by IDconst result = await memory.getSemanticMemory("doc-456");
if (result.success && result.document) { // Use the retrieved knowledge document console.log("Knowledge retrieved:", result.document);}
searchSemanticMemory
needle: string
Promise<{ success: boolean; documentSearchResponse?: { results: Array<{ chunkSignature?: string; text?: string; source?: string | { object?: string }; payloadSignature?: string; score?: number; embed?: Float32Array; type?: string; }>; }; error?: string;}>
Example
Search knowledge base for relevant information
// Search semantic memory for related knowledgeconst results = await memory.searchSemanticMemory("API authentication patterns");
if (results.success && results.documentSearchResponse) { // Process search results results.documentSearchResponse.results.forEach(result => { console.log(`Found: ${result.text} (score: ${result.score})`); });}
putSemanticMemory
document: Record<string, unknown>
Promise<{ success: boolean; objectId?: string; error?: string;}>
Example
Store knowledge document in semantic memory
// Store new knowledge documentconst document = { title: "API Best Practices", content: "Always validate input parameters and handle errors gracefully...", category: "development", tags: ["api", "security", "validation"]};
const result = await memory.putSemanticMemory(document);
if (result.success) { console.log(`Stored document with ID: ${result.objectId}`);}
deleteSemanticMemory
objectId: string
Promise<{ success: boolean; error?: string;}>
Example
Remove knowledge document from semantic memory
// Delete a knowledge documentconst result = await memory.deleteSemanticMemory("doc-456");
if (result.success) { console.log("Document deleted successfully");}
Procedural Memory Methods
getProceduralMemory
id?: string
Promise<ActorStub<SmartProceduralMemory>>
Example
Access procedural memory for templates and skills
// Get procedural memory interfaceconst proceduralMemory = await memory.getProceduralMemory();
// Store a reusable procedureawait proceduralMemory.putProcedure("email_template", "Subject: Welcome to our service\n\nDear {name}, welcome aboard!");
putProcedure
key: stringvalue: string
Promise<void>
Example
Store reusable procedure or template
// Store a procedure templateawait proceduralMemory.putProcedure("code_review_checklist", `1. Check for security vulnerabilities2. Verify error handling3. Review performance implications4. Validate test coverage`);
getProcedure
key: string
Promise<string | null>
Example
Retrieve stored procedure by key
// Get a specific procedureconst checklist = await proceduralMemory.getProcedure("code_review_checklist");
if (checklist) { console.log("Code review steps:", checklist);}
deleteProcedure
key: string
Promise<boolean>
Example
Remove procedure from storage
// Delete a procedureconst deleted = await proceduralMemory.deleteProcedure("old_template");
if (deleted) { console.log("Procedure removed successfully");}
listProcedures
// No parameters required
Promise<ProcedureEntry[]>
Example
Get all stored procedures
// List all available proceduresconst procedures = await proceduralMemory.listProcedures();
procedures.forEach(proc => { console.log(`${proc.key}: ${proc.value.substring(0, 50)}...`);});
searchProcedures
query: ProceduralMemorySearchQuery = { terms: string; // required search terms nMostRecent?: number; // defaults to 'all' searchKeys?: boolean; // search keys (default: true) searchValues?: boolean; // search values (default: true)}
Promise<ProcedureEntry[] | null>
Example
Search stored procedures by text matching
// Search procedures for specific termsconst results = await proceduralMemory.searchProcedures({ terms: "review", nMostRecent: 5});
if (results) { results.forEach(proc => { console.log(`Found procedure: ${proc.key}`); });}