n8n-nodes-tembory 1.0.19 → 1.0.21
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 +13 -1
- package/dist/nodes/Mem0/Mem0Memory.node.js +41 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Node de memoria operacional da Tembory para agentes de IA no n8n.
|
|
4
4
|
|
|
5
|
-
Versao atual: `1.0.
|
|
5
|
+
Versao atual: `1.0.21`.
|
|
6
|
+
|
|
7
|
+
## 1.0.21
|
|
8
|
+
|
|
9
|
+
- O contexto principal passa a anexar o input atual do agente ao transcript antes de renderizar memoria.
|
|
10
|
+
- `Conversation frame` agora inclui `recent_messages_chronological`, com janela curta usuario/assistente em ordem.
|
|
11
|
+
- Mesmo antes do `saveContext`, o agente recebe a mensagem atual e a mensagem anterior do cliente no contexto estrutural.
|
|
12
|
+
|
|
13
|
+
## 1.0.20
|
|
14
|
+
|
|
15
|
+
- Torna `Conversation frame` obrigatorio em todo contexto estruturado, antes de estado operacional e historico de tools.
|
|
16
|
+
- Expõe `current_user_message`, `previous_user_message` e ultimas mensagens do cliente como fonte autoritativa de curto prazo.
|
|
17
|
+
- Remove a dependencia de detectar termos como `msg`/`mensagem` para o agente conseguir responder sobre a ultima mensagem do cliente.
|
|
6
18
|
|
|
7
19
|
## 1.0.19
|
|
8
20
|
|
|
@@ -1090,6 +1090,16 @@ const dedupeRecentMessages = (items) => {
|
|
|
1090
1090
|
}
|
|
1091
1091
|
return out;
|
|
1092
1092
|
};
|
|
1093
|
+
const appendCurrentUserMessage = (items = [], query = '') => {
|
|
1094
|
+
const content = String(query || '').trim();
|
|
1095
|
+
if (!content)
|
|
1096
|
+
return items || [];
|
|
1097
|
+
const normalized = normalizeIntentText(content).trim();
|
|
1098
|
+
const lastUser = [...(items || [])].reverse().find((msg) => /^(user|human)$/i.test(String(msg.role || '')));
|
|
1099
|
+
if (lastUser && normalizeIntentText(lastUser.content).trim() === normalized)
|
|
1100
|
+
return items || [];
|
|
1101
|
+
return (items || []).concat([{ role: 'user', content: truncate(content, 2000), at: nowIso(), source: 'current_input' }]);
|
|
1102
|
+
};
|
|
1093
1103
|
const dedupeToolHistory = (items) => {
|
|
1094
1104
|
const seen = new Set();
|
|
1095
1105
|
const out = [];
|
|
@@ -1167,6 +1177,27 @@ const previousUserMessageForQuery = (query = '', recentMessages = []) => {
|
|
|
1167
1177
|
return users[1] || null;
|
|
1168
1178
|
return users[0] || null;
|
|
1169
1179
|
};
|
|
1180
|
+
const buildConversationFrame = ({ query = '', recentMessages = [], workingMemory = {} }) => {
|
|
1181
|
+
const normalizedQuery = normalizeIntentText(query).trim();
|
|
1182
|
+
const users = recentUserMessages(recentMessages);
|
|
1183
|
+
const currentUser = users.find((msg) => normalizeIntentText(msg.content).trim() === normalizedQuery) || (query ? { role: 'user', content: query, at: nowIso() } : null);
|
|
1184
|
+
const previousUser = previousUserMessageForQuery(query, recentMessages);
|
|
1185
|
+
const chronological = pruneByLimit(recentMessages || [], 10).map((msg) => ({
|
|
1186
|
+
role: msg.role,
|
|
1187
|
+
content: truncate(msg.content, 500),
|
|
1188
|
+
at: msg.at,
|
|
1189
|
+
}));
|
|
1190
|
+
return cleanContextValue({
|
|
1191
|
+
current_user_message: currentUser ? truncate(currentUser.content, 500) : truncate(query, 500),
|
|
1192
|
+
previous_user_message: previousUser ? truncate(previousUser.content, 500) : (workingMemory === null || workingMemory === void 0 ? void 0 : workingMemory.last_user_message) || null,
|
|
1193
|
+
recent_messages_chronological: chronological,
|
|
1194
|
+
recent_user_messages: users
|
|
1195
|
+
.filter((msg) => normalizeIntentText(msg.content).trim() !== normalizedQuery)
|
|
1196
|
+
.slice(0, 5)
|
|
1197
|
+
.map((msg) => ({ role: msg.role, content: truncate(msg.content, 500), at: msg.at })),
|
|
1198
|
+
instruction: 'This is the authoritative short-term conversation frame. If the user asks about the last/current/previous client message, answer from previous_user_message/recent_user_messages before using vector memories, summaries, operational state, or tool history.',
|
|
1199
|
+
});
|
|
1200
|
+
};
|
|
1170
1201
|
const buildCurrentTurnFocus = ({ query = '', recentMessages = [], operationalState = {}, workingMemory = {} }) => {
|
|
1171
1202
|
const recall = isConversationRecallQuery(query);
|
|
1172
1203
|
const agendaStatus = isAgendaStatusQuery(query);
|
|
@@ -1850,10 +1881,15 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1850
1881
|
section: 'context_header',
|
|
1851
1882
|
title: 'Tembory context',
|
|
1852
1883
|
value: compactForAgent || compactStateSections
|
|
1853
|
-
? 'Read-only memory. Follow next_expected_action when present. Before calling downstream tools, verify required prior tool context in tool_history or operational_state. Do not repeat tools listed in do_not_repeat_tools.'
|
|
1854
|
-
: 'Use this context as read-only memory. Prefer it over guessing. Do not mention internal section names to the user. Treat next_expected_action as an instruction, not as a suggestion. If it says to call a tool now, call that tool instead of asking the user the same question again. If the user asks to continue, chooses a slot, says ok/sim, reserve, confirm, update, cancel, or performs any downstream action that depends on a prior tool result, first verify the required prior result in tool_history, recent_messages, or vector memories. If the required prior result is absent, do not call the downstream tool; ask for the missing context or call the appropriate prerequisite tool.',
|
|
1884
|
+
? 'Read-only memory. Conversation frame is authoritative for current/previous client messages. Follow next_expected_action when present. Before calling downstream tools, verify required prior tool context in tool_history or operational_state. Do not repeat tools listed in do_not_repeat_tools.'
|
|
1885
|
+
: 'Use this context as read-only memory. Prefer it over guessing. Do not mention internal section names to the user. The Conversation frame is authoritative for current, previous, and recent client messages. Treat next_expected_action as an instruction, not as a suggestion. If it says to call a tool now, call that tool instead of asking the user the same question again. If the user asks to continue, chooses a slot, says ok/sim, reserve, confirm, update, cancel, or performs any downstream action that depends on a prior tool result, first verify the required prior result in tool_history, recent_messages, or vector memories. If the required prior result is absent, do not call the downstream tool; ask for the missing context or call the appropriate prerequisite tool.',
|
|
1855
1886
|
});
|
|
1856
1887
|
}
|
|
1888
|
+
sections.push({
|
|
1889
|
+
section: 'conversation_frame',
|
|
1890
|
+
title: 'Conversation frame',
|
|
1891
|
+
value: buildConversationFrame({ query, recentMessages, workingMemory }),
|
|
1892
|
+
});
|
|
1857
1893
|
const currentTurnFocus = buildCurrentTurnFocus({ query, recentMessages, operationalState, workingMemory });
|
|
1858
1894
|
if (currentTurnFocus) {
|
|
1859
1895
|
sections.push({
|
|
@@ -3013,8 +3049,9 @@ class Mem0Memory {
|
|
|
3013
3049
|
.flatMap(toolHistoryItemsFromMemory)
|
|
3014
3050
|
.sort((a, b) => new Date(a.at || 0).getTime() - new Date(b.at || 0).getTime());
|
|
3015
3051
|
}
|
|
3016
|
-
const
|
|
3017
|
-
const
|
|
3052
|
+
const storedRecentMessages = adv.includeRecentMessages === false ? [] : (store.recentMessages[key] || []).concat(persistedRecentMessages);
|
|
3053
|
+
const allRecentMessages = dedupeRecentMessages(appendCurrentUserMessage(storedRecentMessages, query));
|
|
3054
|
+
const recentMessages = pruneByLimit(allRecentMessages, Math.max(Number(adv.recentMessagesLastN || 8), 8));
|
|
3018
3055
|
const toolHistoryFromRecentMessages = [];
|
|
3019
3056
|
if (adv.includeToolHistory !== false) {
|
|
3020
3057
|
for (const msg of recentMessages)
|
package/package.json
CHANGED