@elizaos/plugin-memory 1.0.5 → 1.0.7
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 +58 -34
- package/dist/browser/index.browser.js +133 -75
- package/dist/browser/index.browser.js.map +10 -9
- package/dist/cjs/index.node.cjs +379 -332
- package/dist/cjs/index.node.js.map +10 -9
- package/dist/index.d.ts +3 -0
- package/dist/node/index.node.js +390 -340
- package/dist/node/index.node.js.map +10 -9
- package/dist/providers/context-summary.d.ts +12 -0
- package/dist/providers/recent-messages.d.ts +15 -0
- package/dist/types/index.d.ts +9 -10
- package/package.json +1 -1
- package/dist/providers/short-term-memory.d.ts +0 -19
package/dist/cjs/index.node.cjs
CHANGED
|
@@ -30,10 +30,13 @@ var __export = (target, all) => {
|
|
|
30
30
|
var exports_index_node = {};
|
|
31
31
|
__export(exports_index_node, {
|
|
32
32
|
sessionSummaries: () => sessionSummaries,
|
|
33
|
+
recentMessagesProvider: () => recentMessagesProvider,
|
|
33
34
|
memoryPlugin: () => memoryPlugin,
|
|
34
35
|
memoryAccessLogs: () => memoryAccessLogs,
|
|
36
|
+
longTermMemoryProvider: () => longTermMemoryProvider,
|
|
35
37
|
longTermMemories: () => longTermMemories,
|
|
36
38
|
default: () => src_default,
|
|
39
|
+
contextSummaryProvider: () => contextSummaryProvider,
|
|
37
40
|
MemoryService: () => MemoryService,
|
|
38
41
|
LongTermMemoryCategory: () => LongTermMemoryCategory
|
|
39
42
|
});
|
|
@@ -127,13 +130,13 @@ class MemoryService extends import_core.Service {
|
|
|
127
130
|
this.lastExtractionCheckpoints = new Map;
|
|
128
131
|
this.memoryConfig = {
|
|
129
132
|
shortTermSummarizationThreshold: 16,
|
|
130
|
-
shortTermRetainRecent:
|
|
133
|
+
shortTermRetainRecent: 6,
|
|
131
134
|
shortTermSummarizationInterval: 10,
|
|
132
135
|
longTermExtractionEnabled: true,
|
|
133
136
|
longTermVectorSearchEnabled: false,
|
|
134
|
-
longTermConfidenceThreshold: 0.
|
|
135
|
-
longTermExtractionThreshold:
|
|
136
|
-
longTermExtractionInterval:
|
|
137
|
+
longTermConfidenceThreshold: 0.85,
|
|
138
|
+
longTermExtractionThreshold: 30,
|
|
139
|
+
longTermExtractionInterval: 10,
|
|
137
140
|
summaryModelType: "TEXT_LARGE",
|
|
138
141
|
summaryMaxTokens: 2500,
|
|
139
142
|
summaryMaxNewMessages: 20
|
|
@@ -183,7 +186,7 @@ class MemoryService extends import_core.Service {
|
|
|
183
186
|
if (extractionInterval) {
|
|
184
187
|
this.memoryConfig.longTermExtractionInterval = parseInt(extractionInterval, 10);
|
|
185
188
|
}
|
|
186
|
-
import_core.logger.
|
|
189
|
+
import_core.logger.debug({
|
|
187
190
|
summarizationThreshold: this.memoryConfig.shortTermSummarizationThreshold,
|
|
188
191
|
summarizationInterval: this.memoryConfig.shortTermSummarizationInterval,
|
|
189
192
|
maxNewMessages: this.memoryConfig.summaryMaxNewMessages,
|
|
@@ -540,6 +543,16 @@ ${items}`);
|
|
|
540
543
|
|
|
541
544
|
// src/evaluators/summarization.ts
|
|
542
545
|
var import_core2 = require("@elizaos/core");
|
|
546
|
+
async function getDialogueMessageCount(runtime, roomId) {
|
|
547
|
+
const messages = await runtime.getMemories({
|
|
548
|
+
tableName: "messages",
|
|
549
|
+
roomId,
|
|
550
|
+
count: 100,
|
|
551
|
+
unique: false
|
|
552
|
+
});
|
|
553
|
+
const dialogueMessages = messages.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result") && (msg.metadata?.type === "agent_response_message" || msg.metadata?.type === "user_message"));
|
|
554
|
+
return dialogueMessages.length;
|
|
555
|
+
}
|
|
543
556
|
var initialSummarizationTemplate = `# Task: Summarize Conversation
|
|
544
557
|
|
|
545
558
|
You are analyzing a conversation to create a concise summary that captures the key points, topics, and important details.
|
|
@@ -627,26 +640,26 @@ var summarizationEvaluator = {
|
|
|
627
640
|
return false;
|
|
628
641
|
}
|
|
629
642
|
const config = memoryService.getConfig();
|
|
630
|
-
const
|
|
643
|
+
const currentDialogueCount = await getDialogueMessageCount(runtime, message.roomId);
|
|
631
644
|
const existingSummary = await memoryService.getCurrentSessionSummary(message.roomId);
|
|
632
645
|
if (!existingSummary) {
|
|
633
|
-
const shouldSummarize =
|
|
646
|
+
const shouldSummarize = currentDialogueCount >= config.shortTermSummarizationThreshold;
|
|
634
647
|
import_core2.logger.debug({
|
|
635
648
|
roomId: message.roomId,
|
|
636
|
-
|
|
649
|
+
currentDialogueCount,
|
|
637
650
|
threshold: config.shortTermSummarizationThreshold,
|
|
638
651
|
shouldSummarize,
|
|
639
652
|
reason: "initial_summary_check"
|
|
640
653
|
}, "Summarization validation check");
|
|
641
654
|
return shouldSummarize;
|
|
642
655
|
} else {
|
|
643
|
-
const
|
|
644
|
-
const shouldUpdate =
|
|
656
|
+
const newDialogueCount = currentDialogueCount - existingSummary.lastMessageOffset;
|
|
657
|
+
const shouldUpdate = newDialogueCount >= config.shortTermSummarizationInterval;
|
|
645
658
|
import_core2.logger.debug({
|
|
646
659
|
roomId: message.roomId,
|
|
647
|
-
|
|
660
|
+
currentDialogueCount,
|
|
648
661
|
lastOffset: existingSummary.lastMessageOffset,
|
|
649
|
-
|
|
662
|
+
newDialogueCount,
|
|
650
663
|
interval: config.shortTermSummarizationInterval,
|
|
651
664
|
shouldUpdate,
|
|
652
665
|
reason: "summary_update_check"
|
|
@@ -666,30 +679,31 @@ var summarizationEvaluator = {
|
|
|
666
679
|
import_core2.logger.info(`Starting summarization for room ${roomId}`);
|
|
667
680
|
const existingSummary = await memoryService.getCurrentSessionSummary(roomId);
|
|
668
681
|
const lastOffset = existingSummary?.lastMessageOffset || 0;
|
|
669
|
-
const
|
|
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
|
-
}
|
|
680
|
-
const newMessages = await runtime.getMemories({
|
|
682
|
+
const allMessages = await runtime.getMemories({
|
|
681
683
|
tableName: "messages",
|
|
682
684
|
roomId,
|
|
683
|
-
count:
|
|
684
|
-
unique: false
|
|
685
|
-
start: lastOffset
|
|
685
|
+
count: 1000,
|
|
686
|
+
unique: false
|
|
686
687
|
});
|
|
687
|
-
|
|
688
|
-
|
|
688
|
+
const allDialogueMessages = allMessages.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result") && (msg.metadata?.type === "agent_response_message" || msg.metadata?.type === "user_message"));
|
|
689
|
+
const totalDialogueCount = allDialogueMessages.length;
|
|
690
|
+
const newDialogueCount = totalDialogueCount - lastOffset;
|
|
691
|
+
if (newDialogueCount === 0) {
|
|
692
|
+
import_core2.logger.debug("No new dialogue messages to summarize");
|
|
689
693
|
return;
|
|
690
694
|
}
|
|
691
|
-
const
|
|
692
|
-
const
|
|
695
|
+
const maxNewMessages = config.summaryMaxNewMessages || 50;
|
|
696
|
+
const messagesToProcess = Math.min(newDialogueCount, maxNewMessages);
|
|
697
|
+
if (newDialogueCount > maxNewMessages) {
|
|
698
|
+
import_core2.logger.warn(`Capping new dialogue messages at ${maxNewMessages} (${newDialogueCount} available). Oldest messages will be skipped.`);
|
|
699
|
+
}
|
|
700
|
+
const sortedDialogueMessages = allDialogueMessages.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0));
|
|
701
|
+
const newDialogueMessages = sortedDialogueMessages.slice(lastOffset, lastOffset + messagesToProcess);
|
|
702
|
+
if (newDialogueMessages.length === 0) {
|
|
703
|
+
import_core2.logger.debug("No new dialogue messages retrieved after filtering");
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
const formattedMessages = newDialogueMessages.map((msg) => {
|
|
693
707
|
const sender = msg.entityId === runtime.agentId ? runtime.character.name : "User";
|
|
694
708
|
return `${sender}: ${msg.content.text || "[non-text message]"}`;
|
|
695
709
|
}).join(`
|
|
@@ -709,11 +723,16 @@ var summarizationEvaluator = {
|
|
|
709
723
|
template
|
|
710
724
|
});
|
|
711
725
|
} else {
|
|
726
|
+
const initialMessages = sortedDialogueMessages.map((msg) => {
|
|
727
|
+
const sender = msg.entityId === runtime.agentId ? runtime.character.name : "User";
|
|
728
|
+
return `${sender}: ${msg.content.text || "[non-text message]"}`;
|
|
729
|
+
}).join(`
|
|
730
|
+
`);
|
|
712
731
|
template = initialSummarizationTemplate;
|
|
713
732
|
prompt = import_core2.composePromptFromState({
|
|
714
733
|
state: {
|
|
715
734
|
...state,
|
|
716
|
-
recentMessages:
|
|
735
|
+
recentMessages: initialMessages
|
|
717
736
|
},
|
|
718
737
|
template
|
|
719
738
|
});
|
|
@@ -724,15 +743,15 @@ var summarizationEvaluator = {
|
|
|
724
743
|
});
|
|
725
744
|
const summaryResult = parseSummaryXML(response);
|
|
726
745
|
import_core2.logger.info(`${existingSummary ? "Updated" : "Generated"} summary: ${summaryResult.summary.substring(0, 100)}...`);
|
|
727
|
-
const newOffset =
|
|
728
|
-
const firstMessage =
|
|
729
|
-
const lastMessage =
|
|
746
|
+
const newOffset = lastOffset + newDialogueMessages.length;
|
|
747
|
+
const firstMessage = newDialogueMessages[0];
|
|
748
|
+
const lastMessage = newDialogueMessages[newDialogueMessages.length - 1];
|
|
730
749
|
const startTime = existingSummary ? existingSummary.startTime : firstMessage?.createdAt && firstMessage.createdAt > 0 ? new Date(firstMessage.createdAt) : new Date;
|
|
731
750
|
const endTime = lastMessage?.createdAt && lastMessage.createdAt > 0 ? new Date(lastMessage.createdAt) : new Date;
|
|
732
751
|
if (existingSummary) {
|
|
733
752
|
await memoryService.updateSessionSummary(existingSummary.id, roomId, {
|
|
734
753
|
summary: summaryResult.summary,
|
|
735
|
-
messageCount: existingSummary.messageCount +
|
|
754
|
+
messageCount: existingSummary.messageCount + newDialogueMessages.length,
|
|
736
755
|
lastMessageOffset: newOffset,
|
|
737
756
|
endTime,
|
|
738
757
|
topics: summaryResult.topics,
|
|
@@ -740,15 +759,15 @@ var summarizationEvaluator = {
|
|
|
740
759
|
keyPoints: summaryResult.keyPoints
|
|
741
760
|
}
|
|
742
761
|
});
|
|
743
|
-
import_core2.logger.info(`Updated summary for room ${roomId}: ${
|
|
762
|
+
import_core2.logger.info(`Updated summary for room ${roomId}: ${newDialogueMessages.length} new dialogue messages processed (offset: ${lastOffset} → ${newOffset})`);
|
|
744
763
|
} else {
|
|
745
764
|
await memoryService.storeSessionSummary({
|
|
746
765
|
agentId: runtime.agentId,
|
|
747
766
|
roomId,
|
|
748
767
|
entityId: message.entityId !== runtime.agentId ? message.entityId : undefined,
|
|
749
768
|
summary: summaryResult.summary,
|
|
750
|
-
messageCount:
|
|
751
|
-
lastMessageOffset:
|
|
769
|
+
messageCount: totalDialogueCount,
|
|
770
|
+
lastMessageOffset: totalDialogueCount,
|
|
752
771
|
startTime,
|
|
753
772
|
endTime,
|
|
754
773
|
topics: summaryResult.topics,
|
|
@@ -756,7 +775,7 @@ var summarizationEvaluator = {
|
|
|
756
775
|
keyPoints: summaryResult.keyPoints
|
|
757
776
|
}
|
|
758
777
|
});
|
|
759
|
-
import_core2.logger.info(`Created new summary for room ${roomId}: ${
|
|
778
|
+
import_core2.logger.info(`Created new summary for room ${roomId}: ${totalDialogueCount} dialogue messages summarized (offset: 0 → ${totalDialogueCount})`);
|
|
760
779
|
}
|
|
761
780
|
} catch (error) {
|
|
762
781
|
import_core2.logger.error({ error }, "Error during summarization:");
|
|
@@ -771,21 +790,15 @@ var import_core3 = require("@elizaos/core");
|
|
|
771
790
|
// src/types/index.ts
|
|
772
791
|
var LongTermMemoryCategory;
|
|
773
792
|
((LongTermMemoryCategory2) => {
|
|
774
|
-
LongTermMemoryCategory2["
|
|
775
|
-
LongTermMemoryCategory2["
|
|
776
|
-
LongTermMemoryCategory2["
|
|
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";
|
|
793
|
+
LongTermMemoryCategory2["EPISODIC"] = "episodic";
|
|
794
|
+
LongTermMemoryCategory2["SEMANTIC"] = "semantic";
|
|
795
|
+
LongTermMemoryCategory2["PROCEDURAL"] = "procedural";
|
|
783
796
|
})(LongTermMemoryCategory ||= {});
|
|
784
797
|
|
|
785
798
|
// src/evaluators/long-term-extraction.ts
|
|
786
|
-
var extractionTemplate = `# Task: Extract Long-Term Memory
|
|
799
|
+
var extractionTemplate = `# Task: Extract Long-Term Memory (Strict Criteria)
|
|
787
800
|
|
|
788
|
-
You are analyzing a conversation to extract ONLY the most
|
|
801
|
+
You are analyzing a conversation to extract ONLY the most critical, persistent information about the user using cognitive science memory categories.
|
|
789
802
|
|
|
790
803
|
# Recent Messages
|
|
791
804
|
{{recentMessages}}
|
|
@@ -793,66 +806,127 @@ You are analyzing a conversation to extract ONLY the most important, persistent
|
|
|
793
806
|
# Current Long-Term Memories
|
|
794
807
|
{{existingMemories}}
|
|
795
808
|
|
|
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
|
|
809
|
+
# Memory Categories (Based on Cognitive Science)
|
|
806
810
|
|
|
807
|
-
|
|
811
|
+
## 1. EPISODIC Memory
|
|
812
|
+
Personal experiences and specific events with temporal/spatial context.
|
|
813
|
+
**Examples:**
|
|
814
|
+
- "User completed migration project from MongoDB to PostgreSQL in Q2 2024"
|
|
815
|
+
- "User encountered authentication bug in production on March 15th"
|
|
816
|
+
- "User had a negative experience with Docker networking in previous job"
|
|
808
817
|
|
|
809
|
-
**
|
|
810
|
-
-
|
|
811
|
-
-
|
|
812
|
-
-
|
|
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
|
|
818
|
+
**Requirements:**
|
|
819
|
+
- Must include WHO did WHAT, WHEN/WHERE
|
|
820
|
+
- Must be a specific, concrete event (not a pattern)
|
|
821
|
+
- Must have significant impact or relevance to future work
|
|
817
822
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
-
|
|
822
|
-
-
|
|
823
|
-
-
|
|
824
|
-
-
|
|
825
|
-
- Random or playful requests that don't indicate lasting preference
|
|
826
|
-
- Information that could change or is situational
|
|
823
|
+
## 2. SEMANTIC Memory
|
|
824
|
+
General facts, concepts, knowledge, and established truths about the user.
|
|
825
|
+
**Examples:**
|
|
826
|
+
- "User is a senior backend engineer with 8 years experience"
|
|
827
|
+
- "User specializes in distributed systems and microservices architecture"
|
|
828
|
+
- "User's primary programming language is TypeScript"
|
|
829
|
+
- "User works at Acme Corp as technical lead"
|
|
827
830
|
|
|
828
|
-
|
|
829
|
-
-
|
|
830
|
-
-
|
|
831
|
-
-
|
|
832
|
-
-
|
|
831
|
+
**Requirements:**
|
|
832
|
+
- Must be factual, timeless information
|
|
833
|
+
- Must be explicitly stated or demonstrated conclusively
|
|
834
|
+
- No speculation or inference from single instances
|
|
835
|
+
- Core identity, expertise, or knowledge only
|
|
833
836
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
-
|
|
838
|
-
-
|
|
839
|
-
-
|
|
837
|
+
## 3. PROCEDURAL Memory
|
|
838
|
+
Skills, workflows, methodologies, and how-to knowledge.
|
|
839
|
+
**Examples:**
|
|
840
|
+
- "User follows strict TDD workflow: write tests first, then implementation"
|
|
841
|
+
- "User prefers git rebase over merge to maintain linear history"
|
|
842
|
+
- "User's debugging process: check logs → reproduce locally → binary search"
|
|
843
|
+
- "User always writes JSDoc comments before implementing functions"
|
|
840
844
|
|
|
841
|
-
**
|
|
845
|
+
**Requirements:**
|
|
846
|
+
- Must describe HOW user does something
|
|
847
|
+
- Must be a repeated, consistent pattern (seen 3+ times or explicitly stated as standard practice)
|
|
848
|
+
- Must be a workflow, methodology, or skill application
|
|
849
|
+
- Not one-off preferences
|
|
842
850
|
|
|
843
|
-
|
|
851
|
+
# ULTRA-STRICT EXTRACTION CRITERIA
|
|
852
|
+
|
|
853
|
+
## ✅ DO EXTRACT (Only These):
|
|
854
|
+
|
|
855
|
+
**EPISODIC:**
|
|
856
|
+
- Significant completed projects or milestones
|
|
857
|
+
- Important bugs, incidents, or problems encountered
|
|
858
|
+
- Major decisions made with lasting impact
|
|
859
|
+
- Formative experiences that shape future work
|
|
860
|
+
|
|
861
|
+
**SEMANTIC:**
|
|
862
|
+
- Professional identity (role, title, company)
|
|
863
|
+
- Core expertise and specializations (stated explicitly or demonstrated conclusively)
|
|
864
|
+
- Primary languages, frameworks, or tools (not exploratory use)
|
|
865
|
+
- Established facts about their work context
|
|
866
|
+
|
|
867
|
+
**PROCEDURAL:**
|
|
868
|
+
- Consistent workflows demonstrated 3+ times or explicitly stated
|
|
869
|
+
- Standard practices user always follows
|
|
870
|
+
- Methodology preferences with clear rationale
|
|
871
|
+
- Debugging, testing, or development processes
|
|
872
|
+
|
|
873
|
+
## ❌ NEVER EXTRACT:
|
|
874
|
+
|
|
875
|
+
- **One-time requests or tasks** (e.g., "can you generate an image", "help me debug this")
|
|
876
|
+
- **Casual conversations** without lasting significance
|
|
877
|
+
- **Exploratory questions** (e.g., "how does X work?")
|
|
878
|
+
- **Temporary context** (current bug, today's task)
|
|
879
|
+
- **Preferences from single occurrence** (e.g., user asked for code once)
|
|
880
|
+
- **Social pleasantries** (thank you, greetings)
|
|
881
|
+
- **Testing or experimentation** (trying out a feature)
|
|
882
|
+
- **Common patterns everyone has** (likes clear explanations)
|
|
883
|
+
- **Situational information** (working on feature X today)
|
|
884
|
+
- **Opinions without persistence** (single complaint, isolated praise)
|
|
885
|
+
- **General knowledge** (not specific to user)
|
|
886
|
+
|
|
887
|
+
# Quality Gates (ALL Must Pass)
|
|
888
|
+
|
|
889
|
+
1. **Significance Test**: Will this matter in 3+ months?
|
|
890
|
+
2. **Specificity Test**: Is this concrete and actionable?
|
|
891
|
+
3. **Evidence Test**: Is there strong evidence (3+ instances OR explicit self-identification)?
|
|
892
|
+
4. **Uniqueness Test**: Is this specific to THIS user (not generic)?
|
|
893
|
+
5. **Confidence Test**: Confidence must be >= 0.85 (be VERY conservative)
|
|
894
|
+
6. **Non-Redundancy Test**: Does this add NEW information not in existing memories?
|
|
895
|
+
|
|
896
|
+
# Confidence Scoring (Be Conservative)
|
|
897
|
+
|
|
898
|
+
- **0.95-1.0**: User explicitly stated as core identity/practice AND demonstrated multiple times
|
|
899
|
+
- **0.85-0.94**: User explicitly stated OR consistently demonstrated 5+ times
|
|
900
|
+
- **0.75-0.84**: Strong pattern (3-4 instances) with supporting context
|
|
901
|
+
- **Below 0.75**: DO NOT EXTRACT (insufficient evidence)
|
|
902
|
+
|
|
903
|
+
# Critical Instructions
|
|
904
|
+
|
|
905
|
+
1. **Default to NOT extracting** - When in doubt, skip it
|
|
906
|
+
2. **Require overwhelming evidence** - One or two mentions is NOT enough
|
|
907
|
+
3. **Focus on what's PERSISTENT** - Not what's temporary or situational
|
|
908
|
+
4. **Verify against existing memories** - Don't duplicate or contradict
|
|
909
|
+
5. **Maximum 2-3 extractions per run** - Quality over quantity
|
|
910
|
+
|
|
911
|
+
**If there are no qualifying facts (which is common), respond with <memories></memories>**
|
|
912
|
+
|
|
913
|
+
# Response Format
|
|
844
914
|
|
|
845
|
-
Respond in this XML format:
|
|
846
915
|
<memories>
|
|
847
916
|
<memory>
|
|
848
|
-
<category>
|
|
849
|
-
<content>User is a
|
|
917
|
+
<category>semantic</category>
|
|
918
|
+
<content>User is a senior TypeScript developer with 8 years of backend experience</content>
|
|
850
919
|
<confidence>0.95</confidence>
|
|
851
920
|
</memory>
|
|
852
921
|
<memory>
|
|
853
|
-
<category>
|
|
854
|
-
<content>
|
|
855
|
-
<confidence>0.
|
|
922
|
+
<category>procedural</category>
|
|
923
|
+
<content>User follows TDD workflow: writes tests before implementation, runs tests after each change</content>
|
|
924
|
+
<confidence>0.88</confidence>
|
|
925
|
+
</memory>
|
|
926
|
+
<memory>
|
|
927
|
+
<category>episodic</category>
|
|
928
|
+
<content>User led database migration from MongoDB to PostgreSQL for payment system in Q2 2024</content>
|
|
929
|
+
<confidence>0.92</confidence>
|
|
856
930
|
</memory>
|
|
857
931
|
</memories>`;
|
|
858
932
|
function parseMemoryExtractionXML(xml) {
|
|
@@ -941,7 +1015,7 @@ var longTermExtractionEvaluator = {
|
|
|
941
1015
|
const extractions = parseMemoryExtractionXML(response);
|
|
942
1016
|
import_core3.logger.info(`Extracted ${extractions.length} long-term memories`);
|
|
943
1017
|
for (const extraction of extractions) {
|
|
944
|
-
if (extraction.confidence >= config.longTermConfidenceThreshold) {
|
|
1018
|
+
if (extraction.confidence >= Math.max(config.longTermConfidenceThreshold, 0.85)) {
|
|
945
1019
|
await memoryService.storeLongTermMemory({
|
|
946
1020
|
agentId: runtime.agentId,
|
|
947
1021
|
entityId,
|
|
@@ -956,7 +1030,7 @@ var longTermExtractionEvaluator = {
|
|
|
956
1030
|
});
|
|
957
1031
|
import_core3.logger.info(`Stored long-term memory: [${extraction.category}] ${extraction.content.substring(0, 50)}...`);
|
|
958
1032
|
} else {
|
|
959
|
-
import_core3.logger.debug(`Skipped low-confidence memory: ${extraction.content} (confidence: ${extraction.confidence})`);
|
|
1033
|
+
import_core3.logger.debug(`Skipped low-confidence memory: ${extraction.content} (confidence: ${extraction.confidence}, threshold: ${Math.max(config.longTermConfidenceThreshold, 0.85)})`);
|
|
960
1034
|
}
|
|
961
1035
|
}
|
|
962
1036
|
const currentMessageCount = await runtime.countMemories(roomId, false, "messages");
|
|
@@ -969,235 +1043,8 @@ var longTermExtractionEvaluator = {
|
|
|
969
1043
|
examples: []
|
|
970
1044
|
};
|
|
971
1045
|
|
|
972
|
-
// src/providers/short-term-memory.ts
|
|
973
|
-
var import_core4 = require("@elizaos/core");
|
|
974
|
-
var shortTermMemoryProvider = {
|
|
975
|
-
name: "SHORT_TERM_MEMORY",
|
|
976
|
-
description: "Adaptive conversation context with smart summarization",
|
|
977
|
-
position: 95,
|
|
978
|
-
get: async (runtime, message, _state) => {
|
|
979
|
-
try {
|
|
980
|
-
const memoryService = runtime.getService("memory");
|
|
981
|
-
if (!memoryService) {
|
|
982
|
-
return {
|
|
983
|
-
data: { summaries: [], recentMessages: [], mode: "disabled" },
|
|
984
|
-
values: {},
|
|
985
|
-
text: ""
|
|
986
|
-
};
|
|
987
|
-
}
|
|
988
|
-
const { roomId } = message;
|
|
989
|
-
const config = memoryService.getConfig();
|
|
990
|
-
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([
|
|
994
|
-
import_core4.getEntityDetails({ runtime, roomId }),
|
|
995
|
-
runtime.getRoom(roomId),
|
|
996
|
-
runtime.getMemories({
|
|
997
|
-
tableName: "messages",
|
|
998
|
-
roomId,
|
|
999
|
-
count: conversationLength,
|
|
1000
|
-
unique: false
|
|
1001
|
-
})
|
|
1002
|
-
]);
|
|
1003
|
-
const actionResultMessages = recentMessagesData.filter((msg) => msg.content?.type === "action_result" && msg.metadata?.type === "action_result");
|
|
1004
|
-
const dialogueMessages = recentMessagesData.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result"));
|
|
1005
|
-
const isPostFormat = room?.type ? room.type === import_core4.ChannelType.FEED || room.type === import_core4.ChannelType.THREAD : false;
|
|
1006
|
-
const [formattedRecentMessages, formattedRecentPosts] = await Promise.all([
|
|
1007
|
-
import_core4.formatMessages({
|
|
1008
|
-
messages: dialogueMessages,
|
|
1009
|
-
entities: entitiesData
|
|
1010
|
-
}),
|
|
1011
|
-
import_core4.formatPosts({
|
|
1012
|
-
messages: dialogueMessages,
|
|
1013
|
-
entities: entitiesData,
|
|
1014
|
-
conversationHeader: false
|
|
1015
|
-
})
|
|
1016
|
-
]);
|
|
1017
|
-
let actionResultsText = "";
|
|
1018
|
-
if (actionResultMessages.length > 0) {
|
|
1019
|
-
const groupedByRun = new Map;
|
|
1020
|
-
for (const mem of actionResultMessages) {
|
|
1021
|
-
const runId = String(mem.content?.runId || "unknown");
|
|
1022
|
-
if (!groupedByRun.has(runId)) {
|
|
1023
|
-
groupedByRun.set(runId, []);
|
|
1024
|
-
}
|
|
1025
|
-
groupedByRun.get(runId)?.push(mem);
|
|
1026
|
-
}
|
|
1027
|
-
const formattedActionResults = Array.from(groupedByRun.entries()).slice(-3).map(([runId, memories]) => {
|
|
1028
|
-
const sortedMemories = memories.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0));
|
|
1029
|
-
const thought = sortedMemories[0]?.content?.planThought || "";
|
|
1030
|
-
const runText = sortedMemories.map((mem) => {
|
|
1031
|
-
const actionName = mem.content?.actionName || "Unknown";
|
|
1032
|
-
const status = mem.content?.actionStatus || "unknown";
|
|
1033
|
-
const planStep = mem.content?.planStep || "";
|
|
1034
|
-
const text5 = mem.content?.text || "";
|
|
1035
|
-
const error = mem.content?.error || "";
|
|
1036
|
-
let memText = ` - ${actionName} (${status})`;
|
|
1037
|
-
if (planStep)
|
|
1038
|
-
memText += ` [${planStep}]`;
|
|
1039
|
-
if (error) {
|
|
1040
|
-
memText += `: Error - ${error}`;
|
|
1041
|
-
} else if (text5 && text5 !== `Executed action: ${actionName}`) {
|
|
1042
|
-
memText += `: ${text5}`;
|
|
1043
|
-
}
|
|
1044
|
-
return memText;
|
|
1045
|
-
}).join(`
|
|
1046
|
-
`);
|
|
1047
|
-
return `**Action Run ${runId.slice(0, 8)}**${thought ? ` - "${thought}"` : ""}
|
|
1048
|
-
${runText}`;
|
|
1049
|
-
}).join(`
|
|
1050
|
-
|
|
1051
|
-
`);
|
|
1052
|
-
actionResultsText = formattedActionResults ? import_core4.addHeader("# Recent Action Executions", formattedActionResults) : "";
|
|
1053
|
-
}
|
|
1054
|
-
const recentPosts = formattedRecentPosts && formattedRecentPosts.length > 0 ? import_core4.addHeader("# Posts in Thread", formattedRecentPosts) : "";
|
|
1055
|
-
const recentMessages = formattedRecentMessages && formattedRecentMessages.length > 0 ? import_core4.addHeader("# Conversation Messages", formattedRecentMessages) : "";
|
|
1056
|
-
if (!recentPosts && !recentMessages && dialogueMessages.length === 0 && !message.content.text) {
|
|
1057
|
-
return {
|
|
1058
|
-
data: {
|
|
1059
|
-
summaries: [],
|
|
1060
|
-
recentMessages: [],
|
|
1061
|
-
actionResults: [],
|
|
1062
|
-
mode: "full_conversation"
|
|
1063
|
-
},
|
|
1064
|
-
values: {
|
|
1065
|
-
recentMessage: "No recent message available."
|
|
1066
|
-
},
|
|
1067
|
-
text: "No recent messages available"
|
|
1068
|
-
};
|
|
1069
|
-
}
|
|
1070
|
-
let recentMessage = "No recent message available.";
|
|
1071
|
-
if (dialogueMessages.length > 0) {
|
|
1072
|
-
const mostRecentMessage = [...dialogueMessages].sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0))[0];
|
|
1073
|
-
const formattedSingleMessage = import_core4.formatMessages({
|
|
1074
|
-
messages: [mostRecentMessage],
|
|
1075
|
-
entities: entitiesData
|
|
1076
|
-
});
|
|
1077
|
-
if (formattedSingleMessage) {
|
|
1078
|
-
recentMessage = formattedSingleMessage;
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
const metaData = message.metadata;
|
|
1082
|
-
const senderName = entitiesData.find((entity) => entity.id === message.entityId)?.names[0] || metaData?.entityName || "Unknown User";
|
|
1083
|
-
const receivedMessageContent = message.content.text;
|
|
1084
|
-
const hasReceivedMessage = !!receivedMessageContent?.trim();
|
|
1085
|
-
const receivedMessageHeader = hasReceivedMessage ? import_core4.addHeader("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
|
|
1086
|
-
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.`) : "";
|
|
1087
|
-
const text4 = [
|
|
1088
|
-
isPostFormat ? recentPosts : recentMessages,
|
|
1089
|
-
actionResultsText,
|
|
1090
|
-
recentMessages || recentPosts || message.content.text ? receivedMessageHeader : "",
|
|
1091
|
-
recentMessages || recentPosts || message.content.text ? focusHeader : ""
|
|
1092
|
-
].filter(Boolean).join(`
|
|
1093
|
-
|
|
1094
|
-
`);
|
|
1095
|
-
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
|
-
},
|
|
1112
|
-
text: text4
|
|
1113
|
-
};
|
|
1114
|
-
} else {
|
|
1115
|
-
const currentSummary = await memoryService.getCurrentSessionSummary(roomId);
|
|
1116
|
-
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);
|
|
1126
|
-
const isPostFormat = room?.type ? room.type === import_core4.ChannelType.FEED || room.type === import_core4.ChannelType.THREAD : false;
|
|
1127
|
-
let recentMessagesText = "";
|
|
1128
|
-
if (unsummarizedMessages.length > 0) {
|
|
1129
|
-
const dialogueMessages = unsummarizedMessages.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result"));
|
|
1130
|
-
if (isPostFormat) {
|
|
1131
|
-
recentMessagesText = import_core4.formatPosts({
|
|
1132
|
-
messages: dialogueMessages,
|
|
1133
|
-
entities: entitiesData,
|
|
1134
|
-
conversationHeader: false
|
|
1135
|
-
});
|
|
1136
|
-
} else {
|
|
1137
|
-
recentMessagesText = import_core4.formatMessages({
|
|
1138
|
-
messages: dialogueMessages,
|
|
1139
|
-
entities: entitiesData
|
|
1140
|
-
});
|
|
1141
|
-
}
|
|
1142
|
-
if (recentMessagesText) {
|
|
1143
|
-
recentMessagesText = import_core4.addHeader("# Recent Messages", recentMessagesText);
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
let summaryText = "";
|
|
1147
|
-
if (currentSummary) {
|
|
1148
|
-
const messageRange = `${currentSummary.messageCount} messages`;
|
|
1149
|
-
const timeRange = new Date(currentSummary.startTime).toLocaleDateString();
|
|
1150
|
-
summaryText = `**Previous Conversation** (${messageRange}, ${timeRange})
|
|
1151
|
-
`;
|
|
1152
|
-
summaryText += currentSummary.summary;
|
|
1153
|
-
if (currentSummary.topics && currentSummary.topics.length > 0) {
|
|
1154
|
-
summaryText += `
|
|
1155
|
-
*Topics: ${currentSummary.topics.join(", ")}*`;
|
|
1156
|
-
}
|
|
1157
|
-
summaryText = import_core4.addHeader("# Conversation Summary", summaryText);
|
|
1158
|
-
}
|
|
1159
|
-
const metaData = message.metadata;
|
|
1160
|
-
const senderName = entitiesData.find((entity) => entity.id === message.entityId)?.names[0] || metaData?.entityName || "Unknown User";
|
|
1161
|
-
const receivedMessageContent = message.content.text;
|
|
1162
|
-
const hasReceivedMessage = !!receivedMessageContent?.trim();
|
|
1163
|
-
const receivedMessageHeader = hasReceivedMessage ? import_core4.addHeader("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
|
|
1164
|
-
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.`) : "";
|
|
1165
|
-
const text4 = [
|
|
1166
|
-
summaryText,
|
|
1167
|
-
recentMessagesText,
|
|
1168
|
-
hasReceivedMessage ? receivedMessageHeader : "",
|
|
1169
|
-
hasReceivedMessage ? focusHeader : ""
|
|
1170
|
-
].filter(Boolean).join(`
|
|
1171
|
-
|
|
1172
|
-
`);
|
|
1173
|
-
return {
|
|
1174
|
-
data: {
|
|
1175
|
-
summaries: currentSummary ? [currentSummary] : [],
|
|
1176
|
-
recentMessages: unsummarizedMessages,
|
|
1177
|
-
mode: "summarized"
|
|
1178
|
-
},
|
|
1179
|
-
values: {
|
|
1180
|
-
...summaryText && { sessionSummaries: summaryText },
|
|
1181
|
-
...recentMessagesText && { recentMessages: recentMessagesText },
|
|
1182
|
-
...receivedMessageHeader && { receivedMessageHeader },
|
|
1183
|
-
...focusHeader && { focusHeader }
|
|
1184
|
-
},
|
|
1185
|
-
text: text4
|
|
1186
|
-
};
|
|
1187
|
-
}
|
|
1188
|
-
} catch (error) {
|
|
1189
|
-
import_core4.logger.error({ error }, "Error in shortTermMemoryProvider:");
|
|
1190
|
-
return {
|
|
1191
|
-
data: { summaries: [], recentMessages: [], mode: "error" },
|
|
1192
|
-
values: {},
|
|
1193
|
-
text: "Error retrieving conversation context."
|
|
1194
|
-
};
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
};
|
|
1198
|
-
|
|
1199
1046
|
// src/providers/long-term-memory.ts
|
|
1200
|
-
var
|
|
1047
|
+
var import_core4 = require("@elizaos/core");
|
|
1201
1048
|
var longTermMemoryProvider = {
|
|
1202
1049
|
name: "LONG_TERM_MEMORY",
|
|
1203
1050
|
description: "Persistent facts and preferences about the user",
|
|
@@ -1229,7 +1076,7 @@ var longTermMemoryProvider = {
|
|
|
1229
1076
|
};
|
|
1230
1077
|
}
|
|
1231
1078
|
const formattedMemories = await memoryService.getFormattedLongTermMemories(entityId);
|
|
1232
|
-
const text4 =
|
|
1079
|
+
const text4 = import_core4.addHeader("# What I Know About You", formattedMemories);
|
|
1233
1080
|
const categoryCounts = new Map;
|
|
1234
1081
|
for (const memory of memories) {
|
|
1235
1082
|
const count = categoryCounts.get(memory.category) || 0;
|
|
@@ -1248,7 +1095,7 @@ var longTermMemoryProvider = {
|
|
|
1248
1095
|
text: text4
|
|
1249
1096
|
};
|
|
1250
1097
|
} catch (error) {
|
|
1251
|
-
|
|
1098
|
+
import_core4.logger.error({ error }, "Error in longTermMemoryProvider:");
|
|
1252
1099
|
return {
|
|
1253
1100
|
data: { memories: [] },
|
|
1254
1101
|
values: { longTermMemories: "" },
|
|
@@ -1258,15 +1105,215 @@ var longTermMemoryProvider = {
|
|
|
1258
1105
|
}
|
|
1259
1106
|
};
|
|
1260
1107
|
|
|
1108
|
+
// src/providers/context-summary.ts
|
|
1109
|
+
var import_core5 = require("@elizaos/core");
|
|
1110
|
+
var contextSummaryProvider = {
|
|
1111
|
+
name: "SUMMARIZED_CONTEXT",
|
|
1112
|
+
description: "Provides summarized context from previous conversations",
|
|
1113
|
+
position: 96,
|
|
1114
|
+
get: async (runtime, message, _state) => {
|
|
1115
|
+
try {
|
|
1116
|
+
const memoryService = runtime.getService("memory");
|
|
1117
|
+
const { roomId } = message;
|
|
1118
|
+
if (!memoryService) {
|
|
1119
|
+
return {
|
|
1120
|
+
data: {
|
|
1121
|
+
summary: null
|
|
1122
|
+
},
|
|
1123
|
+
values: {
|
|
1124
|
+
sessionSummaries: "",
|
|
1125
|
+
sessionSummariesWithTopics: ""
|
|
1126
|
+
},
|
|
1127
|
+
text: ""
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
const currentSummary = await memoryService.getCurrentSessionSummary(roomId);
|
|
1131
|
+
if (!currentSummary) {
|
|
1132
|
+
return {
|
|
1133
|
+
data: {
|
|
1134
|
+
summary: null
|
|
1135
|
+
},
|
|
1136
|
+
values: {
|
|
1137
|
+
sessionSummaries: "",
|
|
1138
|
+
sessionSummariesWithTopics: ""
|
|
1139
|
+
},
|
|
1140
|
+
text: ""
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
const messageRange = `${currentSummary.messageCount} messages`;
|
|
1144
|
+
const timeRange = new Date(currentSummary.startTime).toLocaleDateString();
|
|
1145
|
+
let summaryOnly = `**Previous Conversation** (${messageRange}, ${timeRange})
|
|
1146
|
+
`;
|
|
1147
|
+
summaryOnly += currentSummary.summary;
|
|
1148
|
+
let summaryWithTopics = summaryOnly;
|
|
1149
|
+
if (currentSummary.topics && currentSummary.topics.length > 0) {
|
|
1150
|
+
summaryWithTopics += `
|
|
1151
|
+
*Topics: ${currentSummary.topics.join(", ")}*`;
|
|
1152
|
+
}
|
|
1153
|
+
const sessionSummaries2 = import_core5.addHeader("# Conversation Summary", summaryOnly);
|
|
1154
|
+
const sessionSummariesWithTopics = import_core5.addHeader("# Conversation Summary", summaryWithTopics);
|
|
1155
|
+
return {
|
|
1156
|
+
data: {
|
|
1157
|
+
summary: currentSummary
|
|
1158
|
+
},
|
|
1159
|
+
values: {
|
|
1160
|
+
sessionSummaries: sessionSummaries2,
|
|
1161
|
+
sessionSummariesWithTopics
|
|
1162
|
+
},
|
|
1163
|
+
text: sessionSummariesWithTopics
|
|
1164
|
+
};
|
|
1165
|
+
} catch (error) {
|
|
1166
|
+
import_core5.logger.error({ error }, "Error in contextSummaryProvider:");
|
|
1167
|
+
return {
|
|
1168
|
+
data: {
|
|
1169
|
+
summary: null
|
|
1170
|
+
},
|
|
1171
|
+
values: {
|
|
1172
|
+
sessionSummaries: "",
|
|
1173
|
+
sessionSummariesWithTopics: ""
|
|
1174
|
+
},
|
|
1175
|
+
text: ""
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
|
|
1181
|
+
// src/providers/recent-messages.ts
|
|
1182
|
+
var import_core6 = require("@elizaos/core");
|
|
1183
|
+
var recentMessagesProvider = {
|
|
1184
|
+
name: "RECENT_MESSAGES",
|
|
1185
|
+
description: "Provides recent conversation messages with detailed context",
|
|
1186
|
+
position: 94,
|
|
1187
|
+
get: async (runtime, message, _state) => {
|
|
1188
|
+
try {
|
|
1189
|
+
const memoryService = runtime.getService("memory");
|
|
1190
|
+
const { roomId } = message;
|
|
1191
|
+
const config = memoryService?.getConfig() || {
|
|
1192
|
+
shortTermSummarizationThreshold: 16,
|
|
1193
|
+
shortTermRetainRecent: 6
|
|
1194
|
+
};
|
|
1195
|
+
const conversationLength = runtime.getConversationLength();
|
|
1196
|
+
let messagesToFetch = config.shortTermRetainRecent;
|
|
1197
|
+
let startOffset = 0;
|
|
1198
|
+
let hasSummary = false;
|
|
1199
|
+
if (memoryService) {
|
|
1200
|
+
const currentSummary = await memoryService.getCurrentSessionSummary(roomId);
|
|
1201
|
+
if (currentSummary) {
|
|
1202
|
+
hasSummary = true;
|
|
1203
|
+
startOffset = currentSummary.lastMessageOffset || 0;
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
if (!hasSummary) {
|
|
1207
|
+
const allMessages = await runtime.getMemories({
|
|
1208
|
+
tableName: "messages",
|
|
1209
|
+
roomId,
|
|
1210
|
+
count: conversationLength,
|
|
1211
|
+
unique: false
|
|
1212
|
+
});
|
|
1213
|
+
const dialogueMessageCount = allMessages.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result") && (msg.metadata?.type === "agent_response_message" || msg.metadata?.type === "user_message")).length;
|
|
1214
|
+
if (dialogueMessageCount < config.shortTermSummarizationThreshold) {
|
|
1215
|
+
messagesToFetch = conversationLength;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
const [entitiesData, room, recentMessagesData] = await Promise.all([
|
|
1219
|
+
import_core6.getEntityDetails({ runtime, roomId }),
|
|
1220
|
+
runtime.getRoom(roomId),
|
|
1221
|
+
runtime.getMemories({
|
|
1222
|
+
tableName: "messages",
|
|
1223
|
+
roomId,
|
|
1224
|
+
count: messagesToFetch,
|
|
1225
|
+
unique: false,
|
|
1226
|
+
start: startOffset
|
|
1227
|
+
})
|
|
1228
|
+
]);
|
|
1229
|
+
const isPostFormat = room?.type ? room.type === import_core6.ChannelType.FEED || room.type === import_core6.ChannelType.THREAD : false;
|
|
1230
|
+
const dialogueMessages = recentMessagesData.filter((msg) => !(msg.content?.type === "action_result" && msg.metadata?.type === "action_result") && (msg.metadata?.type === "agent_response_message" || msg.metadata?.type === "user_message"));
|
|
1231
|
+
let recentMessagesText = "";
|
|
1232
|
+
if (dialogueMessages.length > 0) {
|
|
1233
|
+
if (isPostFormat) {
|
|
1234
|
+
recentMessagesText = import_core6.formatPosts({
|
|
1235
|
+
messages: dialogueMessages,
|
|
1236
|
+
entities: entitiesData,
|
|
1237
|
+
conversationHeader: false
|
|
1238
|
+
});
|
|
1239
|
+
} else {
|
|
1240
|
+
recentMessagesText = import_core6.formatMessages({
|
|
1241
|
+
messages: dialogueMessages,
|
|
1242
|
+
entities: entitiesData
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
if (recentMessagesText) {
|
|
1246
|
+
recentMessagesText = import_core6.addHeader("# Recent Messages", recentMessagesText);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
const formatConversationLog = (messages, includeThoughts) => {
|
|
1250
|
+
return messages.sort((a, b) => (a.createdAt || 0) - (b.createdAt || 0)).map((msg) => {
|
|
1251
|
+
const entity = entitiesData.find((e) => e.id === msg.entityId);
|
|
1252
|
+
const entityName = entity?.names[0] || (msg.entityId === runtime.agentId ? runtime.character.name : "Unknown");
|
|
1253
|
+
const timestamp4 = msg.createdAt ? new Date(msg.createdAt).toLocaleString() : "Unknown time";
|
|
1254
|
+
const text5 = msg.content.text || "";
|
|
1255
|
+
const thought = includeThoughts && msg.content.internalMonologue ? `
|
|
1256
|
+
[Internal thought: ${msg.content.internalMonologue}]` : "";
|
|
1257
|
+
return `[${timestamp4}] ${entityName}: ${text5}${thought}`;
|
|
1258
|
+
}).join(`
|
|
1259
|
+
`);
|
|
1260
|
+
};
|
|
1261
|
+
const conversationLog = import_core6.addHeader("# Conversation Messages", formatConversationLog(dialogueMessages, false));
|
|
1262
|
+
const conversationLogWithAgentThoughts = import_core6.addHeader("# Conversation Messages", formatConversationLog(dialogueMessages, true));
|
|
1263
|
+
const metaData = message.metadata;
|
|
1264
|
+
const senderName = entitiesData.find((entity) => entity.id === message.entityId)?.names[0] || metaData?.entityName || "Unknown User";
|
|
1265
|
+
const receivedMessageContent = message.content.text;
|
|
1266
|
+
const hasReceivedMessage = !!receivedMessageContent?.trim();
|
|
1267
|
+
const receivedMessageHeader = hasReceivedMessage ? import_core6.addHeader("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
|
|
1268
|
+
const focusHeader = hasReceivedMessage ? import_core6.addHeader("# Focus your response", `You are replying to the above message from **${senderName}**. Keep your answer relevant to that message.`) : "";
|
|
1269
|
+
const text4 = [recentMessagesText, receivedMessageHeader, focusHeader].filter(Boolean).join(`
|
|
1270
|
+
|
|
1271
|
+
`);
|
|
1272
|
+
return {
|
|
1273
|
+
data: {
|
|
1274
|
+
messages: dialogueMessages
|
|
1275
|
+
},
|
|
1276
|
+
values: {
|
|
1277
|
+
recentMessages: recentMessagesText,
|
|
1278
|
+
conversationLog,
|
|
1279
|
+
conversationLogWithAgentThoughts,
|
|
1280
|
+
...receivedMessageHeader && { receivedMessageHeader },
|
|
1281
|
+
...focusHeader && { focusHeader }
|
|
1282
|
+
},
|
|
1283
|
+
text: text4
|
|
1284
|
+
};
|
|
1285
|
+
} catch (error) {
|
|
1286
|
+
import_core6.logger.error({ error }, "Error in recentMessagesProvider:");
|
|
1287
|
+
return {
|
|
1288
|
+
data: {
|
|
1289
|
+
messages: []
|
|
1290
|
+
},
|
|
1291
|
+
values: {
|
|
1292
|
+
recentMessages: "",
|
|
1293
|
+
conversationLog: "",
|
|
1294
|
+
conversationLogWithAgentThoughts: "",
|
|
1295
|
+
receivedMessageHeader: "",
|
|
1296
|
+
focusHeader: ""
|
|
1297
|
+
},
|
|
1298
|
+
text: ""
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1261
1304
|
// src/index.ts
|
|
1262
1305
|
var memoryPlugin = {
|
|
1263
1306
|
name: "memory",
|
|
1264
1307
|
description: "Advanced memory management with conversation summarization and long-term persistent memory",
|
|
1265
1308
|
services: [MemoryService],
|
|
1266
1309
|
evaluators: [summarizationEvaluator, longTermExtractionEvaluator],
|
|
1267
|
-
providers: [
|
|
1310
|
+
providers: [
|
|
1311
|
+
longTermMemoryProvider,
|
|
1312
|
+
contextSummaryProvider,
|
|
1313
|
+
recentMessagesProvider
|
|
1314
|
+
],
|
|
1268
1315
|
schema: exports_schemas
|
|
1269
1316
|
};
|
|
1270
1317
|
var src_default = memoryPlugin;
|
|
1271
1318
|
|
|
1272
|
-
//# debugId=
|
|
1319
|
+
//# debugId=D8A71511D9B322A664756E2164756E21
|