@elizaos/plugin-memory 1.0.4 → 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.
- package/README.md +72 -31
- package/dist/browser/index.browser.js +148 -48
- package/dist/browser/index.browser.js.map +7 -7
- package/dist/cjs/index.node.cjs +493 -108
- package/dist/cjs/index.node.js.map +7 -7
- package/dist/evaluators/summarization.d.ts +13 -6
- package/dist/node/index.node.js +493 -108
- package/dist/node/index.node.js.map +7 -7
- package/dist/providers/short-term-memory.d.ts +8 -6
- package/dist/services/memory-service.d.ts +6 -3
- package/dist/types/index.d.ts +12 -10
- package/package.json +1 -1
package/dist/cjs/index.node.cjs
CHANGED
|
@@ -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:
|
|
130
|
-
shortTermRetainRecent:
|
|
129
|
+
shortTermSummarizationThreshold: 16,
|
|
130
|
+
shortTermRetainRecent: 6,
|
|
131
|
+
shortTermSummarizationInterval: 10,
|
|
131
132
|
longTermExtractionEnabled: true,
|
|
132
133
|
longTermVectorSearchEnabled: false,
|
|
133
|
-
longTermConfidenceThreshold: 0.
|
|
134
|
-
|
|
134
|
+
longTermConfidenceThreshold: 0.85,
|
|
135
|
+
longTermExtractionThreshold: 30,
|
|
136
|
+
longTermExtractionInterval: 10,
|
|
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 >=
|
|
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
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
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:
|
|
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
|
|
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,
|
|
@@ -710,21 +771,15 @@ var import_core3 = require("@elizaos/core");
|
|
|
710
771
|
// src/types/index.ts
|
|
711
772
|
var LongTermMemoryCategory;
|
|
712
773
|
((LongTermMemoryCategory2) => {
|
|
713
|
-
LongTermMemoryCategory2["
|
|
714
|
-
LongTermMemoryCategory2["
|
|
715
|
-
LongTermMemoryCategory2["
|
|
716
|
-
LongTermMemoryCategory2["PREFERENCES"] = "preferences";
|
|
717
|
-
LongTermMemoryCategory2["DATA_SOURCES"] = "data_sources";
|
|
718
|
-
LongTermMemoryCategory2["GOALS"] = "goals";
|
|
719
|
-
LongTermMemoryCategory2["CONSTRAINTS"] = "constraints";
|
|
720
|
-
LongTermMemoryCategory2["DEFINITIONS"] = "definitions";
|
|
721
|
-
LongTermMemoryCategory2["BEHAVIORAL_PATTERNS"] = "behavioral_patterns";
|
|
774
|
+
LongTermMemoryCategory2["EPISODIC"] = "episodic";
|
|
775
|
+
LongTermMemoryCategory2["SEMANTIC"] = "semantic";
|
|
776
|
+
LongTermMemoryCategory2["PROCEDURAL"] = "procedural";
|
|
722
777
|
})(LongTermMemoryCategory ||= {});
|
|
723
778
|
|
|
724
779
|
// src/evaluators/long-term-extraction.ts
|
|
725
|
-
var extractionTemplate = `# Task: Extract Long-Term Memory
|
|
780
|
+
var extractionTemplate = `# Task: Extract Long-Term Memory (Strict Criteria)
|
|
726
781
|
|
|
727
|
-
You are analyzing a conversation to extract
|
|
782
|
+
You are analyzing a conversation to extract ONLY the most critical, persistent information about the user using cognitive science memory categories.
|
|
728
783
|
|
|
729
784
|
# Recent Messages
|
|
730
785
|
{{recentMessages}}
|
|
@@ -732,37 +787,127 @@ You are analyzing a conversation to extract facts that should be remembered long
|
|
|
732
787
|
# Current Long-Term Memories
|
|
733
788
|
{{existingMemories}}
|
|
734
789
|
|
|
735
|
-
# Memory Categories
|
|
736
|
-
1. **identity**: User's name, role, identity (e.g., "I'm a data scientist")
|
|
737
|
-
2. **expertise**: User's skills, knowledge domains, or unfamiliarity with topics
|
|
738
|
-
3. **projects**: Ongoing projects, past interactions, recurring topics
|
|
739
|
-
4. **preferences**: Communication style, format preferences, verbosity, etc.
|
|
740
|
-
5. **data_sources**: Frequently used files, databases, APIs
|
|
741
|
-
6. **goals**: Broader intentions (e.g., "preparing for interview")
|
|
742
|
-
7. **constraints**: User-defined rules or limitations
|
|
743
|
-
8. **definitions**: Custom terms, acronyms, glossaries
|
|
744
|
-
9. **behavioral_patterns**: How the user tends to interact
|
|
790
|
+
# Memory Categories (Based on Cognitive Science)
|
|
745
791
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
-
|
|
750
|
-
-
|
|
751
|
-
-
|
|
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"
|
|
752
798
|
|
|
753
|
-
|
|
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
|
|
803
|
+
|
|
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"
|
|
811
|
+
|
|
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
|
|
817
|
+
|
|
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"
|
|
825
|
+
|
|
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
|
|
831
|
+
|
|
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
|
|
754
895
|
|
|
755
|
-
Respond in this XML format:
|
|
756
896
|
<memories>
|
|
757
897
|
<memory>
|
|
758
|
-
<category>
|
|
759
|
-
<content>User is a
|
|
898
|
+
<category>semantic</category>
|
|
899
|
+
<content>User is a senior TypeScript developer with 8 years of backend experience</content>
|
|
760
900
|
<confidence>0.95</confidence>
|
|
761
901
|
</memory>
|
|
762
902
|
<memory>
|
|
763
|
-
<category>
|
|
764
|
-
<content>
|
|
765
|
-
<confidence>0.
|
|
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>
|
|
766
911
|
</memory>
|
|
767
912
|
</memories>`;
|
|
768
913
|
function parseMemoryExtractionXML(xml) {
|
|
@@ -851,7 +996,7 @@ var longTermExtractionEvaluator = {
|
|
|
851
996
|
const extractions = parseMemoryExtractionXML(response);
|
|
852
997
|
import_core3.logger.info(`Extracted ${extractions.length} long-term memories`);
|
|
853
998
|
for (const extraction of extractions) {
|
|
854
|
-
if (extraction.confidence >= config.longTermConfidenceThreshold) {
|
|
999
|
+
if (extraction.confidence >= Math.max(config.longTermConfidenceThreshold, 0.85)) {
|
|
855
1000
|
await memoryService.storeLongTermMemory({
|
|
856
1001
|
agentId: runtime.agentId,
|
|
857
1002
|
entityId,
|
|
@@ -866,7 +1011,7 @@ var longTermExtractionEvaluator = {
|
|
|
866
1011
|
});
|
|
867
1012
|
import_core3.logger.info(`Stored long-term memory: [${extraction.category}] ${extraction.content.substring(0, 50)}...`);
|
|
868
1013
|
} else {
|
|
869
|
-
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)})`);
|
|
870
1015
|
}
|
|
871
1016
|
}
|
|
872
1017
|
const currentMessageCount = await runtime.countMemories(roomId, false, "messages");
|
|
@@ -881,26 +1026,31 @@ var longTermExtractionEvaluator = {
|
|
|
881
1026
|
|
|
882
1027
|
// src/providers/short-term-memory.ts
|
|
883
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
|
+
};
|
|
884
1037
|
var shortTermMemoryProvider = {
|
|
885
1038
|
name: "SHORT_TERM_MEMORY",
|
|
886
|
-
description: "
|
|
1039
|
+
description: "Unified conversation context with smart summarization and interactions",
|
|
887
1040
|
position: 95,
|
|
888
1041
|
get: async (runtime, message, _state) => {
|
|
889
1042
|
try {
|
|
890
1043
|
const memoryService = runtime.getService("memory");
|
|
891
|
-
if (!memoryService) {
|
|
892
|
-
return {
|
|
893
|
-
data: { summaries: [], recentMessages: [], mode: "disabled" },
|
|
894
|
-
values: {},
|
|
895
|
-
text: ""
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
1044
|
const { roomId } = message;
|
|
899
|
-
const
|
|
1045
|
+
const conversationLength = 16;
|
|
1046
|
+
const config = memoryService?.getConfig() || {
|
|
1047
|
+
shortTermSummarizationThreshold: 16,
|
|
1048
|
+
shortTermRetainRecent: 6
|
|
1049
|
+
};
|
|
900
1050
|
const totalMessageCount = await runtime.countMemories(roomId, false, "messages");
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
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([
|
|
904
1054
|
import_core4.getEntityDetails({ runtime, roomId }),
|
|
905
1055
|
runtime.getRoom(roomId),
|
|
906
1056
|
runtime.getMemories({
|
|
@@ -908,7 +1058,8 @@ var shortTermMemoryProvider = {
|
|
|
908
1058
|
roomId,
|
|
909
1059
|
count: conversationLength,
|
|
910
1060
|
unique: false
|
|
911
|
-
})
|
|
1061
|
+
}),
|
|
1062
|
+
message.entityId !== runtime.agentId ? getRecentInteractions(runtime, message.entityId, runtime.agentId, roomId) : Promise.resolve([])
|
|
912
1063
|
]);
|
|
913
1064
|
const actionResultMessages = recentMessagesData.filter((msg) => msg.content?.type === "action_result" && msg.metadata?.type === "action_result");
|
|
914
1065
|
const dialogueMessages = recentMessagesData.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result"));
|
|
@@ -924,6 +1075,20 @@ var shortTermMemoryProvider = {
|
|
|
924
1075
|
conversationHeader: false
|
|
925
1076
|
})
|
|
926
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);
|
|
927
1092
|
let actionResultsText = "";
|
|
928
1093
|
if (actionResultMessages.length > 0) {
|
|
929
1094
|
const groupedByRun = new Map;
|
|
@@ -932,7 +1097,10 @@ var shortTermMemoryProvider = {
|
|
|
932
1097
|
if (!groupedByRun.has(runId)) {
|
|
933
1098
|
groupedByRun.set(runId, []);
|
|
934
1099
|
}
|
|
935
|
-
groupedByRun.get(runId)
|
|
1100
|
+
const memories = groupedByRun.get(runId);
|
|
1101
|
+
if (memories) {
|
|
1102
|
+
memories.push(mem);
|
|
1103
|
+
}
|
|
936
1104
|
}
|
|
937
1105
|
const formattedActionResults = Array.from(groupedByRun.entries()).slice(-3).map(([runId, memories]) => {
|
|
938
1106
|
const sortedMemories = memories.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0));
|
|
@@ -968,11 +1136,20 @@ ${runText}`;
|
|
|
968
1136
|
data: {
|
|
969
1137
|
summaries: [],
|
|
970
1138
|
recentMessages: [],
|
|
1139
|
+
recentInteractions: [],
|
|
971
1140
|
actionResults: [],
|
|
972
1141
|
mode: "full_conversation"
|
|
973
1142
|
},
|
|
974
1143
|
values: {
|
|
975
|
-
|
|
1144
|
+
recentPosts: "",
|
|
1145
|
+
recentMessages: "",
|
|
1146
|
+
recentMessageInteractions: "",
|
|
1147
|
+
recentPostInteractions: "",
|
|
1148
|
+
recentInteractions: "",
|
|
1149
|
+
recentActionResults: "",
|
|
1150
|
+
recentMessage: "No recent message available.",
|
|
1151
|
+
conversationLog: "",
|
|
1152
|
+
conversationLogWithAgentThoughts: ""
|
|
976
1153
|
},
|
|
977
1154
|
text: "No recent messages available"
|
|
978
1155
|
};
|
|
@@ -994,6 +1171,80 @@ ${runText}`;
|
|
|
994
1171
|
const hasReceivedMessage = !!receivedMessageContent?.trim();
|
|
995
1172
|
const receivedMessageHeader = hasReceivedMessage ? import_core4.addHeader("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
|
|
996
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
|
+
};
|
|
997
1248
|
const text4 = [
|
|
998
1249
|
isPostFormat ? recentPosts : recentMessages,
|
|
999
1250
|
actionResultsText,
|
|
@@ -1003,40 +1254,68 @@ ${runText}`;
|
|
|
1003
1254
|
|
|
1004
1255
|
`);
|
|
1005
1256
|
return {
|
|
1006
|
-
data
|
|
1007
|
-
|
|
1008
|
-
recentMessages: dialogueMessages,
|
|
1009
|
-
actionResults: actionResultMessages,
|
|
1010
|
-
mode: "full_conversation"
|
|
1011
|
-
},
|
|
1012
|
-
values: {
|
|
1013
|
-
...(isPostFormat ? recentPosts : recentMessages) && {
|
|
1014
|
-
recentMessages: isPostFormat ? recentPosts : recentMessages
|
|
1015
|
-
},
|
|
1016
|
-
...recentPosts && { recentPosts },
|
|
1017
|
-
...actionResultsText && { recentActionResults: actionResultsText },
|
|
1018
|
-
...recentMessage && { recentMessage },
|
|
1019
|
-
...receivedMessageHeader && { receivedMessageHeader },
|
|
1020
|
-
...focusHeader && { focusHeader }
|
|
1021
|
-
},
|
|
1257
|
+
data,
|
|
1258
|
+
values,
|
|
1022
1259
|
text: text4
|
|
1023
1260
|
};
|
|
1024
1261
|
} else {
|
|
1025
1262
|
const currentSummary = await memoryService.getCurrentSessionSummary(roomId);
|
|
1026
1263
|
const lastOffset = currentSummary?.lastMessageOffset || 0;
|
|
1027
|
-
const
|
|
1028
|
-
|
|
1029
|
-
roomId,
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
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
|
+
]);
|
|
1036
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
|
+
}
|
|
1037
1317
|
let recentMessagesText = "";
|
|
1038
|
-
if (
|
|
1039
|
-
const dialogueMessages = unsummarizedMessages.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result"));
|
|
1318
|
+
if (dialogueMessages.length > 0) {
|
|
1040
1319
|
if (isPostFormat) {
|
|
1041
1320
|
recentMessagesText = import_core4.formatPosts({
|
|
1042
1321
|
messages: dialogueMessages,
|
|
@@ -1053,6 +1332,31 @@ ${runText}`;
|
|
|
1053
1332
|
recentMessagesText = import_core4.addHeader("# Recent Messages", recentMessagesText);
|
|
1054
1333
|
}
|
|
1055
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);
|
|
1056
1360
|
let summaryText = "";
|
|
1057
1361
|
if (currentSummary) {
|
|
1058
1362
|
const messageRange = `${currentSummary.messageCount} messages`;
|
|
@@ -1072,9 +1376,66 @@ ${runText}`;
|
|
|
1072
1376
|
const hasReceivedMessage = !!receivedMessageContent?.trim();
|
|
1073
1377
|
const receivedMessageHeader = hasReceivedMessage ? import_core4.addHeader("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
|
|
1074
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
|
+
]);
|
|
1075
1435
|
const text4 = [
|
|
1076
1436
|
summaryText,
|
|
1077
1437
|
recentMessagesText,
|
|
1438
|
+
actionResultsText,
|
|
1078
1439
|
hasReceivedMessage ? receivedMessageHeader : "",
|
|
1079
1440
|
hasReceivedMessage ? focusHeader : ""
|
|
1080
1441
|
].filter(Boolean).join(`
|
|
@@ -1083,12 +1444,21 @@ ${runText}`;
|
|
|
1083
1444
|
return {
|
|
1084
1445
|
data: {
|
|
1085
1446
|
summaries: currentSummary ? [currentSummary] : [],
|
|
1086
|
-
recentMessages:
|
|
1447
|
+
recentMessages: dialogueMessages,
|
|
1448
|
+
recentInteractions: recentInteractionsData,
|
|
1449
|
+
actionResults: actionResultMessages,
|
|
1087
1450
|
mode: "summarized"
|
|
1088
1451
|
},
|
|
1089
1452
|
values: {
|
|
1090
1453
|
...summaryText && { sessionSummaries: summaryText },
|
|
1091
1454
|
...recentMessagesText && { recentMessages: recentMessagesText },
|
|
1455
|
+
recentMessageInteractions,
|
|
1456
|
+
recentPostInteractions,
|
|
1457
|
+
recentInteractions: isPostFormat ? recentPostInteractions : recentMessageInteractions,
|
|
1458
|
+
...actionResultsText && { recentActionResults: actionResultsText },
|
|
1459
|
+
recentMessage,
|
|
1460
|
+
conversationLog,
|
|
1461
|
+
conversationLogWithAgentThoughts,
|
|
1092
1462
|
...receivedMessageHeader && { receivedMessageHeader },
|
|
1093
1463
|
...focusHeader && { focusHeader }
|
|
1094
1464
|
},
|
|
@@ -1098,8 +1468,23 @@ ${runText}`;
|
|
|
1098
1468
|
} catch (error) {
|
|
1099
1469
|
import_core4.logger.error({ error }, "Error in shortTermMemoryProvider:");
|
|
1100
1470
|
return {
|
|
1101
|
-
data: {
|
|
1102
|
-
|
|
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
|
+
},
|
|
1103
1488
|
text: "Error retrieving conversation context."
|
|
1104
1489
|
};
|
|
1105
1490
|
}
|
|
@@ -1179,4 +1564,4 @@ var memoryPlugin = {
|
|
|
1179
1564
|
};
|
|
1180
1565
|
var src_default = memoryPlugin;
|
|
1181
1566
|
|
|
1182
|
-
//# debugId=
|
|
1567
|
+
//# debugId=A3C66779A69339CA64756E2164756E21
|