n8n-nodes-tembory 1.0.37 → 1.0.39
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/dist/nodes/Mem0/Mem0Memory.node.js +209 -39
- package/package.json +1 -1
|
@@ -852,10 +852,13 @@ const makeToolEventId = (tool, sequence = 0) => {
|
|
|
852
852
|
return `tool_${hashString(base)}`;
|
|
853
853
|
};
|
|
854
854
|
const canonicalToolInput = (value) => {
|
|
855
|
-
const text =
|
|
856
|
-
|
|
855
|
+
const text = value === undefined || value === null
|
|
856
|
+
? ''
|
|
857
|
+
: (typeof value === 'string' ? value : stableStringify(value));
|
|
858
|
+
const trimmed = String(text).trim();
|
|
859
|
+
if (trimmed === '""' || trimmed === "''")
|
|
857
860
|
return '';
|
|
858
|
-
return
|
|
861
|
+
return trimmed;
|
|
859
862
|
};
|
|
860
863
|
const normalizeToolCall = (tool, sequence = 0, defaults = {}) => {
|
|
861
864
|
const at = tool.at || defaults.at || nowIso();
|
|
@@ -910,6 +913,73 @@ const readDeep = (value, visitor, seen = new Set()) => {
|
|
|
910
913
|
for (const item of Object.values(value))
|
|
911
914
|
readDeep(item, visitor, seen);
|
|
912
915
|
};
|
|
916
|
+
const messageTypeOf = (message) => {
|
|
917
|
+
if (typeof (message === null || message === void 0 ? void 0 : message._getType) === 'function')
|
|
918
|
+
return String(message._getType() || '');
|
|
919
|
+
return String((message === null || message === void 0 ? void 0 : message.role) || (message === null || message === void 0 ? void 0 : message.type) || (message === null || message === void 0 ? void 0 : message.lc_kwargs && message.lc_kwargs.type) || '').toLowerCase();
|
|
920
|
+
};
|
|
921
|
+
const messageContentOf = (message) => typeof (message === null || message === void 0 ? void 0 : message.content) === 'string' ? message.content : safeStringify(message === null || message === void 0 ? void 0 : message.content);
|
|
922
|
+
const extractToolCallsFromMessages = (messages = []) => {
|
|
923
|
+
const calls = [];
|
|
924
|
+
const toolCallById = new Map();
|
|
925
|
+
const push = (tool, index = calls.length) => {
|
|
926
|
+
if (!tool || !(tool.name || tool.tool || tool.toolName))
|
|
927
|
+
return;
|
|
928
|
+
const normalized = normalizeToolCall({
|
|
929
|
+
id: tool.id || tool.callId || tool.call_id || tool.toolCallId || tool.tool_call_id,
|
|
930
|
+
turnId: tool.turnId || tool.turn_id,
|
|
931
|
+
sequence: tool.sequence || index + 1,
|
|
932
|
+
name: tool.name || tool.tool || tool.toolName,
|
|
933
|
+
input: tool.input !== undefined ? tool.input : tool.args !== undefined ? tool.args : tool.toolInput !== undefined ? tool.toolInput : '',
|
|
934
|
+
ok: tool.ok !== false,
|
|
935
|
+
result: tool.result !== undefined ? tool.result : tool.output !== undefined ? tool.output : tool.observation !== undefined ? tool.observation : '',
|
|
936
|
+
at: tool.at || nowIso(),
|
|
937
|
+
source: tool.source || 'langchain_message',
|
|
938
|
+
}, calls.length + 1);
|
|
939
|
+
calls.push(normalized);
|
|
940
|
+
if (normalized.id)
|
|
941
|
+
toolCallById.set(String(normalized.id), normalized);
|
|
942
|
+
};
|
|
943
|
+
for (const [index, message] of (messages || []).entries()) {
|
|
944
|
+
const type = messageTypeOf(message);
|
|
945
|
+
const additional = (message && (message.additional_kwargs || message.additionalKwargs)) || {};
|
|
946
|
+
const kwargs = (message && message.lc_kwargs) || {};
|
|
947
|
+
const toolCalls = message && (message.tool_calls || message.toolCalls || additional.tool_calls || additional.toolCalls || kwargs.tool_calls || kwargs.toolCalls);
|
|
948
|
+
if (Array.isArray(toolCalls)) {
|
|
949
|
+
for (const tool of toolCalls)
|
|
950
|
+
push({ ...tool, source: 'ai_message_tool_calls' }, index);
|
|
951
|
+
}
|
|
952
|
+
const invalidToolCalls = message && (message.invalid_tool_calls || message.invalidToolCalls || additional.invalid_tool_calls || additional.invalidToolCalls);
|
|
953
|
+
if (Array.isArray(invalidToolCalls)) {
|
|
954
|
+
for (const tool of invalidToolCalls)
|
|
955
|
+
push({ ...tool, ok: false, source: 'ai_message_invalid_tool_calls' }, index);
|
|
956
|
+
}
|
|
957
|
+
if (type === 'tool') {
|
|
958
|
+
const id = message.tool_call_id || message.toolCallId || additional.tool_call_id || additional.toolCallId || message.id;
|
|
959
|
+
const name = message.name || message.toolName || message.tool || additional.name || additional.tool_name || additional.toolName || kwargs.name || 'tool';
|
|
960
|
+
const existing = id ? toolCallById.get(String(id)) : null;
|
|
961
|
+
if (existing) {
|
|
962
|
+
existing.result = summarizeToolResult(messageContentOf(message));
|
|
963
|
+
existing.result_summary = existing.result;
|
|
964
|
+
existing.ok = true;
|
|
965
|
+
existing.status = 'ok';
|
|
966
|
+
existing.result_hash = stableHash(existing.result || '');
|
|
967
|
+
existing.dedupe_key = toolEventKey(existing);
|
|
968
|
+
}
|
|
969
|
+
else {
|
|
970
|
+
push({
|
|
971
|
+
id,
|
|
972
|
+
name,
|
|
973
|
+
input: '',
|
|
974
|
+
result: messageContentOf(message),
|
|
975
|
+
ok: true,
|
|
976
|
+
source: 'tool_message',
|
|
977
|
+
}, index);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
return dedupeToolHistory(calls);
|
|
982
|
+
};
|
|
913
983
|
const extractToolCallsFromText = (text, at = nowIso()) => {
|
|
914
984
|
const calls = [];
|
|
915
985
|
const source = String(text || '');
|
|
@@ -1022,15 +1092,17 @@ const getMemoryStore = (ctx) => {
|
|
|
1022
1092
|
data.tembory.memoryCompression = data.tembory.memoryCompression || {};
|
|
1023
1093
|
data.tembory.activeSummary = data.tembory.activeSummary || {};
|
|
1024
1094
|
data.tembory.connectedModelSummaryCache = data.tembory.connectedModelSummaryCache || {};
|
|
1095
|
+
data.tembory.captureState = data.tembory.captureState || {};
|
|
1025
1096
|
return data.tembory;
|
|
1026
1097
|
}
|
|
1027
1098
|
catch {
|
|
1028
|
-
global.__temboryMemory = global.__temboryMemory || { toolHistory: {}, recentMessages: {}, profileFacts: {}, workingMemory: {}, decisionState: {}, memoryCompression: {}, activeSummary: {}, connectedModelSummaryCache: {} };
|
|
1099
|
+
global.__temboryMemory = global.__temboryMemory || { toolHistory: {}, recentMessages: {}, profileFacts: {}, workingMemory: {}, decisionState: {}, memoryCompression: {}, activeSummary: {}, connectedModelSummaryCache: {}, captureState: {} };
|
|
1029
1100
|
global.__temboryMemory.workingMemory = global.__temboryMemory.workingMemory || {};
|
|
1030
1101
|
global.__temboryMemory.decisionState = global.__temboryMemory.decisionState || {};
|
|
1031
1102
|
global.__temboryMemory.memoryCompression = global.__temboryMemory.memoryCompression || {};
|
|
1032
1103
|
global.__temboryMemory.activeSummary = global.__temboryMemory.activeSummary || {};
|
|
1033
1104
|
global.__temboryMemory.connectedModelSummaryCache = global.__temboryMemory.connectedModelSummaryCache || {};
|
|
1105
|
+
global.__temboryMemory.captureState = global.__temboryMemory.captureState || {};
|
|
1034
1106
|
return global.__temboryMemory;
|
|
1035
1107
|
}
|
|
1036
1108
|
};
|
|
@@ -1041,8 +1113,50 @@ const userKeyFrom = (threadId, adv, project = '') => {
|
|
|
1041
1113
|
return namespace ? `${namespace}::${base}` : base;
|
|
1042
1114
|
};
|
|
1043
1115
|
const applyOperationalPreset = (advanced = {}) => {
|
|
1044
|
-
const preset = String(advanced.operationPreset || '
|
|
1116
|
+
const preset = String(advanced.operationPreset || 'productionFast');
|
|
1045
1117
|
const presets = {
|
|
1118
|
+
productionFast: {
|
|
1119
|
+
summarySource: 'activeContext',
|
|
1120
|
+
includeConnectedModelSummary: true,
|
|
1121
|
+
includeActiveSummary: true,
|
|
1122
|
+
persistActiveSummary: true,
|
|
1123
|
+
activeSummaryMaxChars: 1800,
|
|
1124
|
+
activeSummaryRetentionDays: 30,
|
|
1125
|
+
enableTransientSummaryCache: true,
|
|
1126
|
+
transientSummaryCacheTTLSeconds: 300,
|
|
1127
|
+
compactStateSections: true,
|
|
1128
|
+
useVectorMemory: false,
|
|
1129
|
+
persistBackendMemories: false,
|
|
1130
|
+
includeRecentMessageProbe: false,
|
|
1131
|
+
includeToolLedgerProbe: false,
|
|
1132
|
+
includeContextHeader: true,
|
|
1133
|
+
includeSummary: true,
|
|
1134
|
+
includeScores: false,
|
|
1135
|
+
includeDiagnostics: false,
|
|
1136
|
+
includeRelations: false,
|
|
1137
|
+
includeToolHistory: true,
|
|
1138
|
+
includeToolResults: true,
|
|
1139
|
+
persistToolFactsToMem0: false,
|
|
1140
|
+
includeToolHistorySemanticFallback: false,
|
|
1141
|
+
includeProfileFacts: true,
|
|
1142
|
+
includeOperationalState: true,
|
|
1143
|
+
includeActionLedger: true,
|
|
1144
|
+
includeEntityTimeline: false,
|
|
1145
|
+
includeWorkingMemory: true,
|
|
1146
|
+
includeDecisionState: true,
|
|
1147
|
+
includeMemoryCompression: true,
|
|
1148
|
+
includeRecentMessages: true,
|
|
1149
|
+
includeRecentHighlights: false,
|
|
1150
|
+
topK: 0,
|
|
1151
|
+
lastN: 0,
|
|
1152
|
+
maxReturn: 0,
|
|
1153
|
+
toolHistoryLastN: 15,
|
|
1154
|
+
recentMessagesLastN: 50,
|
|
1155
|
+
vectorMemoryMaxChars: 220,
|
|
1156
|
+
contextMaxChars: 9000,
|
|
1157
|
+
connectedModelSummaryMaxChars: 1200,
|
|
1158
|
+
connectedModelSummaryInputMaxChars: 4200,
|
|
1159
|
+
},
|
|
1046
1160
|
diagnostic: {
|
|
1047
1161
|
summarySource: 'auto',
|
|
1048
1162
|
includeConnectedModelSummary: true,
|
|
@@ -1617,13 +1731,13 @@ const deriveContextHealth = ({ userId = '', project = '', vectorMemories = [], r
|
|
|
1617
1731
|
namespace_stable: Boolean(userId && !/^mcp-session-\d+$/i.test(String(userId))),
|
|
1618
1732
|
has_recent_messages: Array.isArray(recentMessages) && recentMessages.length > 0,
|
|
1619
1733
|
has_tool_history: Array.isArray(toolHistory) && toolHistory.length > 0,
|
|
1620
|
-
has_vector_memories: Array.isArray(vectorMemories) && vectorMemories.length > 0,
|
|
1734
|
+
has_vector_memories: diagnostics.vectorMemoryEnabled === false ? true : Array.isArray(vectorMemories) && vectorMemories.length > 0,
|
|
1621
1735
|
has_working_memory: Boolean(workingMemory && Object.keys(workingMemory).length),
|
|
1622
1736
|
has_decision_state: Boolean(decisionState && Object.keys(decisionState).length),
|
|
1623
1737
|
has_memory_compression: Boolean(memoryCompression && Object.keys(memoryCompression).length),
|
|
1624
1738
|
has_operational_state: Boolean(operationalState && Object.keys(operationalState).length),
|
|
1625
1739
|
connected_language_model: Boolean(diagnostics.connectedAi && diagnostics.connectedAi.languageModel),
|
|
1626
|
-
connected_embedding: Boolean(diagnostics.connectedAi && diagnostics.connectedAi.embedding),
|
|
1740
|
+
connected_embedding: diagnostics.vectorMemoryEnabled === false ? true : Boolean(diagnostics.connectedAi && diagnostics.connectedAi.embedding),
|
|
1627
1741
|
no_connected_ai_errors: !((diagnostics.connectedAi && diagnostics.connectedAi.errors) || []).length,
|
|
1628
1742
|
};
|
|
1629
1743
|
const weights = {
|
|
@@ -1824,9 +1938,20 @@ const compactEntityTimelineForAgent = (timeline = [], maxItems = 8) => pruneByLi
|
|
|
1824
1938
|
at: item.at,
|
|
1825
1939
|
source: item.source_type || item.source,
|
|
1826
1940
|
}));
|
|
1941
|
+
const isConversationEchoMemory = (memory) => {
|
|
1942
|
+
const meta = metadataOf(memory);
|
|
1943
|
+
const kind = String(meta.kind || meta.type || '').toLowerCase();
|
|
1944
|
+
if (/^(recent_message|conversation_ledger|conversation_message)$/i.test(kind))
|
|
1945
|
+
return true;
|
|
1946
|
+
const raw = memoryText(memory);
|
|
1947
|
+
if (parseRecentMessageMarker(raw) || parseConversationLedgerMarker(raw).length)
|
|
1948
|
+
return true;
|
|
1949
|
+
return /__tembory_conversation_ledger_v1__/.test(String(raw || ''));
|
|
1950
|
+
};
|
|
1827
1951
|
const compactVectorMemoriesForAgent = (vectorMemories = [], toolHistory = [], maxItems = 3) => {
|
|
1828
1952
|
const hasStructuredTools = Array.isArray(toolHistory) && toolHistory.length > 0;
|
|
1829
1953
|
return (vectorMemories || [])
|
|
1954
|
+
.filter((memory) => !isConversationEchoMemory(memory))
|
|
1830
1955
|
.map((memory) => contextMemoryText(memory, 220))
|
|
1831
1956
|
.filter(Boolean)
|
|
1832
1957
|
.filter((text) => !/^\[recent_message\]/i.test(text))
|
|
@@ -2202,7 +2327,7 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
2202
2327
|
sections.push({
|
|
2203
2328
|
section: 'vector',
|
|
2204
2329
|
title: 'Vector memories',
|
|
2205
|
-
value: compactStateSections ? compactVectorMemoriesForAgent(vectorMemories, toolHistory, Number(adv.maxReturn || adv.topK || 4)) : vectorMemories.map((m) => {
|
|
2330
|
+
value: compactStateSections ? compactVectorMemoriesForAgent(vectorMemories, toolHistory, Number(adv.maxReturn || adv.topK || 4)) : vectorMemories.filter((m) => !isConversationEchoMemory(m)).map((m) => {
|
|
2206
2331
|
const scoreMeta = scoreMetaOf(m);
|
|
2207
2332
|
const rawScore = scoreOf(m);
|
|
2208
2333
|
return {
|
|
@@ -2440,12 +2565,13 @@ class Mem0Memory {
|
|
|
2440
2565
|
options: [
|
|
2441
2566
|
{ name: 'Custom', value: 'custom' },
|
|
2442
2567
|
{ name: 'Diagnóstico Completo', value: 'diagnostic' },
|
|
2568
|
+
{ name: 'Produção Rápida (Thread + SLM)', value: 'productionFast' },
|
|
2443
2569
|
{ name: 'Produção Balanceada', value: 'productionBalanced' },
|
|
2444
2570
|
{ name: 'Produção Econômica', value: 'productionCheap' },
|
|
2445
2571
|
{ name: 'Produção Nano/SLM', value: 'productionNano' },
|
|
2446
2572
|
{ name: 'Auditoria', value: 'audit' },
|
|
2447
2573
|
],
|
|
2448
|
-
default: '
|
|
2574
|
+
default: 'productionFast',
|
|
2449
2575
|
description: 'Preenche defaults seguros para contexto, historico de tools e memoria ativa.',
|
|
2450
2576
|
},
|
|
2451
2577
|
{ displayName: 'Incluir Cabeçalho de Contexto', name: 'includeContextHeader', type: 'boolean', default: true },
|
|
@@ -2472,6 +2598,10 @@ class Mem0Memory {
|
|
|
2472
2598
|
{ displayName: 'Máximo de Relações', name: 'maxRelations', type: 'number', default: 10 },
|
|
2473
2599
|
{ displayName: 'Incluir Action Ledger', name: 'includeActionLedger', type: 'boolean', default: true },
|
|
2474
2600
|
{ displayName: 'Incluir Entity Timeline', name: 'includeEntityTimeline', type: 'boolean', default: true },
|
|
2601
|
+
{ displayName: 'Usar Memória Vetorial no Caminho Quente', name: 'useVectorMemory', type: 'boolean', default: false },
|
|
2602
|
+
{ displayName: 'Persistir Memórias no Backend', name: 'persistBackendMemories', type: 'boolean', default: false },
|
|
2603
|
+
{ displayName: 'Probe Vetorial de Mensagens Recentes', name: 'includeRecentMessageProbe', type: 'boolean', default: false },
|
|
2604
|
+
{ displayName: 'Probe Vetorial de Tool Ledger', name: 'includeToolLedgerProbe', type: 'boolean', default: false },
|
|
2475
2605
|
],
|
|
2476
2606
|
},
|
|
2477
2607
|
{
|
|
@@ -2552,18 +2682,21 @@ class Mem0Memory {
|
|
|
2552
2682
|
options: [
|
|
2553
2683
|
{ name: 'Custom', value: 'custom' },
|
|
2554
2684
|
{ name: 'Diagnóstico Completo', value: 'diagnostic' },
|
|
2685
|
+
{ name: 'Produção Rápida (Thread + SLM)', value: 'productionFast' },
|
|
2555
2686
|
{ name: 'Produção Balanceada', value: 'productionBalanced' },
|
|
2556
2687
|
{ name: 'Produção Econômica', value: 'productionCheap' },
|
|
2557
2688
|
{ name: 'Produção Nano/SLM', value: 'productionNano' },
|
|
2558
2689
|
{ name: 'Auditoria', value: 'audit' },
|
|
2559
2690
|
],
|
|
2560
|
-
default: '
|
|
2691
|
+
default: 'productionFast',
|
|
2561
2692
|
description: 'Preenche defaults seguros para contexto, diagnostico, historico de tools e mensagens recentes. Valores definidos manualmente continuam tendo prioridade.',
|
|
2562
2693
|
},
|
|
2563
2694
|
{ displayName: 'Agent ID', name: 'agentId', type: 'string', default: '' },
|
|
2564
2695
|
{ displayName: 'App ID', name: 'appId', type: 'string', default: '' },
|
|
2565
2696
|
{ displayName: 'Run ID', name: 'runId', type: 'string', default: '' },
|
|
2566
2697
|
{ displayName: 'Top K', name: 'topK', type: 'number', typeOptions: { minValue: 1 }, default: 25, description: 'Quantidade de memórias a recuperar (modos semânticos e limites de recentes)' },
|
|
2698
|
+
{ displayName: 'Usar Memória Vetorial no Caminho Quente', name: 'useVectorMemory', type: 'boolean', default: false, description: 'Quando desligado, o padrão usa thread estruturada, tools e SLM sem buscar/vetorizar a cada turno.' },
|
|
2699
|
+
{ displayName: 'Persistir Memórias no Backend', name: 'persistBackendMemories', type: 'boolean', default: false, description: 'Quando desligado, mantém o estado no workflow/static data para reduzir latência.' },
|
|
2567
2700
|
{ displayName: 'Rerank', name: 'rerank', type: 'boolean', default: true, description: 'Reordenação por relevância (modos semânticos)', displayOptions: { show: { '/retrievalMode': ['semantic', 'semanticV2', 'hybrid'] } } },
|
|
2568
2701
|
{ displayName: 'Fields (lista separada por vírgula)', name: 'fields', type: 'string', default: '', description: 'Campos específicos a retornar da API (modos semânticos)', displayOptions: { show: { '/retrievalMode': ['semantic', 'semanticV2', 'hybrid'] } } },
|
|
2569
2702
|
{ displayName: 'Filters (JSON)', name: 'filters', type: 'json', default: '{}', description: 'Objeto de filtros avançados para busca v2', displayOptions: { show: { '/retrievalMode': ['semanticV2', 'hybrid'] } } },
|
|
@@ -2634,6 +2767,18 @@ class Mem0Memory {
|
|
|
2634
2767
|
const memoryKey = this.getNodeParameter('memoryKey', itemIndex);
|
|
2635
2768
|
let currentMessages = [];
|
|
2636
2769
|
const loadCache = new Map();
|
|
2770
|
+
const recordMemoryEvent = (action, payload = {}, error) => {
|
|
2771
|
+
const { index } = this.addInputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, [
|
|
2772
|
+
[{ json: { action, ...(payload.input !== undefined ? { input: payload.input } : {}), ...(payload.values !== undefined ? { values: payload.values } : {}) } }],
|
|
2773
|
+
]);
|
|
2774
|
+
if (error) {
|
|
2775
|
+
this.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, error);
|
|
2776
|
+
return;
|
|
2777
|
+
}
|
|
2778
|
+
this.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, [
|
|
2779
|
+
[{ json: { action, ...payload } }],
|
|
2780
|
+
]);
|
|
2781
|
+
};
|
|
2637
2782
|
const memory = {
|
|
2638
2783
|
memoryKeys: [memoryKey],
|
|
2639
2784
|
inputKey: 'input',
|
|
@@ -2643,21 +2788,25 @@ class Mem0Memory {
|
|
|
2643
2788
|
getMessages: async () => currentMessages,
|
|
2644
2789
|
addMessage: async (message) => {
|
|
2645
2790
|
currentMessages.push(message);
|
|
2646
|
-
await Mem0Memory.prototype.saveMessagesForItem.call(this, itemIndex, [message]);
|
|
2791
|
+
const saved = await Mem0Memory.prototype.saveMessagesForItem.call(this, itemIndex, [message]);
|
|
2792
|
+
recordMemoryEvent('chatHistory.addMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
|
|
2647
2793
|
},
|
|
2648
2794
|
addUserMessage: async (message) => {
|
|
2649
2795
|
const baseMessage = toBaseMessage({ role: 'user', content: message });
|
|
2650
2796
|
currentMessages.push(baseMessage);
|
|
2651
|
-
await Mem0Memory.prototype.saveMessagesForItem.call(this, itemIndex, [baseMessage]);
|
|
2797
|
+
const saved = await Mem0Memory.prototype.saveMessagesForItem.call(this, itemIndex, [baseMessage]);
|
|
2798
|
+
recordMemoryEvent('chatHistory.addUserMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
|
|
2652
2799
|
},
|
|
2653
2800
|
addAIChatMessage: async (message) => {
|
|
2654
2801
|
const baseMessage = toBaseMessage({ role: 'assistant', content: message });
|
|
2655
2802
|
currentMessages.push(baseMessage);
|
|
2656
|
-
await Mem0Memory.prototype.saveMessagesForItem.call(this, itemIndex, [baseMessage]);
|
|
2803
|
+
const saved = await Mem0Memory.prototype.saveMessagesForItem.call(this, itemIndex, [baseMessage]);
|
|
2804
|
+
recordMemoryEvent('chatHistory.addAIChatMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
|
|
2657
2805
|
},
|
|
2658
2806
|
addMessages: async (messages) => {
|
|
2659
2807
|
currentMessages.push(...messages);
|
|
2660
|
-
await Mem0Memory.prototype.saveMessagesForItem.call(this, itemIndex, messages);
|
|
2808
|
+
const saved = await Mem0Memory.prototype.saveMessagesForItem.call(this, itemIndex, messages);
|
|
2809
|
+
recordMemoryEvent('chatHistory.addMessages', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: Array.isArray(messages) ? messages.length : 0 });
|
|
2661
2810
|
},
|
|
2662
2811
|
clear: async () => {
|
|
2663
2812
|
currentMessages = [];
|
|
@@ -2722,25 +2871,16 @@ class Mem0Memory {
|
|
|
2722
2871
|
async saveMessagesForItem(itemIndex, messages = []) {
|
|
2723
2872
|
const inputValues = {};
|
|
2724
2873
|
const outputValues = {};
|
|
2725
|
-
const toolCalls =
|
|
2874
|
+
const toolCalls = extractToolCallsFromMessages(messages);
|
|
2726
2875
|
const inputParts = [];
|
|
2727
2876
|
const outputParts = [];
|
|
2728
2877
|
for (const message of messages || []) {
|
|
2729
|
-
const type =
|
|
2730
|
-
const content =
|
|
2878
|
+
const type = messageTypeOf(message);
|
|
2879
|
+
const content = messageContentOf(message);
|
|
2731
2880
|
if (type === 'human' || type === 'user')
|
|
2732
2881
|
inputParts.push(content);
|
|
2733
2882
|
else if (type === 'ai' || type === 'assistant')
|
|
2734
2883
|
outputParts.push(content);
|
|
2735
|
-
else if (type === 'tool') {
|
|
2736
|
-
toolCalls.push({
|
|
2737
|
-
name: message.name || message.toolName || message.tool || (message.additional_kwargs && (message.additional_kwargs.name || message.additional_kwargs.tool_name)) || 'tool',
|
|
2738
|
-
input: '',
|
|
2739
|
-
ok: true,
|
|
2740
|
-
result: summarizeToolResult(content),
|
|
2741
|
-
at: nowIso(),
|
|
2742
|
-
});
|
|
2743
|
-
}
|
|
2744
2884
|
}
|
|
2745
2885
|
if (inputParts.length)
|
|
2746
2886
|
inputValues.input = inputParts.join('\n');
|
|
@@ -2751,8 +2891,11 @@ class Mem0Memory {
|
|
|
2751
2891
|
outputValues.output = outputParts.join('\n').trim();
|
|
2752
2892
|
if (toolContext.length)
|
|
2753
2893
|
outputValues.__temboryToolCalls = toolContext;
|
|
2754
|
-
if (inputValues.input || outputValues.output)
|
|
2894
|
+
if (inputValues.input || outputValues.output || toolContext.length) {
|
|
2755
2895
|
await Mem0Memory.prototype.saveContextForItem.call(this, itemIndex, inputValues, outputValues);
|
|
2896
|
+
return { saved: true, input: inputValues, output: outputValues, toolCalls: toolContext };
|
|
2897
|
+
}
|
|
2898
|
+
return { saved: false, input: inputValues, output: outputValues, toolCalls: toolContext };
|
|
2756
2899
|
}
|
|
2757
2900
|
async saveContextForItem(itemIndex, inputValues = {}, outputValues = {}) {
|
|
2758
2901
|
const threadId = this.getNodeParameter('threadId', itemIndex);
|
|
@@ -2764,6 +2907,14 @@ class Mem0Memory {
|
|
|
2764
2907
|
const rawOutput = pickText(outputValues, ['output', 'response', 'text', 'answer']);
|
|
2765
2908
|
const output = cleanAssistantTranscriptText(rawOutput);
|
|
2766
2909
|
const toolCalls = extractToolCalls(outputValues);
|
|
2910
|
+
store.captureState[key] = {
|
|
2911
|
+
last_save_at: nowIso(),
|
|
2912
|
+
last_save_had_input: Boolean(input),
|
|
2913
|
+
last_save_had_output: Boolean(output),
|
|
2914
|
+
last_save_tool_calls_captured: toolCalls.length,
|
|
2915
|
+
last_save_tool_names: toolCalls.map((tool) => tool.name).filter(Boolean).slice(0, 20),
|
|
2916
|
+
last_save_capture_sources: Array.from(new Set(toolCalls.map((tool) => tool.source).filter(Boolean))),
|
|
2917
|
+
};
|
|
2767
2918
|
const recentForMem0 = [];
|
|
2768
2919
|
const profileFromTurn = extractProfileFactsFromText(input, 'user_message', nowIso());
|
|
2769
2920
|
if (Object.keys(profileFromTurn).length) {
|
|
@@ -2851,7 +3002,9 @@ class Mem0Memory {
|
|
|
2851
3002
|
body.app_id = String(adv.appId);
|
|
2852
3003
|
if (adv.runId)
|
|
2853
3004
|
body.run_id = String(adv.runId);
|
|
2854
|
-
|
|
3005
|
+
if (adv.persistBackendMemories === false)
|
|
3006
|
+
return;
|
|
3007
|
+
const connectedEmbedding = adv.useVectorMemory === false ? null : await getConnectedEmbedding(this, itemIndex);
|
|
2855
3008
|
if (connectedEmbedding) {
|
|
2856
3009
|
const ids = { user_id: body.user_id, agent_id: body.agent_id, run_id: body.run_id };
|
|
2857
3010
|
const clientMemories = [];
|
|
@@ -3119,6 +3272,8 @@ class Mem0Memory {
|
|
|
3119
3272
|
const project = this.getNodeParameter('project', itemIndex, '');
|
|
3120
3273
|
const adv = applyOperationalPreset(readAdvancedOptions(this, itemIndex));
|
|
3121
3274
|
payloadFormat = adv.payloadFormat || payloadFormat;
|
|
3275
|
+
const vectorMemoryEnabled = adv.useVectorMemory !== false;
|
|
3276
|
+
const backendPersistenceEnabled = adv.persistBackendMemories !== false;
|
|
3122
3277
|
const store = getMemoryStore(this);
|
|
3123
3278
|
const key = userKeyFrom(threadId, adv, project);
|
|
3124
3279
|
const queryParam = this.getNodeParameter('query', itemIndex, '');
|
|
@@ -3139,12 +3294,14 @@ class Mem0Memory {
|
|
|
3139
3294
|
catch (error) {
|
|
3140
3295
|
connectedAi.errors.push(`languageModel: ${error.message || String(error)}`);
|
|
3141
3296
|
}
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3297
|
+
if (vectorMemoryEnabled) {
|
|
3298
|
+
try {
|
|
3299
|
+
connectedEmbedding = await this.getInputConnectionData(n8n_workflow_1.NodeConnectionTypes.AiEmbedding, itemIndex);
|
|
3300
|
+
connectedAi.embedding = true;
|
|
3301
|
+
}
|
|
3302
|
+
catch (error) {
|
|
3303
|
+
connectedAi.errors.push(`embedding: ${error.message || String(error)}`);
|
|
3304
|
+
}
|
|
3148
3305
|
}
|
|
3149
3306
|
if (connectedEmbedding && typeof connectedEmbedding.embedQuery === 'function' && String(query || '').trim()) {
|
|
3150
3307
|
try {
|
|
@@ -3166,7 +3323,7 @@ class Mem0Memory {
|
|
|
3166
3323
|
catch { }
|
|
3167
3324
|
let payload;
|
|
3168
3325
|
let vectorMemories = [];
|
|
3169
|
-
if (retrievalMode === 'semantic' || retrievalMode === 'semanticV2' || retrievalMode === 'hybrid') {
|
|
3326
|
+
if (vectorMemoryEnabled && (retrievalMode === 'semantic' || retrievalMode === 'semanticV2' || retrievalMode === 'hybrid')) {
|
|
3170
3327
|
const body = { query: String(query || '') };
|
|
3171
3328
|
// IDs
|
|
3172
3329
|
body.user_id = key;
|
|
@@ -3303,7 +3460,7 @@ class Mem0Memory {
|
|
|
3303
3460
|
payload = semMemories.map((m) => { var _a, _b; return ({ role: 'system', content: (_b = (_a = m.memory) !== null && _a !== void 0 ? _a : m.text) !== null && _b !== void 0 ? _b : JSON.stringify(m) }); });
|
|
3304
3461
|
}
|
|
3305
3462
|
}
|
|
3306
|
-
else {
|
|
3463
|
+
else if (backendPersistenceEnabled) {
|
|
3307
3464
|
const qs = {};
|
|
3308
3465
|
qs.user_id = key;
|
|
3309
3466
|
if (adv.agentId)
|
|
@@ -3339,7 +3496,7 @@ class Mem0Memory {
|
|
|
3339
3496
|
connectedAi.errors.push(`graph.relations: ${error.message || String(error)}`);
|
|
3340
3497
|
}
|
|
3341
3498
|
}
|
|
3342
|
-
if (connectedEmbedding && adv.includeRecentMessages !== false) {
|
|
3499
|
+
if (vectorMemoryEnabled && connectedEmbedding && adv.includeRecentMessages !== false && adv.includeRecentMessageProbe !== false) {
|
|
3343
3500
|
try {
|
|
3344
3501
|
const transcriptProbe = [
|
|
3345
3502
|
'recent conversation transcript',
|
|
@@ -3374,7 +3531,7 @@ class Mem0Memory {
|
|
|
3374
3531
|
connectedAi.errors.push(`recentMessageProbe: ${error.message || String(error)}`);
|
|
3375
3532
|
}
|
|
3376
3533
|
}
|
|
3377
|
-
if (connectedEmbedding && adv.includeToolHistory !== false) {
|
|
3534
|
+
if (vectorMemoryEnabled && connectedEmbedding && adv.includeToolHistory !== false && adv.includeToolLedgerProbe !== false) {
|
|
3378
3535
|
try {
|
|
3379
3536
|
const toolProbe = [
|
|
3380
3537
|
'Tool history ledger',
|
|
@@ -3412,7 +3569,7 @@ class Mem0Memory {
|
|
|
3412
3569
|
let persistedRecentMessages = [];
|
|
3413
3570
|
let persistedToolHistory = [];
|
|
3414
3571
|
let persistedMemoryItems = [];
|
|
3415
|
-
if (adv.includeRecentMessages !== false || adv.includeToolHistory !== false) {
|
|
3572
|
+
if (backendPersistenceEnabled && (adv.includeRecentMessages !== false || adv.includeToolHistory !== false)) {
|
|
3416
3573
|
try {
|
|
3417
3574
|
const qs = { user_id: key, limit: Math.max(Number(adv.recentMessagesLastN || 50) * 8, Number(adv.toolHistoryLastN || 10) * 12, 200) };
|
|
3418
3575
|
if (adv.agentId)
|
|
@@ -3559,6 +3716,16 @@ class Mem0Memory {
|
|
|
3559
3716
|
graph: graph.length,
|
|
3560
3717
|
project: project || null,
|
|
3561
3718
|
memoryNamespace: key,
|
|
3719
|
+
vectorMemoryEnabled,
|
|
3720
|
+
backendPersistenceEnabled,
|
|
3721
|
+
captureState: store.captureState[key] || {
|
|
3722
|
+
last_save_at: null,
|
|
3723
|
+
last_save_had_input: false,
|
|
3724
|
+
last_save_had_output: false,
|
|
3725
|
+
last_save_tool_calls_captured: 0,
|
|
3726
|
+
last_save_tool_names: [],
|
|
3727
|
+
last_save_capture_sources: [],
|
|
3728
|
+
},
|
|
3562
3729
|
connectedAi,
|
|
3563
3730
|
activeSummary: summaryDiagnostics,
|
|
3564
3731
|
};
|
|
@@ -3803,6 +3970,7 @@ exports.Mem0Memory = Mem0Memory;
|
|
|
3803
3970
|
exports.__private = {
|
|
3804
3971
|
extractToolCallsFromText,
|
|
3805
3972
|
extractToolCalls,
|
|
3973
|
+
extractToolCallsFromMessages,
|
|
3806
3974
|
toolHistoryItemsFromMemory,
|
|
3807
3975
|
explicitToolHistoryItemsFromMemory,
|
|
3808
3976
|
toolHistoryFromMemory,
|
|
@@ -3855,6 +4023,8 @@ exports.__private = {
|
|
|
3855
4023
|
embedQueryCached,
|
|
3856
4024
|
compactToolResult,
|
|
3857
4025
|
compactToolHistoryForAgent,
|
|
4026
|
+
compactVectorMemoriesForAgent,
|
|
4027
|
+
isConversationEchoMemory,
|
|
3858
4028
|
compactOperationalStateForAgent,
|
|
3859
4029
|
activeSummaryIsFresh,
|
|
3860
4030
|
readActiveSummary,
|
package/package.json
CHANGED