@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.
@@ -126,14 +126,17 @@ class MemoryService extends import_core.Service {
126
126
  this.sessionMessageCounts = new Map;
127
127
  this.lastExtractionCheckpoints = new Map;
128
128
  this.memoryConfig = {
129
- shortTermSummarizationThreshold: 5,
129
+ shortTermSummarizationThreshold: 16,
130
130
  shortTermRetainRecent: 10,
131
+ shortTermSummarizationInterval: 10,
131
132
  longTermExtractionEnabled: true,
132
133
  longTermVectorSearchEnabled: false,
133
134
  longTermConfidenceThreshold: 0.7,
135
+ longTermExtractionThreshold: 20,
134
136
  longTermExtractionInterval: 5,
135
137
  summaryModelType: "TEXT_LARGE",
136
- summaryMaxTokens: 2500
138
+ summaryMaxTokens: 2500,
139
+ summaryMaxNewMessages: 20
137
140
  };
138
141
  }
139
142
  static async start(runtime) {
@@ -154,6 +157,14 @@ class MemoryService extends import_core.Service {
154
157
  if (retainRecent) {
155
158
  this.memoryConfig.shortTermRetainRecent = parseInt(retainRecent, 10);
156
159
  }
160
+ const summarizationInterval = runtime.getSetting("MEMORY_SUMMARIZATION_INTERVAL");
161
+ if (summarizationInterval) {
162
+ this.memoryConfig.shortTermSummarizationInterval = parseInt(summarizationInterval, 10);
163
+ }
164
+ const maxNewMessages = runtime.getSetting("MEMORY_MAX_NEW_MESSAGES");
165
+ if (maxNewMessages) {
166
+ this.memoryConfig.summaryMaxNewMessages = parseInt(maxNewMessages, 10);
167
+ }
157
168
  const longTermEnabled = runtime.getSetting("MEMORY_LONG_TERM_ENABLED");
158
169
  if (longTermEnabled === "false") {
159
170
  this.memoryConfig.longTermExtractionEnabled = false;
@@ -164,10 +175,21 @@ class MemoryService extends import_core.Service {
164
175
  if (confidenceThreshold) {
165
176
  this.memoryConfig.longTermConfidenceThreshold = parseFloat(confidenceThreshold);
166
177
  }
178
+ const extractionThreshold = runtime.getSetting("MEMORY_EXTRACTION_THRESHOLD");
179
+ if (extractionThreshold) {
180
+ this.memoryConfig.longTermExtractionThreshold = parseInt(extractionThreshold, 10);
181
+ }
182
+ const extractionInterval = runtime.getSetting("MEMORY_EXTRACTION_INTERVAL");
183
+ if (extractionInterval) {
184
+ this.memoryConfig.longTermExtractionInterval = parseInt(extractionInterval, 10);
185
+ }
167
186
  import_core.logger.info({
168
187
  summarizationThreshold: this.memoryConfig.shortTermSummarizationThreshold,
188
+ summarizationInterval: this.memoryConfig.shortTermSummarizationInterval,
189
+ maxNewMessages: this.memoryConfig.summaryMaxNewMessages,
169
190
  retainRecent: this.memoryConfig.shortTermRetainRecent,
170
191
  longTermEnabled: this.memoryConfig.longTermExtractionEnabled,
192
+ extractionThreshold: this.memoryConfig.longTermExtractionThreshold,
171
193
  extractionInterval: this.memoryConfig.longTermExtractionInterval,
172
194
  confidenceThreshold: this.memoryConfig.longTermConfidenceThreshold
173
195
  }, "MemoryService initialized");
@@ -228,14 +250,26 @@ class MemoryService extends import_core.Service {
228
250
  }
229
251
  }
230
252
  async shouldRunExtraction(entityId, roomId, currentMessageCount) {
253
+ const threshold = this.memoryConfig.longTermExtractionThreshold;
231
254
  const interval = this.memoryConfig.longTermExtractionInterval;
255
+ if (currentMessageCount < threshold) {
256
+ import_core.logger.debug({
257
+ entityId,
258
+ roomId,
259
+ currentMessageCount,
260
+ threshold,
261
+ shouldRun: false
262
+ }, "Extraction check: below threshold");
263
+ return false;
264
+ }
232
265
  const lastCheckpoint = await this.getLastExtractionCheckpoint(entityId, roomId);
233
266
  const currentCheckpoint = Math.floor(currentMessageCount / interval) * interval;
234
- const shouldRun = currentMessageCount >= interval && currentCheckpoint > lastCheckpoint;
267
+ const shouldRun = currentMessageCount >= threshold && currentCheckpoint > lastCheckpoint;
235
268
  import_core.logger.debug({
236
269
  entityId,
237
270
  roomId,
238
271
  currentMessageCount,
272
+ threshold,
239
273
  interval,
240
274
  lastCheckpoint,
241
275
  currentCheckpoint,
@@ -303,7 +337,7 @@ class MemoryService extends import_core.Service {
303
337
  accessCount: row.accessCount
304
338
  }));
305
339
  }
306
- async updateLongTermMemory(id, updates) {
340
+ async updateLongTermMemory(id, entityId, updates) {
307
341
  const db = this.getDb();
308
342
  const updateData = {
309
343
  updatedAt: new Date
@@ -326,13 +360,13 @@ class MemoryService extends import_core.Service {
326
360
  if (updates.accessCount !== undefined) {
327
361
  updateData.accessCount = updates.accessCount;
328
362
  }
329
- await db.update(longTermMemories).set(updateData).where(import_drizzle_orm4.eq(longTermMemories.id, id));
330
- import_core.logger.info(`Updated long-term memory: ${id}`);
363
+ await db.update(longTermMemories).set(updateData).where(import_drizzle_orm4.and(import_drizzle_orm4.eq(longTermMemories.id, id), import_drizzle_orm4.eq(longTermMemories.agentId, this.runtime.agentId), import_drizzle_orm4.eq(longTermMemories.entityId, entityId)));
364
+ import_core.logger.info(`Updated long-term memory: ${id} for entity ${entityId}`);
331
365
  }
332
- async deleteLongTermMemory(id) {
366
+ async deleteLongTermMemory(id, entityId) {
333
367
  const db = this.getDb();
334
- await db.delete(longTermMemories).where(import_drizzle_orm4.eq(longTermMemories.id, id));
335
- import_core.logger.info(`Deleted long-term memory: ${id}`);
368
+ await db.delete(longTermMemories).where(import_drizzle_orm4.and(import_drizzle_orm4.eq(longTermMemories.id, id), import_drizzle_orm4.eq(longTermMemories.agentId, this.runtime.agentId), import_drizzle_orm4.eq(longTermMemories.entityId, entityId)));
369
+ import_core.logger.info(`Deleted long-term memory: ${id} for entity ${entityId}`);
336
370
  }
337
371
  async getCurrentSessionSummary(roomId) {
338
372
  const db = this.getDb();
@@ -387,7 +421,7 @@ class MemoryService extends import_core.Service {
387
421
  import_core.logger.info(`Stored session summary for room ${newSummary.roomId}`);
388
422
  return newSummary;
389
423
  }
390
- async updateSessionSummary(id, updates) {
424
+ async updateSessionSummary(id, roomId, updates) {
391
425
  const db = this.getDb();
392
426
  const updateData = {
393
427
  updatedAt: new Date
@@ -413,8 +447,8 @@ class MemoryService extends import_core.Service {
413
447
  if (updates.embedding !== undefined) {
414
448
  updateData.embedding = updates.embedding;
415
449
  }
416
- await db.update(sessionSummaries).set(updateData).where(import_drizzle_orm4.eq(sessionSummaries.id, id));
417
- import_core.logger.info(`Updated session summary: ${id}`);
450
+ await db.update(sessionSummaries).set(updateData).where(import_drizzle_orm4.and(import_drizzle_orm4.eq(sessionSummaries.id, id), import_drizzle_orm4.eq(sessionSummaries.agentId, this.runtime.agentId), import_drizzle_orm4.eq(sessionSummaries.roomId, roomId)));
451
+ import_core.logger.info(`Updated session summary: ${id} for room ${roomId}`);
418
452
  }
419
453
  async getSessionSummaries(roomId, limit = 5) {
420
454
  const db = this.getDb();
@@ -594,14 +628,31 @@ var summarizationEvaluator = {
594
628
  }
595
629
  const config = memoryService.getConfig();
596
630
  const currentMessageCount = await runtime.countMemories(message.roomId, false, "messages");
597
- const shouldSummarize = currentMessageCount >= config.shortTermSummarizationThreshold;
598
- import_core2.logger.debug({
599
- roomId: message.roomId,
600
- currentMessageCount,
601
- threshold: config.shortTermSummarizationThreshold,
602
- shouldSummarize
603
- }, "Summarization validation check");
604
- return shouldSummarize;
631
+ const existingSummary = await memoryService.getCurrentSessionSummary(message.roomId);
632
+ if (!existingSummary) {
633
+ const shouldSummarize = currentMessageCount >= config.shortTermSummarizationThreshold;
634
+ import_core2.logger.debug({
635
+ roomId: message.roomId,
636
+ currentMessageCount,
637
+ threshold: config.shortTermSummarizationThreshold,
638
+ shouldSummarize,
639
+ reason: "initial_summary_check"
640
+ }, "Summarization validation check");
641
+ return shouldSummarize;
642
+ } else {
643
+ const newMessageCount = currentMessageCount - existingSummary.lastMessageOffset;
644
+ const shouldUpdate = newMessageCount >= config.shortTermSummarizationInterval;
645
+ import_core2.logger.debug({
646
+ roomId: message.roomId,
647
+ currentMessageCount,
648
+ lastOffset: existingSummary.lastMessageOffset,
649
+ newMessageCount,
650
+ interval: config.shortTermSummarizationInterval,
651
+ shouldUpdate,
652
+ reason: "summary_update_check"
653
+ }, "Summarization validation check");
654
+ return shouldUpdate;
655
+ }
605
656
  },
606
657
  handler: async (runtime, message) => {
607
658
  const memoryService = runtime.getService("memory");
@@ -616,15 +667,25 @@ var summarizationEvaluator = {
616
667
  const existingSummary = await memoryService.getCurrentSessionSummary(roomId);
617
668
  const lastOffset = existingSummary?.lastMessageOffset || 0;
618
669
  const totalMessageCount = await runtime.countMemories(roomId, false, "messages");
670
+ const newMessageCount = totalMessageCount - lastOffset;
671
+ const maxNewMessages = config.summaryMaxNewMessages || 50;
672
+ const messagesToFetch = Math.min(newMessageCount, maxNewMessages);
673
+ if (messagesToFetch === 0) {
674
+ import_core2.logger.debug("No new messages to summarize");
675
+ return;
676
+ }
677
+ if (newMessageCount > maxNewMessages) {
678
+ import_core2.logger.warn(`Capping new messages at ${maxNewMessages} (${newMessageCount} available). Oldest messages will be skipped.`);
679
+ }
619
680
  const newMessages = await runtime.getMemories({
620
681
  tableName: "messages",
621
682
  roomId,
622
- count: config.shortTermSummarizationThreshold,
683
+ count: messagesToFetch,
623
684
  unique: false,
624
685
  start: lastOffset
625
686
  });
626
687
  if (newMessages.length === 0) {
627
- import_core2.logger.debug("No new messages to summarize");
688
+ import_core2.logger.debug("No new messages retrieved");
628
689
  return;
629
690
  }
630
691
  const sortedMessages = newMessages.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0));
@@ -669,7 +730,7 @@ var summarizationEvaluator = {
669
730
  const startTime = existingSummary ? existingSummary.startTime : firstMessage?.createdAt && firstMessage.createdAt > 0 ? new Date(firstMessage.createdAt) : new Date;
670
731
  const endTime = lastMessage?.createdAt && lastMessage.createdAt > 0 ? new Date(lastMessage.createdAt) : new Date;
671
732
  if (existingSummary) {
672
- await memoryService.updateSessionSummary(existingSummary.id, {
733
+ await memoryService.updateSessionSummary(existingSummary.id, roomId, {
673
734
  summary: summaryResult.summary,
674
735
  messageCount: existingSummary.messageCount + sortedMessages.length,
675
736
  lastMessageOffset: newOffset,
@@ -724,7 +785,7 @@ var LongTermMemoryCategory;
724
785
  // src/evaluators/long-term-extraction.ts
725
786
  var extractionTemplate = `# Task: Extract Long-Term Memory
726
787
 
727
- You are analyzing a conversation to extract facts that should be remembered long-term about the user.
788
+ You are analyzing a conversation to extract ONLY the most important, persistent facts about the user that should be remembered long-term.
728
789
 
729
790
  # Recent Messages
730
791
  {{recentMessages}}
@@ -743,12 +804,41 @@ You are analyzing a conversation to extract facts that should be remembered long
743
804
  8. **definitions**: Custom terms, acronyms, glossaries
744
805
  9. **behavioral_patterns**: How the user tends to interact
745
806
 
807
+ # STRICT EXTRACTION CRITERIA
808
+
809
+ **DO EXTRACT** - Facts that are:
810
+ - Explicitly stated personal information (name, role, profession)
811
+ - Repeated patterns across multiple conversations (3+ occurrences)
812
+ - Core preferences stated with clear emphasis ("I always prefer...", "I never want...")
813
+ - Important ongoing projects or goals mentioned multiple times
814
+ - Persistent technical constraints or requirements
815
+ - Domain expertise demonstrated consistently
816
+ - Custom terminology the user defines and uses repeatedly
817
+
818
+ **DO NOT EXTRACT** - Facts that are:
819
+ - One-time requests or isolated tasks (e.g., "generate an image or similar")
820
+ - Single interactions without pattern repetition
821
+ - Casual preferences from single occurrences
822
+ - Testing or exploratory questions
823
+ - Temporary context or transient information
824
+ - General courtesy or social patterns (greetings, thank yous)
825
+ - Random or playful requests that don't indicate lasting preference
826
+ - Information that could change or is situational
827
+
828
+ # Quality Standards
829
+ - **Confidence threshold**: Only extract if confidence >= 0.8
830
+ - **Persistence required**: Must see evidence across multiple messages or strong explicit statement
831
+ - **Meaningful value**: Would this fact improve future interactions weeks from now?
832
+ - **Not redundant**: Avoid if existing memories already cover this information
833
+
746
834
  # Instructions
747
- Extract any NEW information that should be remembered long-term. For each item:
835
+ Extract ONLY truly important NEW information that meets the strict criteria above. For each item:
748
836
  - Determine which category it belongs to
749
837
  - Write a clear, factual statement
750
- - Assess confidence (0.0 to 1.0)
751
- - Only include information explicitly stated or strongly implied
838
+ - Assess confidence (0.0 to 1.0) - BE CONSERVATIVE
839
+ - Require strong evidence before extraction
840
+
841
+ **When in doubt, DO NOT extract.** It's better to miss temporary information than to clutter long-term memory.
752
842
 
753
843
  If there are no new long-term facts to extract, respond with <memories></memories>
754
844
 
@@ -891,7 +981,7 @@ var shortTermMemoryProvider = {
891
981
  if (!memoryService) {
892
982
  return {
893
983
  data: { summaries: [], recentMessages: [], mode: "disabled" },
894
- values: { sessionSummaries: "", recentMessages: "" },
984
+ values: {},
895
985
  text: ""
896
986
  };
897
987
  }
@@ -972,9 +1062,7 @@ ${runText}`;
972
1062
  mode: "full_conversation"
973
1063
  },
974
1064
  values: {
975
- sessionSummaries: "",
976
- recentMessages: "",
977
- recentActionResults: ""
1065
+ recentMessage: "No recent message available."
978
1066
  },
979
1067
  text: "No recent messages available"
980
1068
  };
@@ -1012,10 +1100,14 @@ ${runText}`;
1012
1100
  mode: "full_conversation"
1013
1101
  },
1014
1102
  values: {
1015
- sessionSummaries: "",
1016
- recentMessages: isPostFormat ? recentPosts : recentMessages,
1017
- recentActionResults: actionResultsText,
1018
- recentMessage
1103
+ ...(isPostFormat ? recentPosts : recentMessages) && {
1104
+ recentMessages: isPostFormat ? recentPosts : recentMessages
1105
+ },
1106
+ ...recentPosts && { recentPosts },
1107
+ ...actionResultsText && { recentActionResults: actionResultsText },
1108
+ ...recentMessage && { recentMessage },
1109
+ ...receivedMessageHeader && { receivedMessageHeader },
1110
+ ...focusHeader && { focusHeader }
1019
1111
  },
1020
1112
  text: text4
1021
1113
  };
@@ -1085,8 +1177,10 @@ ${runText}`;
1085
1177
  mode: "summarized"
1086
1178
  },
1087
1179
  values: {
1088
- sessionSummaries: summaryText,
1089
- recentMessages: recentMessagesText
1180
+ ...summaryText && { sessionSummaries: summaryText },
1181
+ ...recentMessagesText && { recentMessages: recentMessagesText },
1182
+ ...receivedMessageHeader && { receivedMessageHeader },
1183
+ ...focusHeader && { focusHeader }
1090
1184
  },
1091
1185
  text: text4
1092
1186
  };
@@ -1095,7 +1189,7 @@ ${runText}`;
1095
1189
  import_core4.logger.error({ error }, "Error in shortTermMemoryProvider:");
1096
1190
  return {
1097
1191
  data: { summaries: [], recentMessages: [], mode: "error" },
1098
- values: { sessionSummaries: "", recentMessages: "" },
1192
+ values: {},
1099
1193
  text: "Error retrieving conversation context."
1100
1194
  };
1101
1195
  }
@@ -1175,4 +1269,4 @@ var memoryPlugin = {
1175
1269
  };
1176
1270
  var src_default = memoryPlugin;
1177
1271
 
1178
- //# debugId=965D3FAC4FCE781C64756E2164756E21
1272
+ //# debugId=3C20A9F0BA14039464756E2164756E21