@elizaos/plugin-memory 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -13
- package/dist/browser/index.browser.js +49 -20
- package/dist/browser/index.browser.js.map +7 -7
- package/dist/cjs/index.node.cjs +133 -39
- package/dist/cjs/index.node.js.map +7 -7
- package/dist/evaluators/summarization.d.ts +13 -6
- package/dist/node/index.node.js +133 -39
- package/dist/node/index.node.js.map +7 -7
- package/dist/services/memory-service.d.ts +6 -3
- package/dist/types/index.d.ts +3 -0
- package/package.json +1 -1
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/services/memory-service.ts", "../../src/schemas/long-term-memories.ts", "../../src/schemas/session-summaries.ts", "../../src/schemas/memory-access-logs.ts", "../../src/evaluators/summarization.ts", "../../src/evaluators/long-term-extraction.ts", "../../src/types/index.ts", "../../src/providers/short-term-memory.ts", "../../src/providers/long-term-memory.ts", "../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n type IAgentRuntime,\n Service,\n type UUID,\n logger,\n type ServiceTypeName,\n} from '@elizaos/core';\nimport { eq, and, desc, sql, cosineDistance, gte } from 'drizzle-orm';\nimport {\n type LongTermMemory,\n type SessionSummary,\n type MemoryConfig,\n LongTermMemoryCategory,\n} from '../types/index';\nimport { longTermMemories, sessionSummaries } from '../schemas/index';\n\n/**\n * Memory Service\n * Manages both short-term (session summaries) and long-term (persistent facts) memory\n */\nexport class MemoryService extends Service {\n static serviceType: ServiceTypeName = 'memory' as ServiceTypeName;\n\n private sessionMessageCounts: Map<UUID, number>;\n private memoryConfig: MemoryConfig;\n private lastExtractionCheckpoints: Map<string, number>; // Track last extraction per entity-room pair\n\n capabilityDescription =\n 'Advanced memory management with short-term summarization and long-term persistent facts';\n\n constructor(runtime?: IAgentRuntime) {\n super(runtime);\n this.sessionMessageCounts = new Map();\n this.lastExtractionCheckpoints = new Map();\n this.memoryConfig = {\n shortTermSummarizationThreshold: 5,\n shortTermRetainRecent: 10,\n longTermExtractionEnabled: true,\n longTermVectorSearchEnabled: false,\n longTermConfidenceThreshold: 0.7,\n longTermExtractionInterval: 5, // Run extraction every N messages\n summaryModelType: 'TEXT_LARGE',\n summaryMaxTokens: 2500,\n };\n }\n\n static async start(runtime: IAgentRuntime): Promise<Service> {\n const service = new MemoryService(runtime);\n await service.initialize(runtime);\n return service;\n }\n\n async stop(): Promise<void> {\n // No cleanup needed for this service\n logger.info('MemoryService stopped');\n }\n\n async initialize(runtime: IAgentRuntime): Promise<void> {\n this.runtime = runtime;\n\n // Load configuration from runtime settings\n const threshold = runtime.getSetting('MEMORY_SUMMARIZATION_THRESHOLD');\n if (threshold) {\n this.memoryConfig.shortTermSummarizationThreshold = parseInt(threshold, 10);\n }\n\n const retainRecent = runtime.getSetting('MEMORY_RETAIN_RECENT');\n if (retainRecent) {\n this.memoryConfig.shortTermRetainRecent = parseInt(retainRecent, 10);\n }\n\n const longTermEnabled = runtime.getSetting('MEMORY_LONG_TERM_ENABLED');\n // Only override default if explicitly set to 'false'\n if (longTermEnabled === 'false') {\n this.memoryConfig.longTermExtractionEnabled = false;\n } else if (longTermEnabled === 'true') {\n this.memoryConfig.longTermExtractionEnabled = true;\n }\n // Otherwise keep the default value (true)\n\n const confidenceThreshold = runtime.getSetting('MEMORY_CONFIDENCE_THRESHOLD');\n if (confidenceThreshold) {\n this.memoryConfig.longTermConfidenceThreshold = parseFloat(confidenceThreshold);\n }\n\n logger.info(\n {\n summarizationThreshold: this.memoryConfig.shortTermSummarizationThreshold,\n retainRecent: this.memoryConfig.shortTermRetainRecent,\n longTermEnabled: this.memoryConfig.longTermExtractionEnabled,\n extractionInterval: this.memoryConfig.longTermExtractionInterval,\n confidenceThreshold: this.memoryConfig.longTermConfidenceThreshold,\n },\n 'MemoryService initialized'\n );\n }\n\n /**\n * Get the Drizzle database instance\n */\n private getDb(): any {\n const db = (this.runtime as any).db;\n if (!db) {\n throw new Error('Database not available');\n }\n return db;\n }\n\n /**\n * Get configuration\n */\n getConfig(): MemoryConfig {\n return { ...this.memoryConfig };\n }\n\n /**\n * Update configuration\n */\n updateConfig(updates: Partial<MemoryConfig>): void {\n this.memoryConfig = { ...this.memoryConfig, ...updates };\n }\n\n /**\n * Track message count for a room\n */\n incrementMessageCount(roomId: UUID): number {\n const current = this.sessionMessageCounts.get(roomId) || 0;\n const newCount = current + 1;\n this.sessionMessageCounts.set(roomId, newCount);\n return newCount;\n }\n\n /**\n * Reset message count for a room\n */\n resetMessageCount(roomId: UUID): void {\n this.sessionMessageCounts.set(roomId, 0);\n }\n\n /**\n * Check if summarization is needed for a room\n */\n async shouldSummarize(roomId: UUID): Promise<boolean> {\n const count = await this.runtime.countMemories(roomId, false, 'messages');\n return count >= this.memoryConfig.shortTermSummarizationThreshold;\n }\n\n /**\n * Generate cache key for tracking extraction checkpoints per entity-room pair\n */\n private getExtractionKey(entityId: UUID, roomId: UUID): string {\n return `memory:extraction:${entityId}:${roomId}`;\n }\n\n /**\n * Get the last extraction checkpoint for an entity in a room\n * Uses the cache table via adapter\n */\n async getLastExtractionCheckpoint(entityId: UUID, roomId: UUID): Promise<number> {\n const key = this.getExtractionKey(entityId, roomId);\n\n // Check in-memory cache first\n const cached = this.lastExtractionCheckpoints.get(key);\n if (cached !== undefined) {\n return cached;\n }\n\n // Check database cache table via adapter\n try {\n const checkpoint = await this.runtime.getCache<number>(key);\n const messageCount = checkpoint ?? 0;\n\n // Cache it in memory for faster access\n this.lastExtractionCheckpoints.set(key, messageCount);\n\n return messageCount;\n } catch (error) {\n logger.warn({ error }, 'Failed to get extraction checkpoint from cache');\n return 0;\n }\n }\n\n /**\n * Set the last extraction checkpoint for an entity in a room\n * Uses the cache table via adapter\n */\n async setLastExtractionCheckpoint(\n entityId: UUID,\n roomId: UUID,\n messageCount: number\n ): Promise<void> {\n const key = this.getExtractionKey(entityId, roomId);\n\n // Update in-memory cache\n this.lastExtractionCheckpoints.set(key, messageCount);\n\n // Persist to database cache table via adapter\n try {\n await this.runtime.setCache(key, messageCount);\n logger.debug(\n `Set extraction checkpoint for ${entityId} in room ${roomId} at message count ${messageCount}`\n );\n } catch (error) {\n logger.error({ error }, 'Failed to persist extraction checkpoint to cache');\n }\n }\n\n /**\n * Check if long-term extraction should run based on message count and interval\n */\n async shouldRunExtraction(\n entityId: UUID,\n roomId: UUID,\n currentMessageCount: number\n ): Promise<boolean> {\n const interval = this.memoryConfig.longTermExtractionInterval;\n const lastCheckpoint = await this.getLastExtractionCheckpoint(entityId, roomId);\n\n // Calculate the current checkpoint (e.g., if interval=5: 5, 10, 15, 20...)\n const currentCheckpoint = Math.floor(currentMessageCount / interval) * interval;\n\n // Run if we're at or past a checkpoint and haven't processed this checkpoint yet\n const shouldRun = currentMessageCount >= interval && currentCheckpoint > lastCheckpoint;\n\n logger.debug(\n {\n entityId,\n roomId,\n currentMessageCount,\n interval,\n lastCheckpoint,\n currentCheckpoint,\n shouldRun,\n },\n 'Extraction check'\n );\n\n return shouldRun;\n }\n\n /**\n * Store a long-term memory\n */\n async storeLongTermMemory(\n memory: Omit<LongTermMemory, 'id' | 'createdAt' | 'updatedAt'>\n ): Promise<LongTermMemory> {\n const db = this.getDb();\n\n const id = crypto.randomUUID() as UUID;\n const now = new Date();\n\n const newMemory: LongTermMemory = {\n id,\n createdAt: now,\n updatedAt: now,\n accessCount: 0,\n ...memory,\n };\n\n try {\n await db.insert(longTermMemories).values({\n id: newMemory.id,\n agentId: newMemory.agentId,\n entityId: newMemory.entityId,\n category: newMemory.category,\n content: newMemory.content,\n metadata: newMemory.metadata || {},\n embedding: newMemory.embedding,\n confidence: newMemory.confidence,\n source: newMemory.source,\n accessCount: newMemory.accessCount,\n createdAt: now,\n updatedAt: now,\n lastAccessedAt: newMemory.lastAccessedAt,\n });\n } catch (error) {\n logger.error({ error }, 'Failed to store long-term memory');\n throw error;\n }\n\n logger.info(`Stored long-term memory: ${newMemory.category} for entity ${newMemory.entityId}`);\n return newMemory;\n }\n\n /**\n * Retrieve long-term memories for an entity\n */\n async getLongTermMemories(\n entityId: UUID,\n category?: LongTermMemoryCategory,\n limit: number = 10\n ): Promise<LongTermMemory[]> {\n const db = this.getDb();\n\n const conditions = [\n eq(longTermMemories.agentId, this.runtime.agentId),\n eq(longTermMemories.entityId, entityId),\n ];\n\n if (category) {\n conditions.push(eq(longTermMemories.category, category));\n }\n\n const results = await db\n .select()\n .from(longTermMemories)\n .where(and(...conditions))\n .orderBy(desc(longTermMemories.confidence), desc(longTermMemories.updatedAt))\n .limit(limit);\n\n return results.map((row) => ({\n id: row.id as UUID,\n agentId: row.agentId as UUID,\n entityId: row.entityId as UUID,\n category: row.category as LongTermMemoryCategory,\n content: row.content,\n metadata: row.metadata as Record<string, unknown>,\n embedding: row.embedding as number[],\n confidence: row.confidence as number,\n source: row.source as string,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n lastAccessedAt: row.lastAccessedAt,\n accessCount: row.accessCount as number,\n }));\n }\n\n /**\n * Update a long-term memory\n */\n async updateLongTermMemory(\n id: UUID,\n updates: Partial<Omit<LongTermMemory, 'id' | 'agentId' | 'createdAt'>>\n ): Promise<void> {\n const db = this.getDb();\n\n const updateData: any = {\n updatedAt: new Date(),\n };\n\n if (updates.content !== undefined) {\n updateData.content = updates.content;\n }\n\n if (updates.metadata !== undefined) {\n updateData.metadata = updates.metadata;\n }\n\n if (updates.confidence !== undefined) {\n updateData.confidence = updates.confidence;\n }\n\n if (updates.embedding !== undefined) {\n updateData.embedding = updates.embedding;\n }\n\n if (updates.lastAccessedAt !== undefined) {\n updateData.lastAccessedAt = updates.lastAccessedAt;\n }\n\n if (updates.accessCount !== undefined) {\n updateData.accessCount = updates.accessCount;\n }\n\n await db.update(longTermMemories).set(updateData).where(eq(longTermMemories.id, id));\n\n logger.info(`Updated long-term memory: ${id}`);\n }\n\n /**\n * Delete a long-term memory\n */\n async deleteLongTermMemory(id: UUID): Promise<void> {\n const db = this.getDb();\n\n await db.delete(longTermMemories).where(eq(longTermMemories.id, id));\n\n logger.info(`Deleted long-term memory: ${id}`);\n }\n\n /**\n * Get the current session summary for a room (latest one)\n */\n async getCurrentSessionSummary(roomId: UUID): Promise<SessionSummary | null> {\n const db = this.getDb();\n\n const results = await db\n .select()\n .from(sessionSummaries)\n .where(\n and(eq(sessionSummaries.agentId, this.runtime.agentId), eq(sessionSummaries.roomId, roomId))\n )\n .orderBy(desc(sessionSummaries.updatedAt))\n .limit(1);\n\n if (results.length === 0) {\n return null;\n }\n\n const row = results[0];\n return {\n id: row.id as UUID,\n agentId: row.agentId as UUID,\n roomId: row.roomId as UUID,\n entityId: row.entityId as UUID | undefined,\n summary: row.summary,\n messageCount: row.messageCount,\n lastMessageOffset: row.lastMessageOffset,\n startTime: row.startTime,\n endTime: row.endTime,\n topics: (row.topics as string[]) || [],\n metadata: row.metadata as Record<string, unknown>,\n embedding: row.embedding as number[],\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n }\n\n /**\n * Store a session summary (initial creation)\n */\n async storeSessionSummary(\n summary: Omit<SessionSummary, 'id' | 'createdAt' | 'updatedAt'>\n ): Promise<SessionSummary> {\n const db = this.getDb();\n\n const id = crypto.randomUUID() as UUID;\n const now = new Date();\n\n const newSummary: SessionSummary = {\n id,\n createdAt: now,\n updatedAt: now,\n ...summary,\n };\n\n await db.insert(sessionSummaries).values({\n id: newSummary.id,\n agentId: newSummary.agentId,\n roomId: newSummary.roomId,\n entityId: newSummary.entityId || null,\n summary: newSummary.summary,\n messageCount: newSummary.messageCount,\n lastMessageOffset: newSummary.lastMessageOffset,\n startTime: newSummary.startTime,\n endTime: newSummary.endTime,\n topics: newSummary.topics || [],\n metadata: newSummary.metadata || {},\n embedding: newSummary.embedding,\n createdAt: now,\n updatedAt: now,\n });\n\n logger.info(`Stored session summary for room ${newSummary.roomId}`);\n return newSummary;\n }\n\n /**\n * Update an existing session summary\n */\n async updateSessionSummary(\n id: UUID,\n updates: Partial<Omit<SessionSummary, 'id' | 'agentId' | 'roomId' | 'createdAt' | 'updatedAt'>>\n ): Promise<void> {\n const db = this.getDb();\n\n const updateData: any = {\n updatedAt: new Date(),\n };\n\n if (updates.summary !== undefined) {\n updateData.summary = updates.summary;\n }\n\n if (updates.messageCount !== undefined) {\n updateData.messageCount = updates.messageCount;\n }\n\n if (updates.lastMessageOffset !== undefined) {\n updateData.lastMessageOffset = updates.lastMessageOffset;\n }\n\n if (updates.endTime !== undefined) {\n updateData.endTime = updates.endTime;\n }\n\n if (updates.topics !== undefined) {\n updateData.topics = updates.topics;\n }\n\n if (updates.metadata !== undefined) {\n updateData.metadata = updates.metadata;\n }\n\n if (updates.embedding !== undefined) {\n updateData.embedding = updates.embedding;\n }\n\n await db.update(sessionSummaries).set(updateData).where(eq(sessionSummaries.id, id));\n\n logger.info(`Updated session summary: ${id}`);\n }\n\n /**\n * Get session summaries for a room\n */\n async getSessionSummaries(roomId: UUID, limit: number = 5): Promise<SessionSummary[]> {\n const db = this.getDb();\n\n const results = await db\n .select()\n .from(sessionSummaries)\n .where(\n and(eq(sessionSummaries.agentId, this.runtime.agentId), eq(sessionSummaries.roomId, roomId))\n )\n .orderBy(desc(sessionSummaries.updatedAt))\n .limit(limit);\n\n return results.map((row) => ({\n id: row.id as UUID,\n agentId: row.agentId as UUID,\n roomId: row.roomId as UUID,\n entityId: row.entityId as UUID | undefined,\n summary: row.summary,\n messageCount: row.messageCount,\n lastMessageOffset: row.lastMessageOffset,\n startTime: row.startTime,\n endTime: row.endTime,\n topics: (row.topics as string[]) || [],\n metadata: row.metadata as Record<string, unknown>,\n embedding: row.embedding as number[],\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n }));\n }\n\n /**\n * Search long-term memories by semantic similarity (if embeddings are available)\n */\n async searchLongTermMemories(\n entityId: UUID,\n queryEmbedding: number[],\n limit: number = 5,\n matchThreshold: number = 0.7\n ): Promise<LongTermMemory[]> {\n if (!this.memoryConfig.longTermVectorSearchEnabled) {\n logger.warn('Vector search is not enabled, falling back to recent memories');\n return this.getLongTermMemories(entityId, undefined, limit);\n }\n\n const db = this.getDb();\n\n try {\n // Clean the vector to ensure all numbers are finite and properly formatted\n const cleanVector = queryEmbedding.map((n) =>\n Number.isFinite(n) ? Number(n.toFixed(6)) : 0\n );\n\n // Calculate similarity using Drizzle's cosineDistance\n const similarity = sql<number>`1 - (${cosineDistance(\n longTermMemories.embedding,\n cleanVector\n )})`;\n\n const conditions = [\n eq(longTermMemories.agentId, this.runtime.agentId),\n eq(longTermMemories.entityId, entityId),\n sql`${longTermMemories.embedding} IS NOT NULL`,\n ];\n\n // Add similarity threshold if specified\n if (matchThreshold > 0) {\n conditions.push(gte(similarity, matchThreshold));\n }\n\n const results = await db\n .select({\n memory: longTermMemories,\n similarity,\n })\n .from(longTermMemories)\n .where(and(...conditions))\n .orderBy(desc(similarity))\n .limit(limit);\n\n return results.map((row) => ({\n id: row.memory.id as UUID,\n agentId: row.memory.agentId as UUID,\n entityId: row.memory.entityId as UUID,\n category: row.memory.category as LongTermMemoryCategory,\n content: row.memory.content,\n metadata: row.memory.metadata as Record<string, unknown>,\n embedding: row.memory.embedding as number[],\n confidence: row.memory.confidence as number,\n source: row.memory.source as string,\n createdAt: row.memory.createdAt,\n updatedAt: row.memory.updatedAt,\n lastAccessedAt: row.memory.lastAccessedAt,\n accessCount: row.memory.accessCount as number,\n similarity: row.similarity,\n }));\n } catch (error) {\n logger.warn({ error }, 'Vector search failed, falling back to recent memories');\n return this.getLongTermMemories(entityId, undefined, limit);\n }\n }\n\n /**\n * Get all long-term memories formatted for context\n */\n async getFormattedLongTermMemories(entityId: UUID): Promise<string> {\n const memories = await this.getLongTermMemories(entityId, undefined, 20);\n\n if (memories.length === 0) {\n return '';\n }\n\n // Group by category\n const grouped = new Map<LongTermMemoryCategory, LongTermMemory[]>();\n\n for (const memory of memories) {\n if (!grouped.has(memory.category)) {\n grouped.set(memory.category, []);\n }\n grouped.get(memory.category)?.push(memory);\n }\n\n // Format each category\n const sections: string[] = [];\n\n for (const [category, categoryMemories] of grouped.entries()) {\n const categoryName = category\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n const items = categoryMemories.map((m) => `- ${m.content}`).join('\\n');\n sections.push(`**${categoryName}**:\\n${items}`);\n }\n\n return sections.join('\\n\\n');\n }\n}\n",
|
|
5
|
+
"import {\n type IAgentRuntime,\n Service,\n type UUID,\n logger,\n type ServiceTypeName,\n} from '@elizaos/core';\nimport { eq, and, desc, sql, cosineDistance, gte } from 'drizzle-orm';\nimport {\n type LongTermMemory,\n type SessionSummary,\n type MemoryConfig,\n LongTermMemoryCategory,\n} from '../types/index';\nimport { longTermMemories, sessionSummaries } from '../schemas/index';\n\n/**\n * Memory Service\n * Manages both short-term (session summaries) and long-term (persistent facts) memory\n */\nexport class MemoryService extends Service {\n static serviceType: ServiceTypeName = 'memory' as ServiceTypeName;\n\n private sessionMessageCounts: Map<UUID, number>;\n private memoryConfig: MemoryConfig;\n private lastExtractionCheckpoints: Map<string, number>; // Track last extraction per entity-room pair\n\n capabilityDescription =\n 'Advanced memory management with short-term summarization and long-term persistent facts';\n\n constructor(runtime?: IAgentRuntime) {\n super(runtime);\n this.sessionMessageCounts = new Map();\n this.lastExtractionCheckpoints = new Map();\n this.memoryConfig = {\n shortTermSummarizationThreshold: 16, // Start summarization at 16 messages\n shortTermRetainRecent: 10,\n shortTermSummarizationInterval: 10, // Update summary every 10 new messages\n longTermExtractionEnabled: true,\n longTermVectorSearchEnabled: false,\n longTermConfidenceThreshold: 0.7,\n longTermExtractionThreshold: 20, // Minimum messages before starting extraction\n longTermExtractionInterval: 5, // Run extraction every N messages after threshold\n summaryModelType: 'TEXT_LARGE',\n summaryMaxTokens: 2500,\n summaryMaxNewMessages: 20, // Cap new messages in update to prevent context bloat\n };\n }\n\n static async start(runtime: IAgentRuntime): Promise<Service> {\n const service = new MemoryService(runtime);\n await service.initialize(runtime);\n return service;\n }\n\n async stop(): Promise<void> {\n // No cleanup needed for this service\n logger.info('MemoryService stopped');\n }\n\n async initialize(runtime: IAgentRuntime): Promise<void> {\n this.runtime = runtime;\n\n // Load configuration from runtime settings\n const threshold = runtime.getSetting('MEMORY_SUMMARIZATION_THRESHOLD');\n if (threshold) {\n this.memoryConfig.shortTermSummarizationThreshold = parseInt(threshold, 10);\n }\n\n const retainRecent = runtime.getSetting('MEMORY_RETAIN_RECENT');\n if (retainRecent) {\n this.memoryConfig.shortTermRetainRecent = parseInt(retainRecent, 10);\n }\n\n const summarizationInterval = runtime.getSetting('MEMORY_SUMMARIZATION_INTERVAL');\n if (summarizationInterval) {\n this.memoryConfig.shortTermSummarizationInterval = parseInt(summarizationInterval, 10);\n }\n\n const maxNewMessages = runtime.getSetting('MEMORY_MAX_NEW_MESSAGES');\n if (maxNewMessages) {\n this.memoryConfig.summaryMaxNewMessages = parseInt(maxNewMessages, 10);\n }\n\n const longTermEnabled = runtime.getSetting('MEMORY_LONG_TERM_ENABLED');\n // Only override default if explicitly set to 'false'\n if (longTermEnabled === 'false') {\n this.memoryConfig.longTermExtractionEnabled = false;\n } else if (longTermEnabled === 'true') {\n this.memoryConfig.longTermExtractionEnabled = true;\n }\n // Otherwise keep the default value (true)\n\n const confidenceThreshold = runtime.getSetting('MEMORY_CONFIDENCE_THRESHOLD');\n if (confidenceThreshold) {\n this.memoryConfig.longTermConfidenceThreshold = parseFloat(confidenceThreshold);\n }\n\n const extractionThreshold = runtime.getSetting('MEMORY_EXTRACTION_THRESHOLD');\n if (extractionThreshold) {\n this.memoryConfig.longTermExtractionThreshold = parseInt(extractionThreshold, 10);\n }\n\n const extractionInterval = runtime.getSetting('MEMORY_EXTRACTION_INTERVAL');\n if (extractionInterval) {\n this.memoryConfig.longTermExtractionInterval = parseInt(extractionInterval, 10);\n }\n\n logger.info(\n {\n summarizationThreshold: this.memoryConfig.shortTermSummarizationThreshold,\n summarizationInterval: this.memoryConfig.shortTermSummarizationInterval,\n maxNewMessages: this.memoryConfig.summaryMaxNewMessages,\n retainRecent: this.memoryConfig.shortTermRetainRecent,\n longTermEnabled: this.memoryConfig.longTermExtractionEnabled,\n extractionThreshold: this.memoryConfig.longTermExtractionThreshold,\n extractionInterval: this.memoryConfig.longTermExtractionInterval,\n confidenceThreshold: this.memoryConfig.longTermConfidenceThreshold,\n },\n 'MemoryService initialized'\n );\n }\n\n /**\n * Get the Drizzle database instance\n */\n private getDb(): any {\n const db = (this.runtime as any).db;\n if (!db) {\n throw new Error('Database not available');\n }\n return db;\n }\n\n /**\n * Get configuration\n */\n getConfig(): MemoryConfig {\n return { ...this.memoryConfig };\n }\n\n /**\n * Update configuration\n */\n updateConfig(updates: Partial<MemoryConfig>): void {\n this.memoryConfig = { ...this.memoryConfig, ...updates };\n }\n\n /**\n * Track message count for a room\n */\n incrementMessageCount(roomId: UUID): number {\n const current = this.sessionMessageCounts.get(roomId) || 0;\n const newCount = current + 1;\n this.sessionMessageCounts.set(roomId, newCount);\n return newCount;\n }\n\n /**\n * Reset message count for a room\n */\n resetMessageCount(roomId: UUID): void {\n this.sessionMessageCounts.set(roomId, 0);\n }\n\n /**\n * Check if summarization is needed for a room\n */\n async shouldSummarize(roomId: UUID): Promise<boolean> {\n const count = await this.runtime.countMemories(roomId, false, 'messages');\n return count >= this.memoryConfig.shortTermSummarizationThreshold;\n }\n\n /**\n * Generate cache key for tracking extraction checkpoints per entity-room pair\n */\n private getExtractionKey(entityId: UUID, roomId: UUID): string {\n return `memory:extraction:${entityId}:${roomId}`;\n }\n\n /**\n * Get the last extraction checkpoint for an entity in a room\n * Uses the cache table via adapter\n */\n async getLastExtractionCheckpoint(entityId: UUID, roomId: UUID): Promise<number> {\n const key = this.getExtractionKey(entityId, roomId);\n\n // Check in-memory cache first\n const cached = this.lastExtractionCheckpoints.get(key);\n if (cached !== undefined) {\n return cached;\n }\n\n // Check database cache table via adapter\n try {\n const checkpoint = await this.runtime.getCache<number>(key);\n const messageCount = checkpoint ?? 0;\n\n // Cache it in memory for faster access\n this.lastExtractionCheckpoints.set(key, messageCount);\n\n return messageCount;\n } catch (error) {\n logger.warn({ error }, 'Failed to get extraction checkpoint from cache');\n return 0;\n }\n }\n\n /**\n * Set the last extraction checkpoint for an entity in a room\n * Uses the cache table via adapter\n */\n async setLastExtractionCheckpoint(\n entityId: UUID,\n roomId: UUID,\n messageCount: number\n ): Promise<void> {\n const key = this.getExtractionKey(entityId, roomId);\n\n // Update in-memory cache\n this.lastExtractionCheckpoints.set(key, messageCount);\n\n // Persist to database cache table via adapter\n try {\n await this.runtime.setCache(key, messageCount);\n logger.debug(\n `Set extraction checkpoint for ${entityId} in room ${roomId} at message count ${messageCount}`\n );\n } catch (error) {\n logger.error({ error }, 'Failed to persist extraction checkpoint to cache');\n }\n }\n\n /**\n * Check if long-term extraction should run based on message count and interval\n */\n async shouldRunExtraction(\n entityId: UUID,\n roomId: UUID,\n currentMessageCount: number\n ): Promise<boolean> {\n const threshold = this.memoryConfig.longTermExtractionThreshold;\n const interval = this.memoryConfig.longTermExtractionInterval;\n \n // Don't run extraction until we reach the minimum threshold\n if (currentMessageCount < threshold) {\n logger.debug(\n {\n entityId,\n roomId,\n currentMessageCount,\n threshold,\n shouldRun: false,\n },\n 'Extraction check: below threshold'\n );\n return false;\n }\n\n const lastCheckpoint = await this.getLastExtractionCheckpoint(entityId, roomId);\n\n // Calculate the current checkpoint (e.g., if interval=5: 20, 25, 30, 35...)\n const currentCheckpoint = Math.floor(currentMessageCount / interval) * interval;\n\n // Run if we're at or past a checkpoint and haven't processed this checkpoint yet\n const shouldRun = currentMessageCount >= threshold && currentCheckpoint > lastCheckpoint;\n\n logger.debug(\n {\n entityId,\n roomId,\n currentMessageCount,\n threshold,\n interval,\n lastCheckpoint,\n currentCheckpoint,\n shouldRun,\n },\n 'Extraction check'\n );\n\n return shouldRun;\n }\n\n /**\n * Store a long-term memory\n */\n async storeLongTermMemory(\n memory: Omit<LongTermMemory, 'id' | 'createdAt' | 'updatedAt'>\n ): Promise<LongTermMemory> {\n const db = this.getDb();\n\n const id = crypto.randomUUID() as UUID;\n const now = new Date();\n\n const newMemory: LongTermMemory = {\n id,\n createdAt: now,\n updatedAt: now,\n accessCount: 0,\n ...memory,\n };\n\n try {\n await db.insert(longTermMemories).values({\n id: newMemory.id,\n agentId: newMemory.agentId,\n entityId: newMemory.entityId,\n category: newMemory.category,\n content: newMemory.content,\n metadata: newMemory.metadata || {},\n embedding: newMemory.embedding,\n confidence: newMemory.confidence,\n source: newMemory.source,\n accessCount: newMemory.accessCount,\n createdAt: now,\n updatedAt: now,\n lastAccessedAt: newMemory.lastAccessedAt,\n });\n } catch (error) {\n logger.error({ error }, 'Failed to store long-term memory');\n throw error;\n }\n\n logger.info(`Stored long-term memory: ${newMemory.category} for entity ${newMemory.entityId}`);\n return newMemory;\n }\n\n /**\n * Retrieve long-term memories for an entity\n */\n async getLongTermMemories(\n entityId: UUID,\n category?: LongTermMemoryCategory,\n limit: number = 10\n ): Promise<LongTermMemory[]> {\n const db = this.getDb();\n\n const conditions = [\n eq(longTermMemories.agentId, this.runtime.agentId),\n eq(longTermMemories.entityId, entityId),\n ];\n\n if (category) {\n conditions.push(eq(longTermMemories.category, category));\n }\n\n const results = await db\n .select()\n .from(longTermMemories)\n .where(and(...conditions))\n .orderBy(desc(longTermMemories.confidence), desc(longTermMemories.updatedAt))\n .limit(limit);\n\n return results.map((row) => ({\n id: row.id as UUID,\n agentId: row.agentId as UUID,\n entityId: row.entityId as UUID,\n category: row.category as LongTermMemoryCategory,\n content: row.content,\n metadata: row.metadata as Record<string, unknown>,\n embedding: row.embedding as number[],\n confidence: row.confidence as number,\n source: row.source as string,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n lastAccessedAt: row.lastAccessedAt,\n accessCount: row.accessCount as number,\n }));\n }\n\n /**\n * Update a long-term memory\n * Enforces multi-tenancy by verifying agentId and entityId\n */\n async updateLongTermMemory(\n id: UUID,\n entityId: UUID,\n updates: Partial<Omit<LongTermMemory, 'id' | 'agentId' | 'entityId' | 'createdAt'>>\n ): Promise<void> {\n const db = this.getDb();\n\n const updateData: any = {\n updatedAt: new Date(),\n };\n\n if (updates.content !== undefined) {\n updateData.content = updates.content;\n }\n\n if (updates.metadata !== undefined) {\n updateData.metadata = updates.metadata;\n }\n\n if (updates.confidence !== undefined) {\n updateData.confidence = updates.confidence;\n }\n\n if (updates.embedding !== undefined) {\n updateData.embedding = updates.embedding;\n }\n\n if (updates.lastAccessedAt !== undefined) {\n updateData.lastAccessedAt = updates.lastAccessedAt;\n }\n\n if (updates.accessCount !== undefined) {\n updateData.accessCount = updates.accessCount;\n }\n\n // Enforce multi-tenancy: only update if agentId and entityId match\n await db\n .update(longTermMemories)\n .set(updateData)\n .where(\n and(\n eq(longTermMemories.id, id),\n eq(longTermMemories.agentId, this.runtime.agentId),\n eq(longTermMemories.entityId, entityId)\n )\n );\n\n logger.info(`Updated long-term memory: ${id} for entity ${entityId}`);\n }\n\n /**\n * Delete a long-term memory\n * Enforces multi-tenancy by verifying agentId and entityId\n */\n async deleteLongTermMemory(id: UUID, entityId: UUID): Promise<void> {\n const db = this.getDb();\n\n // Enforce multi-tenancy: only delete if agentId and entityId match\n await db\n .delete(longTermMemories)\n .where(\n and(\n eq(longTermMemories.id, id),\n eq(longTermMemories.agentId, this.runtime.agentId),\n eq(longTermMemories.entityId, entityId)\n )\n );\n\n logger.info(`Deleted long-term memory: ${id} for entity ${entityId}`);\n }\n\n /**\n * Get the current session summary for a room (latest one)\n */\n async getCurrentSessionSummary(roomId: UUID): Promise<SessionSummary | null> {\n const db = this.getDb();\n\n const results = await db\n .select()\n .from(sessionSummaries)\n .where(\n and(eq(sessionSummaries.agentId, this.runtime.agentId), eq(sessionSummaries.roomId, roomId))\n )\n .orderBy(desc(sessionSummaries.updatedAt))\n .limit(1);\n\n if (results.length === 0) {\n return null;\n }\n\n const row = results[0];\n return {\n id: row.id as UUID,\n agentId: row.agentId as UUID,\n roomId: row.roomId as UUID,\n entityId: row.entityId as UUID | undefined,\n summary: row.summary,\n messageCount: row.messageCount,\n lastMessageOffset: row.lastMessageOffset,\n startTime: row.startTime,\n endTime: row.endTime,\n topics: (row.topics as string[]) || [],\n metadata: row.metadata as Record<string, unknown>,\n embedding: row.embedding as number[],\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n }\n\n /**\n * Store a session summary (initial creation)\n */\n async storeSessionSummary(\n summary: Omit<SessionSummary, 'id' | 'createdAt' | 'updatedAt'>\n ): Promise<SessionSummary> {\n const db = this.getDb();\n\n const id = crypto.randomUUID() as UUID;\n const now = new Date();\n\n const newSummary: SessionSummary = {\n id,\n createdAt: now,\n updatedAt: now,\n ...summary,\n };\n\n await db.insert(sessionSummaries).values({\n id: newSummary.id,\n agentId: newSummary.agentId,\n roomId: newSummary.roomId,\n entityId: newSummary.entityId || null,\n summary: newSummary.summary,\n messageCount: newSummary.messageCount,\n lastMessageOffset: newSummary.lastMessageOffset,\n startTime: newSummary.startTime,\n endTime: newSummary.endTime,\n topics: newSummary.topics || [],\n metadata: newSummary.metadata || {},\n embedding: newSummary.embedding,\n createdAt: now,\n updatedAt: now,\n });\n\n logger.info(`Stored session summary for room ${newSummary.roomId}`);\n return newSummary;\n }\n\n /**\n * Update an existing session summary\n * Enforces multi-tenancy by verifying agentId\n */\n async updateSessionSummary(\n id: UUID,\n roomId: UUID,\n updates: Partial<Omit<SessionSummary, 'id' | 'agentId' | 'roomId' | 'createdAt' | 'updatedAt'>>\n ): Promise<void> {\n const db = this.getDb();\n\n const updateData: any = {\n updatedAt: new Date(),\n };\n\n if (updates.summary !== undefined) {\n updateData.summary = updates.summary;\n }\n\n if (updates.messageCount !== undefined) {\n updateData.messageCount = updates.messageCount;\n }\n\n if (updates.lastMessageOffset !== undefined) {\n updateData.lastMessageOffset = updates.lastMessageOffset;\n }\n\n if (updates.endTime !== undefined) {\n updateData.endTime = updates.endTime;\n }\n\n if (updates.topics !== undefined) {\n updateData.topics = updates.topics;\n }\n\n if (updates.metadata !== undefined) {\n updateData.metadata = updates.metadata;\n }\n\n if (updates.embedding !== undefined) {\n updateData.embedding = updates.embedding;\n }\n\n // Enforce multi-tenancy: only update if agentId and roomId match\n await db\n .update(sessionSummaries)\n .set(updateData)\n .where(\n and(\n eq(sessionSummaries.id, id),\n eq(sessionSummaries.agentId, this.runtime.agentId),\n eq(sessionSummaries.roomId, roomId)\n )\n );\n\n logger.info(`Updated session summary: ${id} for room ${roomId}`);\n }\n\n /**\n * Get session summaries for a room\n */\n async getSessionSummaries(roomId: UUID, limit: number = 5): Promise<SessionSummary[]> {\n const db = this.getDb();\n\n const results = await db\n .select()\n .from(sessionSummaries)\n .where(\n and(eq(sessionSummaries.agentId, this.runtime.agentId), eq(sessionSummaries.roomId, roomId))\n )\n .orderBy(desc(sessionSummaries.updatedAt))\n .limit(limit);\n\n return results.map((row) => ({\n id: row.id as UUID,\n agentId: row.agentId as UUID,\n roomId: row.roomId as UUID,\n entityId: row.entityId as UUID | undefined,\n summary: row.summary,\n messageCount: row.messageCount,\n lastMessageOffset: row.lastMessageOffset,\n startTime: row.startTime,\n endTime: row.endTime,\n topics: (row.topics as string[]) || [],\n metadata: row.metadata as Record<string, unknown>,\n embedding: row.embedding as number[],\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n }));\n }\n\n /**\n * Search long-term memories by semantic similarity (if embeddings are available)\n */\n async searchLongTermMemories(\n entityId: UUID,\n queryEmbedding: number[],\n limit: number = 5,\n matchThreshold: number = 0.7\n ): Promise<LongTermMemory[]> {\n if (!this.memoryConfig.longTermVectorSearchEnabled) {\n logger.warn('Vector search is not enabled, falling back to recent memories');\n return this.getLongTermMemories(entityId, undefined, limit);\n }\n\n const db = this.getDb();\n\n try {\n // Clean the vector to ensure all numbers are finite and properly formatted\n const cleanVector = queryEmbedding.map((n) =>\n Number.isFinite(n) ? Number(n.toFixed(6)) : 0\n );\n\n // Calculate similarity using Drizzle's cosineDistance\n const similarity = sql<number>`1 - (${cosineDistance(\n longTermMemories.embedding,\n cleanVector\n )})`;\n\n const conditions = [\n eq(longTermMemories.agentId, this.runtime.agentId),\n eq(longTermMemories.entityId, entityId),\n sql`${longTermMemories.embedding} IS NOT NULL`,\n ];\n\n // Add similarity threshold if specified\n if (matchThreshold > 0) {\n conditions.push(gte(similarity, matchThreshold));\n }\n\n const results = await db\n .select({\n memory: longTermMemories,\n similarity,\n })\n .from(longTermMemories)\n .where(and(...conditions))\n .orderBy(desc(similarity))\n .limit(limit);\n\n return results.map((row) => ({\n id: row.memory.id as UUID,\n agentId: row.memory.agentId as UUID,\n entityId: row.memory.entityId as UUID,\n category: row.memory.category as LongTermMemoryCategory,\n content: row.memory.content,\n metadata: row.memory.metadata as Record<string, unknown>,\n embedding: row.memory.embedding as number[],\n confidence: row.memory.confidence as number,\n source: row.memory.source as string,\n createdAt: row.memory.createdAt,\n updatedAt: row.memory.updatedAt,\n lastAccessedAt: row.memory.lastAccessedAt,\n accessCount: row.memory.accessCount as number,\n similarity: row.similarity,\n }));\n } catch (error) {\n logger.warn({ error }, 'Vector search failed, falling back to recent memories');\n return this.getLongTermMemories(entityId, undefined, limit);\n }\n }\n\n /**\n * Get all long-term memories formatted for context\n */\n async getFormattedLongTermMemories(entityId: UUID): Promise<string> {\n const memories = await this.getLongTermMemories(entityId, undefined, 20);\n\n if (memories.length === 0) {\n return '';\n }\n\n // Group by category\n const grouped = new Map<LongTermMemoryCategory, LongTermMemory[]>();\n\n for (const memory of memories) {\n if (!grouped.has(memory.category)) {\n grouped.set(memory.category, []);\n }\n grouped.get(memory.category)?.push(memory);\n }\n\n // Format each category\n const sections: string[] = [];\n\n for (const [category, categoryMemories] of grouped.entries()) {\n const categoryName = category\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n const items = categoryMemories.map((m) => `- ${m.content}`).join('\\n');\n sections.push(`**${categoryName}**:\\n${items}`);\n }\n\n return sections.join('\\n\\n');\n }\n}\n",
|
|
6
6
|
"import { sql } from 'drizzle-orm';\nimport {\n pgTable,\n text,\n integer,\n jsonb,\n real,\n index,\n varchar,\n timestamp,\n} from 'drizzle-orm/pg-core';\n\n/**\n * Long-term memory storage table\n * Stores persistent facts about users across all conversations\n */\nexport const longTermMemories = pgTable(\n 'long_term_memories',\n {\n id: varchar('id', { length: 36 }).primaryKey(),\n agentId: varchar('agent_id', { length: 36 }).notNull(),\n entityId: varchar('entity_id', { length: 36 }).notNull(),\n category: text('category').notNull(),\n content: text('content').notNull(),\n metadata: jsonb('metadata'),\n embedding: real('embedding').array(),\n confidence: real('confidence').default(1.0),\n source: text('source'),\n createdAt: timestamp('created_at')\n .default(sql`now()`)\n .notNull(),\n updatedAt: timestamp('updated_at')\n .default(sql`now()`)\n .notNull(),\n lastAccessedAt: timestamp('last_accessed_at'),\n accessCount: integer('access_count').default(0),\n },\n (table) => ({\n agentEntityIdx: index('long_term_memories_agent_entity_idx').on(table.agentId, table.entityId),\n categoryIdx: index('long_term_memories_category_idx').on(table.category),\n confidenceIdx: index('long_term_memories_confidence_idx').on(table.confidence),\n createdAtIdx: index('long_term_memories_created_at_idx').on(table.createdAt),\n })\n);\n",
|
|
7
7
|
"import { sql } from 'drizzle-orm';\nimport {\n pgTable,\n text,\n integer,\n jsonb,\n real,\n index,\n varchar,\n timestamp,\n} from 'drizzle-orm/pg-core';\n\n/**\n * Session summaries table\n * Stores condensed summaries of conversation sessions\n */\nexport const sessionSummaries = pgTable(\n 'session_summaries',\n {\n id: varchar('id', { length: 36 }).primaryKey(),\n agentId: varchar('agent_id', { length: 36 }).notNull(),\n roomId: varchar('room_id', { length: 36 }).notNull(),\n entityId: varchar('entity_id', { length: 36 }),\n summary: text('summary').notNull(),\n messageCount: integer('message_count').notNull(),\n lastMessageOffset: integer('last_message_offset').notNull().default(0),\n startTime: timestamp('start_time').notNull(),\n endTime: timestamp('end_time').notNull(),\n topics: jsonb('topics'),\n metadata: jsonb('metadata'),\n embedding: real('embedding').array(),\n createdAt: timestamp('created_at')\n .default(sql`now()`)\n .notNull(),\n updatedAt: timestamp('updated_at')\n .default(sql`now()`)\n .notNull(),\n },\n (table) => ({\n agentRoomIdx: index('session_summaries_agent_room_idx').on(table.agentId, table.roomId),\n entityIdx: index('session_summaries_entity_idx').on(table.entityId),\n startTimeIdx: index('session_summaries_start_time_idx').on(table.startTime),\n })\n);\n",
|
|
8
8
|
"import { sql } from 'drizzle-orm';\nimport { pgTable, text, integer, real, index, varchar, timestamp } from 'drizzle-orm/pg-core';\n\n/**\n * Memory access logs (optional - for tracking and improving memory retrieval)\n */\nexport const memoryAccessLogs = pgTable(\n 'memory_access_logs',\n {\n id: varchar('id', { length: 36 }).primaryKey(),\n agentId: varchar('agent_id', { length: 36 }).notNull(),\n memoryId: varchar('memory_id', { length: 36 }).notNull(),\n memoryType: text('memory_type').notNull(), // 'long_term' or 'session_summary'\n accessedAt: timestamp('accessed_at')\n .default(sql`now()`)\n .notNull(),\n roomId: varchar('room_id', { length: 36 }),\n relevanceScore: real('relevance_score'),\n wasUseful: integer('was_useful'), // 1 = useful, 0 = not useful, null = unknown\n },\n (table) => ({\n memoryIdx: index('memory_access_logs_memory_idx').on(table.memoryId),\n agentIdx: index('memory_access_logs_agent_idx').on(table.agentId),\n accessedAtIdx: index('memory_access_logs_accessed_at_idx').on(table.accessedAt),\n })\n);\n",
|
|
9
|
-
"import {\n type IAgentRuntime,\n type Memory,\n type Evaluator,\n logger,\n ModelType,\n composePromptFromState,\n} from '@elizaos/core';\nimport { MemoryService } from '../services/memory-service';\nimport type { SummaryResult } from '../types/index';\n\n/**\n * Template for generating initial conversation summary\n */\nconst initialSummarizationTemplate = `# Task: Summarize Conversation\n\nYou are analyzing a conversation to create a concise summary that captures the key points, topics, and important details.\n\n# Recent Messages\n{{recentMessages}}\n\n# Instructions\nGenerate a summary that:\n1. Captures the main topics discussed\n2. Highlights key information shared\n3. Notes any decisions made or questions asked\n4. Maintains context for future reference\n5. Is concise but comprehensive\n\n**IMPORTANT**: Keep the summary under 2500 tokens. Be comprehensive but concise.\n\nAlso extract:\n- **Topics**: List of main topics discussed (comma-separated)\n- **Key Points**: Important facts or decisions (bullet points)\n\nRespond in this XML format:\n<summary>\n <text>Your comprehensive summary here</text>\n <topics>topic1, topic2, topic3</topics>\n <keyPoints>\n <point>First key point</point>\n <point>Second key point</point>\n </keyPoints>\n</summary>`;\n\n/**\n * Template for updating/condensing an existing summary\n */\nconst updateSummarizationTemplate = `# Task: Update and Condense Conversation Summary\n\nYou are updating an existing conversation summary with new messages, while keeping the total summary concise.\n\n# Existing Summary\n{{existingSummary}}\n\n# Existing Topics\n{{existingTopics}}\n\n# New Messages Since Last Summary\n{{newMessages}}\n\n# Instructions\nUpdate the summary by:\n1. Merging the existing summary with insights from the new messages\n2. Removing redundant or less important details to stay under the token limit\n3. Keeping the most important context and decisions\n4. Adding new topics if they emerge\n5. **CRITICAL**: Keep the ENTIRE updated summary under 2500 tokens\n\nThe goal is a rolling summary that captures the essence of the conversation without growing indefinitely.\n\nRespond in this XML format:\n<summary>\n <text>Your updated and condensed summary here</text>\n <topics>topic1, topic2, topic3</topics>\n <keyPoints>\n <point>First key point</point>\n <point>Second key point</point>\n </keyPoints>\n</summary>`;\n\n/**\n * Parse XML summary response\n */\nfunction parseSummaryXML(xml: string): SummaryResult {\n const summaryMatch = xml.match(/<text>([\\s\\S]*?)<\\/text>/);\n const topicsMatch = xml.match(/<topics>([\\s\\S]*?)<\\/topics>/);\n const keyPointsMatches = xml.matchAll(/<point>([\\s\\S]*?)<\\/point>/g);\n\n const summary = summaryMatch ? summaryMatch[1].trim() : 'Summary not available';\n const topics = topicsMatch\n ? topicsMatch[1]\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean)\n : [];\n const keyPoints = Array.from(keyPointsMatches).map((match) => match[1].trim());\n\n return { summary, topics, keyPoints };\n}\n\n/**\n * Short-term Memory Summarization Evaluator\n *\n * Automatically generates and updates conversation summaries when conversations\n * exceed the configured threshold (default: 5 messages).\n *\n * BEHAVIOR:\n * - Monitors message count per room\n * - Triggers when count >= threshold\n * - Creates initial summary for first batch of messages\n * - Updates/condenses existing summary as conversation continues\n * - Tracks offset to know which messages have been summarized\n *\n * INTEGRATION:\n * Works with shortTermMemoryProvider which:\n * - Shows full conversation when < threshold (no summarization needed)\n * - Shows summaries + recent messages when >= threshold (optimized context)\n *\n * This creates an adaptive system that starts with full context and seamlessly\n * transitions to summarization as conversations grow.\n */\nexport const summarizationEvaluator: Evaluator = {\n name: 'MEMORY_SUMMARIZATION',\n description: 'Automatically summarizes conversations to optimize context usage',\n similes: ['CONVERSATION_SUMMARY', 'CONTEXT_COMPRESSION', 'MEMORY_OPTIMIZATION'],\n alwaysRun: true,\n\n validate: async (runtime: IAgentRuntime, message: Memory): Promise<boolean> => {\n // Only run after actual messages (not during generation or on empty messages)\n if (!message.content?.text) {\n logger.debug('Skipping summarization: no message text');\n return false;\n }\n\n const memoryService = runtime.getService('memory') as MemoryService | null;\n if (!memoryService) {\n logger.debug('Skipping summarization: memory service not available');\n return false;\n }\n\n const config = memoryService.getConfig();\n const currentMessageCount = await runtime.countMemories(message.roomId, false, 'messages');\n\n // Only summarize when we've reached the threshold\n // Before this, shortTermMemoryProvider shows full conversation\n const shouldSummarize = currentMessageCount >= config.shortTermSummarizationThreshold;\n\n logger.debug(\n {\n roomId: message.roomId,\n currentMessageCount,\n threshold: config.shortTermSummarizationThreshold,\n shouldSummarize,\n },\n 'Summarization validation check'\n );\n\n return shouldSummarize;\n },\n\n handler: async (runtime: IAgentRuntime, message: Memory): Promise<void> => {\n const memoryService = runtime.getService('memory') as MemoryService;\n if (!memoryService) {\n logger.error('MemoryService not found');\n return;\n }\n\n const config = memoryService.getConfig();\n const { roomId } = message;\n\n try {\n logger.info(`Starting summarization for room ${roomId}`);\n\n // Get the current summary (if any)\n const existingSummary = await memoryService.getCurrentSessionSummary(roomId);\n const lastOffset = existingSummary?.lastMessageOffset || 0;\n\n // Get total message count\n const totalMessageCount = await runtime.countMemories(roomId, false, 'messages');\n\n // Get new messages since last offset\n const newMessages = await runtime.getMemories({\n tableName: 'messages',\n roomId,\n count: config.shortTermSummarizationThreshold,\n unique: false,\n start: lastOffset,\n });\n\n if (newMessages.length === 0) {\n logger.debug('No new messages to summarize');\n return;\n }\n\n // Sort by timestamp\n const sortedMessages = newMessages.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0));\n\n // Format messages for summarization\n const formattedMessages = sortedMessages\n .map((msg) => {\n const sender = msg.entityId === runtime.agentId ? runtime.character.name : 'User';\n return `${sender}: ${msg.content.text || '[non-text message]'}`;\n })\n .join('\\n');\n\n // Generate or update summary using LLM\n const state = await runtime.composeState(message);\n let prompt: string;\n let template: string;\n\n if (existingSummary) {\n // Update existing summary\n template = updateSummarizationTemplate;\n prompt = composePromptFromState({\n state: {\n ...state,\n existingSummary: existingSummary.summary,\n existingTopics: existingSummary.topics?.join(', ') || 'None',\n newMessages: formattedMessages,\n },\n template,\n });\n } else {\n // Create initial summary\n template = initialSummarizationTemplate;\n prompt = composePromptFromState({\n state: {\n ...state,\n recentMessages: formattedMessages,\n },\n template,\n });\n }\n\n const response = await runtime.useModel(ModelType.TEXT_LARGE, {\n prompt,\n maxTokens: config.summaryMaxTokens || 2500,\n });\n\n const summaryResult = parseSummaryXML(response);\n\n logger.info(\n `${existingSummary ? 'Updated' : 'Generated'} summary: ${summaryResult.summary.substring(0, 100)}...`\n );\n\n // Calculate new offset (current total)\n const newOffset = totalMessageCount;\n\n // Get timing info\n const firstMessage = sortedMessages[0];\n const lastMessage = sortedMessages[sortedMessages.length - 1];\n\n const startTime = existingSummary\n ? existingSummary.startTime\n : firstMessage?.createdAt && firstMessage.createdAt > 0\n ? new Date(firstMessage.createdAt)\n : new Date();\n const endTime =\n lastMessage?.createdAt && lastMessage.createdAt > 0\n ? new Date(lastMessage.createdAt)\n : new Date();\n\n if (existingSummary) {\n // Update existing summary\n await memoryService.updateSessionSummary(existingSummary.id, {\n summary: summaryResult.summary,\n messageCount: existingSummary.messageCount + sortedMessages.length,\n lastMessageOffset: newOffset,\n endTime,\n topics: summaryResult.topics,\n metadata: {\n keyPoints: summaryResult.keyPoints,\n },\n });\n\n logger.info(\n `Updated summary for room ${roomId}: ${sortedMessages.length} new messages processed (offset: ${lastOffset} → ${newOffset})`\n );\n } else {\n // Create new summary\n await memoryService.storeSessionSummary({\n agentId: runtime.agentId,\n roomId,\n entityId: message.entityId !== runtime.agentId ? message.entityId : undefined,\n summary: summaryResult.summary,\n messageCount: sortedMessages.length,\n lastMessageOffset: newOffset,\n startTime,\n endTime,\n topics: summaryResult.topics,\n metadata: {\n keyPoints: summaryResult.keyPoints,\n },\n });\n\n logger.info(\n `Created new summary for room ${roomId}: ${sortedMessages.length} messages summarized (offset: 0 → ${newOffset})`\n );\n }\n\n // Note: We do NOT delete messages - they stay in the database\n // The offset tracks what's been summarized\n } catch (error) {\n logger.error({ error }, 'Error during summarization:');\n }\n },\n\n examples: [],\n};\n",
|
|
10
|
-
"import {\n type IAgentRuntime,\n type Memory,\n type Evaluator,\n logger,\n ModelType,\n composePromptFromState,\n} from '@elizaos/core';\nimport { MemoryService } from '../services/memory-service';\nimport { LongTermMemoryCategory, type MemoryExtraction } from '../types/index';\n\n/**\n * Template for extracting long-term memories\n */\nconst extractionTemplate = `# Task: Extract Long-Term Memory\n\nYou are analyzing a conversation to extract facts that should be remembered long-term
|
|
11
|
-
"import type { UUID } from '@elizaos/core';\n\n/**\n * Categories of long-term memory\n */\nexport enum LongTermMemoryCategory {\n IDENTITY = 'identity', // User identity, name, roles\n EXPERTISE = 'expertise', // Domain knowledge and familiarity\n PROJECTS = 'projects', // Past interactions and recurring topics\n PREFERENCES = 'preferences', // User preferences for interaction style\n DATA_SOURCES = 'data_sources', // Frequently used files, databases, APIs\n GOALS = 'goals', // User's broader intentions and objectives\n CONSTRAINTS = 'constraints', // User-defined rules and limitations\n DEFINITIONS = 'definitions', // Custom terms, acronyms, glossaries\n BEHAVIORAL_PATTERNS = 'behavioral_patterns', // User interaction patterns\n}\n\n/**\n * Long-term memory entry\n */\nexport interface LongTermMemory {\n id: UUID;\n agentId: UUID;\n entityId: UUID; // The user/entity this memory is about\n category: LongTermMemoryCategory;\n content: string; // The actual memory content\n metadata?: Record<string, unknown>; // Additional structured data\n embedding?: number[]; // Vector embedding for semantic search\n confidence?: number; // Confidence score (0-1)\n source?: string; // Where this memory came from (conversation, manual, etc.)\n createdAt: Date;\n updatedAt: Date;\n lastAccessedAt?: Date;\n accessCount?: number;\n similarity?: number; // Optional similarity score from vector search\n}\n\n/**\n * Short-term memory session summary\n */\nexport interface SessionSummary {\n id: UUID;\n agentId: UUID;\n roomId: UUID;\n entityId?: UUID; // Optional: specific user in the session\n summary: string; // The summarized conversation\n messageCount: number; // Number of messages summarized\n lastMessageOffset: number; // Index of last summarized message (for pagination)\n startTime: Date; // Timestamp of first message\n endTime: Date; // Timestamp of last message\n topics?: string[]; // Main topics discussed\n metadata?: Record<string, unknown>;\n embedding?: number[]; // Vector embedding of the summary\n createdAt: Date;\n updatedAt: Date; // Track when summary was last updated\n}\n\n/**\n * Configuration for memory plugin\n */\nexport interface MemoryConfig {\n // Short-term memory settings\n shortTermSummarizationThreshold: number; // Messages count before summarization\n shortTermRetainRecent: number; // Number of recent messages to keep after summarization\n\n // Long-term memory settings\n longTermExtractionEnabled: boolean;\n longTermVectorSearchEnabled: boolean;\n longTermConfidenceThreshold: number; // Minimum confidence to store\n longTermExtractionInterval: number; // Run extraction every N messages (e.g., 5, 10, 15...)\n\n // Summarization settings\n summaryModelType?: string;\n summaryMaxTokens?: number;\n}\n\n/**\n * Memory extraction result from evaluator\n */\nexport interface MemoryExtraction {\n category: LongTermMemoryCategory;\n content: string;\n confidence: number;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Summary generation result\n */\nexport interface SummaryResult {\n summary: string;\n topics: string[];\n keyPoints: string[];\n}\n",
|
|
12
|
-
"import {\n addHeader,\n ChannelType,\n CustomMetadata,\n formatMessages,\n formatPosts,\n getEntityDetails,\n type Entity,\n type IAgentRuntime,\n type Memory,\n type Provider,\n type State,\n logger,\n} from '@elizaos/core';\nimport { MemoryService } from '../services/memory-service';\n\n/**\n * Short-term Memory Provider\n *\n * Adaptive conversation context provider that optimizes based on conversation length:\n *\n * SHORT CONVERSATIONS (< threshold, default 5 messages):\n * - Shows full message history with complete context\n * - No summarization overhead for brief chats\n *\n * LONG CONVERSATIONS (>= threshold):\n * - Shows summaries of older conversation segments\n * - Shows recent unsummarized messages in full\n * - Optimizes context window while preserving information\n *\n * This provider can REPLACE recentMessagesProvider when plugin-memory is active,\n * providing superior context management for both short and long conversations.\n */\nexport const shortTermMemoryProvider: Provider = {\n name: 'SHORT_TERM_MEMORY',\n description: 'Adaptive conversation context with smart summarization',\n position: 95, // Run before recentMessagesProvider (100) to potentially replace it\n\n get: async (runtime: IAgentRuntime, message: Memory, _state: State) => {\n try {\n const memoryService = runtime.getService('memory') as MemoryService | null;\n if (!memoryService) {\n // No memory service - return empty\n return {\n data: { summaries: [], recentMessages: [], mode: 'disabled' },\n values: { sessionSummaries: '', recentMessages: '' },\n text: '',\n };\n }\n\n const { roomId } = message;\n const config = memoryService.getConfig();\n\n // Get total message count to determine mode\n const totalMessageCount = await runtime.countMemories(roomId, false, 'messages');\n\n // ADAPTIVE LOGIC: Use full messages for short conversations, summaries for long ones\n if (totalMessageCount < config.shortTermSummarizationThreshold) {\n // ========== SHORT CONVERSATION MODE ==========\n // Just show all messages - no summarization needed\n\n const conversationLength = runtime.getConversationLength();\n\n // Fetch all necessary data in parallel\n const [entitiesData, room, recentMessagesData] = await Promise.all([\n getEntityDetails({ runtime, roomId }),\n runtime.getRoom(roomId),\n runtime.getMemories({\n tableName: 'messages',\n roomId,\n count: conversationLength,\n unique: false,\n }),\n ]);\n\n // Separate action results from dialogue messages\n const actionResultMessages = recentMessagesData.filter(\n (msg) => msg.content?.type === 'action_result' && msg.metadata?.type === 'action_result'\n );\n\n const dialogueMessages = recentMessagesData.filter(\n (msg) =>\n !(msg.content?.type === 'action_result' && msg.metadata?.type === 'action_result')\n );\n\n // Determine format based on room type\n const isPostFormat = room?.type\n ? room.type === ChannelType.FEED || room.type === ChannelType.THREAD\n : false;\n\n // Format messages in parallel\n const [formattedRecentMessages, formattedRecentPosts] = await Promise.all([\n formatMessages({\n messages: dialogueMessages,\n entities: entitiesData,\n }),\n formatPosts({\n messages: dialogueMessages,\n entities: entitiesData,\n conversationHeader: false,\n }),\n ]);\n\n // Format action results if any\n let actionResultsText = '';\n if (actionResultMessages.length > 0) {\n const groupedByRun = new Map<string, Memory[]>();\n\n for (const mem of actionResultMessages) {\n const runId: string = String(mem.content?.runId || 'unknown');\n if (!groupedByRun.has(runId)) {\n groupedByRun.set(runId, []);\n }\n groupedByRun.get(runId)?.push(mem);\n }\n\n const formattedActionResults = Array.from(groupedByRun.entries())\n .slice(-3) // Show last 3 runs\n .map(([runId, memories]) => {\n const sortedMemories = memories.sort(\n (a: Memory, b: Memory) => (a.createdAt || 0) - (b.createdAt || 0)\n );\n\n const thought = sortedMemories[0]?.content?.planThought || '';\n const runText = sortedMemories\n .map((mem: Memory) => {\n const actionName = mem.content?.actionName || 'Unknown';\n const status = mem.content?.actionStatus || 'unknown';\n const planStep = mem.content?.planStep || '';\n const text = mem.content?.text || '';\n const error = mem.content?.error || '';\n\n let memText = ` - ${actionName} (${status})`;\n if (planStep) memText += ` [${planStep}]`;\n if (error) {\n memText += `: Error - ${error}`;\n } else if (text && text !== `Executed action: ${actionName}`) {\n memText += `: ${text}`;\n }\n\n return memText;\n })\n .join('\\n');\n\n return `**Action Run ${runId.slice(0, 8)}**${\n thought ? ` - \"${thought}\"` : ''\n }\\n${runText}`;\n })\n .join('\\n\\n');\n\n actionResultsText = formattedActionResults\n ? addHeader('# Recent Action Executions', formattedActionResults)\n : '';\n }\n\n // Create formatted text with headers\n const recentPosts =\n formattedRecentPosts && formattedRecentPosts.length > 0\n ? addHeader('# Posts in Thread', formattedRecentPosts)\n : '';\n\n const recentMessages =\n formattedRecentMessages && formattedRecentMessages.length > 0\n ? addHeader('# Conversation Messages', formattedRecentMessages)\n : '';\n\n // Handle empty conversation case\n if (\n !recentPosts &&\n !recentMessages &&\n dialogueMessages.length === 0 &&\n !message.content.text\n ) {\n return {\n data: {\n summaries: [],\n recentMessages: [],\n actionResults: [],\n mode: 'full_conversation',\n },\n values: {\n sessionSummaries: '',\n recentMessages: '',\n recentActionResults: '',\n },\n text: 'No recent messages available',\n };\n }\n\n // Get most recent message for context\n let recentMessage = 'No recent message available.';\n if (dialogueMessages.length > 0) {\n const mostRecentMessage = [...dialogueMessages].sort(\n (a, b) => (b.createdAt || 0) - (a.createdAt || 0)\n )[0];\n\n const formattedSingleMessage = formatMessages({\n messages: [mostRecentMessage],\n entities: entitiesData,\n });\n\n if (formattedSingleMessage) {\n recentMessage = formattedSingleMessage;\n }\n }\n\n // Build received message header\n const metaData = message.metadata as CustomMetadata;\n const senderName =\n entitiesData.find((entity: Entity) => entity.id === message.entityId)?.names[0] ||\n metaData?.entityName ||\n 'Unknown User';\n const receivedMessageContent = message.content.text;\n const hasReceivedMessage = !!receivedMessageContent?.trim();\n\n const receivedMessageHeader = hasReceivedMessage\n ? addHeader('# Received Message', `${senderName}: ${receivedMessageContent}`)\n : '';\n\n const focusHeader = hasReceivedMessage\n ? addHeader(\n '# Focus your response',\n `You are replying to the above message from **${senderName}**. Keep your answer relevant to that message. Do not repeat earlier replies unless the sender asks again.`\n )\n : '';\n\n // Combine all sections\n const text = [\n isPostFormat ? recentPosts : recentMessages,\n actionResultsText,\n recentMessages || recentPosts || message.content.text ? receivedMessageHeader : '',\n recentMessages || recentPosts || message.content.text ? focusHeader : '',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n return {\n data: {\n summaries: [],\n recentMessages: dialogueMessages,\n actionResults: actionResultMessages,\n mode: 'full_conversation',\n },\n values: {\n sessionSummaries: '',\n recentMessages: isPostFormat ? recentPosts : recentMessages,\n recentActionResults: actionResultsText,\n recentMessage,\n },\n text,\n };\n } else {\n // ========== LONG CONVERSATION MODE ==========\n // Use summaries + recent unsummarized messages\n\n const currentSummary = await memoryService.getCurrentSessionSummary(roomId);\n const lastOffset = currentSummary?.lastMessageOffset || 0;\n\n // Get recent unsummarized messages (after the last summary offset)\n const unsummarizedMessages = await runtime.getMemories({\n tableName: 'messages',\n roomId,\n count: config.shortTermRetainRecent,\n unique: false,\n start: lastOffset,\n });\n\n // Get entity details for formatting\n const entitiesData = await getEntityDetails({ runtime, roomId });\n const room = await runtime.getRoom(roomId);\n\n // Determine format\n const isPostFormat = room?.type\n ? room.type === ChannelType.FEED || room.type === ChannelType.THREAD\n : false;\n\n // Format unsummarized messages\n let recentMessagesText = '';\n if (unsummarizedMessages.length > 0) {\n const dialogueMessages = unsummarizedMessages.filter(\n (msg) =>\n !(msg.content?.type === 'action_result' && msg.metadata?.type === 'action_result')\n );\n\n if (isPostFormat) {\n recentMessagesText = formatPosts({\n messages: dialogueMessages,\n entities: entitiesData,\n conversationHeader: false,\n });\n } else {\n recentMessagesText = formatMessages({\n messages: dialogueMessages,\n entities: entitiesData,\n });\n }\n\n if (recentMessagesText) {\n recentMessagesText = addHeader('# Recent Messages', recentMessagesText);\n }\n }\n\n // Format summary\n let summaryText = '';\n if (currentSummary) {\n const messageRange = `${currentSummary.messageCount} messages`;\n const timeRange = new Date(currentSummary.startTime).toLocaleDateString();\n\n summaryText = `**Previous Conversation** (${messageRange}, ${timeRange})\\n`;\n summaryText += currentSummary.summary;\n\n if (currentSummary.topics && currentSummary.topics.length > 0) {\n summaryText += `\\n*Topics: ${currentSummary.topics.join(', ')}*`;\n }\n\n summaryText = addHeader('# Conversation Summary', summaryText);\n }\n\n // Build received message header\n const metaData = message.metadata as CustomMetadata;\n const senderName =\n entitiesData.find((entity: Entity) => entity.id === message.entityId)?.names[0] ||\n metaData?.entityName ||\n 'Unknown User';\n const receivedMessageContent = message.content.text;\n const hasReceivedMessage = !!receivedMessageContent?.trim();\n\n const receivedMessageHeader = hasReceivedMessage\n ? addHeader('# Received Message', `${senderName}: ${receivedMessageContent}`)\n : '';\n\n const focusHeader = hasReceivedMessage\n ? addHeader(\n '# Focus your response',\n `You are replying to the above message from **${senderName}**. Keep your answer relevant to that message.`\n )\n : '';\n\n // Combine sections\n const text = [\n summaryText,\n recentMessagesText,\n hasReceivedMessage ? receivedMessageHeader : '',\n hasReceivedMessage ? focusHeader : '',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n return {\n data: {\n summaries: currentSummary ? [currentSummary] : [],\n recentMessages: unsummarizedMessages,\n mode: 'summarized',\n },\n values: {\n sessionSummaries: summaryText,\n recentMessages: recentMessagesText,\n },\n text,\n };\n }\n } catch (error) {\n logger.error({ error }, 'Error in shortTermMemoryProvider:');\n return {\n data: { summaries: [], recentMessages: [], mode: 'error' },\n values: { sessionSummaries: '', recentMessages: '' },\n text: 'Error retrieving conversation context.',\n };\n }\n },\n};\n",
|
|
9
|
+
"import {\n type IAgentRuntime,\n type Memory,\n type Evaluator,\n logger,\n ModelType,\n composePromptFromState,\n} from '@elizaos/core';\nimport { MemoryService } from '../services/memory-service';\nimport type { SummaryResult } from '../types/index';\n\n/**\n * Template for generating initial conversation summary\n */\nconst initialSummarizationTemplate = `# Task: Summarize Conversation\n\nYou are analyzing a conversation to create a concise summary that captures the key points, topics, and important details.\n\n# Recent Messages\n{{recentMessages}}\n\n# Instructions\nGenerate a summary that:\n1. Captures the main topics discussed\n2. Highlights key information shared\n3. Notes any decisions made or questions asked\n4. Maintains context for future reference\n5. Is concise but comprehensive\n\n**IMPORTANT**: Keep the summary under 2500 tokens. Be comprehensive but concise.\n\nAlso extract:\n- **Topics**: List of main topics discussed (comma-separated)\n- **Key Points**: Important facts or decisions (bullet points)\n\nRespond in this XML format:\n<summary>\n <text>Your comprehensive summary here</text>\n <topics>topic1, topic2, topic3</topics>\n <keyPoints>\n <point>First key point</point>\n <point>Second key point</point>\n </keyPoints>\n</summary>`;\n\n/**\n * Template for updating/condensing an existing summary\n */\nconst updateSummarizationTemplate = `# Task: Update and Condense Conversation Summary\n\nYou are updating an existing conversation summary with new messages, while keeping the total summary concise.\n\n# Existing Summary\n{{existingSummary}}\n\n# Existing Topics\n{{existingTopics}}\n\n# New Messages Since Last Summary\n{{newMessages}}\n\n# Instructions\nUpdate the summary by:\n1. Merging the existing summary with insights from the new messages\n2. Removing redundant or less important details to stay under the token limit\n3. Keeping the most important context and decisions\n4. Adding new topics if they emerge\n5. **CRITICAL**: Keep the ENTIRE updated summary under 2500 tokens\n\nThe goal is a rolling summary that captures the essence of the conversation without growing indefinitely.\n\nRespond in this XML format:\n<summary>\n <text>Your updated and condensed summary here</text>\n <topics>topic1, topic2, topic3</topics>\n <keyPoints>\n <point>First key point</point>\n <point>Second key point</point>\n </keyPoints>\n</summary>`;\n\n/**\n * Parse XML summary response\n */\nfunction parseSummaryXML(xml: string): SummaryResult {\n const summaryMatch = xml.match(/<text>([\\s\\S]*?)<\\/text>/);\n const topicsMatch = xml.match(/<topics>([\\s\\S]*?)<\\/topics>/);\n const keyPointsMatches = xml.matchAll(/<point>([\\s\\S]*?)<\\/point>/g);\n\n const summary = summaryMatch ? summaryMatch[1].trim() : 'Summary not available';\n const topics = topicsMatch\n ? topicsMatch[1]\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean)\n : [];\n const keyPoints = Array.from(keyPointsMatches).map((match) => match[1].trim());\n\n return { summary, topics, keyPoints };\n}\n\n/**\n * Short-term Memory Summarization Evaluator\n *\n * Automatically generates and updates conversation summaries when conversations\n * exceed the configured threshold (default: 16 messages).\n *\n * BEHAVIOR:\n * - Monitors message count per room\n * - Creates initial summary when count >= threshold (e.g., 16 messages)\n * - Updates summary at regular intervals (e.g., every 10 new messages)\n * - Condenses existing summary with new messages to stay under token limit\n * - Tracks offset to avoid re-processing messages\n * - Caps new messages per update to prevent context bloat (default: 20)\n *\n * OPTIMIZATION:\n * - Only triggers LLM when crossing threshold or interval boundaries\n * - Processes only NEW messages since last update\n * - Maintains rolling summary (fixed size, not ever-growing)\n * - LLM is instructed to merge and condense, keeping under 2500 tokens\n *\n * INTEGRATION:\n * Works with shortTermMemoryProvider which:\n * - Shows full conversation when < threshold (no summarization needed)\n * - Shows summaries + recent messages when >= threshold (optimized context)\n *\n * This creates an adaptive system that starts with full context and seamlessly\n * transitions to efficient summarization as conversations grow.\n */\nexport const summarizationEvaluator: Evaluator = {\n name: 'MEMORY_SUMMARIZATION',\n description: 'Automatically summarizes conversations to optimize context usage',\n similes: ['CONVERSATION_SUMMARY', 'CONTEXT_COMPRESSION', 'MEMORY_OPTIMIZATION'],\n alwaysRun: true,\n\n validate: async (runtime: IAgentRuntime, message: Memory): Promise<boolean> => {\n // Only run after actual messages (not during generation or on empty messages)\n if (!message.content?.text) {\n logger.debug('Skipping summarization: no message text');\n return false;\n }\n\n const memoryService = runtime.getService('memory') as MemoryService | null;\n if (!memoryService) {\n logger.debug('Skipping summarization: memory service not available');\n return false;\n }\n\n const config = memoryService.getConfig();\n const currentMessageCount = await runtime.countMemories(message.roomId, false, 'messages');\n\n // Get existing summary to check if we need initial or update\n const existingSummary = await memoryService.getCurrentSessionSummary(message.roomId);\n \n if (!existingSummary) {\n // No summary yet - create initial summary when threshold is reached\n const shouldSummarize = currentMessageCount >= config.shortTermSummarizationThreshold;\n logger.debug(\n {\n roomId: message.roomId,\n currentMessageCount,\n threshold: config.shortTermSummarizationThreshold,\n shouldSummarize,\n reason: 'initial_summary_check',\n },\n 'Summarization validation check'\n );\n return shouldSummarize;\n } else {\n // Summary exists - check if we have enough new messages since last update\n const newMessageCount = currentMessageCount - existingSummary.lastMessageOffset;\n const shouldUpdate = newMessageCount >= config.shortTermSummarizationInterval;\n \n logger.debug(\n {\n roomId: message.roomId,\n currentMessageCount,\n lastOffset: existingSummary.lastMessageOffset,\n newMessageCount,\n interval: config.shortTermSummarizationInterval,\n shouldUpdate,\n reason: 'summary_update_check',\n },\n 'Summarization validation check'\n );\n return shouldUpdate;\n }\n },\n\n handler: async (runtime: IAgentRuntime, message: Memory): Promise<void> => {\n const memoryService = runtime.getService('memory') as MemoryService;\n if (!memoryService) {\n logger.error('MemoryService not found');\n return;\n }\n\n const config = memoryService.getConfig();\n const { roomId } = message;\n\n try {\n logger.info(`Starting summarization for room ${roomId}`);\n\n // Get the current summary (if any)\n const existingSummary = await memoryService.getCurrentSessionSummary(roomId);\n const lastOffset = existingSummary?.lastMessageOffset || 0;\n\n // Get total message count\n const totalMessageCount = await runtime.countMemories(roomId, false, 'messages');\n\n // Calculate how many new messages we have\n const newMessageCount = totalMessageCount - lastOffset;\n \n // Cap the number of new messages to prevent context bloat\n const maxNewMessages = config.summaryMaxNewMessages || 50;\n const messagesToFetch = Math.min(newMessageCount, maxNewMessages);\n \n if (messagesToFetch === 0) {\n logger.debug('No new messages to summarize');\n return;\n }\n\n // Log if we're hitting the cap\n if (newMessageCount > maxNewMessages) {\n logger.warn(\n `Capping new messages at ${maxNewMessages} (${newMessageCount} available). Oldest messages will be skipped.`\n );\n }\n\n // Get new messages since last offset\n const newMessages = await runtime.getMemories({\n tableName: 'messages',\n roomId,\n count: messagesToFetch,\n unique: false,\n start: lastOffset,\n });\n\n if (newMessages.length === 0) {\n logger.debug('No new messages retrieved');\n return;\n }\n\n // Sort by timestamp\n const sortedMessages = newMessages.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0));\n\n // Format messages for summarization\n const formattedMessages = sortedMessages\n .map((msg) => {\n const sender = msg.entityId === runtime.agentId ? runtime.character.name : 'User';\n return `${sender}: ${msg.content.text || '[non-text message]'}`;\n })\n .join('\\n');\n\n // Generate or update summary using LLM\n const state = await runtime.composeState(message);\n let prompt: string;\n let template: string;\n\n if (existingSummary) {\n // Update existing summary\n template = updateSummarizationTemplate;\n prompt = composePromptFromState({\n state: {\n ...state,\n existingSummary: existingSummary.summary,\n existingTopics: existingSummary.topics?.join(', ') || 'None',\n newMessages: formattedMessages,\n },\n template,\n });\n } else {\n // Create initial summary\n template = initialSummarizationTemplate;\n prompt = composePromptFromState({\n state: {\n ...state,\n recentMessages: formattedMessages,\n },\n template,\n });\n }\n\n const response = await runtime.useModel(ModelType.TEXT_LARGE, {\n prompt,\n maxTokens: config.summaryMaxTokens || 2500,\n });\n\n const summaryResult = parseSummaryXML(response);\n\n logger.info(\n `${existingSummary ? 'Updated' : 'Generated'} summary: ${summaryResult.summary.substring(0, 100)}...`\n );\n\n // Calculate new offset (current total)\n const newOffset = totalMessageCount;\n\n // Get timing info\n const firstMessage = sortedMessages[0];\n const lastMessage = sortedMessages[sortedMessages.length - 1];\n\n const startTime = existingSummary\n ? existingSummary.startTime\n : firstMessage?.createdAt && firstMessage.createdAt > 0\n ? new Date(firstMessage.createdAt)\n : new Date();\n const endTime =\n lastMessage?.createdAt && lastMessage.createdAt > 0\n ? new Date(lastMessage.createdAt)\n : new Date();\n\n if (existingSummary) {\n // Update existing summary\n await memoryService.updateSessionSummary(existingSummary.id, roomId, {\n summary: summaryResult.summary,\n messageCount: existingSummary.messageCount + sortedMessages.length,\n lastMessageOffset: newOffset,\n endTime,\n topics: summaryResult.topics,\n metadata: {\n keyPoints: summaryResult.keyPoints,\n },\n });\n\n logger.info(\n `Updated summary for room ${roomId}: ${sortedMessages.length} new messages processed (offset: ${lastOffset} → ${newOffset})`\n );\n } else {\n // Create new summary\n await memoryService.storeSessionSummary({\n agentId: runtime.agentId,\n roomId,\n entityId: message.entityId !== runtime.agentId ? message.entityId : undefined,\n summary: summaryResult.summary,\n messageCount: sortedMessages.length,\n lastMessageOffset: newOffset,\n startTime,\n endTime,\n topics: summaryResult.topics,\n metadata: {\n keyPoints: summaryResult.keyPoints,\n },\n });\n\n logger.info(\n `Created new summary for room ${roomId}: ${sortedMessages.length} messages summarized (offset: 0 → ${newOffset})`\n );\n }\n\n // Note: We do NOT delete messages - they stay in the database\n // The offset tracks what's been summarized\n } catch (error) {\n logger.error({ error }, 'Error during summarization:');\n }\n },\n\n examples: [],\n};\n",
|
|
10
|
+
"import {\n type IAgentRuntime,\n type Memory,\n type Evaluator,\n logger,\n ModelType,\n composePromptFromState,\n} from '@elizaos/core';\nimport { MemoryService } from '../services/memory-service';\nimport { LongTermMemoryCategory, type MemoryExtraction } from '../types/index';\n\n/**\n * Template for extracting long-term memories\n */\nconst extractionTemplate = `# Task: Extract Long-Term Memory\n\nYou are analyzing a conversation to extract ONLY the most important, persistent facts about the user that should be remembered long-term.\n\n# Recent Messages\n{{recentMessages}}\n\n# Current Long-Term Memories\n{{existingMemories}}\n\n# Memory Categories\n1. **identity**: User's name, role, identity (e.g., \"I'm a data scientist\")\n2. **expertise**: User's skills, knowledge domains, or unfamiliarity with topics\n3. **projects**: Ongoing projects, past interactions, recurring topics\n4. **preferences**: Communication style, format preferences, verbosity, etc.\n5. **data_sources**: Frequently used files, databases, APIs\n6. **goals**: Broader intentions (e.g., \"preparing for interview\")\n7. **constraints**: User-defined rules or limitations\n8. **definitions**: Custom terms, acronyms, glossaries\n9. **behavioral_patterns**: How the user tends to interact\n\n# STRICT EXTRACTION CRITERIA\n\n**DO EXTRACT** - Facts that are:\n- Explicitly stated personal information (name, role, profession)\n- Repeated patterns across multiple conversations (3+ occurrences)\n- Core preferences stated with clear emphasis (\"I always prefer...\", \"I never want...\")\n- Important ongoing projects or goals mentioned multiple times\n- Persistent technical constraints or requirements\n- Domain expertise demonstrated consistently\n- Custom terminology the user defines and uses repeatedly\n\n**DO NOT EXTRACT** - Facts that are:\n- One-time requests or isolated tasks (e.g., \"generate an image or similar\")\n- Single interactions without pattern repetition\n- Casual preferences from single occurrences\n- Testing or exploratory questions\n- Temporary context or transient information\n- General courtesy or social patterns (greetings, thank yous)\n- Random or playful requests that don't indicate lasting preference\n- Information that could change or is situational\n\n# Quality Standards\n- **Confidence threshold**: Only extract if confidence >= 0.8\n- **Persistence required**: Must see evidence across multiple messages or strong explicit statement\n- **Meaningful value**: Would this fact improve future interactions weeks from now?\n- **Not redundant**: Avoid if existing memories already cover this information\n\n# Instructions\nExtract ONLY truly important NEW information that meets the strict criteria above. For each item:\n- Determine which category it belongs to\n- Write a clear, factual statement\n- Assess confidence (0.0 to 1.0) - BE CONSERVATIVE\n- Require strong evidence before extraction\n\n**When in doubt, DO NOT extract.** It's better to miss temporary information than to clutter long-term memory.\n\nIf there are no new long-term facts to extract, respond with <memories></memories>\n\nRespond in this XML format:\n<memories>\n <memory>\n <category>identity</category>\n <content>User is a software engineer specializing in backend development</content>\n <confidence>0.95</confidence>\n </memory>\n <memory>\n <category>preferences</category>\n <content>Prefers code examples over lengthy explanations</content>\n <confidence>0.85</confidence>\n </memory>\n</memories>`;\n\n/**\n * Parse XML memory extraction response\n */\nfunction parseMemoryExtractionXML(xml: string): MemoryExtraction[] {\n const memoryMatches = xml.matchAll(\n /<memory>[\\s\\S]*?<category>(.*?)<\\/category>[\\s\\S]*?<content>(.*?)<\\/content>[\\s\\S]*?<confidence>(.*?)<\\/confidence>[\\s\\S]*?<\\/memory>/g\n );\n\n const extractions: MemoryExtraction[] = [];\n\n for (const match of memoryMatches) {\n const category = match[1].trim() as LongTermMemoryCategory;\n const content = match[2].trim();\n const confidence = parseFloat(match[3].trim());\n\n // Validate category\n if (!Object.values(LongTermMemoryCategory).includes(category)) {\n logger.warn(`Invalid memory category: ${category}`);\n continue;\n }\n\n if (content && !isNaN(confidence)) {\n extractions.push({ category, content, confidence });\n }\n }\n\n return extractions;\n}\n\n/**\n * Long-term Memory Extraction Evaluator\n *\n * Analyzes conversations to extract persistent facts about users that should be remembered\n * across all future conversations.\n */\nexport const longTermExtractionEvaluator: Evaluator = {\n name: 'LONG_TERM_MEMORY_EXTRACTION',\n description: 'Extracts long-term facts about users from conversations',\n similes: ['MEMORY_EXTRACTION', 'FACT_LEARNING', 'USER_PROFILING'],\n alwaysRun: true,\n\n validate: async (runtime: IAgentRuntime, message: Memory): Promise<boolean> => {\n logger.debug(`Validating long-term memory extraction for message: ${message.content?.text}`);\n // Only run on user messages (not agent's own)\n if (message.entityId === runtime.agentId) {\n logger.debug(\"Skipping long-term memory extraction for agent's own message\");\n return false;\n }\n\n if (!message.content?.text) {\n logger.debug('Skipping long-term memory extraction for message without text');\n return false;\n }\n\n const memoryService = runtime.getService('memory') as MemoryService | null;\n if (!memoryService) {\n logger.debug('MemoryService not found');\n return false;\n }\n\n const config = memoryService.getConfig();\n if (!config.longTermExtractionEnabled) {\n logger.debug('Long-term memory extraction is disabled');\n return false;\n }\n\n // Count total messages from this entity in this room\n const currentMessageCount = await runtime.countMemories(message.roomId, false, 'messages');\n\n const shouldRun = await memoryService.shouldRunExtraction(\n message.entityId,\n message.roomId,\n currentMessageCount\n );\n logger.debug(`Should run extraction: ${shouldRun}`);\n return shouldRun;\n },\n\n handler: async (runtime: IAgentRuntime, message: Memory): Promise<void> => {\n const memoryService = runtime.getService('memory') as MemoryService;\n if (!memoryService) {\n logger.error('MemoryService not found');\n return;\n }\n\n const config = memoryService.getConfig();\n const { entityId, roomId } = message;\n\n try {\n logger.info(`Extracting long-term memories for entity ${entityId}`);\n\n // Get recent conversation context\n const recentMessages = await runtime.getMemories({\n tableName: 'messages',\n roomId,\n count: 20,\n unique: false,\n });\n\n const formattedMessages = recentMessages\n .sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0))\n .map((msg) => {\n const sender = msg.entityId === runtime.agentId ? runtime.character.name : 'User';\n return `${sender}: ${msg.content.text || '[non-text message]'}`;\n })\n .join('\\n');\n\n // Get existing long-term memories\n const existingMemories = await memoryService.getLongTermMemories(entityId, undefined, 30);\n const formattedExisting =\n existingMemories.length > 0\n ? existingMemories\n .map((m) => `[${m.category}] ${m.content} (confidence: ${m.confidence})`)\n .join('\\n')\n : 'None yet';\n\n // Generate extraction using LLM\n const state = await runtime.composeState(message);\n const prompt = composePromptFromState({\n state: {\n ...state,\n recentMessages: formattedMessages,\n existingMemories: formattedExisting,\n },\n template: extractionTemplate,\n });\n\n const response = await runtime.useModel(ModelType.TEXT_LARGE, {\n prompt,\n });\n\n const extractions = parseMemoryExtractionXML(response);\n\n logger.info(`Extracted ${extractions.length} long-term memories`);\n\n // Store each extracted memory\n for (const extraction of extractions) {\n if (extraction.confidence >= config.longTermConfidenceThreshold) {\n await memoryService.storeLongTermMemory({\n agentId: runtime.agentId,\n entityId,\n category: extraction.category,\n content: extraction.content,\n confidence: extraction.confidence,\n source: 'conversation',\n metadata: {\n roomId,\n extractedAt: new Date().toISOString(),\n },\n });\n\n logger.info(\n `Stored long-term memory: [${extraction.category}] ${extraction.content.substring(0, 50)}...`\n );\n } else {\n logger.debug(\n `Skipped low-confidence memory: ${extraction.content} (confidence: ${extraction.confidence})`\n );\n }\n }\n\n // Update the extraction checkpoint after successful extraction\n const currentMessageCount = await runtime.countMemories(roomId, false, 'messages');\n await memoryService.setLastExtractionCheckpoint(entityId, roomId, currentMessageCount);\n logger.debug(\n `Updated extraction checkpoint to ${currentMessageCount} for entity ${entityId} in room ${roomId}`\n );\n } catch (error) {\n logger.error({ error }, 'Error during long-term memory extraction:');\n }\n },\n\n examples: [],\n};\n",
|
|
11
|
+
"import type { UUID } from '@elizaos/core';\n\n/**\n * Categories of long-term memory\n */\nexport enum LongTermMemoryCategory {\n IDENTITY = 'identity', // User identity, name, roles\n EXPERTISE = 'expertise', // Domain knowledge and familiarity\n PROJECTS = 'projects', // Past interactions and recurring topics\n PREFERENCES = 'preferences', // User preferences for interaction style\n DATA_SOURCES = 'data_sources', // Frequently used files, databases, APIs\n GOALS = 'goals', // User's broader intentions and objectives\n CONSTRAINTS = 'constraints', // User-defined rules and limitations\n DEFINITIONS = 'definitions', // Custom terms, acronyms, glossaries\n BEHAVIORAL_PATTERNS = 'behavioral_patterns', // User interaction patterns\n}\n\n/**\n * Long-term memory entry\n */\nexport interface LongTermMemory {\n id: UUID;\n agentId: UUID;\n entityId: UUID; // The user/entity this memory is about\n category: LongTermMemoryCategory;\n content: string; // The actual memory content\n metadata?: Record<string, unknown>; // Additional structured data\n embedding?: number[]; // Vector embedding for semantic search\n confidence?: number; // Confidence score (0-1)\n source?: string; // Where this memory came from (conversation, manual, etc.)\n createdAt: Date;\n updatedAt: Date;\n lastAccessedAt?: Date;\n accessCount?: number;\n similarity?: number; // Optional similarity score from vector search\n}\n\n/**\n * Short-term memory session summary\n */\nexport interface SessionSummary {\n id: UUID;\n agentId: UUID;\n roomId: UUID;\n entityId?: UUID; // Optional: specific user in the session\n summary: string; // The summarized conversation\n messageCount: number; // Number of messages summarized\n lastMessageOffset: number; // Index of last summarized message (for pagination)\n startTime: Date; // Timestamp of first message\n endTime: Date; // Timestamp of last message\n topics?: string[]; // Main topics discussed\n metadata?: Record<string, unknown>;\n embedding?: number[]; // Vector embedding of the summary\n createdAt: Date;\n updatedAt: Date; // Track when summary was last updated\n}\n\n/**\n * Configuration for memory plugin\n */\nexport interface MemoryConfig {\n // Short-term memory settings\n shortTermSummarizationThreshold: number; // Messages count before summarization\n shortTermRetainRecent: number; // Number of recent messages to keep after summarization\n shortTermSummarizationInterval: number; // Update summary every N messages after threshold (e.g., 10)\n\n // Long-term memory settings\n longTermExtractionEnabled: boolean;\n longTermVectorSearchEnabled: boolean;\n longTermConfidenceThreshold: number; // Minimum confidence to store\n longTermExtractionThreshold: number; // Minimum messages before starting extraction (default 20)\n longTermExtractionInterval: number; // Run extraction every N messages after threshold (e.g., 5, 10, 15...)\n\n // Summarization settings\n summaryModelType?: string;\n summaryMaxTokens?: number;\n summaryMaxNewMessages?: number; // Max new messages to include in update (prevents context bloat)\n}\n\n/**\n * Memory extraction result from evaluator\n */\nexport interface MemoryExtraction {\n category: LongTermMemoryCategory;\n content: string;\n confidence: number;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Summary generation result\n */\nexport interface SummaryResult {\n summary: string;\n topics: string[];\n keyPoints: string[];\n}\n",
|
|
12
|
+
"import {\n addHeader,\n ChannelType,\n CustomMetadata,\n formatMessages,\n formatPosts,\n getEntityDetails,\n type Entity,\n type IAgentRuntime,\n type Memory,\n type Provider,\n type State,\n logger,\n} from '@elizaos/core';\nimport { MemoryService } from '../services/memory-service';\n\n/**\n * Short-term Memory Provider\n *\n * Adaptive conversation context provider that optimizes based on conversation length:\n *\n * SHORT CONVERSATIONS (< threshold, default 5 messages):\n * - Shows full message history with complete context\n * - No summarization overhead for brief chats\n *\n * LONG CONVERSATIONS (>= threshold):\n * - Shows summaries of older conversation segments\n * - Shows recent unsummarized messages in full\n * - Optimizes context window while preserving information\n *\n * This provider can REPLACE recentMessagesProvider when plugin-memory is active,\n * providing superior context management for both short and long conversations.\n */\nexport const shortTermMemoryProvider: Provider = {\n name: 'SHORT_TERM_MEMORY',\n description: 'Adaptive conversation context with smart summarization',\n position: 95, // Run before recentMessagesProvider (100) to potentially replace it\n\n get: async (runtime: IAgentRuntime, message: Memory, _state: State) => {\n try {\n const memoryService = runtime.getService('memory') as MemoryService | null;\n if (!memoryService) {\n // No memory service - return empty\n return {\n data: { summaries: [], recentMessages: [], mode: 'disabled' },\n values: {},\n text: '',\n };\n }\n\n const { roomId } = message;\n const config = memoryService.getConfig();\n\n // Get total message count to determine mode\n const totalMessageCount = await runtime.countMemories(roomId, false, 'messages');\n\n // ADAPTIVE LOGIC: Use full messages for short conversations, summaries for long ones\n if (totalMessageCount < config.shortTermSummarizationThreshold) {\n // ========== SHORT CONVERSATION MODE ==========\n // Just show all messages - no summarization needed\n\n const conversationLength = runtime.getConversationLength();\n\n // Fetch all necessary data in parallel\n const [entitiesData, room, recentMessagesData] = await Promise.all([\n getEntityDetails({ runtime, roomId }),\n runtime.getRoom(roomId),\n runtime.getMemories({\n tableName: 'messages',\n roomId,\n count: conversationLength,\n unique: false,\n }),\n ]);\n\n // Separate action results from dialogue messages\n const actionResultMessages = recentMessagesData.filter(\n (msg) => msg.content?.type === 'action_result' && msg.metadata?.type === 'action_result'\n );\n\n const dialogueMessages = recentMessagesData.filter(\n (msg) =>\n !(msg.content?.type === 'action_result' && msg.metadata?.type === 'action_result')\n );\n\n // Determine format based on room type\n const isPostFormat = room?.type\n ? room.type === ChannelType.FEED || room.type === ChannelType.THREAD\n : false;\n\n // Format messages in parallel\n const [formattedRecentMessages, formattedRecentPosts] = await Promise.all([\n formatMessages({\n messages: dialogueMessages,\n entities: entitiesData,\n }),\n formatPosts({\n messages: dialogueMessages,\n entities: entitiesData,\n conversationHeader: false,\n }),\n ]);\n\n // Format action results if any\n let actionResultsText = '';\n if (actionResultMessages.length > 0) {\n const groupedByRun = new Map<string, Memory[]>();\n\n for (const mem of actionResultMessages) {\n const runId: string = String(mem.content?.runId || 'unknown');\n if (!groupedByRun.has(runId)) {\n groupedByRun.set(runId, []);\n }\n groupedByRun.get(runId)?.push(mem);\n }\n\n const formattedActionResults = Array.from(groupedByRun.entries())\n .slice(-3) // Show last 3 runs\n .map(([runId, memories]) => {\n const sortedMemories = memories.sort(\n (a: Memory, b: Memory) => (a.createdAt || 0) - (b.createdAt || 0)\n );\n\n const thought = sortedMemories[0]?.content?.planThought || '';\n const runText = sortedMemories\n .map((mem: Memory) => {\n const actionName = mem.content?.actionName || 'Unknown';\n const status = mem.content?.actionStatus || 'unknown';\n const planStep = mem.content?.planStep || '';\n const text = mem.content?.text || '';\n const error = mem.content?.error || '';\n\n let memText = ` - ${actionName} (${status})`;\n if (planStep) memText += ` [${planStep}]`;\n if (error) {\n memText += `: Error - ${error}`;\n } else if (text && text !== `Executed action: ${actionName}`) {\n memText += `: ${text}`;\n }\n\n return memText;\n })\n .join('\\n');\n\n return `**Action Run ${runId.slice(0, 8)}**${\n thought ? ` - \"${thought}\"` : ''\n }\\n${runText}`;\n })\n .join('\\n\\n');\n\n actionResultsText = formattedActionResults\n ? addHeader('# Recent Action Executions', formattedActionResults)\n : '';\n }\n\n // Create formatted text with headers\n const recentPosts =\n formattedRecentPosts && formattedRecentPosts.length > 0\n ? addHeader('# Posts in Thread', formattedRecentPosts)\n : '';\n\n const recentMessages =\n formattedRecentMessages && formattedRecentMessages.length > 0\n ? addHeader('# Conversation Messages', formattedRecentMessages)\n : '';\n\n // Handle empty conversation case\n if (\n !recentPosts &&\n !recentMessages &&\n dialogueMessages.length === 0 &&\n !message.content.text\n ) {\n return {\n data: {\n summaries: [],\n recentMessages: [],\n actionResults: [],\n mode: 'full_conversation',\n },\n values: {\n recentMessage: 'No recent message available.',\n },\n text: 'No recent messages available',\n };\n }\n\n // Get most recent message for context\n let recentMessage = 'No recent message available.';\n if (dialogueMessages.length > 0) {\n const mostRecentMessage = [...dialogueMessages].sort(\n (a, b) => (b.createdAt || 0) - (a.createdAt || 0)\n )[0];\n\n const formattedSingleMessage = formatMessages({\n messages: [mostRecentMessage],\n entities: entitiesData,\n });\n\n if (formattedSingleMessage) {\n recentMessage = formattedSingleMessage;\n }\n }\n\n // Build received message header\n const metaData = message.metadata as CustomMetadata;\n const senderName =\n entitiesData.find((entity: Entity) => entity.id === message.entityId)?.names[0] ||\n metaData?.entityName ||\n 'Unknown User';\n const receivedMessageContent = message.content.text;\n const hasReceivedMessage = !!receivedMessageContent?.trim();\n\n const receivedMessageHeader = hasReceivedMessage\n ? addHeader('# Received Message', `${senderName}: ${receivedMessageContent}`)\n : '';\n\n const focusHeader = hasReceivedMessage\n ? addHeader(\n '# Focus your response',\n `You are replying to the above message from **${senderName}**. Keep your answer relevant to that message. Do not repeat earlier replies unless the sender asks again.`\n )\n : '';\n\n // Combine all sections\n const text = [\n isPostFormat ? recentPosts : recentMessages,\n actionResultsText,\n recentMessages || recentPosts || message.content.text ? receivedMessageHeader : '',\n recentMessages || recentPosts || message.content.text ? focusHeader : '',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n return {\n data: {\n summaries: [],\n recentMessages: dialogueMessages,\n actionResults: actionResultMessages,\n mode: 'full_conversation',\n },\n values: {\n ...((isPostFormat ? recentPosts : recentMessages) && {\n recentMessages: isPostFormat ? recentPosts : recentMessages,\n }),\n ...(recentPosts && { recentPosts }),\n ...(actionResultsText && { recentActionResults: actionResultsText }),\n ...(recentMessage && { recentMessage }),\n ...(receivedMessageHeader && { receivedMessageHeader }),\n ...(focusHeader && { focusHeader }),\n },\n text,\n };\n } else {\n // ========== LONG CONVERSATION MODE ==========\n // Use summaries + recent unsummarized messages\n\n const currentSummary = await memoryService.getCurrentSessionSummary(roomId);\n const lastOffset = currentSummary?.lastMessageOffset || 0;\n\n // Get recent unsummarized messages (after the last summary offset)\n const unsummarizedMessages = await runtime.getMemories({\n tableName: 'messages',\n roomId,\n count: config.shortTermRetainRecent,\n unique: false,\n start: lastOffset,\n });\n\n // Get entity details for formatting\n const entitiesData = await getEntityDetails({ runtime, roomId });\n const room = await runtime.getRoom(roomId);\n\n // Determine format\n const isPostFormat = room?.type\n ? room.type === ChannelType.FEED || room.type === ChannelType.THREAD\n : false;\n\n // Format unsummarized messages\n let recentMessagesText = '';\n if (unsummarizedMessages.length > 0) {\n const dialogueMessages = unsummarizedMessages.filter(\n (msg) =>\n !(msg.content?.type === 'action_result' && msg.metadata?.type === 'action_result')\n );\n\n if (isPostFormat) {\n recentMessagesText = formatPosts({\n messages: dialogueMessages,\n entities: entitiesData,\n conversationHeader: false,\n });\n } else {\n recentMessagesText = formatMessages({\n messages: dialogueMessages,\n entities: entitiesData,\n });\n }\n\n if (recentMessagesText) {\n recentMessagesText = addHeader('# Recent Messages', recentMessagesText);\n }\n }\n\n // Format summary\n let summaryText = '';\n if (currentSummary) {\n const messageRange = `${currentSummary.messageCount} messages`;\n const timeRange = new Date(currentSummary.startTime).toLocaleDateString();\n\n summaryText = `**Previous Conversation** (${messageRange}, ${timeRange})\\n`;\n summaryText += currentSummary.summary;\n\n if (currentSummary.topics && currentSummary.topics.length > 0) {\n summaryText += `\\n*Topics: ${currentSummary.topics.join(', ')}*`;\n }\n\n summaryText = addHeader('# Conversation Summary', summaryText);\n }\n\n // Build received message header\n const metaData = message.metadata as CustomMetadata;\n const senderName =\n entitiesData.find((entity: Entity) => entity.id === message.entityId)?.names[0] ||\n metaData?.entityName ||\n 'Unknown User';\n const receivedMessageContent = message.content.text;\n const hasReceivedMessage = !!receivedMessageContent?.trim();\n\n const receivedMessageHeader = hasReceivedMessage\n ? addHeader('# Received Message', `${senderName}: ${receivedMessageContent}`)\n : '';\n\n const focusHeader = hasReceivedMessage\n ? addHeader(\n '# Focus your response',\n `You are replying to the above message from **${senderName}**. Keep your answer relevant to that message.`\n )\n : '';\n\n // Combine sections\n const text = [\n summaryText,\n recentMessagesText,\n hasReceivedMessage ? receivedMessageHeader : '',\n hasReceivedMessage ? focusHeader : '',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n return {\n data: {\n summaries: currentSummary ? [currentSummary] : [],\n recentMessages: unsummarizedMessages,\n mode: 'summarized',\n },\n values: {\n ...(summaryText && { sessionSummaries: summaryText }),\n ...(recentMessagesText && { recentMessages: recentMessagesText }),\n ...(receivedMessageHeader && { receivedMessageHeader }),\n ...(focusHeader && { focusHeader }),\n },\n text,\n };\n }\n } catch (error) {\n logger.error({ error }, 'Error in shortTermMemoryProvider:');\n return {\n data: { summaries: [], recentMessages: [], mode: 'error' },\n values: {},\n text: 'Error retrieving conversation context.',\n };\n }\n },\n};\n",
|
|
13
13
|
"import {\n type IAgentRuntime,\n type Memory,\n type Provider,\n type State,\n logger,\n addHeader,\n} from '@elizaos/core';\nimport { MemoryService } from '../services/memory-service';\n\n/**\n * Long-term Memory Provider\n *\n * Provides persistent facts about the user that have been learned across\n * all conversations. This includes:\n * - User identity and roles\n * - Domain expertise\n * - Preferences\n * - Goals and projects\n * - Custom definitions\n * - Behavioral patterns\n *\n * This provider enriches the context with relevant long-term information\n * to make the agent's responses more personalized and contextually aware.\n */\nexport const longTermMemoryProvider: Provider = {\n name: 'LONG_TERM_MEMORY',\n description: 'Persistent facts and preferences about the user',\n position: 50, // Run early to establish user context\n\n get: async (runtime: IAgentRuntime, message: Memory, _state: State) => {\n try {\n const memoryService = runtime.getService('memory') as MemoryService | null;\n if (!memoryService) {\n return {\n data: { memories: [] },\n values: { longTermMemories: '' },\n text: '',\n };\n }\n\n const { entityId } = message;\n\n // Skip for agent's own messages\n if (entityId === runtime.agentId) {\n return {\n data: { memories: [] },\n values: { longTermMemories: '' },\n text: '',\n };\n }\n\n // Get long-term memories for this entity\n const memories = await memoryService.getLongTermMemories(entityId, undefined, 25);\n\n if (memories.length === 0) {\n return {\n data: { memories: [] },\n values: { longTermMemories: '' },\n text: '',\n };\n }\n\n // Format memories using the service's built-in formatter\n const formattedMemories = await memoryService.getFormattedLongTermMemories(entityId);\n\n const text = addHeader('# What I Know About You', formattedMemories);\n\n // Create a summary of memory categories for quick reference\n const categoryCounts = new Map<string, number>();\n for (const memory of memories) {\n const count = categoryCounts.get(memory.category) || 0;\n categoryCounts.set(memory.category, count + 1);\n }\n\n const categoryList = Array.from(categoryCounts.entries())\n .map(([cat, count]) => `${cat}: ${count}`)\n .join(', ');\n\n return {\n data: {\n memories,\n categoryCounts: Object.fromEntries(categoryCounts),\n },\n values: {\n longTermMemories: text,\n memoryCategories: categoryList,\n },\n text,\n };\n } catch (error) {\n logger.error({ error }, 'Error in longTermMemoryProvider:');\n return {\n data: { memories: [] },\n values: { longTermMemories: '' },\n text: '',\n };\n }\n },\n};\n",
|
|
14
14
|
"import type { Plugin } from '@elizaos/core';\nimport { MemoryService } from './services/memory-service';\nimport { summarizationEvaluator } from './evaluators/summarization';\nimport { longTermExtractionEvaluator } from './evaluators/long-term-extraction';\nimport { shortTermMemoryProvider } from './providers/short-term-memory';\nimport { longTermMemoryProvider } from './providers/long-term-memory';\n// import { rememberAction } from './actions/remember';\nimport * as schema from './schemas/index';\n\nexport * from './types/index';\nexport * from './schemas/index';\nexport { MemoryService } from './services/memory-service';\n\n/**\n * Memory Plugin\n *\n * Advanced memory management plugin that provides:\n *\n * **Short-term Memory (Conversation Summarization)**:\n * - Automatically summarizes long conversations to reduce context size\n * - Retains recent messages while archiving older ones as summaries\n * - Configurable thresholds for when to summarize\n *\n * **Long-term Memory (Persistent Facts)**:\n * - Extracts and stores persistent facts about users\n * - Categorizes information (identity, expertise, preferences, etc.)\n * - Provides context-aware user profiles across all conversations\n *\n * **Components**:\n * - `MemoryService`: Manages all memory operations\n * - Evaluators: Process conversations to create summaries and extract facts\n * - Providers: Inject memory context into conversations\n * - Actions: Allow manual memory storage via user commands\n *\n * **Configuration** (via environment variables):\n * - `MEMORY_SUMMARIZATION_THRESHOLD`: Messages before summarization (default: 50)\n * - `MEMORY_RETAIN_RECENT`: Recent messages to keep (default: 10)\n * - `MEMORY_LONG_TERM_ENABLED`: Enable long-term extraction (default: true)\n * - `MEMORY_CONFIDENCE_THRESHOLD`: Minimum confidence to store (default: 0.7)\n *\n * **Database Tables**:\n * - `long_term_memories`: Persistent user facts\n * - `session_summaries`: Conversation summaries\n * - `memory_access_logs`: Optional usage tracking\n */\nexport const memoryPlugin: Plugin = {\n name: 'memory',\n description:\n 'Advanced memory management with conversation summarization and long-term persistent memory',\n\n services: [MemoryService],\n\n evaluators: [summarizationEvaluator, longTermExtractionEvaluator],\n\n providers: [longTermMemoryProvider, shortTermMemoryProvider],\n\n // actions: [rememberAction],\n\n // Export schema for dynamic migrations\n schema,\n};\n\nexport default memoryPlugin;\n"
|
|
15
15
|
],
|
|
16
|
-
"mappings": "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",
|
|
17
|
-
"debugId": "
|
|
16
|
+
"mappings": "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",
|
|
17
|
+
"debugId": "3C20A9F0BA14039464756E2164756E21",
|
|
18
18
|
"names": []
|
|
19
19
|
}
|
|
@@ -3,14 +3,21 @@ import { type Evaluator } from '@elizaos/core';
|
|
|
3
3
|
* Short-term Memory Summarization Evaluator
|
|
4
4
|
*
|
|
5
5
|
* Automatically generates and updates conversation summaries when conversations
|
|
6
|
-
* exceed the configured threshold (default:
|
|
6
|
+
* exceed the configured threshold (default: 16 messages).
|
|
7
7
|
*
|
|
8
8
|
* BEHAVIOR:
|
|
9
9
|
* - Monitors message count per room
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
13
|
-
* - Tracks offset to
|
|
10
|
+
* - Creates initial summary when count >= threshold (e.g., 16 messages)
|
|
11
|
+
* - Updates summary at regular intervals (e.g., every 10 new messages)
|
|
12
|
+
* - Condenses existing summary with new messages to stay under token limit
|
|
13
|
+
* - Tracks offset to avoid re-processing messages
|
|
14
|
+
* - Caps new messages per update to prevent context bloat (default: 20)
|
|
15
|
+
*
|
|
16
|
+
* OPTIMIZATION:
|
|
17
|
+
* - Only triggers LLM when crossing threshold or interval boundaries
|
|
18
|
+
* - Processes only NEW messages since last update
|
|
19
|
+
* - Maintains rolling summary (fixed size, not ever-growing)
|
|
20
|
+
* - LLM is instructed to merge and condense, keeping under 2500 tokens
|
|
14
21
|
*
|
|
15
22
|
* INTEGRATION:
|
|
16
23
|
* Works with shortTermMemoryProvider which:
|
|
@@ -18,6 +25,6 @@ import { type Evaluator } from '@elizaos/core';
|
|
|
18
25
|
* - Shows summaries + recent messages when >= threshold (optimized context)
|
|
19
26
|
*
|
|
20
27
|
* This creates an adaptive system that starts with full context and seamlessly
|
|
21
|
-
* transitions to summarization as conversations grow.
|
|
28
|
+
* transitions to efficient summarization as conversations grow.
|
|
22
29
|
*/
|
|
23
30
|
export declare const summarizationEvaluator: Evaluator;
|