@elizaos/plugin-memory 1.1.0 → 1.1.2
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 +230 -330
- package/dist/actions/remember.d.ts +11 -0
- package/dist/browser/index.browser.js +205 -348
- package/dist/browser/index.browser.js.map +13 -23
- package/dist/cjs/index.node.cjs +936 -2193
- package/dist/cjs/index.node.js.map +13 -23
- package/dist/evaluators/long-term-extraction.d.ts +8 -0
- package/dist/evaluators/summarization.d.ts +25 -6
- package/dist/index.d.ts +32 -152
- package/dist/node/index.node.js +944 -2210
- package/dist/node/index.node.js.map +13 -23
- package/dist/providers/context-summary.d.ts +12 -0
- package/dist/providers/long-term-memory.d.ts +11 -18
- package/dist/schemas/index.d.ts +6 -16
- package/dist/schemas/long-term-memories.d.ts +70 -308
- package/dist/schemas/memory-access-logs.d.ts +154 -0
- package/dist/schemas/session-summaries.d.ts +283 -0
- package/dist/services/memory-service.d.ts +51 -95
- package/dist/types/index.d.ts +53 -298
- package/package.json +2 -84
- package/dist/evaluators/consolidation.d.ts +0 -19
- package/dist/prompts/consolidation.d.ts +0 -35
- package/dist/prompts/summarization.d.ts +0 -25
- package/dist/providers/action-results.d.ts +0 -2
- package/dist/providers/recent-conversation-summary.d.ts +0 -2
- package/dist/repositories/conversation-summary.d.ts +0 -33
- package/dist/repositories/index.d.ts +0 -17
- package/dist/repositories/long-term-memory.d.ts +0 -53
- package/dist/schemas/conversation-summaries.d.ts +0 -494
- package/dist/utils/db-mapping.d.ts +0 -20
- package/dist/utils/decay-scoring.d.ts +0 -41
- package/dist/utils/embedding.d.ts +0 -21
- package/dist/utils/formatting.d.ts +0 -17
- package/dist/utils/index.d.ts +0 -17
- package/dist/utils/search-merging.d.ts +0 -18
- package/dist/utils/token-counter.d.ts +0 -53
|
@@ -1,348 +1,205 @@
|
|
|
1
|
-
var nJ=Object.defineProperty;var iJ=(J,Q)=>{for(var W in Q)nJ(J,W,{get:Q[W],enumerable:!0,configurable:!0,set:($)=>Q[W]=()=>$})};import{Service as GQ,logger as F,ModelType as o,parseKeyValueXml as YQ,parseBooleanFromText as jQ}from"@elizaos/core";import{BM25 as NQ}from"@elizaos/core";var e={384:"dim384",512:"dim512",768:"dim768",1024:"dim1024",1536:"dim1536",3072:"dim3072"},_J;(($)=>{$.EPISODIC="EPISODIC";$.SEMANTIC="SEMANTIC";$.PROCEDURAL="PROCEDURAL"})(_J||={});var tJ;(($)=>{$.EXPONENTIAL="EXPONENTIAL";$.LINEAR="LINEAR";$.NONE="NONE"})(tJ||={});import{logger as h}from"@elizaos/core";import{eq as H,and as $J,desc as XJ,sql as ZJ,cosineDistance as eJ,gte as LJ,or as JQ,isNull as QQ}from"drizzle-orm";var QJ={};iJ(QJ,{longTermMemoryEmbeddings:()=>D,longTermMemories:()=>A,conversationSummaryEmbeddings:()=>R,conversationSummaries:()=>k});import{sql as kJ}from"drizzle-orm";import{pgTable as PJ,text as d,integer as oJ,jsonb as OJ,real as VJ,index as C,varchar as f,timestamp as JJ,boolean as aJ,vector as v,foreignKey as mJ}from"drizzle-orm/pg-core";import{VECTOR_DIMS as S}from"@elizaos/core";var A=PJ("long_term_memories",{id:f("id",{length:36}).primaryKey(),agentId:f("agent_id",{length:36}).notNull(),entityId:f("entity_id",{length:36}).notNull(),roomId:f("room_id",{length:36}),type:d("type").notNull(),content:d("content").notNull(),embeddingContext:d("embedding_context").notNull(),confidence:VJ("confidence").notNull().default(1),decayRate:VJ("decay_rate").notNull().default(0.01),decayFunction:d("decay_function").notNull().default("EXPONENTIAL"),createdAt:JJ("created_at").default(kJ`now()`).notNull(),lastAccessedAt:JJ("last_accessed_at"),accessCount:oJ("access_count").default(0).notNull(),isActive:aJ("is_active").default(!0).notNull(),source:OJ("source").notNull().default({}),metadata:OJ("metadata").notNull().default({}),supersedesId:f("supersedes_id",{length:36})},(J)=>({agentEntityIdx:C("ltm_agent_entity_idx").on(J.agentId,J.entityId),typeIdx:C("ltm_type_idx").on(J.type),roomIdx:C("ltm_room_idx").on(J.roomId),activeIdx:C("ltm_active_idx").on(J.isActive),confidenceIdx:C("ltm_confidence_idx").on(J.confidence),createdAtIdx:C("ltm_created_at_idx").on(J.createdAt),lastAccessedIdx:C("ltm_last_accessed_idx").on(J.lastAccessedAt),agentEntityActiveConfidenceIdx:C("ltm_agent_entity_active_conf_idx").on(J.agentId,J.entityId,J.isActive,J.confidence)})),D=PJ("long_term_memory_embeddings",{id:f("id",{length:36}).primaryKey(),memoryId:f("memory_id",{length:36}).notNull().references(()=>A.id,{onDelete:"cascade"}),dim384:v("dim_384",{dimensions:S.SMALL}),dim512:v("dim_512",{dimensions:S.MEDIUM}),dim768:v("dim_768",{dimensions:S.LARGE}),dim1024:v("dim_1024",{dimensions:S.XL}),dim1536:v("dim_1536",{dimensions:S.XXL}),dim3072:v("dim_3072",{dimensions:S.XXXL}),createdAt:JJ("created_at").default(kJ`now()`).notNull()},(J)=>[C("idx_ltm_embedding_memory_id").on(J.memoryId),mJ({name:"fk_ltm_embedding_memory",columns:[J.memoryId],foreignColumns:[A.id]}).onDelete("cascade")]);import{sql as BJ}from"drizzle-orm";import{pgTable as qJ,text as sJ,integer as n,jsonb as HJ,index as E,varchar as w,timestamp as u,vector as b,foreignKey as rJ}from"drizzle-orm/pg-core";import{VECTOR_DIMS as M}from"@elizaos/core";var k=qJ("conversation_summaries",{id:w("id",{length:36}).primaryKey(),agentId:w("agent_id",{length:36}).notNull(),entityId:w("entity_id",{length:36}).notNull(),roomId:w("room_id",{length:36}).notNull(),level:n("level").notNull().default(1),parentSummaryId:w("parent_summary_id",{length:36}),content:sJ("content").notNull(),tokenCount:n("token_count").notNull(),startTime:u("start_time").notNull(),endTime:u("end_time").notNull(),sourceCount:n("source_count").notNull(),sourceIds:HJ("source_ids").notNull().default([]),createdAt:u("created_at").default(BJ`now()`).notNull(),lastAccessedAt:u("last_accessed_at"),accessCount:n("access_count").default(0).notNull(),metadata:HJ("metadata").notNull().default({})},(J)=>({agentEntityRoomIdx:E("cs_agent_entity_room_idx").on(J.agentId,J.entityId,J.roomId),levelIdx:E("cs_level_idx").on(J.level),parentIdx:E("cs_parent_idx").on(J.parentSummaryId),timeRangeIdx:E("cs_time_range_idx").on(J.startTime,J.endTime),createdAtIdx:E("cs_created_at_idx").on(J.createdAt),lastAccessedIdx:E("cs_last_accessed_idx").on(J.lastAccessedAt),entityRoomLevelTimeIdx:E("cs_entity_room_level_time_idx").on(J.entityId,J.roomId,J.level,J.createdAt)})),R=qJ("conversation_summary_embeddings",{id:w("id",{length:36}).primaryKey(),summaryId:w("summary_id",{length:36}).notNull().references(()=>k.id,{onDelete:"cascade"}),dim384:b("dim_384",{dimensions:M.SMALL}),dim512:b("dim_512",{dimensions:M.MEDIUM}),dim768:b("dim_768",{dimensions:M.LARGE}),dim1024:b("dim_1024",{dimensions:M.XL}),dim1536:b("dim_1536",{dimensions:M.XXL}),dim3072:b("dim_3072",{dimensions:M.XXXL}),createdAt:u("created_at").default(BJ`now()`).notNull()},(J)=>[E("idx_cs_embedding_summary_id").on(J.summaryId),rJ({name:"fk_cs_embedding_summary",columns:[J.summaryId],foreignColumns:[k.id]}).onDelete("cascade")]);function i(J){return{id:J.id,agentId:J.agentId,entityId:J.entityId,roomId:J.roomId,type:J.type,content:J.content,embeddingContext:J.embeddingContext,embedding:J.embedding,confidence:J.confidence,decayRate:J.decayRate,decayFunction:J.decayFunction,createdAt:J.createdAt,lastAccessedAt:J.lastAccessedAt,accessCount:J.accessCount,isActive:J.isActive,source:J.source,metadata:J.metadata,supersedesId:J.supersedesId}}function WJ(J){return{id:J.id,agentId:J.agentId,entityId:J.entityId,roomId:J.roomId,level:J.level,parentSummaryId:J.parentSummaryId,content:J.content,embedding:J.embedding,tokenCount:J.tokenCount,startTime:J.startTime,endTime:J.endTime,sourceCount:J.sourceCount,sourceIds:J.sourceIds,createdAt:J.createdAt,lastAccessedAt:J.lastAccessedAt,accessCount:J.accessCount,metadata:J.metadata||{}}}class KJ{runtime;embeddingDimension;constructor(J,Q){this.runtime=J;this.embeddingDimension=Q}async getDb(){let J=this.runtime.adapter||this.runtime,Q=J.db;if(!Q)throw Error("Database not available");try{if(!await J.isReady()){if(h.warn("[LongTermMemoryRepository] Database not ready, attempting reconnect..."),await new Promise((Z)=>setTimeout(Z,1000)),await J.isReady()===!1)throw Error("Database connection lost and could not reconnect")}}catch(W){throw h.error("[LongTermMemoryRepository] Database health check failed:",W),Error("Database connection health check failed")}return Q}async insert(J,Q){let W=await this.getDb(),$=crypto.randomUUID(),Z=new Date,X={id:$,createdAt:Z,lastAccessedAt:null,accessCount:0,isActive:!0,embedding:Q||[],...J};return await W.transaction(async(G)=>{if(await G.insert(A).values({id:X.id,agentId:X.agentId,entityId:X.entityId,roomId:X.roomId||null,type:X.type,content:X.content,embeddingContext:X.embeddingContext,confidence:X.confidence,decayRate:X.decayRate,decayFunction:X.decayFunction,createdAt:Z,lastAccessedAt:null,accessCount:0,isActive:!0,source:X.source,metadata:X.metadata,supersedesId:X.supersedesId||null}),Q&&this.embeddingDimension){let K={id:crypto.randomUUID(),memoryId:$,createdAt:Z};K[this.embeddingDimension]=Q,await G.insert(D).values(K)}}),h.info({id:X.id,type:X.type,entityId:X.entityId,confidence:X.confidence},"Stored new long-term memory"),X}async findById(J){let W=await(await this.getDb()).select().from(A).where(H(A.id,J)).limit(1);if(W.length===0)return null;return i(W[0])}async update(J,Q,W){let $=await this.getDb(),Z={};if(Q.content!==void 0)Z.content=Q.content;if(Q.embeddingContext!==void 0)Z.embeddingContext=Q.embeddingContext;if(Q.confidence!==void 0)Z.confidence=Q.confidence;if(Q.decayRate!==void 0)Z.decayRate=Q.decayRate;if(Q.decayFunction!==void 0)Z.decayFunction=Q.decayFunction;if(Q.lastAccessedAt!==void 0)Z.lastAccessedAt=Q.lastAccessedAt;if(Q.accessCount!==void 0)Z.accessCount=Q.accessCount;if(Q.isActive!==void 0)Z.isActive=Q.isActive;if(Q.source!==void 0)Z.source=Q.source;if(Q.metadata!==void 0)Z.metadata=Q.metadata;if(Q.supersedesId!==void 0)Z.supersedesId=Q.supersedesId;await $.transaction(async(X)=>{if(await X.update(A).set(Z).where(H(A.id,J)),W&&this.embeddingDimension){let G={};G[this.embeddingDimension]=W,await X.update(D).set(G).where(H(D.memoryId,J))}}),h.info({id:J},"Updated long-term memory")}async delete(J){await(await this.getDb()).delete(A).where(H(A.id,J)),h.info({id:J},"Deleted long-term memory")}async findByEntity(J,Q,W=20,$=!1){let Z=await this.getDb(),X=[H(A.agentId,this.runtime.agentId),H(A.entityId,J)];if(!$)X.push(H(A.isActive,!0));if(Q)X.push(H(A.type,Q));return(await Z.select().from(A).where($J(...X)).orderBy(XJ(A.confidence),XJ(A.createdAt)).limit(W)).map((K)=>i(K))}async vectorSearch(J,Q,W=0.3){if(!this.embeddingDimension)return h.warn("Embedding dimension not set, skipping vector search"),[];let $=await this.getDb();try{let Z=ZJ`1 - (${eJ(D[this.embeddingDimension],Q)})`,X=[H(A.agentId,this.runtime.agentId),H(A.entityId,J.entityId),ZJ`${D[this.embeddingDimension]} IS NOT NULL`,LJ(Z,W)];if(J.minConfidence)X.push(LJ(A.confidence,J.minConfidence));if(!J.includeInactive)X.push(H(A.isActive,!0));if(J.type)X.push(H(A.type,J.type));if(J.roomId)X.push(JQ(H(A.roomId,J.roomId),QQ(A.roomId)));return(await $.select({memory:A,embedding:D[this.embeddingDimension],similarity:Z}).from(A).innerJoin(D,H(D.memoryId,A.id)).where($J(...X)).orderBy(XJ(Z)).limit(J.limit||20)).map((K)=>({...i(K.memory),embedding:K.embedding,relevanceScore:K.similarity,activationScore:0,finalScore:0}))}catch(Z){return h.error("Failed to execute vector search:",JSON.stringify(Z)),[]}}async fetchAllActive(){return(await(await this.getDb()).select().from(A).where($J(H(A.agentId,this.runtime.agentId),H(A.isActive,!0)))).map((W)=>({id:W.id,content:W.content,embeddingContext:W.embeddingContext}))}async updateAccessMetadata(J){if(J.length===0)return;let Q=await this.getDb(),W=new Date;try{for(let $ of J)await Q.update(A).set({lastAccessedAt:W,accessCount:ZJ`${A.accessCount} + 1`}).where(H(A.id,$));h.debug({count:J.length},"Updated access metadata")}catch($){h.error({error:$},"Failed to update access metadata")}}}import{logger as x}from"@elizaos/core";import{eq as I,and as zJ,desc as DJ,sql as GJ,cosineDistance as WQ}from"drizzle-orm";class YJ{runtime;embeddingDimension;constructor(J,Q){this.runtime=J;this.embeddingDimension=Q}async getDb(){let J=this.runtime.adapter||this.runtime,Q=J.db;if(!Q)throw Error("Database not available");try{if(!await J.isReady()){if(x.warn("[ConversationSummaryRepository] Database not ready, attempting reconnect..."),await new Promise((Z)=>setTimeout(Z,1000)),await J.isReady()===!1)throw Error("Database connection lost and could not reconnect")}}catch(W){throw x.error("[ConversationSummaryRepository] Database health check failed:",W),Error("Database connection health check failed")}return Q}async insert(J,Q){let W=await this.getDb(),$=crypto.randomUUID(),Z=new Date,X={id:$,createdAt:Z,lastAccessedAt:null,accessCount:0,embedding:Q||[],...J};return await W.transaction(async(G)=>{if(await G.insert(k).values({id:X.id,agentId:X.agentId,entityId:X.entityId,roomId:X.roomId,level:X.level,parentSummaryId:X.parentSummaryId||null,content:X.content,tokenCount:X.tokenCount,startTime:X.startTime,endTime:X.endTime,sourceCount:X.sourceCount,sourceIds:X.sourceIds,createdAt:Z,lastAccessedAt:null,accessCount:0,metadata:X.metadata}),Q&&this.embeddingDimension){let K={id:crypto.randomUUID(),summaryId:$,createdAt:Z};K[this.embeddingDimension]=Q,await G.insert(R).values(K)}}),x.info({id:X.id,level:X.level,tokenCount:X.tokenCount,sourceCount:X.sourceCount},"Stored conversation summary"),X}async findByLevel(J,Q){return(await(await this.getDb()).select().from(k).where(zJ(I(k.agentId,this.runtime.agentId),I(k.roomId,J),I(k.level,Q))).orderBy(DJ(k.createdAt))).map((Z)=>WJ(Z))}async vectorSearch(J,Q,W,$=5){if(!this.embeddingDimension)return x.warn("Embedding dimension not set, skipping summary search"),[];let Z=await this.getDb();try{let X=GJ`1 - (${WQ(R[this.embeddingDimension],W)})`;return(await Z.select({summary:k,embedding:R[this.embeddingDimension],similarity:X}).from(k).innerJoin(R,I(R.summaryId,k.id)).where(zJ(I(k.agentId,this.runtime.agentId),I(k.entityId,J),I(k.roomId,Q),GJ`${R[this.embeddingDimension]} IS NOT NULL`)).orderBy(DJ(X)).limit($*2)).map((K)=>({...WJ(K.summary),embedding:K.embedding}))}catch(X){return x.error("Failed to search summaries:",JSON.stringify(X)),[]}}async updateAccessMetadata(J){if(J.length===0)return;let Q=await this.getDb(),W=new Date;try{for(let $ of J)await Q.update(k).set({lastAccessedAt:W,accessCount:GJ`${k.accessCount} + 1`}).where(I(k.id,$));x.debug({count:J.length},"Updated summary access metadata")}catch($){x.error({error:$},"Failed to update summary access metadata")}}}import{ModelType as $Q,logger as XQ}from"@elizaos/core";async function p(J,Q){try{return await J.useModel($Q.TEXT_EMBEDDING,Q)}catch(W){return XQ.error({error:W},"Failed to generate embedding"),Array(1536).fill(0)}}function y(J){return J.map((Q)=>Number.isFinite(Q)?Number(Q.toFixed(6)):0)}function ZQ(J,Q,W){switch(J){case"EXPONENTIAL":return Math.exp(-Q*W);case"LINEAR":return Math.max(0,1-Q*W);case"NONE":return 1;default:return 1}}function KQ(J){return 1+Math.log(1+J)*0.1}function CJ(J){let Q=Date.now();return J.map((W)=>{let $=W.lastAccessedAt?.getTime()||W.createdAt.getTime(),Z=(Q-$)/86400000,X=ZQ(W.decayFunction,W.decayRate,Z),G=KQ(W.accessCount),K=W.confidence*X*G,Y=W.relevanceScore*K;return{...W,activationScore:K,finalScore:Y}})}function RJ(J,Q){let W=new Map;for(let $ of J)W.set($.id,$);for(let $ of Q)if(W.has($.id)){let Z=W.get($.id);Z.relevanceScore=(Z.relevanceScore+$.relevanceScore)/2}else W.set($.id,$);return Array.from(W.values())}function hJ(J){if(J.length===0)return"";let Q=new Map;for(let $ of J){if(!Q.has($.type))Q.set($.type,[]);Q.get($.type).push($)}let W=[];if(Q.has("SEMANTIC")){let Z=Q.get("SEMANTIC").map((X)=>`- ${X.content} (confidence: ${X.confidence.toFixed(2)})`).join(`
|
|
2
|
-
`);
|
|
3
|
-
${
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
1.
|
|
50
|
-
2.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
- "
|
|
83
|
-
- "
|
|
84
|
-
- "
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
- "
|
|
95
|
-
- "
|
|
96
|
-
- "
|
|
97
|
-
- "
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
- "
|
|
111
|
-
- "
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
- TAGS: Comma-separated list of key topics (lowercase)
|
|
207
|
-
- CONTENT: The narrative summary text (must be a single line, no newlines)
|
|
208
|
-
`;function NJ(J,Q){return`${Q?`
|
|
209
|
-
# PREVIOUS SUMMARY
|
|
210
|
-
<previous_summary>
|
|
211
|
-
${Q}
|
|
212
|
-
</previous_summary>
|
|
213
|
-
|
|
214
|
-
**Note**: The above is what was discussed before. Ensure your new summary:
|
|
215
|
-
- Does not duplicate information already captured in the previous summary
|
|
216
|
-
- Focuses only on the NEW conversation below
|
|
217
|
-
- Maintains continuity (e.g., "Conversation continued with...")
|
|
218
|
-
`:""}
|
|
219
|
-
# INPUT DATA
|
|
220
|
-
<messages>
|
|
221
|
-
${J}
|
|
222
|
-
</messages>
|
|
223
|
-
|
|
224
|
-
# FEW-SHOT EXAMPLES
|
|
225
|
-
|
|
226
|
-
<example_1_task_oriented>
|
|
227
|
-
Input:
|
|
228
|
-
[Message 1] User: I need help deploying my React app to Vercel
|
|
229
|
-
[Message 2] Agent: Sure! First, make sure you have the Vercel CLI installed...
|
|
230
|
-
[Message 3] User: Done. What's next?
|
|
231
|
-
[Message 4] Agent: Run 'vercel' in your project directory...
|
|
232
|
-
[Message 5] User: It worked! Thanks!
|
|
233
|
-
|
|
234
|
-
Output:
|
|
235
|
-
[ANALYSIS]
|
|
236
|
-
- Topic: React app deployment to Vercel.
|
|
237
|
-
- Action: CLI installation and deployment.
|
|
238
|
-
- Outcome: Success.
|
|
239
|
-
- Draft: User requested help... -> React app deployment...
|
|
240
|
-
[RESULT]
|
|
241
|
-
SUMM|deployment,react,vercel,cli|React app deployment to Vercel was successfully completed following CLI installation and configuration guidance.
|
|
242
|
-
</example_1_task_oriented>
|
|
243
|
-
|
|
244
|
-
<example_2_identity_revelation>
|
|
245
|
-
Input:
|
|
246
|
-
[Message 1] User: I'm working on a side project in my spare time
|
|
247
|
-
[Message 2] Agent: That's great! What kind of project?
|
|
248
|
-
[Message 3] User: A machine learning app for analyzing stock data. I'm a data scientist by profession.
|
|
249
|
-
[Message 4] Agent: Interesting! Are you using Python?
|
|
250
|
-
[Message 5] User: Yeah, mostly PyTorch and pandas.
|
|
251
|
-
|
|
252
|
-
Output:
|
|
253
|
-
[ANALYSIS]
|
|
254
|
-
- Identity: Data scientist.
|
|
255
|
-
- Project: Stock data analysis (ML).
|
|
256
|
-
- Tech Stack: Python, PyTorch, pandas.
|
|
257
|
-
- Draft: User discussed... -> Stock data analysis project...
|
|
258
|
-
[RESULT]
|
|
259
|
-
SUMM|machine learning,data science,python,stocks|Stock data analysis project (Machine Learning) utilizing Python (PyTorch, pandas) is in development by a data scientist.
|
|
260
|
-
</example_2_identity_revelation>
|
|
261
|
-
|
|
262
|
-
<example_3_chitchat>
|
|
263
|
-
Input:
|
|
264
|
-
[Message 1] User: Hey, how's it going?
|
|
265
|
-
[Message 2] Agent: I'm doing well, thanks for asking! How can I help you today?
|
|
266
|
-
[Message 3] User: Just saying hi
|
|
267
|
-
[Message 4] Agent: Nice to hear from you!
|
|
268
|
-
|
|
269
|
-
Output:
|
|
270
|
-
[ANALYSIS]
|
|
271
|
-
- Content: Greetings only.
|
|
272
|
-
- Substance: None.
|
|
273
|
-
[RESULT]
|
|
274
|
-
SUMM|greeting,casual|Casual greeting exchanged; no substantive topics discussed.
|
|
275
|
-
</example_3_chitchat>
|
|
276
|
-
|
|
277
|
-
Begin the [ANALYSIS] phase now.`}var xJ=`You are "Chronos", a Meta-Summarization Agent.
|
|
278
|
-
Your task is to compress multiple conversation summaries into a single, higher-level summary.
|
|
279
|
-
|
|
280
|
-
# MISSION
|
|
281
|
-
Transform a list of conversation summaries into one concise meta-summary that captures:
|
|
282
|
-
1. **Overarching themes** across the summaries
|
|
283
|
-
2. **Key events or milestones** (e.g., "User onboarded", "Project completed")
|
|
284
|
-
3. **Evolving context** (e.g., "User's preferences shifted from X to Y")
|
|
285
|
-
|
|
286
|
-
# RULES
|
|
287
|
-
- **Subject-First**: Focus on the topic, not the user.
|
|
288
|
-
- **Abstract Higher**: Don't repeat specifics from each summary. Find the pattern.
|
|
289
|
-
- **Chronological Flow**: Maintain temporal order if it matters.
|
|
290
|
-
- **Preserve Critical Facts**: If summaries mention important identity or preferences, keep them.
|
|
291
|
-
|
|
292
|
-
# OUTPUT FORMAT
|
|
293
|
-
Phase 1: [ANALYSIS]
|
|
294
|
-
- Identify themes and milestones.
|
|
295
|
-
- Combine related points.
|
|
296
|
-
- Refine to subject-first.
|
|
297
|
-
|
|
298
|
-
Phase 2: [RESULT]
|
|
299
|
-
Format: \`SUMM|TAGS|CONTENT\`
|
|
300
|
-
- TAGS: Comma-separated list of key topics (lowercase)
|
|
301
|
-
- CONTENT: The meta-summary text (must be a single line, no newlines)
|
|
302
|
-
`;function TJ(J){return`# INPUT DATA
|
|
303
|
-
<summaries>
|
|
304
|
-
${J}
|
|
305
|
-
</summaries>
|
|
306
|
-
|
|
307
|
-
# FEW-SHOT EXAMPLES
|
|
308
|
-
|
|
309
|
-
<example_1_meta_summary>
|
|
310
|
-
Input:
|
|
311
|
-
<summary1>Stock data analysis project (Machine Learning) utilizing Python (PyTorch, pandas) is in development by a data scientist.</summary1>
|
|
312
|
-
<summary2>Flask and Vercel were suggested for ML model deployment to a web app.</summary2>
|
|
313
|
-
<summary3>CORS configuration issues were resolved, leading to successful deployment.</summary3>
|
|
314
|
-
|
|
315
|
-
Output:
|
|
316
|
-
[ANALYSIS]
|
|
317
|
-
- Theme: ML App Development & Deployment.
|
|
318
|
-
- Flow: Development -> Stack Choice -> Deployment -> Troubleshooting -> Success.
|
|
319
|
-
- Draft: User, a data scientist... -> Machine learning stock analysis app...
|
|
320
|
-
[RESULT]
|
|
321
|
-
SUMM|data science,machine learning,python,deployment,flask,vercel|Machine learning stock analysis app (Python/PyTorch) was developed and successfully deployed to Vercel using Flask after resolving CORS configuration issues.
|
|
322
|
-
</example_1_meta_summary>
|
|
323
|
-
|
|
324
|
-
Begin the [ANALYSIS] phase now.`}function UJ(J){return Math.ceil(J.length/4)}var g=new Map,SJ={name:"SUMMARIZATION",similes:["HIERARCHICAL_SUMMARIZATION","EPISODIC_COMPRESSION","CONVERSATION_SUMMARY"],description:"Hierarchical conversation summarization that compresses message history into multi-level narrative summaries for token-efficient long-term episodic memory.",validate:async(J,Q)=>{let W=J.getService("memory");if(!W)return!1;let $=W.getConfig();if(!$.summarization?.enabled)return B.debug("Summarization is not enabled"),!1;if(!g.has(Q.roomId))g.set(Q.roomId,0);let Z=g.get(Q.roomId)+1;g.set(Q.roomId,Z);let X=$.summarization.messagesPerSummary;B.debug({currentCount:Z,threshold:X,messageId:Q.id,entityId:Q.entityId,roomId:Q.roomId},"Message counted for summarization (user + agent messages)");let G=Z>=X;if(G)B.info({roomId:Q.roomId,messageCount:Z,threshold:X},"Summarization threshold reached (Level 1) - triggering summarization");return G},handler:async(J,Q)=>{let W=J.getService("memory");if(!W){B.warn("MemoryService not available for summarization");return}if(!W.getConfig().summarization?.enabled)return;let Z=g.get(Q.roomId)||0;if(Z===0)return;B.info({roomId:Q.roomId,messageCount:Z},"Starting Level 1 summarization - pulling messages from database");try{let X=await W.getMostRecentLevel1Summary(Q.roomId,Q.entityId),G=await OQ(J,Q.roomId,X?.endTime);if(G.length===0){B.warn({roomId:Q.roomId},"No messages found for summarization");return}let K=await VQ(J,W,G,Q.roomId,X);if(K)B.info({summaryId:K.id,tokenCount:K.tokenCount,messageCount:G.length,startTime:K.startTime,endTime:K.endTime},"Created Level 1 summary from database messages"),g.set(Q.roomId,0),await MJ(J,W,K.roomId,K.level)}catch(X){B.error({error:X,roomId:Q.roomId},"Failed to create summary")}},examples:[]};async function OQ(J,Q,W){let $=await J.getMemories({tableName:"messages",roomId:Q,count:1000,unique:!1}),Z=$.filter((G)=>!(G.content?.type==="action_result"&&G.metadata?.type==="action_result")),X=Z;if(W)X=Z.filter((G)=>{if(!G.createdAt)return!1;return new Date(G.createdAt)>W});return X.sort((G,K)=>(G.createdAt||0)-(K.createdAt||0)),B.debug({roomId:Q,totalMessages:$.length,dialogueMessages:Z.length,filteredMessages:X.length,lastSummaryEndTime:W?.toISOString()},"Fetched messages for summarization"),X}function bJ(J){try{let Q=typeof J==="string"?J:JSON.stringify(J),W=Q.match(/\[ANALYSIS\](.*?)(?:\[RESULT\]|$)/s),$=W?W[1].trim():"",Z=Q.match(/\[RESULT\](.*?)$/s),X=Z?Z[1].trim():"",G="",K="";if(X){let Y=X.split(`
|
|
325
|
-
`);for(let j of Y){let N=j.trim();if(N.startsWith("SUMM|")){let U=N.split("|");if(U.length>=3){K=U[1].trim(),G=U.slice(2).join("|").trim();break}}}}return{summary:G,keyTopics:K,reasoningTrace:$}}catch(Q){return B.error({error:Q},"Failed to parse summarization response"),{summary:"",keyTopics:"",reasoningTrace:""}}}async function VQ(J,Q,W,$,Z){let X=W.map((Y,j)=>{let N=typeof Y.content==="string"?Y.content:Y.content.text||"",U=Y.entityId===J.agentId?"Agent":"User";return`[${Y.createdAt?new Date(Y.createdAt).toISOString():"Unknown time"}] ${U}: ${N}`}).join(`
|
|
326
|
-
`),G;if(Z)G=NJ(X,Z.content);else G=NJ(X);let K=J.character.system;try{J.character.system=wJ,B.debug("Calling LLM for Level 1 summarization with timestamped conversation log");let Y=await J.useModel(vJ.TEXT_LARGE,{prompt:G,temperature:0.3});J.character.system=K;let{summary:j,keyTopics:N,reasoningTrace:U}=bJ(Y);if(!j)return B.warn({reasoningTrace:U},"No summary extracted from LLM response"),null;let _=UJ(j),O=W[0].createdAt?new Date(W[0].createdAt):new Date,P=W[W.length-1].createdAt?new Date(W[W.length-1].createdAt):new Date,q={agentId:J.agentId,entityId:W[0].entityId,roomId:$,level:1,parentSummaryId:void 0,content:j,tokenCount:_,startTime:O,endTime:P,sourceCount:W.length,sourceIds:W.map((V)=>V.id),metadata:{keyTopics:N,hasPreviousSummary:!!Z}};return await Q.storeSummary(q)}catch(Y){return B.error({error:Y},"Failed to call LLM for Level 1 summarization"),J.character.system=K,null}}async function MJ(J,Q,W,$){let Z=Q.getConfig();if(!Z.summarization)return;if($>=Z.summarization.maxDepth){B.debug({currentLevel:$,maxDepth:Z.summarization.maxDepth},"Max depth reached");return}let X=await Q.getSummariesByLevel(W,$),G=Z.summarization.summariesPerLevel;if(X.length<G)return;if(B.info({level:$,count:X.length,nextLevel:$+1},`Triggering Level ${$+1} summarization`),await kQ(J,Q,X,W,$+1))await MJ(J,Q,W,$+1)}async function kQ(J,Q,W,$,Z){let X=W.map((Y,j)=>`<summary${j+1}>${Y.content}</summary${j+1}>`).join(`
|
|
327
|
-
`),G=TJ(X),K=J.character.system;try{J.character.system=xJ;let Y=await J.useModel(vJ.TEXT_LARGE,{prompt:G,temperature:0.3});J.character.system=K;let{summary:j,keyTopics:N,reasoningTrace:U}=bJ(Y);if(!j)return B.warn({reasoningTrace:U},"No higher-level summary extracted from LLM response"),null;let _=UJ(j),O=new Date(Math.min(...W.map((V)=>V.startTime.getTime()))),P=new Date(Math.max(...W.map((V)=>V.endTime.getTime()))),q={agentId:J.agentId,entityId:W[0].entityId,roomId:$,level:Z,parentSummaryId:void 0,content:j,tokenCount:_,startTime:O,endTime:P,sourceCount:W.length,sourceIds:W.map((V)=>V.id),metadata:{keyTopics:N,compressedSummaries:W.length}};return await Q.storeSummary(q)}catch(Y){return B.error({error:Y,level:Z},"Failed to create higher-level summary"),J.character.system=K,null}}import{logger as a,addHeader as FJ}from"@elizaos/core";var pJ={name:"LONG_TERM_MEMORY",description:"User knowledge and facts (semantic + procedural memory)",position:80,get:async(J,Q,W)=>{try{let $=J.getService("memory");if(!$)return a.warn("Memory service not available"),{data:{},values:{},text:""};let{entityId:Z,roomId:X}=Q,G=typeof Q.content==="string"?Q.content:Q.content.text||JSON.stringify(Q.content);a.debug({entityId:Z,roomId:X,queryLength:G.length},"Retrieving unified memories");let K=$.getConfig(),[Y,j,N]=await Promise.all([$.searchLongTermMemories({entityId:Z,query:G,roomId:X,type:"SEMANTIC",limit:K.retrievalLimit,minConfidence:K.minConfidence,similarityThreshold:0.15}),$.searchLongTermMemories({entityId:Z,query:G,roomId:X,type:"PROCEDURAL",limit:Math.floor(K.retrievalLimit/2),minConfidence:K.minConfidence,similarityThreshold:0.15}),$.searchLongTermMemories({entityId:Z,query:G,roomId:X,type:"EPISODIC",limit:K.retrievalLimit,minConfidence:K.minConfidence,similarityThreshold:0.15})]),U=[];if(Y.length>0){let V=Y.map((z)=>`- ${z.content} (confidence: ${z.confidence.toFixed(2)}, strength: ${z.activationScore.toFixed(2)})`).join(`
|
|
328
|
-
`);U.push(FJ("## Semantic Knowledge (Facts)",V))}if(j.length>0){let V=j.map((z)=>`- ${z.content}`).join(`
|
|
329
|
-
`);U.push(FJ("## Procedural Knowledge (Skills & Patterns)",V))}if(N.length>0){let V=N.map((z)=>`- ${z.content} (occurred: ${z.createdAt?new Date(z.createdAt).toLocaleDateString():"Unknown"})`).join(`
|
|
330
|
-
`);U.push(FJ("## Significant Past Events",V))}let _=U.join(`
|
|
331
|
-
|
|
332
|
-
`),O={semanticMemories:Y,proceduralMemories:j,episodicMemories:N,config:{retrievalLimit:K.retrievalLimit,tokenBudget:K.tokenBudget}},P={longTermMemories:_},q=_;return a.info({semanticCount:Y.length,proceduralCount:j.length,episodicCount:N.length},"Retrieved long-term memory facts"),{data:O,values:P,text:q}}catch($){return a.error({error:$},"Failed to retrieve long-term memories"),{data:{},values:{longTermMemories:""},text:""}}}};import{addHeader as m,ChannelType as s,formatMessages as PQ,formatPosts as HQ,getEntityDetails as BQ,logger as T}from"@elizaos/core";var yJ=(J)=>({overlapUserMessageCount:parseInt(J.getSetting("CONTEXT_OVERLAP_USER_MESSAGES")||"2",10)});async function qQ(J,Q){let[W,$,Z]=await Promise.all([BQ({runtime:J,roomId:Q}),J.getRoom(Q),J.getMemories({tableName:"messages",roomId:Q,count:100,unique:!1})]);return{entities:W,room:$,allMessages:Z}}function LQ(J){let Q=J.filter((W)=>!(W.content?.type==="action_result"&&W.metadata?.type==="action_result"));return Q.sort((W,$)=>(W.createdAt||0)-($.createdAt||0)),Q}async function zQ(J,Q,W,$){let Z="",X=-1,G=J.getService("memory");if(!G?.searchSummaries)return{compressedHistoryText:Z,lastSummarizedIndex:X};try{let K=await G.searchSummaries({entityId:Q.entityId,roomId:Q.roomId,query:typeof Q.content==="string"?Q.content:Q.content.text||"",limit:3,tokenBudget:500});if(K.length===0)return{compressedHistoryText:Z,lastSummarizedIndex:X};X=DQ(K,W);let Y=K.map((N)=>{return`**[${N.level===1?"Recent Session":`Overview (L${N.level})`}]** ${N.content}`}).join(`
|
|
333
|
-
|
|
334
|
-
`),j=`# Conversation History (Compressed)
|
|
335
|
-
**Session Started:** ${AJ($)}`;Z=m(j,Y),T.debug({summaryCount:K.length,totalTokens:K.reduce((N,U)=>N+U.tokenCount,0),lastSummarizedIndex:X},"Using hierarchical summaries for compressed history")}catch(K){T.warn({error:K},"Failed to retrieve summaries")}return{compressedHistoryText:Z,lastSummarizedIndex:X}}function DQ(J,Q){let W=J.filter((Z)=>Z.level===1);if(W.length===0)return-1;let $=new Set;W.forEach((Z)=>{Z.sourceIds.forEach((X)=>$.add(X))});for(let Z=Q.length-1;Z>=0;Z--)if($.has(Q[Z].id))return T.debug({lastSummarizedIndex:Z,totalMessages:Q.length,summarizedCount:$.size},"Determined last summarized message index"),Z;return-1}function CQ(J,Q,W,$,Z){let X;if(W>=0&&$){let G=Q.slice(0,W+1),Y=G.filter((U)=>U.entityId!==J.agentId).slice(-Z),j=Q.slice(W+1),N=W+1;if(Y.length>0){let U=Y[0].id,_=Q.findIndex((O)=>O.id===U);if(_>=0)N=_}X=Q.slice(N),T.debug({lastSummarizedIndex:W,summarizedMessageCount:G.length,overlapStartIndex:N,overlapSize:W+1-N,newUnsummarizedCount:j.length,bufferSize:X.length,totalDialogueMessages:Q.length,overlapUserMessageCount:Z},`Dynamic buffer: [overlap: last ${Z} user msgs from summary] + [all new unsummarized messages]`)}else X=Q,T.debug({bufferSize:X.length,totalMessages:Q.length},"Using full conversation: no summaries yet");return{bufferMessages:X,lastSummarizedIndex:W}}function AJ(J){return new Date(J).toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1})}function RQ(J){return J.replace(/\s*\[[\w\-]+\]/g,"").replace(/\s*\([^)]*'s internal thought:[^)]*\)/gi,"").split(`
|
|
336
|
-
`).map((Q)=>Q.trim()).join(`
|
|
337
|
-
`).replace(/\n{3,}/g,`
|
|
338
|
-
|
|
339
|
-
`)}async function hQ(J,Q,W,$){let Z=W?.type?W.type===s.FEED||W.type===s.THREAD:!1,[X,G]=await Promise.all([PQ({messages:J,entities:Q}),HQ({messages:J,entities:Q,conversationHeader:!1})]),K=(Z?G:X)||"";K=RQ(K);let Y=J.length>0?J[0].createdAt:null,j=J.length>0?J[J.length-1].createdAt:null,N=`# Recent Messages (Last ${J.length})`;if(Y&&j)N+=`
|
|
340
|
-
**Time Range:** ${AJ(Y)} - ${AJ(j)}`;return K?m(N,K):""}function EQ(J,Q){let W=J.metadata,$=Q.find((Y)=>Y.id===J.entityId)?.names[0]||W?.entityName||"Unknown User",Z=J.content.text,X=!!Z?.trim(),G=X?m("# Current Message",`**From ${$}:** ${Z}`):"",K=X?m("# Response Focus",`Reply to **${$}**'s current message above. Stay relevant to their question. Don't repeat previous responses unless asked again.`):"";return{receivedMessageHeader:G,focusHeader:K}}function IQ(J,Q,W,$){return[J,Q,W,$].filter(Boolean).join(`
|
|
341
|
-
|
|
342
|
-
`)}var cJ={name:"RECENT_CONVERSATION_SUMMARY",description:"Intelligent context management combining recent messages with hierarchical summaries for optimal token efficiency",position:100,get:async(J,Q)=>{try{let{roomId:W}=Q,$=yJ(J),{entities:Z,room:X,allMessages:G}=await qQ(J,W),K=LQ(G),Y=K.length>0?K[0].createdAt||Date.now():Date.now(),{compressedHistoryText:j,lastSummarizedIndex:N}=await zQ(J,Q,K,Y),U=!!j,{bufferMessages:_}=CQ(J,K,N,U,$.overlapUserMessageCount),O=await hQ(_,Z,X,Y),{receivedMessageHeader:P,focusHeader:q}=EQ(Q,Z),V=IQ(j,O,P,q),z={dialogueMessages:_,messageCount:K.length,lastSummarizedIndex:N,config:$},r=X?.type?X.type===s.FEED||X.type===s.THREAD:!1,dJ={compressedHistory:j,recentMessages:O,receivedMessage:P,focusInstruction:q,recentPosts:r?O:""};return T.info({messageCount:K.length,bufferSize:_.length,hasSummaries:U,lastSummarizedIndex:N,estimatedTokens:Math.ceil(V.length/4),overlapUserMessageCount:$.overlapUserMessageCount},"Recent context assembled"),{data:z,values:dJ,text:V}}catch(W){return T.error({error:W},"Error in recentContextProvider"),{data:{dialogueMessages:[],messageCount:0,lastSummarizedIndex:-1,config:yJ(J)},values:{compressedHistory:"",recentMessages:"",receivedMessage:"",focusInstruction:"",recentPosts:""},text:"Error retrieving context."}}}};import{addHeader as fQ,logger as lJ}from"@elizaos/core";var gJ=(J)=>({limit:parseInt(J.getSetting("CONTEXT_ACTION_RESULTS_LIMIT")||"3",10)});function wQ(J,Q){if(J.length===0)return"";let W=new Map;for(let Z of J){let X=String(Z.content?.runId||"unknown");if(!W.has(X))W.set(X,[]);W.get(X).push(Z)}let $=Array.from(W.entries()).slice(-Q).map(([Z,X])=>{let G=X.sort((j,N)=>(j.createdAt||0)-(N.createdAt||0)),K=G[0]?.content?.planThought||"",Y=G.map((j)=>{let N=j.content?.actionName||"Unknown",U=j.content?.actionStatus||"unknown",_=j.content?.planStep||"",O=j.content?.text||"",P=j.content?.error||"",q=` - ${N} (${U})`;if(_)q+=` [${_}]`;if(P)q+=`: Error - ${P}`;else if(O&&O!==`Executed action: ${N}`)q+=`: ${O}`;return q}).join(`
|
|
343
|
-
`);return`**Action Run ${Z.slice(0,8)}**${K?` - "${K}"`:""}
|
|
344
|
-
${Y}`}).join(`
|
|
345
|
-
|
|
346
|
-
`);return $?fQ("# Recent Action Executions",$):""}var uJ={name:"ACTION_RESULTS",description:"Recent action executions with their outcomes (tool memory)",position:101,get:async(J,Q)=>{try{let{roomId:W}=Q,$=gJ(J),X=(await J.getMemories({tableName:"messages",roomId:W,count:50,unique:!1})).filter((K)=>K.content?.type==="action_result"&&K.metadata?.type==="action_result");X.sort((K,Y)=>(K.createdAt||0)-(Y.createdAt||0));let G=wQ(X,$.limit);return lJ.debug({actionResultCount:X.length,limit:$.limit},"Action results provider assembled"),{data:{actionResults:X,config:$},values:{recentActionResults:G},text:G}}catch(W){return lJ.error({error:W},"Error in actionResultsProvider"),{data:{actionResults:[],config:gJ(J)},values:{recentActionResults:""},text:""}}}};var xQ={name:"memory",description:"State-of-the-art cognitive memory system with episodic, semantic, and procedural memory, featuring hybrid retrieval (Vector + BM25 + Graph), exponential decay, contextual embeddings, and contradiction detection",services:[c],evaluators:[fJ,SJ],providers:[pJ,cJ,uJ],schema:QJ},TQ=xQ;export{jJ as trimToTokenBudget,cJ as recentContextProvider,RJ as mergeSearchResults,xQ as memoryPlugin,i as mapDbRowToLongTermMemory,WJ as mapDbRowToConversationSummary,pJ as longTermMemoryProvider,D as longTermMemoryEmbeddings,A as longTermMemories,p as generateEmbedding,jW as formatTokenCount,hJ as formatMemoriesForContext,UJ as estimateTokensInSummary,YW as estimateTokenCountForArray,t as estimateTokenCount,TQ as default,R as conversationSummaryEmbeddings,k as conversationSummaries,y as cleanEmbedding,ZQ as calculateDecayFactor,KQ as calculateAccessBoost,NJ as buildLevel1SummaryPrompt,TJ as buildHigherLevelSummaryPrompt,IJ as buildExtractionPrompt,PW as buildContradictionPrompt,CJ as applyDecayScoring,uJ as actionResultsProvider,wJ as SUMMARIZATION_SYSTEM_PROMPT,_J as MemoryType,c as MemoryService,e as MEMORY_DIMENSION_MAP,KJ as LongTermMemoryRepository,xJ as HIGHER_LEVEL_SUMMARIZATION_SYSTEM_PROMPT,tJ as DecayFunction,YJ as ConversationSummaryRepository,EJ as CONSOLIDATION_SYSTEM_PROMPT};
|
|
347
|
-
|
|
348
|
-
//# debugId=9601D2A9C282652E64756E2164756E21
|
|
1
|
+
var _A=Object.defineProperty;var $A=(B,Q)=>{for(var J in Q)_A(B,J,{get:Q[J],enumerable:!0,configurable:!0,set:(K)=>Q[J]=()=>K})};import{Service as OA,logger as H}from"@elizaos/core";import{eq as X,and as R,desc as f,sql as AA,cosineDistance as RA,gte as kA}from"drizzle-orm";var d={};$A(d,{sessionSummaries:()=>j,memoryAccessLogs:()=>e,longTermMemories:()=>$});import{sql as s}from"drizzle-orm";import{pgTable as UA,text as p,integer as VA,jsonb as GA,real as m,index as C,varchar as w,timestamp as y}from"drizzle-orm/pg-core";var $=UA("long_term_memories",{id:w("id",{length:36}).primaryKey(),agentId:w("agent_id",{length:36}).notNull(),entityId:w("entity_id",{length:36}).notNull(),category:p("category").notNull(),content:p("content").notNull(),metadata:GA("metadata"),embedding:m("embedding").array(),confidence:m("confidence").default(1),source:p("source"),createdAt:y("created_at").default(s`now()`).notNull(),updatedAt:y("updated_at").default(s`now()`).notNull(),lastAccessedAt:y("last_accessed_at"),accessCount:VA("access_count").default(0)},(B)=>({agentEntityIdx:C("long_term_memories_agent_entity_idx").on(B.agentId,B.entityId),categoryIdx:C("long_term_memories_category_idx").on(B.category),confidenceIdx:C("long_term_memories_confidence_idx").on(B.confidence),createdAtIdx:C("long_term_memories_created_at_idx").on(B.createdAt)}));import{sql as o}from"drizzle-orm";import{pgTable as XA,text as jA,integer as t,jsonb as r,real as HA,index as c,varchar as T,timestamp as v}from"drizzle-orm/pg-core";var j=XA("session_summaries",{id:T("id",{length:36}).primaryKey(),agentId:T("agent_id",{length:36}).notNull(),roomId:T("room_id",{length:36}).notNull(),entityId:T("entity_id",{length:36}),summary:jA("summary").notNull(),messageCount:t("message_count").notNull(),lastMessageOffset:t("last_message_offset").notNull().default(0),startTime:v("start_time").notNull(),endTime:v("end_time").notNull(),topics:r("topics"),metadata:r("metadata"),embedding:HA("embedding").array(),createdAt:v("created_at").default(o`now()`).notNull(),updatedAt:v("updated_at").default(o`now()`).notNull()},(B)=>({agentRoomIdx:c("session_summaries_agent_room_idx").on(B.agentId,B.roomId),entityIdx:c("session_summaries_entity_idx").on(B.entityId),startTimeIdx:c("session_summaries_start_time_idx").on(B.startTime)}));import{sql as WA}from"drizzle-orm";import{pgTable as FA,text as NA,integer as EA,real as LA,index as l,varchar as h,timestamp as PA}from"drizzle-orm/pg-core";var e=FA("memory_access_logs",{id:h("id",{length:36}).primaryKey(),agentId:h("agent_id",{length:36}).notNull(),memoryId:h("memory_id",{length:36}).notNull(),memoryType:NA("memory_type").notNull(),accessedAt:PA("accessed_at").default(WA`now()`).notNull(),roomId:h("room_id",{length:36}),relevanceScore:LA("relevance_score"),wasUseful:EA("was_useful")},(B)=>({memoryIdx:l("memory_access_logs_memory_idx").on(B.memoryId),agentIdx:l("memory_access_logs_agent_idx").on(B.agentId),accessedAtIdx:l("memory_access_logs_accessed_at_idx").on(B.accessedAt)}));class D extends OA{static serviceType="memory";sessionMessageCounts;memoryConfig;lastExtractionCheckpoints;capabilityDescription="Advanced memory management with short-term summarization and long-term persistent facts";constructor(B){super(B);this.sessionMessageCounts=new Map,this.lastExtractionCheckpoints=new Map,this.memoryConfig={shortTermSummarizationThreshold:16,shortTermRetainRecent:6,shortTermSummarizationInterval:10,longTermExtractionEnabled:!0,longTermVectorSearchEnabled:!1,longTermConfidenceThreshold:0.85,longTermExtractionThreshold:30,longTermExtractionInterval:10,summaryModelType:"TEXT_LARGE",summaryMaxTokens:2500,summaryMaxNewMessages:20}}static async start(B){let Q=new D(B);return await Q.initialize(B),Q}async stop(){H.info("MemoryService stopped")}async initialize(B){this.runtime=B;let Q=B.getSetting("MEMORY_SUMMARIZATION_THRESHOLD");if(Q)this.memoryConfig.shortTermSummarizationThreshold=parseInt(Q,10);let J=B.getSetting("MEMORY_RETAIN_RECENT");if(J)this.memoryConfig.shortTermRetainRecent=parseInt(J,10);let K=B.getSetting("MEMORY_SUMMARIZATION_INTERVAL");if(K)this.memoryConfig.shortTermSummarizationInterval=parseInt(K,10);let A=B.getSetting("MEMORY_MAX_NEW_MESSAGES");if(A)this.memoryConfig.summaryMaxNewMessages=parseInt(A,10);let Y=B.getSetting("MEMORY_LONG_TERM_ENABLED");if(Y==="false")this.memoryConfig.longTermExtractionEnabled=!1;else if(Y==="true")this.memoryConfig.longTermExtractionEnabled=!0;let Z=B.getSetting("MEMORY_CONFIDENCE_THRESHOLD");if(Z)this.memoryConfig.longTermConfidenceThreshold=parseFloat(Z);let U=B.getSetting("MEMORY_EXTRACTION_THRESHOLD");if(U)this.memoryConfig.longTermExtractionThreshold=parseInt(U,10);let V=B.getSetting("MEMORY_EXTRACTION_INTERVAL");if(V)this.memoryConfig.longTermExtractionInterval=parseInt(V,10);H.debug({summarizationThreshold:this.memoryConfig.shortTermSummarizationThreshold,summarizationInterval:this.memoryConfig.shortTermSummarizationInterval,maxNewMessages:this.memoryConfig.summaryMaxNewMessages,retainRecent:this.memoryConfig.shortTermRetainRecent,longTermEnabled:this.memoryConfig.longTermExtractionEnabled,extractionThreshold:this.memoryConfig.longTermExtractionThreshold,extractionInterval:this.memoryConfig.longTermExtractionInterval,confidenceThreshold:this.memoryConfig.longTermConfidenceThreshold},"MemoryService initialized")}getDb(){let B=this.runtime.db;if(!B)throw Error("Database not available");return B}getConfig(){return{...this.memoryConfig}}updateConfig(B){this.memoryConfig={...this.memoryConfig,...B}}incrementMessageCount(B){let J=(this.sessionMessageCounts.get(B)||0)+1;return this.sessionMessageCounts.set(B,J),J}resetMessageCount(B){this.sessionMessageCounts.set(B,0)}async shouldSummarize(B){return await this.runtime.countMemories(B,!1,"messages")>=this.memoryConfig.shortTermSummarizationThreshold}getExtractionKey(B,Q){return`memory:extraction:${B}:${Q}`}async getLastExtractionCheckpoint(B,Q){let J=this.getExtractionKey(B,Q),K=this.lastExtractionCheckpoints.get(J);if(K!==void 0)return K;try{let Y=await this.runtime.getCache(J)??0;return this.lastExtractionCheckpoints.set(J,Y),Y}catch(A){return H.warn({error:A},"Failed to get extraction checkpoint from cache"),0}}async setLastExtractionCheckpoint(B,Q,J){let K=this.getExtractionKey(B,Q);this.lastExtractionCheckpoints.set(K,J);try{await this.runtime.setCache(K,J),H.debug(`Set extraction checkpoint for ${B} in room ${Q} at message count ${J}`)}catch(A){H.error({error:A},"Failed to persist extraction checkpoint to cache")}}async shouldRunExtraction(B,Q,J){let K=this.memoryConfig.longTermExtractionThreshold,A=this.memoryConfig.longTermExtractionInterval;if(J<K)return!1;let Y=await this.getLastExtractionCheckpoint(B,Q),Z=Math.floor(J/A)*A,U=J>=K&&Z>Y;return H.debug({entityId:B,roomId:Q,currentMessageCount:J,threshold:K,interval:A,lastCheckpoint:Y,currentCheckpoint:Z,shouldRun:U},"Extraction check"),U}async storeLongTermMemory(B){let Q=this.getDb(),J=crypto.randomUUID(),K=new Date,A={id:J,createdAt:K,updatedAt:K,accessCount:0,...B};try{await Q.insert($).values({id:A.id,agentId:A.agentId,entityId:A.entityId,category:A.category,content:A.content,metadata:A.metadata||{},embedding:A.embedding,confidence:A.confidence,source:A.source,accessCount:A.accessCount,createdAt:K,updatedAt:K,lastAccessedAt:A.lastAccessedAt})}catch(Y){throw H.error({error:Y},"Failed to store long-term memory"),Y}return H.info(`Stored long-term memory: ${A.category} for entity ${A.entityId}`),A}async getLongTermMemories(B,Q,J=10){let K=this.getDb(),A=[X($.agentId,this.runtime.agentId),X($.entityId,B)];if(Q)A.push(X($.category,Q));return(await K.select().from($).where(R(...A)).orderBy(f($.confidence),f($.updatedAt)).limit(J)).map((Z)=>({id:Z.id,agentId:Z.agentId,entityId:Z.entityId,category:Z.category,content:Z.content,metadata:Z.metadata,embedding:Z.embedding,confidence:Z.confidence,source:Z.source,createdAt:Z.createdAt,updatedAt:Z.updatedAt,lastAccessedAt:Z.lastAccessedAt,accessCount:Z.accessCount}))}async updateLongTermMemory(B,Q,J){let K=this.getDb(),A={updatedAt:new Date};if(J.content!==void 0)A.content=J.content;if(J.metadata!==void 0)A.metadata=J.metadata;if(J.confidence!==void 0)A.confidence=J.confidence;if(J.embedding!==void 0)A.embedding=J.embedding;if(J.lastAccessedAt!==void 0)A.lastAccessedAt=J.lastAccessedAt;if(J.accessCount!==void 0)A.accessCount=J.accessCount;await K.update($).set(A).where(R(X($.id,B),X($.agentId,this.runtime.agentId),X($.entityId,Q))),H.info(`Updated long-term memory: ${B} for entity ${Q}`)}async deleteLongTermMemory(B,Q){await this.getDb().delete($).where(R(X($.id,B),X($.agentId,this.runtime.agentId),X($.entityId,Q))),H.info(`Deleted long-term memory: ${B} for entity ${Q}`)}async getCurrentSessionSummary(B){let J=await this.getDb().select().from(j).where(R(X(j.agentId,this.runtime.agentId),X(j.roomId,B))).orderBy(f(j.updatedAt)).limit(1);if(J.length===0)return null;let K=J[0];return{id:K.id,agentId:K.agentId,roomId:K.roomId,entityId:K.entityId,summary:K.summary,messageCount:K.messageCount,lastMessageOffset:K.lastMessageOffset,startTime:K.startTime,endTime:K.endTime,topics:K.topics||[],metadata:K.metadata,embedding:K.embedding,createdAt:K.createdAt,updatedAt:K.updatedAt}}async storeSessionSummary(B){let Q=this.getDb(),J=crypto.randomUUID(),K=new Date,A={id:J,createdAt:K,updatedAt:K,...B};return await Q.insert(j).values({id:A.id,agentId:A.agentId,roomId:A.roomId,entityId:A.entityId||null,summary:A.summary,messageCount:A.messageCount,lastMessageOffset:A.lastMessageOffset,startTime:A.startTime,endTime:A.endTime,topics:A.topics||[],metadata:A.metadata||{},embedding:A.embedding,createdAt:K,updatedAt:K}),H.info(`Stored session summary for room ${A.roomId}`),A}async updateSessionSummary(B,Q,J){let K=this.getDb(),A={updatedAt:new Date};if(J.summary!==void 0)A.summary=J.summary;if(J.messageCount!==void 0)A.messageCount=J.messageCount;if(J.lastMessageOffset!==void 0)A.lastMessageOffset=J.lastMessageOffset;if(J.endTime!==void 0)A.endTime=J.endTime;if(J.topics!==void 0)A.topics=J.topics;if(J.metadata!==void 0)A.metadata=J.metadata;if(J.embedding!==void 0)A.embedding=J.embedding;await K.update(j).set(A).where(R(X(j.id,B),X(j.agentId,this.runtime.agentId),X(j.roomId,Q))),H.info(`Updated session summary: ${B} for room ${Q}`)}async getSessionSummaries(B,Q=5){return(await this.getDb().select().from(j).where(R(X(j.agentId,this.runtime.agentId),X(j.roomId,B))).orderBy(f(j.updatedAt)).limit(Q)).map((A)=>({id:A.id,agentId:A.agentId,roomId:A.roomId,entityId:A.entityId,summary:A.summary,messageCount:A.messageCount,lastMessageOffset:A.lastMessageOffset,startTime:A.startTime,endTime:A.endTime,topics:A.topics||[],metadata:A.metadata,embedding:A.embedding,createdAt:A.createdAt,updatedAt:A.updatedAt}))}async searchLongTermMemories(B,Q,J=5,K=0.7){if(!this.memoryConfig.longTermVectorSearchEnabled)return H.warn("Vector search is not enabled, falling back to recent memories"),this.getLongTermMemories(B,void 0,J);let A=this.getDb();try{let Y=Q.map((_)=>Number.isFinite(_)?Number(_.toFixed(6)):0),Z=AA`1 - (${RA($.embedding,Y)})`,U=[X($.agentId,this.runtime.agentId),X($.entityId,B),AA`${$.embedding} IS NOT NULL`];if(K>0)U.push(kA(Z,K));return(await A.select({memory:$,similarity:Z}).from($).where(R(...U)).orderBy(f(Z)).limit(J)).map((_)=>({id:_.memory.id,agentId:_.memory.agentId,entityId:_.memory.entityId,category:_.memory.category,content:_.memory.content,metadata:_.memory.metadata,embedding:_.memory.embedding,confidence:_.memory.confidence,source:_.memory.source,createdAt:_.memory.createdAt,updatedAt:_.memory.updatedAt,lastAccessedAt:_.memory.lastAccessedAt,accessCount:_.memory.accessCount,similarity:_.similarity}))}catch(Y){return H.warn({error:Y},"Vector search failed, falling back to recent memories"),this.getLongTermMemories(B,void 0,J)}}async getFormattedLongTermMemories(B){let Q=await this.getLongTermMemories(B,void 0,20);if(Q.length===0)return"";let J=new Map;for(let A of Q){if(!J.has(A.category))J.set(A.category,[]);J.get(A.category)?.push(A)}let K=[];for(let[A,Y]of J.entries()){let Z=A.split("_").map((V)=>V.charAt(0).toUpperCase()+V.slice(1)).join(" "),U=Y.map((V)=>`- ${V.content}`).join(`
|
|
2
|
+
`);K.push(`**${Z}**:
|
|
3
|
+
${U}`)}return K.join(`
|
|
4
|
+
|
|
5
|
+
`)}}import{logger as L,ModelType as zA,composePromptFromState as BA}from"@elizaos/core";async function qA(B,Q){return(await B.getMemories({tableName:"messages",roomId:Q,count:100,unique:!1})).filter((A)=>!(A.content?.type==="action_result"&&A.metadata?.type==="action_result")&&(A.metadata?.type==="agent_response_message"||A.metadata?.type==="user_message")).length}var fA=`# Task: Summarize Conversation
|
|
6
|
+
|
|
7
|
+
You are analyzing a conversation to create a concise summary that captures the key points, topics, and important details.
|
|
8
|
+
|
|
9
|
+
# Recent Messages
|
|
10
|
+
{{recentMessages}}
|
|
11
|
+
|
|
12
|
+
# Instructions
|
|
13
|
+
Generate a summary that:
|
|
14
|
+
1. Captures the main topics discussed
|
|
15
|
+
2. Highlights key information shared
|
|
16
|
+
3. Notes any decisions made or questions asked
|
|
17
|
+
4. Maintains context for future reference
|
|
18
|
+
5. Is concise but comprehensive
|
|
19
|
+
|
|
20
|
+
**IMPORTANT**: Keep the summary under 2500 tokens. Be comprehensive but concise.
|
|
21
|
+
|
|
22
|
+
Also extract:
|
|
23
|
+
- **Topics**: List of main topics discussed (comma-separated)
|
|
24
|
+
- **Key Points**: Important facts or decisions (bullet points)
|
|
25
|
+
|
|
26
|
+
Respond in this XML format:
|
|
27
|
+
<summary>
|
|
28
|
+
<text>Your comprehensive summary here</text>
|
|
29
|
+
<topics>topic1, topic2, topic3</topics>
|
|
30
|
+
<keyPoints>
|
|
31
|
+
<point>First key point</point>
|
|
32
|
+
<point>Second key point</point>
|
|
33
|
+
</keyPoints>
|
|
34
|
+
</summary>`,DA=`# Task: Update and Condense Conversation Summary
|
|
35
|
+
|
|
36
|
+
You are updating an existing conversation summary with new messages, while keeping the total summary concise.
|
|
37
|
+
|
|
38
|
+
# Existing Summary
|
|
39
|
+
{{existingSummary}}
|
|
40
|
+
|
|
41
|
+
# Existing Topics
|
|
42
|
+
{{existingTopics}}
|
|
43
|
+
|
|
44
|
+
# New Messages Since Last Summary
|
|
45
|
+
{{newMessages}}
|
|
46
|
+
|
|
47
|
+
# Instructions
|
|
48
|
+
Update the summary by:
|
|
49
|
+
1. Merging the existing summary with insights from the new messages
|
|
50
|
+
2. Removing redundant or less important details to stay under the token limit
|
|
51
|
+
3. Keeping the most important context and decisions
|
|
52
|
+
4. Adding new topics if they emerge
|
|
53
|
+
5. **CRITICAL**: Keep the ENTIRE updated summary under 2500 tokens
|
|
54
|
+
|
|
55
|
+
The goal is a rolling summary that captures the essence of the conversation without growing indefinitely.
|
|
56
|
+
|
|
57
|
+
Respond in this XML format:
|
|
58
|
+
<summary>
|
|
59
|
+
<text>Your updated and condensed summary here</text>
|
|
60
|
+
<topics>topic1, topic2, topic3</topics>
|
|
61
|
+
<keyPoints>
|
|
62
|
+
<point>First key point</point>
|
|
63
|
+
<point>Second key point</point>
|
|
64
|
+
</keyPoints>
|
|
65
|
+
</summary>`;function bA(B){let Q=B.match(/<text>([\s\S]*?)<\/text>/),J=B.match(/<topics>([\s\S]*?)<\/topics>/),K=B.matchAll(/<point>([\s\S]*?)<\/point>/g),A=Q?Q[1].trim():"Summary not available",Y=J?J[1].split(",").map((U)=>U.trim()).filter(Boolean):[],Z=Array.from(K).map((U)=>U[1].trim());return{summary:A,topics:Y,keyPoints:Z}}var JA={name:"MEMORY_SUMMARIZATION",description:"Automatically summarizes conversations to optimize context usage",similes:["CONVERSATION_SUMMARY","CONTEXT_COMPRESSION","MEMORY_OPTIMIZATION"],alwaysRun:!0,validate:async(B,Q)=>{if(!Q.content?.text)return!1;let J=B.getService("memory");if(!J)return!1;let K=J.getConfig(),A=await qA(B,Q.roomId),Y=await J.getCurrentSessionSummary(Q.roomId);if(!Y)return A>=K.shortTermSummarizationThreshold;else return A-Y.lastMessageOffset>=K.shortTermSummarizationInterval},handler:async(B,Q)=>{let J=B.getService("memory");if(!J){L.error("MemoryService not found");return}let K=J.getConfig(),{roomId:A}=Q;try{L.info(`Starting summarization for room ${A}`);let Y=await J.getCurrentSessionSummary(A),Z=Y?.lastMessageOffset||0,V=(await B.getMemories({tableName:"messages",roomId:A,count:1000,unique:!1})).filter((E)=>!(E.content?.type==="action_result"&&E.metadata?.type==="action_result")&&(E.metadata?.type==="agent_response_message"||E.metadata?.type==="user_message")),_=V.length,W=_-Z;if(W===0){L.debug("No new dialogue messages to summarize");return}let F=K.summaryMaxNewMessages||50,x=Math.min(W,F);if(W>F)L.warn(`Capping new dialogue messages at ${F} (${W} available). Oldest messages will be skipped.`);let k=V.sort((E,q)=>(E.createdAt||0)-(q.createdAt||0)),N=k.slice(Z,Z+x);if(N.length===0){L.debug("No new dialogue messages retrieved after filtering");return}let G=N.map((E)=>{return`${E.entityId===B.agentId?B.character.name:"User"}: ${E.content.text||"[non-text message]"}`}).join(`
|
|
66
|
+
`),z=await B.composeState(Q),S,b;if(Y)b=DA,S=BA({state:{...z,existingSummary:Y.summary,existingTopics:Y.topics?.join(", ")||"None",newMessages:G},template:b});else{let E=k.map((q)=>{return`${q.entityId===B.agentId?B.character.name:"User"}: ${q.content.text||"[non-text message]"}`}).join(`
|
|
67
|
+
`);b=fA,S=BA({state:{...z,recentMessages:E},template:b})}let YA=await B.useModel(zA.TEXT_LARGE,{prompt:S,maxTokens:K.summaryMaxTokens||2500}),O=bA(YA);L.info(`${Y?"Updated":"Generated"} summary: ${O.summary.substring(0,100)}...`);let i=Z+N.length,I=N[0],M=N[N.length-1],ZA=Y?Y.startTime:I?.createdAt&&I.createdAt>0?new Date(I.createdAt):new Date,a=M?.createdAt&&M.createdAt>0?new Date(M.createdAt):new Date;if(Y)await J.updateSessionSummary(Y.id,A,{summary:O.summary,messageCount:Y.messageCount+N.length,lastMessageOffset:i,endTime:a,topics:O.topics,metadata:{keyPoints:O.keyPoints}}),L.info(`Updated summary for room ${A}: ${N.length} new dialogue messages processed (offset: ${Z} → ${i})`);else await J.storeSessionSummary({agentId:B.agentId,roomId:A,entityId:Q.entityId!==B.agentId?Q.entityId:void 0,summary:O.summary,messageCount:_,lastMessageOffset:_,startTime:ZA,endTime:a,topics:O.topics,metadata:{keyPoints:O.keyPoints}}),L.info(`Created new summary for room ${A}: ${_} dialogue messages summarized (offset: 0 → ${_})`)}catch(Y){L.error({error:Y},"Error during summarization:")}},examples:[]};import{logger as P,ModelType as CA,composePromptFromState as TA}from"@elizaos/core";var g;((K)=>{K.EPISODIC="episodic";K.SEMANTIC="semantic";K.PROCEDURAL="procedural"})(g||={});var vA=`# Task: Extract Long-Term Memory (Strict Criteria)
|
|
68
|
+
|
|
69
|
+
You are analyzing a conversation to extract ONLY the most critical, persistent information about the user using cognitive science memory categories.
|
|
70
|
+
|
|
71
|
+
# Recent Messages
|
|
72
|
+
{{recentMessages}}
|
|
73
|
+
|
|
74
|
+
# Current Long-Term Memories
|
|
75
|
+
{{existingMemories}}
|
|
76
|
+
|
|
77
|
+
# Memory Categories (Based on Cognitive Science)
|
|
78
|
+
|
|
79
|
+
## 1. EPISODIC Memory
|
|
80
|
+
Personal experiences and specific events with temporal/spatial context.
|
|
81
|
+
**Examples:**
|
|
82
|
+
- "User completed migration project from MongoDB to PostgreSQL in Q2 2024"
|
|
83
|
+
- "User encountered authentication bug in production on March 15th"
|
|
84
|
+
- "User had a negative experience with Docker networking in previous job"
|
|
85
|
+
|
|
86
|
+
**Requirements:**
|
|
87
|
+
- Must include WHO did WHAT, WHEN/WHERE
|
|
88
|
+
- Must be a specific, concrete event (not a pattern)
|
|
89
|
+
- Must have significant impact or relevance to future work
|
|
90
|
+
|
|
91
|
+
## 2. SEMANTIC Memory
|
|
92
|
+
General facts, concepts, knowledge, and established truths about the user.
|
|
93
|
+
**Examples:**
|
|
94
|
+
- "User is a senior backend engineer with 8 years experience"
|
|
95
|
+
- "User specializes in distributed systems and microservices architecture"
|
|
96
|
+
- "User's primary programming language is TypeScript"
|
|
97
|
+
- "User works at Acme Corp as technical lead"
|
|
98
|
+
|
|
99
|
+
**Requirements:**
|
|
100
|
+
- Must be factual, timeless information
|
|
101
|
+
- Must be explicitly stated or demonstrated conclusively
|
|
102
|
+
- No speculation or inference from single instances
|
|
103
|
+
- Core identity, expertise, or knowledge only
|
|
104
|
+
|
|
105
|
+
## 3. PROCEDURAL Memory
|
|
106
|
+
Skills, workflows, methodologies, and how-to knowledge.
|
|
107
|
+
**Examples:**
|
|
108
|
+
- "User follows strict TDD workflow: write tests first, then implementation"
|
|
109
|
+
- "User prefers git rebase over merge to maintain linear history"
|
|
110
|
+
- "User's debugging process: check logs → reproduce locally → binary search"
|
|
111
|
+
- "User always writes JSDoc comments before implementing functions"
|
|
112
|
+
|
|
113
|
+
**Requirements:**
|
|
114
|
+
- Must describe HOW user does something
|
|
115
|
+
- Must be a repeated, consistent pattern (seen 3+ times or explicitly stated as standard practice)
|
|
116
|
+
- Must be a workflow, methodology, or skill application
|
|
117
|
+
- Not one-off preferences
|
|
118
|
+
|
|
119
|
+
# ULTRA-STRICT EXTRACTION CRITERIA
|
|
120
|
+
|
|
121
|
+
## ✅ DO EXTRACT (Only These):
|
|
122
|
+
|
|
123
|
+
**EPISODIC:**
|
|
124
|
+
- Significant completed projects or milestones
|
|
125
|
+
- Important bugs, incidents, or problems encountered
|
|
126
|
+
- Major decisions made with lasting impact
|
|
127
|
+
- Formative experiences that shape future work
|
|
128
|
+
|
|
129
|
+
**SEMANTIC:**
|
|
130
|
+
- Professional identity (role, title, company)
|
|
131
|
+
- Core expertise and specializations (stated explicitly or demonstrated conclusively)
|
|
132
|
+
- Primary languages, frameworks, or tools (not exploratory use)
|
|
133
|
+
- Established facts about their work context
|
|
134
|
+
|
|
135
|
+
**PROCEDURAL:**
|
|
136
|
+
- Consistent workflows demonstrated 3+ times or explicitly stated
|
|
137
|
+
- Standard practices user always follows
|
|
138
|
+
- Methodology preferences with clear rationale
|
|
139
|
+
- Debugging, testing, or development processes
|
|
140
|
+
|
|
141
|
+
## ❌ NEVER EXTRACT:
|
|
142
|
+
|
|
143
|
+
- **One-time requests or tasks** (e.g., "can you generate an image", "help me debug this")
|
|
144
|
+
- **Casual conversations** without lasting significance
|
|
145
|
+
- **Exploratory questions** (e.g., "how does X work?")
|
|
146
|
+
- **Temporary context** (current bug, today's task)
|
|
147
|
+
- **Preferences from single occurrence** (e.g., user asked for code once)
|
|
148
|
+
- **Social pleasantries** (thank you, greetings)
|
|
149
|
+
- **Testing or experimentation** (trying out a feature)
|
|
150
|
+
- **Common patterns everyone has** (likes clear explanations)
|
|
151
|
+
- **Situational information** (working on feature X today)
|
|
152
|
+
- **Opinions without persistence** (single complaint, isolated praise)
|
|
153
|
+
- **General knowledge** (not specific to user)
|
|
154
|
+
|
|
155
|
+
# Quality Gates (ALL Must Pass)
|
|
156
|
+
|
|
157
|
+
1. **Significance Test**: Will this matter in 3+ months?
|
|
158
|
+
2. **Specificity Test**: Is this concrete and actionable?
|
|
159
|
+
3. **Evidence Test**: Is there strong evidence (3+ instances OR explicit self-identification)?
|
|
160
|
+
4. **Uniqueness Test**: Is this specific to THIS user (not generic)?
|
|
161
|
+
5. **Confidence Test**: Confidence must be >= 0.85 (be VERY conservative)
|
|
162
|
+
6. **Non-Redundancy Test**: Does this add NEW information not in existing memories?
|
|
163
|
+
|
|
164
|
+
# Confidence Scoring (Be Conservative)
|
|
165
|
+
|
|
166
|
+
- **0.95-1.0**: User explicitly stated as core identity/practice AND demonstrated multiple times
|
|
167
|
+
- **0.85-0.94**: User explicitly stated OR consistently demonstrated 5+ times
|
|
168
|
+
- **0.75-0.84**: Strong pattern (3-4 instances) with supporting context
|
|
169
|
+
- **Below 0.75**: DO NOT EXTRACT (insufficient evidence)
|
|
170
|
+
|
|
171
|
+
# Critical Instructions
|
|
172
|
+
|
|
173
|
+
1. **Default to NOT extracting** - When in doubt, skip it
|
|
174
|
+
2. **Require overwhelming evidence** - One or two mentions is NOT enough
|
|
175
|
+
3. **Focus on what's PERSISTENT** - Not what's temporary or situational
|
|
176
|
+
4. **Verify against existing memories** - Don't duplicate or contradict
|
|
177
|
+
5. **Maximum 2-3 extractions per run** - Quality over quantity
|
|
178
|
+
|
|
179
|
+
**If there are no qualifying facts (which is common), respond with <memories></memories>**
|
|
180
|
+
|
|
181
|
+
# Response Format
|
|
182
|
+
|
|
183
|
+
<memories>
|
|
184
|
+
<memory>
|
|
185
|
+
<category>semantic</category>
|
|
186
|
+
<content>User is a senior TypeScript developer with 8 years of backend experience</content>
|
|
187
|
+
<confidence>0.95</confidence>
|
|
188
|
+
</memory>
|
|
189
|
+
<memory>
|
|
190
|
+
<category>procedural</category>
|
|
191
|
+
<content>User follows TDD workflow: writes tests before implementation, runs tests after each change</content>
|
|
192
|
+
<confidence>0.88</confidence>
|
|
193
|
+
</memory>
|
|
194
|
+
<memory>
|
|
195
|
+
<category>episodic</category>
|
|
196
|
+
<content>User led database migration from MongoDB to PostgreSQL for payment system in Q2 2024</content>
|
|
197
|
+
<confidence>0.92</confidence>
|
|
198
|
+
</memory>
|
|
199
|
+
</memories>`;function hA(B){let Q=B.matchAll(/<memory>[\s\S]*?<category>(.*?)<\/category>[\s\S]*?<content>(.*?)<\/content>[\s\S]*?<confidence>(.*?)<\/confidence>[\s\S]*?<\/memory>/g),J=[];for(let K of Q){let A=K[1].trim(),Y=K[2].trim(),Z=parseFloat(K[3].trim());if(!Object.values(g).includes(A)){P.warn(`Invalid memory category: ${A}`);continue}if(Y&&!isNaN(Z))J.push({category:A,content:Y,confidence:Z})}return J}var KA={name:"LONG_TERM_MEMORY_EXTRACTION",description:"Extracts long-term facts about users from conversations",similes:["MEMORY_EXTRACTION","FACT_LEARNING","USER_PROFILING"],alwaysRun:!0,validate:async(B,Q)=>{if(Q.entityId===B.agentId)return!1;if(!Q.content?.text)return!1;let J=B.getService("memory");if(!J)return!1;if(!J.getConfig().longTermExtractionEnabled)return P.debug("Long-term memory extraction is disabled"),!1;let A=await B.countMemories(Q.roomId,!1,"messages");return await J.shouldRunExtraction(Q.entityId,Q.roomId,A)},handler:async(B,Q)=>{let J=B.getService("memory");if(!J){P.error("MemoryService not found");return}let K=J.getConfig(),{entityId:A,roomId:Y}=Q;try{P.info(`Extracting long-term memories for entity ${A}`);let U=(await B.getMemories({tableName:"messages",roomId:Y,count:20,unique:!1})).sort((G,z)=>(G.createdAt||0)-(z.createdAt||0)).map((G)=>{return`${G.entityId===B.agentId?B.character.name:"User"}: ${G.content.text||"[non-text message]"}`}).join(`
|
|
200
|
+
`),V=await J.getLongTermMemories(A,void 0,30),_=V.length>0?V.map((G)=>`[${G.category}] ${G.content} (confidence: ${G.confidence})`).join(`
|
|
201
|
+
`):"None yet",W=await B.composeState(Q),F=TA({state:{...W,recentMessages:U,existingMemories:_},template:vA}),x=await B.useModel(CA.TEXT_LARGE,{prompt:F}),k=hA(x);P.info(`Extracted ${k.length} long-term memories`);for(let G of k)if(G.confidence>=Math.max(K.longTermConfidenceThreshold,0.85))await J.storeLongTermMemory({agentId:B.agentId,entityId:A,category:G.category,content:G.content,confidence:G.confidence,source:"conversation",metadata:{roomId:Y,extractedAt:new Date().toISOString()}}),P.info(`Stored long-term memory: [${G.category}] ${G.content.substring(0,50)}...`);else P.debug(`Skipped low-confidence memory: ${G.content} (confidence: ${G.confidence}, threshold: ${Math.max(K.longTermConfidenceThreshold,0.85)})`);let N=await B.countMemories(Y,!1,"messages");await J.setLastExtractionCheckpoint(A,Y,N),P.debug(`Updated extraction checkpoint to ${N} for entity ${A} in room ${Y}`)}catch(Z){P.error({error:Z},"Error during long-term memory extraction:")}},examples:[]};import{logger as xA,addHeader as SA}from"@elizaos/core";var u={name:"LONG_TERM_MEMORY",description:"Persistent facts and preferences about the user",position:50,get:async(B,Q,J)=>{try{let K=B.getService("memory");if(!K)return{data:{memories:[]},values:{longTermMemories:""},text:""};let{entityId:A}=Q;if(A===B.agentId)return{data:{memories:[]},values:{longTermMemories:""},text:""};let Y=await K.getLongTermMemories(A,void 0,25);if(Y.length===0)return{data:{memories:[]},values:{longTermMemories:""},text:""};let Z=await K.getFormattedLongTermMemories(A),U=SA("# What I Know About You",Z),V=new Map;for(let W of Y){let F=V.get(W.category)||0;V.set(W.category,F+1)}let _=Array.from(V.entries()).map(([W,F])=>`${W}: ${F}`).join(", ");return{data:{memories:Y,categoryCounts:Object.fromEntries(V)},values:{longTermMemories:U,memoryCategories:_},text:U}}catch(K){return xA.error({error:K},"Error in longTermMemoryProvider:"),{data:{memories:[]},values:{longTermMemories:""},text:""}}}};import{addHeader as QA,logger as IA}from"@elizaos/core";var n={name:"SUMMARIZED_CONTEXT",description:"Provides summarized context from previous conversations",position:96,get:async(B,Q,J)=>{try{let K=B.getService("memory"),{roomId:A}=Q;if(!K)return{data:{summary:null},values:{sessionSummaries:"",sessionSummariesWithTopics:""},text:""};let Y=await K.getCurrentSessionSummary(A);if(!Y)return{data:{summary:null},values:{sessionSummaries:"",sessionSummariesWithTopics:""},text:""};let Z=`${Y.messageCount} messages`,U=new Date(Y.startTime).toLocaleDateString(),V=`**Previous Conversation** (${Z}, ${U})
|
|
202
|
+
`;V+=Y.summary;let _=V;if(Y.topics&&Y.topics.length>0)_+=`
|
|
203
|
+
*Topics: ${Y.topics.join(", ")}*`;let W=QA("# Conversation Summary",V),F=QA("# Conversation Summary",_);return{data:{summary:Y},values:{sessionSummaries:W,sessionSummariesWithTopics:F},text:F}}catch(K){return IA.error({error:K},"Error in contextSummaryProvider:"),{data:{summary:null},values:{sessionSummaries:"",sessionSummariesWithTopics:""},text:""}}}};var MA={name:"memory",description:"Advanced memory management with conversation summarization and long-term persistent memory",services:[D],evaluators:[JA,KA],providers:[u,n],schema:d},pA=MA;export{j as sessionSummaries,MA as memoryPlugin,e as memoryAccessLogs,u as longTermMemoryProvider,$ as longTermMemories,pA as default,n as contextSummaryProvider,D as MemoryService,g as LongTermMemoryCategory};
|
|
204
|
+
|
|
205
|
+
//# debugId=63795FFE83D49E7A64756E2164756E21
|