Skip to content

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 control
  • SmartWorkingMemory - Active session memory with timeline organization
  • SmartProceduralMemory - 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

Example

Get access to existing working memory session

// Retrieve an existing working memory session
const sessionId = "session-123";
const workingMemory = await memory.getWorkingMemorySession(sessionId);
// Use the working memory session
const entries = await workingMemory.getMemory({ nMostRecent: 10 });

startWorkingMemorySession

// No parameters required

Example

Create new working memory session for conversation

// Start a new working memory session
const { sessionId, workingMemory } = await memory.startWorkingMemorySession();
// Add first memory entry to the session
await workingMemory.putMemory({
content: "User started new conversation about project planning",
agent: "assistant"
});

rehydrateSession

sessionId: string
summaryOnly?: boolean

Example

Restore previous session from episodic memory

// Restore a previous session with full conversation history
const 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

Example

End working memory session with optional flush to long-term storage

// End the session and flush to episodic memory
await 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
}

Example

Retrieve exact matching memory entries from working session

// Get recent memories from specific timeline
const memories = await workingMemory.getMemory({
timeline: "user_preferences",
nMostRecent: 5
});
// Process retrieved memories
if (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
}

Example

Search working memory for entries similar to given terms

// Search for memories related to specific topic
const results = await workingMemory.searchMemory({
terms: "user authentication",
nMostRecent: 10
});
// Review search results
if (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
}

Example

Add new memory entry to working session

// Add memory entry with metadata
const 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

Example

Remove specific memory entry by ID

// Delete a specific memory entry
await workingMemory.deleteMemory("entry-789");
console.log("Memory entry deleted");

summarizeMemory

memories: MemoryEntry[]
systemPrompt?: string

Example

Generate summary of memory entries using AI model

// Get recent memories and create summary
const 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: string
options?: {
nMostRecent?: number; // defaults to 'all'
startTime?: Date;
endTime?: Date;
}

Example

Search historical conversations for relevant context

// Search for previous discussions about specific topics
const results = await memory.searchEpisodicMemory("database optimization", {
nMostRecent: 5
});
// Review relevant past sessions
results.results.forEach(session => {
console.log(`Session ${session.sessionId}: ${session.summary}`);
});

Semantic Memory Methods

getSemanticMemory

objectId: string

Example

Retrieve specific knowledge document

// Get a specific knowledge document by ID
const 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

Example

Search knowledge base for relevant information

// Search semantic memory for related knowledge
const 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>

Example

Store knowledge document in semantic memory

// Store new knowledge document
const 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

Example

Remove knowledge document from semantic memory

// Delete a knowledge document
const result = await memory.deleteSemanticMemory("doc-456");
if (result.success) {
console.log("Document deleted successfully");
}

Procedural Memory Methods

getProceduralMemory

id?: string

Example

Access procedural memory for templates and skills

// Get procedural memory interface
const proceduralMemory = await memory.getProceduralMemory();
// Store a reusable procedure
await proceduralMemory.putProcedure("email_template",
"Subject: Welcome to our service\n\nDear {name}, welcome aboard!");

putProcedure

key: string
value: string

Example

Store reusable procedure or template

// Store a procedure template
await proceduralMemory.putProcedure("code_review_checklist", `
1. Check for security vulnerabilities
2. Verify error handling
3. Review performance implications
4. Validate test coverage
`);

getProcedure

key: string

Example

Retrieve stored procedure by key

// Get a specific procedure
const checklist = await proceduralMemory.getProcedure("code_review_checklist");
if (checklist) {
console.log("Code review steps:", checklist);
}

deleteProcedure

key: string

Example

Remove procedure from storage

// Delete a procedure
const deleted = await proceduralMemory.deleteProcedure("old_template");
if (deleted) {
console.log("Procedure removed successfully");
}

listProcedures

// No parameters required

Example

Get all stored procedures

// List all available procedures
const 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)
}

Example

Search stored procedures by text matching

// Search procedures for specific terms
const results = await proceduralMemory.searchProcedures({
terms: "review",
nMostRecent: 5
});
if (results) {
results.forEach(proc => {
console.log(`Found procedure: ${proc.key}`);
});
}