n8n-nodes-tembory 1.0.22 → 1.0.23

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 CHANGED
@@ -2,7 +2,12 @@
2
2
 
3
3
  Node de memoria operacional da Tembory para agentes de IA no n8n.
4
4
 
5
- Versao atual: `1.0.22`.
5
+ Versao atual: `1.0.23`.
6
+
7
+ ## 1.0.23
8
+
9
+ - Corrige o frame de conversa para nao repetir a mensagem atual em `previous_user_message` quando ainda nao existe mensagem anterior real.
10
+ - Mantem `previous_user_message: null` explicitamente em perguntas de recall no primeiro turno, evitando respostas erradas sobre "ultima mensagem".
6
11
 
7
12
  ## 1.0.22
8
13
 
@@ -1177,19 +1177,30 @@ const previousUserMessageForQuery = (query = '', recentMessages = []) => {
1177
1177
  return users[1] || null;
1178
1178
  return users[0] || null;
1179
1179
  };
1180
+ const previousUserFallbackFromWorkingMemory = (query = '', workingMemory = {}) => {
1181
+ const candidate = workingMemory === null || workingMemory === void 0 ? void 0 : workingMemory.last_user_message;
1182
+ if (!candidate)
1183
+ return null;
1184
+ const normalizedQuery = normalizeIntentText(query).trim();
1185
+ const normalizedCandidate = normalizeIntentText(candidate).trim();
1186
+ if (normalizedQuery && normalizedCandidate === normalizedQuery)
1187
+ return null;
1188
+ return candidate;
1189
+ };
1180
1190
  const buildConversationFrame = ({ query = '', recentMessages = [], workingMemory = {} }) => {
1181
1191
  const normalizedQuery = normalizeIntentText(query).trim();
1182
1192
  const users = recentUserMessages(recentMessages);
1183
1193
  const currentUser = users.find((msg) => normalizeIntentText(msg.content).trim() === normalizedQuery) || (query ? { role: 'user', content: query, at: nowIso() } : null);
1184
1194
  const previousUser = previousUserMessageForQuery(query, recentMessages);
1195
+ const previousUserMessage = previousUser ? truncate(previousUser.content, 500) : previousUserFallbackFromWorkingMemory(query, workingMemory);
1185
1196
  const chronological = pruneByLimit(recentMessages || [], 10).map((msg) => ({
1186
1197
  role: msg.role,
1187
1198
  content: truncate(msg.content, 500),
1188
1199
  at: msg.at,
1189
1200
  }));
1190
- return cleanContextValue({
1201
+ const frame = cleanContextValue({
1191
1202
  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,
1203
+ previous_user_message: previousUserMessage,
1193
1204
  recent_messages_chronological: chronological,
1194
1205
  recent_user_messages: users
1195
1206
  .filter((msg) => normalizeIntentText(msg.content).trim() !== normalizedQuery)
@@ -1197,6 +1208,9 @@ const buildConversationFrame = ({ query = '', recentMessages = [], workingMemory
1197
1208
  .map((msg) => ({ role: msg.role, content: truncate(msg.content, 500), at: msg.at })),
1198
1209
  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
1210
  });
1211
+ if (!previousUserMessage)
1212
+ frame.previous_user_message = null;
1213
+ return frame;
1200
1214
  };
1201
1215
  const buildCurrentTurnFocus = ({ query = '', recentMessages = [], operationalState = {}, workingMemory = {} }) => {
1202
1216
  const recall = isConversationRecallQuery(query);
@@ -1209,10 +1223,11 @@ const buildCurrentTurnFocus = ({ query = '', recentMessages = [], operationalSta
1209
1223
  .slice(0, 3)
1210
1224
  .map((msg) => ({ role: msg.role, content: truncate(msg.content, 500), at: msg.at }));
1211
1225
  const agenda = (operationalState || {}).agenda_state || {};
1212
- return cleanContextValue({
1226
+ const previousUserMessage = previousUser ? truncate(previousUser.content, 500) : previousUserFallbackFromWorkingMemory(query, workingMemory);
1227
+ const focus = cleanContextValue({
1213
1228
  current_user_request: truncate(query, 500),
1214
1229
  intent: recall ? 'conversation_recall' : 'agenda_status_question',
1215
- previous_user_message: previousUser ? truncate(previousUser.content, 500) : (workingMemory === null || workingMemory === void 0 ? void 0 : workingMemory.last_user_message) || null,
1230
+ previous_user_message: previousUserMessage,
1216
1231
  recent_user_messages: users,
1217
1232
  agenda_status: agendaStatus ? {
1218
1233
  reservation_status: agenda.has_confirmation && !agenda.has_pending_pre_reservation
@@ -1232,6 +1247,9 @@ const buildCurrentTurnFocus = ({ query = '', recentMessages = [], operationalSta
1232
1247
  ? 'Answer the user meta-question from previous_user_message/recent_user_messages. Do not answer with agenda availability unless the user asks for availability.'
1233
1248
  : 'Answer whether the appointment/reservation is already scheduled using agenda_status. Do not offer availability as the main answer unless there is no schedule/reservation state.',
1234
1249
  });
1250
+ if (!previousUserMessage)
1251
+ focus.previous_user_message = null;
1252
+ return focus;
1235
1253
  };
1236
1254
  const inferToolGuard = ({ query, recentMessages, toolHistory, vectorMemories }) => {
1237
1255
  const text = normalizeIntentText(query);
@@ -3487,6 +3505,7 @@ exports.__private = {
3487
3505
  explicitToolHistoryItemsFromMemory,
3488
3506
  toolHistoryFromMemory,
3489
3507
  recentMessageFromMemory,
3508
+ previousUserFallbackFromWorkingMemory,
3490
3509
  dedupeToolHistory,
3491
3510
  applyToolHistoryWindow,
3492
3511
  dedupeRecentMessages,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "description": "Tembory node for n8n AI Agents with profile, tools, timeline, graph and semantic memory",
5
5
  "license": "MIT",
6
6
  "homepage": "https://tembory.com",