n8n-nodes-tembory 1.0.43 → 1.0.44

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.
@@ -632,6 +632,36 @@ const encodeToolLedger = (tools = [], threadId) => {
632
632
  })),
633
633
  })}`;
634
634
  };
635
+ const encodeTurnArchive = ({ threadId, messages = [], tools = [], workingMemory = {}, decisionState = {}, memoryCompression = {}, operationalState = {} }) => {
636
+ const chronological = sortConversationChronological(messages || []);
637
+ const orderedTools = sortToolHistory(tools || []);
638
+ return `Tembory long-term turn archive. Use vector search only when short-term SLM state and recent transcript are insufficient. ${safeStringify({
639
+ marker: 'tembory_turn_archive_v1',
640
+ thread_id: threadId,
641
+ generated_at: nowIso(),
642
+ conversation: chronological.map((msg) => ({
643
+ role: msg.role || 'user',
644
+ content: msg.content || '',
645
+ at: msg.at || nowIso(),
646
+ })),
647
+ tools: orderedTools.map((tool, index) => ({
648
+ id: tool.id || tool.callId || tool.call_id || '',
649
+ turn_id: tool.turnId || tool.turn_id || '',
650
+ sequence: tool.sequence || index + 1,
651
+ name: tool.name || tool.tool || tool.toolName || '',
652
+ reason: tool.reason || tool.source || '',
653
+ input: tool.input || '',
654
+ ok: tool.ok !== false,
655
+ output: tool.result || '',
656
+ at: tool.at || nowIso(),
657
+ source: tool.source || 'n8n',
658
+ })),
659
+ working_memory: workingMemory,
660
+ decision_state: decisionState,
661
+ memory_compression: memoryCompression,
662
+ operational_state: operationalState,
663
+ })}`;
664
+ };
635
665
  const parseRecentMessageMarker = (text) => {
636
666
  if (!text || typeof text !== 'string' || !text.startsWith(RECENT_MESSAGE_MARKER))
637
667
  return null;
@@ -1125,7 +1155,7 @@ const applyOperationalPreset = (advanced = {}) => {
1125
1155
  enableTransientSummaryCache: true,
1126
1156
  transientSummaryCacheTTLSeconds: 300,
1127
1157
  compactStateSections: true,
1128
- useVectorMemory: true,
1158
+ useVectorMemory: false,
1129
1159
  persistBackendMemories: true,
1130
1160
  includeRecentMessageProbe: false,
1131
1161
  includeToolLedgerProbe: false,
@@ -2598,7 +2628,7 @@ class Mem0Memory {
2598
2628
  { displayName: 'Máximo de Relações', name: 'maxRelations', type: 'number', default: 10 },
2599
2629
  { displayName: 'Incluir Action Ledger', name: 'includeActionLedger', type: 'boolean', default: true },
2600
2630
  { displayName: 'Incluir Entity Timeline', name: 'includeEntityTimeline', type: 'boolean', default: false },
2601
- { displayName: 'Usar Memória Vetorial no Caminho Quente', name: 'useVectorMemory', type: 'boolean', default: true },
2631
+ { displayName: 'Usar Memória Vetorial no Caminho Quente', name: 'useVectorMemory', type: 'boolean', default: false },
2602
2632
  { displayName: 'Persistir Memórias no Backend', name: 'persistBackendMemories', type: 'boolean', default: true },
2603
2633
  { displayName: 'Probe Vetorial de Mensagens Recentes', name: 'includeRecentMessageProbe', type: 'boolean', default: false },
2604
2634
  { displayName: 'Probe Vetorial de Tool Ledger', name: 'includeToolLedgerProbe', type: 'boolean', default: false },
@@ -2695,7 +2725,7 @@ class Mem0Memory {
2695
2725
  { displayName: 'App ID', name: 'appId', type: 'string', default: '' },
2696
2726
  { displayName: 'Run ID', name: 'runId', type: 'string', default: '' },
2697
2727
  { 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: true, description: 'Quando ligado, usa uma busca BYO mínima para recuperar memórias persistidas; probes/grafo continuam separados.' },
2728
+ { displayName: 'Usar Memória Vetorial no Caminho Quente', name: 'useVectorMemory', type: 'boolean', default: false, description: 'Quando ligado, usa busca BYO sob demanda para recuperar histórico longo. O padrão mantém o contexto quente em transcript + SLM e apenas arquiva o turno no vetor.' },
2699
2729
  { displayName: 'Persistir Memórias no Backend', name: 'persistBackendMemories', type: 'boolean', default: true, description: 'Quando desligado, mantém o estado no workflow/static data para reduzir latência.' },
2700
2730
  { displayName: 'Rerank', name: 'rerank', type: 'boolean', default: true, description: 'Reordenação por relevância (modos semânticos)', displayOptions: { show: { '/retrievalMode': ['semantic', 'semanticV2', 'hybrid'] } } },
2701
2731
  { 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'] } } },
@@ -3009,69 +3039,27 @@ class Mem0Memory {
3009
3039
  const connectedEmbedding = await getConnectedEmbedding(this, itemIndex);
3010
3040
  if (connectedEmbedding) {
3011
3041
  const ids = { user_id: body.user_id, agent_id: body.agent_id, run_id: body.run_id };
3012
- const clientMemories = [];
3013
- for (const message of messages) {
3014
- clientMemories.push(await createClientVectorMemory(connectedEmbedding, message.content, {
3015
- kind: 'conversation_message',
3016
- role: message.role,
3017
- thread_id: threadId,
3018
- project: project || undefined,
3019
- at: nowIso(),
3020
- source: 'n8n_connected_embedding',
3021
- }, ids));
3022
- }
3023
- if (adv.includeRecentMessages !== false && recentForMem0.length) {
3024
- for (const recent of recentForMem0) {
3025
- clientMemories.push(await createClientVectorMemory(connectedEmbedding, encodeRecentMessage(recent, threadId), {
3026
- kind: 'recent_message',
3027
- role: recent.role,
3028
- content: recent.content,
3029
- at: recent.at,
3030
- thread_id: threadId,
3031
- project: project || undefined,
3032
- source: 'n8n_connected_embedding',
3033
- }, ids));
3034
- }
3035
- clientMemories.push(await createClientVectorMemory(connectedEmbedding, encodeConversationLedger(recentForTurn, threadId), {
3036
- kind: 'conversation_ledger',
3037
- thread_id: threadId,
3038
- project: project || undefined,
3039
- source: 'n8n_connected_embedding',
3040
- generated_at: nowIso(),
3041
- }, ids));
3042
- }
3043
- if (adv.persistToolFactsToMem0 && toolCalls.length) {
3044
- const facts = toolCalls.map((tool) => `Tool ${tool.name} input=${tool.input}${tool.result ? ` result=${tool.result}` : ''}`).join('\n');
3045
- clientMemories.push(await createClientVectorMemory(connectedEmbedding, `Tool facts (read-only):\n${truncate(facts, 2000)}`, {
3046
- kind: 'tool_facts',
3047
- source: 'n8n_connected_embedding',
3048
- }, ids));
3049
- }
3050
- if (adv.includeToolHistory !== false && toolCalls.length) {
3051
- for (const tool of toolCalls) {
3052
- clientMemories.push(await createClientVectorMemory(connectedEmbedding, encodeToolCall(tool, threadId), {
3053
- kind: 'tool_history',
3054
- id: tool.id,
3055
- sequence: tool.sequence,
3056
- turn_id: tool.turnId,
3057
- name: tool.name,
3058
- input: tool.input,
3059
- ok: tool.ok,
3060
- result: tool.result,
3061
- at: tool.at,
3062
- source: tool.source || 'n8n_connected_embedding',
3063
- thread_id: threadId,
3064
- }, ids));
3065
- }
3066
- clientMemories.push(await createClientVectorMemory(connectedEmbedding, encodeToolLedger(toolHistoryForTurn, threadId), {
3067
- kind: 'tool_ledger',
3042
+ const archiveText = encodeTurnArchive({
3043
+ threadId,
3044
+ messages: recentForTurn,
3045
+ tools: toolHistoryForTurn,
3046
+ workingMemory: workingMemoryForTurn,
3047
+ decisionState: decisionStateForTurn,
3048
+ memoryCompression: compressionForTurn,
3049
+ operationalState: operationalStateForTurn,
3050
+ });
3051
+ await saveClientVectorMemories(this, [
3052
+ await createClientVectorMemory(connectedEmbedding, archiveText, {
3053
+ kind: 'turn_archive',
3068
3054
  thread_id: threadId,
3069
3055
  project: project || undefined,
3070
3056
  source: 'n8n_connected_embedding',
3071
3057
  generated_at: nowIso(),
3072
- }, ids));
3073
- }
3074
- await saveClientVectorMemories(this, clientMemories, ids);
3058
+ message_count: recentForTurn.length,
3059
+ tool_count: toolHistoryForTurn.length,
3060
+ latest_tool: toolHistoryForTurn.at(-1)?.name || null,
3061
+ }, ids),
3062
+ ], ids);
3075
3063
  if (adv.includeRecentMessages !== false && recentForMem0.length) {
3076
3064
  for (const recent of recentForMem0) {
3077
3065
  await safePersistLegacyMemory(this, {
@@ -3305,15 +3293,8 @@ class Mem0Memory {
3305
3293
  connectedAi.errors.push(`embedding: ${error.message || String(error)}`);
3306
3294
  }
3307
3295
  }
3308
- if (connectedEmbedding && typeof connectedEmbedding.embedQuery === 'function' && String(query || '').trim()) {
3309
- try {
3310
- await embedQueryCached(connectedEmbedding, String(query));
3311
- connectedAi.embeddingQuery = true;
3312
- }
3313
- catch (error) {
3314
- connectedAi.errors.push(`embedding.embedQuery: ${error.message || String(error)}`);
3315
- }
3316
- }
3296
+ if (connectedEmbedding && typeof connectedEmbedding.embedQuery === 'function' && String(query || '').trim())
3297
+ connectedAi.embeddingQuery = vectorMemoryEnabled;
3317
3298
  try {
3318
3299
  this.logger?.debug('Tembory loading memory variables before model invocation', {
3319
3300
  itemIndex,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.0.43",
3
+ "version": "1.0.44",
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",