@elizaos/plugin-memory 1.0.5 → 1.0.6

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.
@@ -127,13 +127,13 @@ class MemoryService extends import_core.Service {
127
127
  this.lastExtractionCheckpoints = new Map;
128
128
  this.memoryConfig = {
129
129
  shortTermSummarizationThreshold: 16,
130
- shortTermRetainRecent: 10,
130
+ shortTermRetainRecent: 6,
131
131
  shortTermSummarizationInterval: 10,
132
132
  longTermExtractionEnabled: true,
133
133
  longTermVectorSearchEnabled: false,
134
- longTermConfidenceThreshold: 0.7,
135
- longTermExtractionThreshold: 20,
136
- longTermExtractionInterval: 5,
134
+ longTermConfidenceThreshold: 0.85,
135
+ longTermExtractionThreshold: 30,
136
+ longTermExtractionInterval: 10,
137
137
  summaryModelType: "TEXT_LARGE",
138
138
  summaryMaxTokens: 2500,
139
139
  summaryMaxNewMessages: 20
@@ -771,21 +771,15 @@ var import_core3 = require("@elizaos/core");
771
771
  // src/types/index.ts
772
772
  var LongTermMemoryCategory;
773
773
  ((LongTermMemoryCategory2) => {
774
- LongTermMemoryCategory2["IDENTITY"] = "identity";
775
- LongTermMemoryCategory2["EXPERTISE"] = "expertise";
776
- LongTermMemoryCategory2["PROJECTS"] = "projects";
777
- LongTermMemoryCategory2["PREFERENCES"] = "preferences";
778
- LongTermMemoryCategory2["DATA_SOURCES"] = "data_sources";
779
- LongTermMemoryCategory2["GOALS"] = "goals";
780
- LongTermMemoryCategory2["CONSTRAINTS"] = "constraints";
781
- LongTermMemoryCategory2["DEFINITIONS"] = "definitions";
782
- LongTermMemoryCategory2["BEHAVIORAL_PATTERNS"] = "behavioral_patterns";
774
+ LongTermMemoryCategory2["EPISODIC"] = "episodic";
775
+ LongTermMemoryCategory2["SEMANTIC"] = "semantic";
776
+ LongTermMemoryCategory2["PROCEDURAL"] = "procedural";
783
777
  })(LongTermMemoryCategory ||= {});
784
778
 
785
779
  // src/evaluators/long-term-extraction.ts
786
- var extractionTemplate = `# Task: Extract Long-Term Memory
780
+ var extractionTemplate = `# Task: Extract Long-Term Memory (Strict Criteria)
787
781
 
788
- You are analyzing a conversation to extract ONLY the most important, persistent facts about the user that should be remembered long-term.
782
+ You are analyzing a conversation to extract ONLY the most critical, persistent information about the user using cognitive science memory categories.
789
783
 
790
784
  # Recent Messages
791
785
  {{recentMessages}}
@@ -793,66 +787,127 @@ You are analyzing a conversation to extract ONLY the most important, persistent
793
787
  # Current Long-Term Memories
794
788
  {{existingMemories}}
795
789
 
796
- # Memory Categories
797
- 1. **identity**: User's name, role, identity (e.g., "I'm a data scientist")
798
- 2. **expertise**: User's skills, knowledge domains, or unfamiliarity with topics
799
- 3. **projects**: Ongoing projects, past interactions, recurring topics
800
- 4. **preferences**: Communication style, format preferences, verbosity, etc.
801
- 5. **data_sources**: Frequently used files, databases, APIs
802
- 6. **goals**: Broader intentions (e.g., "preparing for interview")
803
- 7. **constraints**: User-defined rules or limitations
804
- 8. **definitions**: Custom terms, acronyms, glossaries
805
- 9. **behavioral_patterns**: How the user tends to interact
790
+ # Memory Categories (Based on Cognitive Science)
806
791
 
807
- # STRICT EXTRACTION CRITERIA
792
+ ## 1. EPISODIC Memory
793
+ Personal experiences and specific events with temporal/spatial context.
794
+ **Examples:**
795
+ - "User completed migration project from MongoDB to PostgreSQL in Q2 2024"
796
+ - "User encountered authentication bug in production on March 15th"
797
+ - "User had a negative experience with Docker networking in previous job"
808
798
 
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
799
+ **Requirements:**
800
+ - Must include WHO did WHAT, WHEN/WHERE
801
+ - Must be a specific, concrete event (not a pattern)
802
+ - Must have significant impact or relevance to future work
817
803
 
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
804
+ ## 2. SEMANTIC Memory
805
+ General facts, concepts, knowledge, and established truths about the user.
806
+ **Examples:**
807
+ - "User is a senior backend engineer with 8 years experience"
808
+ - "User specializes in distributed systems and microservices architecture"
809
+ - "User's primary programming language is TypeScript"
810
+ - "User works at Acme Corp as technical lead"
827
811
 
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
812
+ **Requirements:**
813
+ - Must be factual, timeless information
814
+ - Must be explicitly stated or demonstrated conclusively
815
+ - No speculation or inference from single instances
816
+ - Core identity, expertise, or knowledge only
833
817
 
834
- # Instructions
835
- Extract ONLY truly important NEW information that meets the strict criteria above. For each item:
836
- - Determine which category it belongs to
837
- - Write a clear, factual statement
838
- - Assess confidence (0.0 to 1.0) - BE CONSERVATIVE
839
- - Require strong evidence before extraction
818
+ ## 3. PROCEDURAL Memory
819
+ Skills, workflows, methodologies, and how-to knowledge.
820
+ **Examples:**
821
+ - "User follows strict TDD workflow: write tests first, then implementation"
822
+ - "User prefers git rebase over merge to maintain linear history"
823
+ - "User's debugging process: check logs → reproduce locally → binary search"
824
+ - "User always writes JSDoc comments before implementing functions"
840
825
 
841
- **When in doubt, DO NOT extract.** It's better to miss temporary information than to clutter long-term memory.
826
+ **Requirements:**
827
+ - Must describe HOW user does something
828
+ - Must be a repeated, consistent pattern (seen 3+ times or explicitly stated as standard practice)
829
+ - Must be a workflow, methodology, or skill application
830
+ - Not one-off preferences
842
831
 
843
- If there are no new long-term facts to extract, respond with <memories></memories>
832
+ # ULTRA-STRICT EXTRACTION CRITERIA
833
+
834
+ ## ✅ DO EXTRACT (Only These):
835
+
836
+ **EPISODIC:**
837
+ - Significant completed projects or milestones
838
+ - Important bugs, incidents, or problems encountered
839
+ - Major decisions made with lasting impact
840
+ - Formative experiences that shape future work
841
+
842
+ **SEMANTIC:**
843
+ - Professional identity (role, title, company)
844
+ - Core expertise and specializations (stated explicitly or demonstrated conclusively)
845
+ - Primary languages, frameworks, or tools (not exploratory use)
846
+ - Established facts about their work context
847
+
848
+ **PROCEDURAL:**
849
+ - Consistent workflows demonstrated 3+ times or explicitly stated
850
+ - Standard practices user always follows
851
+ - Methodology preferences with clear rationale
852
+ - Debugging, testing, or development processes
853
+
854
+ ## ❌ NEVER EXTRACT:
855
+
856
+ - **One-time requests or tasks** (e.g., "can you generate an image", "help me debug this")
857
+ - **Casual conversations** without lasting significance
858
+ - **Exploratory questions** (e.g., "how does X work?")
859
+ - **Temporary context** (current bug, today's task)
860
+ - **Preferences from single occurrence** (e.g., user asked for code once)
861
+ - **Social pleasantries** (thank you, greetings)
862
+ - **Testing or experimentation** (trying out a feature)
863
+ - **Common patterns everyone has** (likes clear explanations)
864
+ - **Situational information** (working on feature X today)
865
+ - **Opinions without persistence** (single complaint, isolated praise)
866
+ - **General knowledge** (not specific to user)
867
+
868
+ # Quality Gates (ALL Must Pass)
869
+
870
+ 1. **Significance Test**: Will this matter in 3+ months?
871
+ 2. **Specificity Test**: Is this concrete and actionable?
872
+ 3. **Evidence Test**: Is there strong evidence (3+ instances OR explicit self-identification)?
873
+ 4. **Uniqueness Test**: Is this specific to THIS user (not generic)?
874
+ 5. **Confidence Test**: Confidence must be >= 0.85 (be VERY conservative)
875
+ 6. **Non-Redundancy Test**: Does this add NEW information not in existing memories?
876
+
877
+ # Confidence Scoring (Be Conservative)
878
+
879
+ - **0.95-1.0**: User explicitly stated as core identity/practice AND demonstrated multiple times
880
+ - **0.85-0.94**: User explicitly stated OR consistently demonstrated 5+ times
881
+ - **0.75-0.84**: Strong pattern (3-4 instances) with supporting context
882
+ - **Below 0.75**: DO NOT EXTRACT (insufficient evidence)
883
+
884
+ # Critical Instructions
885
+
886
+ 1. **Default to NOT extracting** - When in doubt, skip it
887
+ 2. **Require overwhelming evidence** - One or two mentions is NOT enough
888
+ 3. **Focus on what's PERSISTENT** - Not what's temporary or situational
889
+ 4. **Verify against existing memories** - Don't duplicate or contradict
890
+ 5. **Maximum 2-3 extractions per run** - Quality over quantity
891
+
892
+ **If there are no qualifying facts (which is common), respond with <memories></memories>**
893
+
894
+ # Response Format
844
895
 
845
- Respond in this XML format:
846
896
  <memories>
847
897
  <memory>
848
- <category>identity</category>
849
- <content>User is a software engineer specializing in backend development</content>
898
+ <category>semantic</category>
899
+ <content>User is a senior TypeScript developer with 8 years of backend experience</content>
850
900
  <confidence>0.95</confidence>
851
901
  </memory>
852
902
  <memory>
853
- <category>preferences</category>
854
- <content>Prefers code examples over lengthy explanations</content>
855
- <confidence>0.85</confidence>
903
+ <category>procedural</category>
904
+ <content>User follows TDD workflow: writes tests before implementation, runs tests after each change</content>
905
+ <confidence>0.88</confidence>
906
+ </memory>
907
+ <memory>
908
+ <category>episodic</category>
909
+ <content>User led database migration from MongoDB to PostgreSQL for payment system in Q2 2024</content>
910
+ <confidence>0.92</confidence>
856
911
  </memory>
857
912
  </memories>`;
858
913
  function parseMemoryExtractionXML(xml) {
@@ -941,7 +996,7 @@ var longTermExtractionEvaluator = {
941
996
  const extractions = parseMemoryExtractionXML(response);
942
997
  import_core3.logger.info(`Extracted ${extractions.length} long-term memories`);
943
998
  for (const extraction of extractions) {
944
- if (extraction.confidence >= config.longTermConfidenceThreshold) {
999
+ if (extraction.confidence >= Math.max(config.longTermConfidenceThreshold, 0.85)) {
945
1000
  await memoryService.storeLongTermMemory({
946
1001
  agentId: runtime.agentId,
947
1002
  entityId,
@@ -956,7 +1011,7 @@ var longTermExtractionEvaluator = {
956
1011
  });
957
1012
  import_core3.logger.info(`Stored long-term memory: [${extraction.category}] ${extraction.content.substring(0, 50)}...`);
958
1013
  } else {
959
- import_core3.logger.debug(`Skipped low-confidence memory: ${extraction.content} (confidence: ${extraction.confidence})`);
1014
+ import_core3.logger.debug(`Skipped low-confidence memory: ${extraction.content} (confidence: ${extraction.confidence}, threshold: ${Math.max(config.longTermConfidenceThreshold, 0.85)})`);
960
1015
  }
961
1016
  }
962
1017
  const currentMessageCount = await runtime.countMemories(roomId, false, "messages");
@@ -971,26 +1026,31 @@ var longTermExtractionEvaluator = {
971
1026
 
972
1027
  // src/providers/short-term-memory.ts
973
1028
  var import_core4 = require("@elizaos/core");
1029
+ var getRecentInteractions = async (runtime, sourceEntityId, targetEntityId, excludeRoomId) => {
1030
+ const rooms = await runtime.getRoomsForParticipants([sourceEntityId, targetEntityId]);
1031
+ return runtime.getMemoriesByRoomIds({
1032
+ tableName: "messages",
1033
+ roomIds: rooms.filter((room) => room !== excludeRoomId),
1034
+ limit: 20
1035
+ });
1036
+ };
974
1037
  var shortTermMemoryProvider = {
975
1038
  name: "SHORT_TERM_MEMORY",
976
- description: "Adaptive conversation context with smart summarization",
1039
+ description: "Unified conversation context with smart summarization and interactions",
977
1040
  position: 95,
978
1041
  get: async (runtime, message, _state) => {
979
1042
  try {
980
1043
  const memoryService = runtime.getService("memory");
981
- if (!memoryService) {
982
- return {
983
- data: { summaries: [], recentMessages: [], mode: "disabled" },
984
- values: {},
985
- text: ""
986
- };
987
- }
988
1044
  const { roomId } = message;
989
- const config = memoryService.getConfig();
1045
+ const conversationLength = 16;
1046
+ const config = memoryService?.getConfig() || {
1047
+ shortTermSummarizationThreshold: 16,
1048
+ shortTermRetainRecent: 6
1049
+ };
990
1050
  const totalMessageCount = await runtime.countMemories(roomId, false, "messages");
991
- if (totalMessageCount < config.shortTermSummarizationThreshold) {
992
- const conversationLength = runtime.getConversationLength();
993
- const [entitiesData, room, recentMessagesData] = await Promise.all([
1051
+ const useSummarization = memoryService && totalMessageCount >= config.shortTermSummarizationThreshold;
1052
+ if (!useSummarization) {
1053
+ const [entitiesData, room, recentMessagesData, recentInteractionsData] = await Promise.all([
994
1054
  import_core4.getEntityDetails({ runtime, roomId }),
995
1055
  runtime.getRoom(roomId),
996
1056
  runtime.getMemories({
@@ -998,7 +1058,8 @@ var shortTermMemoryProvider = {
998
1058
  roomId,
999
1059
  count: conversationLength,
1000
1060
  unique: false
1001
- })
1061
+ }),
1062
+ message.entityId !== runtime.agentId ? getRecentInteractions(runtime, message.entityId, runtime.agentId, roomId) : Promise.resolve([])
1002
1063
  ]);
1003
1064
  const actionResultMessages = recentMessagesData.filter((msg) => msg.content?.type === "action_result" && msg.metadata?.type === "action_result");
1004
1065
  const dialogueMessages = recentMessagesData.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result"));
@@ -1014,6 +1075,20 @@ var shortTermMemoryProvider = {
1014
1075
  conversationHeader: false
1015
1076
  })
1016
1077
  ]);
1078
+ const formatConversationLog = (messages, includeThoughts) => {
1079
+ return messages.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0)).map((msg) => {
1080
+ const entity = entitiesData.find((e) => e.id === msg.entityId);
1081
+ const entityName = entity?.names[0] || (msg.entityId === runtime.agentId ? runtime.character.name : "Unknown");
1082
+ const timestamp4 = msg.createdAt ? new Date(msg.createdAt).toLocaleString() : "Unknown time";
1083
+ const text5 = msg.content.text || "";
1084
+ const thought = includeThoughts && msg.content.internalMonologue ? `
1085
+ [Internal thought: ${msg.content.internalMonologue}]` : "";
1086
+ return `[${timestamp4}] ${entityName}: ${text5}${thought}`;
1087
+ }).join(`
1088
+ `);
1089
+ };
1090
+ const conversationLog = formatConversationLog(dialogueMessages, false);
1091
+ const conversationLogWithAgentThoughts = formatConversationLog(dialogueMessages, true);
1017
1092
  let actionResultsText = "";
1018
1093
  if (actionResultMessages.length > 0) {
1019
1094
  const groupedByRun = new Map;
@@ -1022,7 +1097,10 @@ var shortTermMemoryProvider = {
1022
1097
  if (!groupedByRun.has(runId)) {
1023
1098
  groupedByRun.set(runId, []);
1024
1099
  }
1025
- groupedByRun.get(runId)?.push(mem);
1100
+ const memories = groupedByRun.get(runId);
1101
+ if (memories) {
1102
+ memories.push(mem);
1103
+ }
1026
1104
  }
1027
1105
  const formattedActionResults = Array.from(groupedByRun.entries()).slice(-3).map(([runId, memories]) => {
1028
1106
  const sortedMemories = memories.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0));
@@ -1058,11 +1136,20 @@ ${runText}`;
1058
1136
  data: {
1059
1137
  summaries: [],
1060
1138
  recentMessages: [],
1139
+ recentInteractions: [],
1061
1140
  actionResults: [],
1062
1141
  mode: "full_conversation"
1063
1142
  },
1064
1143
  values: {
1065
- recentMessage: "No recent message available."
1144
+ recentPosts: "",
1145
+ recentMessages: "",
1146
+ recentMessageInteractions: "",
1147
+ recentPostInteractions: "",
1148
+ recentInteractions: "",
1149
+ recentActionResults: "",
1150
+ recentMessage: "No recent message available.",
1151
+ conversationLog: "",
1152
+ conversationLogWithAgentThoughts: ""
1066
1153
  },
1067
1154
  text: "No recent messages available"
1068
1155
  };
@@ -1084,6 +1171,80 @@ ${runText}`;
1084
1171
  const hasReceivedMessage = !!receivedMessageContent?.trim();
1085
1172
  const receivedMessageHeader = hasReceivedMessage ? import_core4.addHeader("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
1086
1173
  const focusHeader = hasReceivedMessage ? import_core4.addHeader("# Focus your response", `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.`) : "";
1174
+ const interactionEntityMap = new Map;
1175
+ if (recentInteractionsData.length > 0) {
1176
+ const uniqueEntityIds = [
1177
+ ...new Set(recentInteractionsData.map((message2) => message2.entityId).filter((id) => id !== runtime.agentId))
1178
+ ];
1179
+ const uniqueEntityIdSet = new Set(uniqueEntityIds);
1180
+ const entitiesDataIdSet = new Set;
1181
+ entitiesData.forEach((entity) => {
1182
+ if (uniqueEntityIdSet.has(entity.id)) {
1183
+ interactionEntityMap.set(entity.id, entity);
1184
+ entitiesDataIdSet.add(entity.id);
1185
+ }
1186
+ });
1187
+ const remainingEntityIds = uniqueEntityIds.filter((id) => !entitiesDataIdSet.has(id));
1188
+ if (remainingEntityIds.length > 0) {
1189
+ const entities = await Promise.all(remainingEntityIds.map((entityId) => runtime.getEntityById(entityId)));
1190
+ entities.forEach((entity, index4) => {
1191
+ if (entity) {
1192
+ interactionEntityMap.set(remainingEntityIds[index4], entity);
1193
+ }
1194
+ });
1195
+ }
1196
+ }
1197
+ const getRecentMessageInteractions = async (recentInteractionsData2) => {
1198
+ const formattedInteractions = recentInteractionsData2.map((message2) => {
1199
+ const isSelf = message2.entityId === runtime.agentId;
1200
+ let sender;
1201
+ if (isSelf) {
1202
+ sender = runtime.character.name;
1203
+ } else {
1204
+ sender = interactionEntityMap.get(message2.entityId)?.metadata?.userName || "unknown";
1205
+ }
1206
+ return `${sender}: ${message2.content.text}`;
1207
+ });
1208
+ return formattedInteractions.join(`
1209
+ `);
1210
+ };
1211
+ const getRecentPostInteractions = async (recentInteractionsData2, entities) => {
1212
+ const combinedEntities = [...entities];
1213
+ const actorIds = new Set(entities.map((entity) => entity.id));
1214
+ for (const [id, entity] of interactionEntityMap.entries()) {
1215
+ if (!actorIds.has(id)) {
1216
+ combinedEntities.push(entity);
1217
+ }
1218
+ }
1219
+ const formattedInteractions = import_core4.formatPosts({
1220
+ messages: recentInteractionsData2,
1221
+ entities: combinedEntities,
1222
+ conversationHeader: true
1223
+ });
1224
+ return formattedInteractions;
1225
+ };
1226
+ const [recentMessageInteractions, recentPostInteractions] = await Promise.all([
1227
+ getRecentMessageInteractions(recentInteractionsData),
1228
+ getRecentPostInteractions(recentInteractionsData, entitiesData)
1229
+ ]);
1230
+ const data = {
1231
+ summaries: [],
1232
+ recentMessages: dialogueMessages,
1233
+ recentInteractions: recentInteractionsData,
1234
+ actionResults: actionResultMessages,
1235
+ mode: "full_conversation"
1236
+ };
1237
+ const values = {
1238
+ recentPosts,
1239
+ recentMessages,
1240
+ recentMessageInteractions,
1241
+ recentPostInteractions,
1242
+ recentInteractions: isPostFormat ? recentPostInteractions : recentMessageInteractions,
1243
+ recentActionResults: actionResultsText,
1244
+ recentMessage,
1245
+ conversationLog,
1246
+ conversationLogWithAgentThoughts
1247
+ };
1087
1248
  const text4 = [
1088
1249
  isPostFormat ? recentPosts : recentMessages,
1089
1250
  actionResultsText,
@@ -1093,40 +1254,68 @@ ${runText}`;
1093
1254
 
1094
1255
  `);
1095
1256
  return {
1096
- data: {
1097
- summaries: [],
1098
- recentMessages: dialogueMessages,
1099
- actionResults: actionResultMessages,
1100
- mode: "full_conversation"
1101
- },
1102
- values: {
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 }
1111
- },
1257
+ data,
1258
+ values,
1112
1259
  text: text4
1113
1260
  };
1114
1261
  } else {
1115
1262
  const currentSummary = await memoryService.getCurrentSessionSummary(roomId);
1116
1263
  const lastOffset = currentSummary?.lastMessageOffset || 0;
1117
- const unsummarizedMessages = await runtime.getMemories({
1118
- tableName: "messages",
1119
- roomId,
1120
- count: config.shortTermRetainRecent,
1121
- unique: false,
1122
- start: lastOffset
1123
- });
1124
- const entitiesData = await import_core4.getEntityDetails({ runtime, roomId });
1125
- const room = await runtime.getRoom(roomId);
1264
+ const recentCount = config.shortTermRetainRecent;
1265
+ const [entitiesData, room, unsummarizedMessages, recentInteractionsData] = await Promise.all([
1266
+ import_core4.getEntityDetails({ runtime, roomId }),
1267
+ runtime.getRoom(roomId),
1268
+ runtime.getMemories({
1269
+ tableName: "messages",
1270
+ roomId,
1271
+ count: recentCount,
1272
+ unique: false,
1273
+ start: lastOffset
1274
+ }),
1275
+ message.entityId !== runtime.agentId ? getRecentInteractions(runtime, message.entityId, runtime.agentId, roomId) : Promise.resolve([])
1276
+ ]);
1126
1277
  const isPostFormat = room?.type ? room.type === import_core4.ChannelType.FEED || room.type === import_core4.ChannelType.THREAD : false;
1278
+ const actionResultMessages = unsummarizedMessages.filter((msg) => msg.content?.type === "action_result" && msg.metadata?.type === "action_result");
1279
+ const dialogueMessages = unsummarizedMessages.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result"));
1280
+ let actionResultsText = "";
1281
+ if (actionResultMessages.length > 0) {
1282
+ const groupedByRun = new Map;
1283
+ for (const mem of actionResultMessages) {
1284
+ const runId = String(mem.content?.runId || "unknown");
1285
+ if (!groupedByRun.has(runId)) {
1286
+ groupedByRun.set(runId, []);
1287
+ }
1288
+ groupedByRun.get(runId)?.push(mem);
1289
+ }
1290
+ const formattedActionResults = Array.from(groupedByRun.entries()).slice(-3).map(([runId, memories]) => {
1291
+ const sortedMemories = memories.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0));
1292
+ const thought = sortedMemories[0]?.content?.planThought || "";
1293
+ const runText = sortedMemories.map((mem) => {
1294
+ const actionName = mem.content?.actionName || "Unknown";
1295
+ const status = mem.content?.actionStatus || "unknown";
1296
+ const planStep = mem.content?.planStep || "";
1297
+ const text5 = mem.content?.text || "";
1298
+ const error = mem.content?.error || "";
1299
+ let memText = ` - ${actionName} (${status})`;
1300
+ if (planStep)
1301
+ memText += ` [${planStep}]`;
1302
+ if (error) {
1303
+ memText += `: Error - ${error}`;
1304
+ } else if (text5 && text5 !== `Executed action: ${actionName}`) {
1305
+ memText += `: ${text5}`;
1306
+ }
1307
+ return memText;
1308
+ }).join(`
1309
+ `);
1310
+ return `**Action Run ${runId.slice(0, 8)}**${thought ? ` - "${thought}"` : ""}
1311
+ ${runText}`;
1312
+ }).join(`
1313
+
1314
+ `);
1315
+ actionResultsText = formattedActionResults ? import_core4.addHeader("# Recent Action Executions", formattedActionResults) : "";
1316
+ }
1127
1317
  let recentMessagesText = "";
1128
- if (unsummarizedMessages.length > 0) {
1129
- const dialogueMessages = unsummarizedMessages.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result"));
1318
+ if (dialogueMessages.length > 0) {
1130
1319
  if (isPostFormat) {
1131
1320
  recentMessagesText = import_core4.formatPosts({
1132
1321
  messages: dialogueMessages,
@@ -1143,6 +1332,31 @@ ${runText}`;
1143
1332
  recentMessagesText = import_core4.addHeader("# Recent Messages", recentMessagesText);
1144
1333
  }
1145
1334
  }
1335
+ let recentMessage = "No recent message available.";
1336
+ if (dialogueMessages.length > 0) {
1337
+ const mostRecentMessage = [...dialogueMessages].sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0))[0];
1338
+ const formattedSingleMessage = import_core4.formatMessages({
1339
+ messages: [mostRecentMessage],
1340
+ entities: entitiesData
1341
+ });
1342
+ if (formattedSingleMessage) {
1343
+ recentMessage = formattedSingleMessage;
1344
+ }
1345
+ }
1346
+ const formatConversationLog = (messages, includeThoughts) => {
1347
+ return messages.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0)).map((msg) => {
1348
+ const entity = entitiesData.find((e) => e.id === msg.entityId);
1349
+ const entityName = entity?.names[0] || (msg.entityId === runtime.agentId ? runtime.character.name : "Unknown");
1350
+ const timestamp4 = msg.createdAt ? new Date(msg.createdAt).toLocaleString() : "Unknown time";
1351
+ const text5 = msg.content.text || "";
1352
+ const thought = includeThoughts && msg.content.internalMonologue ? `
1353
+ [Internal thought: ${msg.content.internalMonologue}]` : "";
1354
+ return `[${timestamp4}] ${entityName}: ${text5}${thought}`;
1355
+ }).join(`
1356
+ `);
1357
+ };
1358
+ const conversationLog = formatConversationLog(dialogueMessages, false);
1359
+ const conversationLogWithAgentThoughts = formatConversationLog(dialogueMessages, true);
1146
1360
  let summaryText = "";
1147
1361
  if (currentSummary) {
1148
1362
  const messageRange = `${currentSummary.messageCount} messages`;
@@ -1162,9 +1376,66 @@ ${runText}`;
1162
1376
  const hasReceivedMessage = !!receivedMessageContent?.trim();
1163
1377
  const receivedMessageHeader = hasReceivedMessage ? import_core4.addHeader("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
1164
1378
  const focusHeader = hasReceivedMessage ? import_core4.addHeader("# Focus your response", `You are replying to the above message from **${senderName}**. Keep your answer relevant to that message.`) : "";
1379
+ const interactionEntityMap = new Map;
1380
+ if (recentInteractionsData.length > 0) {
1381
+ const uniqueEntityIds = [
1382
+ ...new Set(recentInteractionsData.map((message2) => message2.entityId).filter((id) => id !== runtime.agentId))
1383
+ ];
1384
+ const uniqueEntityIdSet = new Set(uniqueEntityIds);
1385
+ const entitiesDataIdSet = new Set;
1386
+ entitiesData.forEach((entity) => {
1387
+ if (uniqueEntityIdSet.has(entity.id)) {
1388
+ interactionEntityMap.set(entity.id, entity);
1389
+ entitiesDataIdSet.add(entity.id);
1390
+ }
1391
+ });
1392
+ const remainingEntityIds = uniqueEntityIds.filter((id) => !entitiesDataIdSet.has(id));
1393
+ if (remainingEntityIds.length > 0) {
1394
+ const entities = await Promise.all(remainingEntityIds.map((entityId) => runtime.getEntityById(entityId)));
1395
+ entities.forEach((entity, index4) => {
1396
+ if (entity) {
1397
+ interactionEntityMap.set(remainingEntityIds[index4], entity);
1398
+ }
1399
+ });
1400
+ }
1401
+ }
1402
+ const getRecentMessageInteractions = async (recentInteractionsData2) => {
1403
+ const formattedInteractions = recentInteractionsData2.map((message2) => {
1404
+ const isSelf = message2.entityId === runtime.agentId;
1405
+ let sender;
1406
+ if (isSelf) {
1407
+ sender = runtime.character.name;
1408
+ } else {
1409
+ sender = interactionEntityMap.get(message2.entityId)?.metadata?.userName || "unknown";
1410
+ }
1411
+ return `${sender}: ${message2.content.text}`;
1412
+ });
1413
+ return formattedInteractions.join(`
1414
+ `);
1415
+ };
1416
+ const getRecentPostInteractions = async (recentInteractionsData2, entities) => {
1417
+ const combinedEntities = [...entities];
1418
+ const actorIds = new Set(entities.map((entity) => entity.id));
1419
+ for (const [id, entity] of interactionEntityMap.entries()) {
1420
+ if (!actorIds.has(id)) {
1421
+ combinedEntities.push(entity);
1422
+ }
1423
+ }
1424
+ const formattedInteractions = import_core4.formatPosts({
1425
+ messages: recentInteractionsData2,
1426
+ entities: combinedEntities,
1427
+ conversationHeader: true
1428
+ });
1429
+ return formattedInteractions;
1430
+ };
1431
+ const [recentMessageInteractions, recentPostInteractions] = await Promise.all([
1432
+ getRecentMessageInteractions(recentInteractionsData),
1433
+ getRecentPostInteractions(recentInteractionsData, entitiesData)
1434
+ ]);
1165
1435
  const text4 = [
1166
1436
  summaryText,
1167
1437
  recentMessagesText,
1438
+ actionResultsText,
1168
1439
  hasReceivedMessage ? receivedMessageHeader : "",
1169
1440
  hasReceivedMessage ? focusHeader : ""
1170
1441
  ].filter(Boolean).join(`
@@ -1173,12 +1444,21 @@ ${runText}`;
1173
1444
  return {
1174
1445
  data: {
1175
1446
  summaries: currentSummary ? [currentSummary] : [],
1176
- recentMessages: unsummarizedMessages,
1447
+ recentMessages: dialogueMessages,
1448
+ recentInteractions: recentInteractionsData,
1449
+ actionResults: actionResultMessages,
1177
1450
  mode: "summarized"
1178
1451
  },
1179
1452
  values: {
1180
1453
  ...summaryText && { sessionSummaries: summaryText },
1181
1454
  ...recentMessagesText && { recentMessages: recentMessagesText },
1455
+ recentMessageInteractions,
1456
+ recentPostInteractions,
1457
+ recentInteractions: isPostFormat ? recentPostInteractions : recentMessageInteractions,
1458
+ ...actionResultsText && { recentActionResults: actionResultsText },
1459
+ recentMessage,
1460
+ conversationLog,
1461
+ conversationLogWithAgentThoughts,
1182
1462
  ...receivedMessageHeader && { receivedMessageHeader },
1183
1463
  ...focusHeader && { focusHeader }
1184
1464
  },
@@ -1188,8 +1468,23 @@ ${runText}`;
1188
1468
  } catch (error) {
1189
1469
  import_core4.logger.error({ error }, "Error in shortTermMemoryProvider:");
1190
1470
  return {
1191
- data: { summaries: [], recentMessages: [], mode: "error" },
1192
- values: {},
1471
+ data: {
1472
+ summaries: [],
1473
+ recentMessages: [],
1474
+ recentInteractions: [],
1475
+ actionResults: [],
1476
+ mode: "error"
1477
+ },
1478
+ values: {
1479
+ recentPosts: "",
1480
+ recentMessages: "",
1481
+ recentMessageInteractions: "",
1482
+ recentPostInteractions: "",
1483
+ recentInteractions: "",
1484
+ recentActionResults: "",
1485
+ conversationLog: "",
1486
+ conversationLogWithAgentThoughts: ""
1487
+ },
1193
1488
  text: "Error retrieving conversation context."
1194
1489
  };
1195
1490
  }
@@ -1269,4 +1564,4 @@ var memoryPlugin = {
1269
1564
  };
1270
1565
  var src_default = memoryPlugin;
1271
1566
 
1272
- //# debugId=3C20A9F0BA14039464756E2164756E21
1567
+ //# debugId=A3C66779A69339CA64756E2164756E21