n8n-nodes-tembory 1.0.8 → 1.0.9
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.
|
@@ -43,7 +43,7 @@ const getConnectedEmbedding = async (ctx, itemIndex) => {
|
|
|
43
43
|
};
|
|
44
44
|
const createClientVectorMemory = async (embedding, text, metadata, ids = {}) => ({
|
|
45
45
|
text: truncate(text, 4000),
|
|
46
|
-
embedding: await embedding
|
|
46
|
+
embedding: await embedQueryCached(embedding, String(text || '')),
|
|
47
47
|
user_id: ids.user_id,
|
|
48
48
|
agent_id: ids.agent_id,
|
|
49
49
|
run_id: ids.run_id,
|
|
@@ -67,7 +67,7 @@ const searchClientVectorMemories = async (ctx, embedding, query, body = {}) => {
|
|
|
67
67
|
return GenericFunctions_1.mem0ApiRequest.call(ctx, 'POST', '/elefai/v1/vector-memories/search', {
|
|
68
68
|
...body,
|
|
69
69
|
query: text,
|
|
70
|
-
embedding: await embedding
|
|
70
|
+
embedding: await embedQueryCached(embedding, text),
|
|
71
71
|
});
|
|
72
72
|
};
|
|
73
73
|
const stableStringify = (value) => {
|
|
@@ -87,6 +87,31 @@ const hashString = (value) => {
|
|
|
87
87
|
return (hash >>> 0).toString(36);
|
|
88
88
|
};
|
|
89
89
|
const stableHash = (value) => hashString(typeof value === 'string' ? value : stableStringify(value));
|
|
90
|
+
const embeddingCacheByModel = new WeakMap();
|
|
91
|
+
const MAX_EMBEDDING_CACHE_ITEMS = 500;
|
|
92
|
+
const embedQueryCached = async (embedding, text) => {
|
|
93
|
+
const query = String(text || '');
|
|
94
|
+
if (!embedding || typeof embedding.embedQuery !== 'function')
|
|
95
|
+
return undefined;
|
|
96
|
+
let cache = embeddingCacheByModel.get(embedding);
|
|
97
|
+
if (!cache) {
|
|
98
|
+
cache = new Map();
|
|
99
|
+
embeddingCacheByModel.set(embedding, cache);
|
|
100
|
+
}
|
|
101
|
+
const key = stableHash(query);
|
|
102
|
+
if (cache.has(key))
|
|
103
|
+
return cache.get(key);
|
|
104
|
+
const promise = Promise.resolve(embedding.embedQuery(query)).catch((error) => {
|
|
105
|
+
cache.delete(key);
|
|
106
|
+
throw error;
|
|
107
|
+
});
|
|
108
|
+
cache.set(key, promise);
|
|
109
|
+
if (cache.size > MAX_EMBEDDING_CACHE_ITEMS) {
|
|
110
|
+
const firstKey = cache.keys().next().value;
|
|
111
|
+
cache.delete(firstKey);
|
|
112
|
+
}
|
|
113
|
+
return promise;
|
|
114
|
+
};
|
|
90
115
|
const pickText = (values, preferredKeys) => {
|
|
91
116
|
for (const key of preferredKeys) {
|
|
92
117
|
const value = values === null || values === void 0 ? void 0 : values[key];
|
|
@@ -1444,11 +1469,15 @@ const wrapElefaiMemory = (memory, ctx, memoryKey) => new Proxy(memory, {
|
|
|
1444
1469
|
]);
|
|
1445
1470
|
try {
|
|
1446
1471
|
const response = await target.loadMemoryVariables(values);
|
|
1447
|
-
const
|
|
1472
|
+
const cacheHit = Boolean(response.elefaiBrainDiagnostics && response.elefaiBrainDiagnostics.cacheHit);
|
|
1473
|
+
const chatHistory = cacheHit
|
|
1474
|
+
? [{ cached: true, messages: Array.isArray(response[memoryKey] || response.chatHistory) ? (response[memoryKey] || response.chatHistory).length : 0 }]
|
|
1475
|
+
: snapshotJson(response[memoryKey] || response.chatHistory || []);
|
|
1448
1476
|
ctx.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, [
|
|
1449
1477
|
[{
|
|
1450
1478
|
json: {
|
|
1451
1479
|
action: 'loadMemoryVariables',
|
|
1480
|
+
cached: cacheHit || undefined,
|
|
1452
1481
|
chatHistory,
|
|
1453
1482
|
context: response.elefaiBrainContext,
|
|
1454
1483
|
contextText: response.elefaiBrainContextText,
|
|
@@ -1903,6 +1932,7 @@ class Mem0Memory {
|
|
|
1903
1932
|
async supplyData(itemIndex) {
|
|
1904
1933
|
const memoryKey = this.getNodeParameter('memoryKey', itemIndex);
|
|
1905
1934
|
let currentMessages = [];
|
|
1935
|
+
const loadCache = new Map();
|
|
1906
1936
|
const memory = {
|
|
1907
1937
|
memoryKeys: [memoryKey],
|
|
1908
1938
|
inputKey: 'input',
|
|
@@ -1933,7 +1963,38 @@ class Mem0Memory {
|
|
|
1933
1963
|
},
|
|
1934
1964
|
},
|
|
1935
1965
|
loadMemoryVariables: async (inputValues = {}) => {
|
|
1936
|
-
const
|
|
1966
|
+
const cacheKey = stableHash({ itemIndex, inputValues, memoryKey });
|
|
1967
|
+
let result;
|
|
1968
|
+
if (loadCache.has(cacheKey)) {
|
|
1969
|
+
result = snapshotJson(loadCache.get(cacheKey));
|
|
1970
|
+
result.response = result.response || {};
|
|
1971
|
+
result.response.elefaiBrainDiagnostics = {
|
|
1972
|
+
...(result.response.elefaiBrainDiagnostics || {}),
|
|
1973
|
+
cacheHit: true,
|
|
1974
|
+
cacheScope: 'supplyData.loadMemoryVariables',
|
|
1975
|
+
};
|
|
1976
|
+
if (result.response.elefaiBrainContext) {
|
|
1977
|
+
result.response.elefaiBrainContext = {
|
|
1978
|
+
kind: result.response.elefaiBrainContext.kind,
|
|
1979
|
+
userId: result.response.elefaiBrainContext.userId,
|
|
1980
|
+
project: result.response.elefaiBrainContext.project,
|
|
1981
|
+
query: result.response.elefaiBrainContext.query,
|
|
1982
|
+
retrievalMode: result.response.elefaiBrainContext.retrievalMode,
|
|
1983
|
+
payloadFormat: result.response.elefaiBrainContext.payloadFormat,
|
|
1984
|
+
contextQualityScore: result.response.elefaiBrainContext.contextQualityScore,
|
|
1985
|
+
cacheHit: true,
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1988
|
+
delete result.response.elefaiBrainContextText;
|
|
1989
|
+
}
|
|
1990
|
+
else {
|
|
1991
|
+
result = await Mem0Memory.prototype.loadMemoryVariablesForItem.call(this, itemIndex, inputValues);
|
|
1992
|
+
loadCache.set(cacheKey, snapshotJson(result));
|
|
1993
|
+
if (loadCache.size > 20) {
|
|
1994
|
+
const firstKey = loadCache.keys().next().value;
|
|
1995
|
+
loadCache.delete(firstKey);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1937
1998
|
const chatHistory = (result.response[memoryKey] || []).map(toBaseMessage);
|
|
1938
1999
|
const extra = { ...(result.response || {}) };
|
|
1939
2000
|
delete extra[memoryKey];
|
|
@@ -1945,6 +2006,7 @@ class Mem0Memory {
|
|
|
1945
2006
|
};
|
|
1946
2007
|
},
|
|
1947
2008
|
saveContext: async (inputValues = {}, outputValues = {}) => {
|
|
2009
|
+
loadCache.clear();
|
|
1948
2010
|
const input = pickText(inputValues, ['input', 'chatInput', 'text', 'query', 'question']);
|
|
1949
2011
|
const output = pickText(outputValues, ['output', 'response', 'text', 'answer']);
|
|
1950
2012
|
if (input)
|
|
@@ -2227,7 +2289,7 @@ class Mem0Memory {
|
|
|
2227
2289
|
}
|
|
2228
2290
|
if (connectedEmbedding && typeof connectedEmbedding.embedQuery === 'function' && String(query || '').trim()) {
|
|
2229
2291
|
try {
|
|
2230
|
-
await connectedEmbedding
|
|
2292
|
+
await embedQueryCached(connectedEmbedding, String(query));
|
|
2231
2293
|
connectedAi.embeddingQuery = true;
|
|
2232
2294
|
}
|
|
2233
2295
|
catch (error) {
|
|
@@ -2467,10 +2529,10 @@ class Mem0Memory {
|
|
|
2467
2529
|
catch { }
|
|
2468
2530
|
}
|
|
2469
2531
|
let connectedModelSummary = '';
|
|
2470
|
-
if (connectedLanguageModel && typeof connectedLanguageModel.invoke === 'function' &&
|
|
2532
|
+
if (connectedLanguageModel && typeof connectedLanguageModel.invoke === 'function' && vectorMemories.length && adv.includeSummary !== false) {
|
|
2471
2533
|
try {
|
|
2472
2534
|
const facts = vectorMemories.slice(0, Number(adv.summaryMaxFacts || 4)).map((memory) => contextMemoryText(memory, 500)).filter(Boolean).join('\n') || '(no vector memories found)';
|
|
2473
|
-
if (facts
|
|
2535
|
+
if (facts) {
|
|
2474
2536
|
const response = await connectedLanguageModel.invoke([
|
|
2475
2537
|
toBaseMessage({
|
|
2476
2538
|
role: 'user',
|
|
@@ -2788,6 +2850,7 @@ exports.__private = {
|
|
|
2788
2850
|
isNoisyProfileValue,
|
|
2789
2851
|
approxTokenCount,
|
|
2790
2852
|
contextSizeOfMessages,
|
|
2853
|
+
embedQueryCached,
|
|
2791
2854
|
compactToolResult,
|
|
2792
2855
|
compactToolHistoryForAgent,
|
|
2793
2856
|
compactOperationalStateForAgent,
|
package/package.json
CHANGED