n8n-nodes-tembory 1.0.14 → 1.0.16

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,22 @@
2
2
 
3
3
  Node de memoria operacional da Tembory para agentes de IA no n8n.
4
4
 
5
- Versao atual: `1.0.14`.
5
+ Versao atual: `1.0.16`.
6
+
7
+ ## 1.0.16
8
+
9
+ - Corrige compatibilidade da UI agrupada com o processamento de parametros do n8n.
10
+ - Mantem `Configuração Tembory` como `fixedCollection`, mas remove o default estrutural pre-preenchido que podia quebrar a renderizacao do editor em alguns runtimes.
11
+ - Preserva os defaults de producao no runtime via `productionBalanced`, mesmo quando os grupos da UI ainda nao foram adicionados manualmente.
12
+ - Adiciona validacao local com `NodeHelpers.getNodeParameters` do `n8n-workflow` para evitar regressao de tela em branco.
13
+
14
+ ## 1.0.15
15
+
16
+ - Reorganiza a interface do node em `Configuração Tembory`, com grupos para Essenciais, Mais Inteligência, Controles Avançados de Busca, Resumo e Estado Persistente, e Diagnóstico e Auditoria.
17
+ - Mantém a coleção legada `Avançado` para compatibilidade com workflows já existentes.
18
+ - Define `Produção Balanceada` como preset padrão para novas configurações.
19
+ - Prioriza IDs estáveis de thread/conversa/contato/cliente antes de `sessionId` na expressão padrão do `ID da Thread`.
20
+ - Adiciona teste para validar a mesclagem dos grupos da nova UI com os presets operacionais.
6
21
 
7
22
  ## 1.0.14
8
23
 
@@ -883,7 +883,7 @@ const userKeyFrom = (threadId, adv, project = '') => {
883
883
  return namespace ? `${namespace}::${base}` : base;
884
884
  };
885
885
  const applyOperationalPreset = (advanced = {}) => {
886
- const preset = String(advanced.operationPreset || 'custom');
886
+ const preset = String(advanced.operationPreset || 'productionBalanced');
887
887
  const presets = {
888
888
  diagnostic: {
889
889
  summarySource: 'auto',
@@ -1053,6 +1053,30 @@ const applyOperationalPreset = (advanced = {}) => {
1053
1053
  };
1054
1054
  return { ...(presets[preset === 'lab' ? 'diagnostic' : preset] || {}), ...advanced };
1055
1055
  };
1056
+ const flattenAdvancedGroups = (groups = {}) => {
1057
+ const flattened = {};
1058
+ const groupNames = ['essentials', 'intelligence', 'retrievalControls', 'summaryState', 'diagnosticsAudit'];
1059
+ for (const groupName of groupNames) {
1060
+ const value = groups === null || groups === void 0 ? void 0 : groups[groupName];
1061
+ const groupValue = Array.isArray(value) ? value[0] : value;
1062
+ if (groupValue && typeof groupValue === 'object')
1063
+ Object.assign(flattened, groupValue);
1064
+ }
1065
+ return flattened;
1066
+ };
1067
+ const readAdvancedOptions = (ctx, itemIndex) => {
1068
+ let legacy = {};
1069
+ let grouped = {};
1070
+ try {
1071
+ legacy = ctx.getNodeParameter('advanced', itemIndex, {}) || {};
1072
+ }
1073
+ catch { }
1074
+ try {
1075
+ grouped = flattenAdvancedGroups(ctx.getNodeParameter('advancedGroups', itemIndex, {}) || {});
1076
+ }
1077
+ catch { }
1078
+ return { ...legacy, ...grouped };
1079
+ };
1056
1080
  const pruneByLimit = (items, limit) => items.slice(Math.max(0, items.length - Math.max(1, Number(limit) || 1)));
1057
1081
  const dedupeRecentMessages = (items) => {
1058
1082
  const seen = new Set();
@@ -2058,7 +2082,7 @@ class Mem0Memory {
2058
2082
  displayName: 'ID da Thread',
2059
2083
  name: 'threadId',
2060
2084
  type: 'string',
2061
- default: '={{ $json.threadId || $json.sessionId || $json.body?.messages?.[0]?.contactId || $json.body?.contactId || $json.contactId || $json.from || $json.sender || $executionId }}',
2085
+ default: '={{ $json.threadId || $json.body?.threadId || $json.body?.conversationId || $json.conversationId || $json.body?.messages?.[0]?.contactId || $json.body?.contactId || $json.contactId || $json.customerId || $json.body?.customerId || $json.from || $json.sender || $json.sessionId || $executionId }}',
2062
2086
  description: 'Identificador estável desta conversa/thread. Usado como user_id se nenhum User ID explícito for informado.',
2063
2087
  },
2064
2088
  {
@@ -2115,11 +2139,129 @@ class Mem0Memory {
2115
2139
  description: 'Como o contexto recuperado será entregue ao agente antes da LLM.',
2116
2140
  },
2117
2141
  {
2118
- displayName: 'Avançado',
2142
+ displayName: 'Configuração Tembory',
2143
+ name: 'advancedGroups',
2144
+ type: 'fixedCollection',
2145
+ placeholder: 'Adicionar Grupo',
2146
+ default: '',
2147
+ typeOptions: {
2148
+ multipleValues: false,
2149
+ },
2150
+ description: 'Grupos recomendados para producao. Todos os recursos continuam disponiveis, mas separados por finalidade.',
2151
+ options: [
2152
+ {
2153
+ name: 'essentials',
2154
+ displayName: 'Essenciais',
2155
+ values: [
2156
+ {
2157
+ displayName: 'Preset Operacional',
2158
+ name: 'operationPreset',
2159
+ type: 'options',
2160
+ options: [
2161
+ { name: 'Custom', value: 'custom' },
2162
+ { name: 'Diagnóstico Completo', value: 'diagnostic' },
2163
+ { name: 'Produção Balanceada', value: 'productionBalanced' },
2164
+ { name: 'Produção Econômica', value: 'productionCheap' },
2165
+ { name: 'Produção Nano/SLM', value: 'productionNano' },
2166
+ { name: 'Auditoria', value: 'audit' },
2167
+ ],
2168
+ default: 'productionBalanced',
2169
+ description: 'Preenche defaults seguros para contexto, historico de tools e memoria ativa.',
2170
+ },
2171
+ { displayName: 'Incluir Cabeçalho de Contexto', name: 'includeContextHeader', type: 'boolean', default: true },
2172
+ { displayName: 'Organizar Seções de Produção', name: 'compactStateSections', type: 'boolean', default: true },
2173
+ { displayName: 'Máximo de Caracteres do Contexto', name: 'contextMaxChars', type: 'number', default: 10000 },
2174
+ { displayName: 'Incluir Tool History', name: 'includeToolHistory', type: 'boolean', default: true },
2175
+ { displayName: 'Incluir Resultado Das Tools', name: 'includeToolResults', type: 'boolean', default: true },
2176
+ { displayName: 'Incluir Working Memory', name: 'includeWorkingMemory', type: 'boolean', default: true },
2177
+ { displayName: 'Incluir Decision State', name: 'includeDecisionState', type: 'boolean', default: true },
2178
+ { displayName: 'Incluir Estado Operacional', name: 'includeOperationalState', type: 'boolean', default: true },
2179
+ { displayName: 'Incluir Compressão de Memória', name: 'includeMemoryCompression', type: 'boolean', default: true },
2180
+ ],
2181
+ },
2182
+ {
2183
+ name: 'intelligence',
2184
+ displayName: 'Mais Inteligência',
2185
+ values: [
2186
+ { displayName: 'Incluir Profile Facts', name: 'includeProfileFacts', type: 'boolean', default: true },
2187
+ { displayName: 'Incluir Mensagens Recentes', name: 'includeRecentMessages', type: 'boolean', default: true },
2188
+ { displayName: 'Últimas N Mensagens', name: 'recentMessagesLastN', type: 'number', default: 6 },
2189
+ { displayName: 'Incluir Highlights Recentes', name: 'includeRecentHighlights', type: 'boolean', default: true },
2190
+ { displayName: 'Máximo de Highlights', name: 'recentHighlightsMaxItems', type: 'number', default: 6 },
2191
+ { displayName: 'Incluir Grafo', name: 'includeRelations', type: 'boolean', default: true },
2192
+ { displayName: 'Máximo de Relações', name: 'maxRelations', type: 'number', default: 10 },
2193
+ { displayName: 'Incluir Action Ledger', name: 'includeActionLedger', type: 'boolean', default: true },
2194
+ { displayName: 'Incluir Entity Timeline', name: 'includeEntityTimeline', type: 'boolean', default: true },
2195
+ ],
2196
+ },
2197
+ {
2198
+ name: 'retrievalControls',
2199
+ displayName: 'Controles Avançados de Busca',
2200
+ values: [
2201
+ { displayName: 'Top K', name: 'topK', type: 'number', typeOptions: { minValue: 1 }, default: 6 },
2202
+ { displayName: 'Rerank', name: 'rerank', type: 'boolean', default: true },
2203
+ { displayName: 'Fields (lista separada por vírgula)', name: 'fields', type: 'string', default: '' },
2204
+ { displayName: 'Filters (JSON)', name: 'filters', type: 'json', default: '{}' },
2205
+ { displayName: 'Last N (recentes)', name: 'lastN', type: 'number', default: 8 },
2206
+ { displayName: 'Alpha (peso semântico)', name: 'alpha', type: 'number', typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2 }, default: 0.65 },
2207
+ { displayName: 'Half-life (horas)', name: 'halfLifeHours', type: 'number', typeOptions: { minValue: 1 }, default: 48 },
2208
+ { displayName: 'Máximo a retornar', name: 'maxReturn', type: 'number', typeOptions: { minValue: 1 }, default: 12 },
2209
+ { displayName: 'MMR (diversidade)', name: 'mmr', type: 'boolean', default: true },
2210
+ { displayName: 'MMR Lambda', name: 'mmrLambda', type: 'number', typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2 }, default: 0.5 },
2211
+ { displayName: 'Compactar Contexto Para Agente', name: 'compactForAgent', type: 'boolean', default: false },
2212
+ ],
2213
+ },
2214
+ {
2215
+ name: 'summaryState',
2216
+ displayName: 'Resumo e Estado Persistente',
2217
+ values: [
2218
+ { displayName: 'Incluir Resumo', name: 'includeSummary', type: 'boolean', default: true },
2219
+ { displayName: 'Incluir Resumo do SLM', name: 'includeConnectedModelSummary', type: 'boolean', default: true },
2220
+ {
2221
+ displayName: 'Fonte do Resumo do SLM',
2222
+ name: 'summarySource',
2223
+ type: 'options',
2224
+ options: [
2225
+ { name: 'Automático', value: 'auto' },
2226
+ { name: 'Contexto Ativo', value: 'activeContext' },
2227
+ { name: 'Somente Vetores', value: 'vectorOnly' },
2228
+ { name: 'Desligado', value: 'off' },
2229
+ ],
2230
+ default: 'auto',
2231
+ },
2232
+ { displayName: 'Máximo de Caracteres de Entrada do SLM', name: 'connectedModelSummaryInputMaxChars', type: 'number', default: 4200 },
2233
+ { displayName: 'Máximo de Caracteres do Resumo do SLM', name: 'connectedModelSummaryMaxChars', type: 'number', default: 1200 },
2234
+ { displayName: 'Incluir Active Summary', name: 'includeActiveSummary', type: 'boolean', default: true },
2235
+ { displayName: 'Persistir Active Summary', name: 'persistActiveSummary', type: 'boolean', default: true },
2236
+ { displayName: 'Máximo de Caracteres do Active Summary', name: 'activeSummaryMaxChars', type: 'number', default: 1800 },
2237
+ { displayName: 'Retenção do Active Summary (Dias)', name: 'activeSummaryRetentionDays', type: 'number', default: 30 },
2238
+ { displayName: 'Ativar Cache Técnico do Resumo SLM', name: 'enableTransientSummaryCache', type: 'boolean', default: true },
2239
+ { displayName: 'TTL do Cache Técnico SLM (Segundos)', name: 'transientSummaryCacheTTLSeconds', type: 'number', default: 300 },
2240
+ { displayName: 'Máximo de Itens no Cache Técnico SLM', name: 'transientSummaryCacheMaxItems', type: 'number', default: 50 },
2241
+ { displayName: 'Máximo de Fatos no Resumo', name: 'summaryMaxFacts', type: 'number', default: 4 },
2242
+ ],
2243
+ },
2244
+ {
2245
+ name: 'diagnosticsAudit',
2246
+ displayName: 'Diagnóstico e Auditoria',
2247
+ values: [
2248
+ { displayName: 'Incluir Scores', name: 'includeScores', type: 'boolean', default: false },
2249
+ { displayName: 'Incluir Diagnóstico', name: 'includeDiagnostics', type: 'boolean', default: false },
2250
+ { displayName: 'Últimas N Tools', name: 'toolHistoryLastN', type: 'number', default: 10 },
2251
+ { displayName: 'TTL Das Tools (Segundos)', name: 'toolHistoryTTLSeconds', type: 'number', default: 3600 },
2252
+ { displayName: 'Persistir Tool Facts no Backend', name: 'persistToolFactsToMem0', type: 'boolean', default: false },
2253
+ { displayName: 'Fallback Semântico Para Tools', name: 'includeToolHistorySemanticFallback', type: 'boolean', default: false },
2254
+ ],
2255
+ },
2256
+ ],
2257
+ },
2258
+ {
2259
+ displayName: 'Avançado Legado (Compatibilidade)',
2119
2260
  name: 'advanced',
2120
2261
  type: 'collection',
2121
2262
  placeholder: 'Opções',
2122
2263
  default: {},
2264
+ description: 'Campos legados preservados para workflows existentes. Para novas configuracoes, use Configuração Tembory.',
2123
2265
  options: [
2124
2266
  { displayName: 'User ID', name: 'userId', type: 'string', default: '' },
2125
2267
  {
@@ -2134,7 +2276,7 @@ class Mem0Memory {
2134
2276
  { name: 'Produção Nano/SLM', value: 'productionNano' },
2135
2277
  { name: 'Auditoria', value: 'audit' },
2136
2278
  ],
2137
- default: 'custom',
2279
+ default: 'productionBalanced',
2138
2280
  description: 'Preenche defaults seguros para contexto, diagnostico, historico de tools e mensagens recentes. Valores definidos manualmente continuam tendo prioridade.',
2139
2281
  },
2140
2282
  { displayName: 'Agent ID', name: 'agentId', type: 'string', default: '' },
@@ -2332,7 +2474,7 @@ class Mem0Memory {
2332
2474
  async saveContextForItem(itemIndex, inputValues = {}, outputValues = {}) {
2333
2475
  const threadId = this.getNodeParameter('threadId', itemIndex);
2334
2476
  const project = this.getNodeParameter('project', itemIndex, '');
2335
- const adv = applyOperationalPreset(this.getNodeParameter('advanced', itemIndex, {}) || {});
2477
+ const adv = applyOperationalPreset(readAdvancedOptions(this, itemIndex));
2336
2478
  const store = getMemoryStore(this);
2337
2479
  const key = userKeyFrom(threadId, adv, project);
2338
2480
  const input = pickText(inputValues, ['input', 'chatInput', 'text', 'query', 'question']);
@@ -2536,7 +2678,7 @@ class Mem0Memory {
2536
2678
  let payloadFormat = this.getNodeParameter('payloadFormat', itemIndex, 'structured');
2537
2679
  const threadId = this.getNodeParameter('threadId', itemIndex);
2538
2680
  const project = this.getNodeParameter('project', itemIndex, '');
2539
- const adv = applyOperationalPreset(this.getNodeParameter('advanced', itemIndex, {}) || {});
2681
+ const adv = applyOperationalPreset(readAdvancedOptions(this, itemIndex));
2540
2682
  payloadFormat = adv.payloadFormat || payloadFormat;
2541
2683
  const store = getMemoryStore(this);
2542
2684
  const key = userKeyFrom(threadId, adv, project);
@@ -3080,7 +3222,7 @@ class Mem0Memory {
3080
3222
  const retrievalMode = this.getNodeParameter('retrievalMode', i);
3081
3223
  const threadId = this.getNodeParameter('threadId', i);
3082
3224
  const project = this.getNodeParameter('project', i, '');
3083
- const adv = applyOperationalPreset(this.getNodeParameter('advanced', i, {}) || {});
3225
+ const adv = applyOperationalPreset(readAdvancedOptions(this, i));
3084
3226
  const key = userKeyFrom(threadId, adv, project);
3085
3227
  const query = asSearchQuery(this.getNodeParameter('query', i, ''));
3086
3228
  const connectedEmbedding = await getConnectedEmbedding(this, i);
@@ -3162,6 +3304,7 @@ exports.__private = {
3162
3304
  encodeRecentMessage,
3163
3305
  userKeyFrom,
3164
3306
  applyOperationalPreset,
3307
+ flattenAdvancedGroups,
3165
3308
  asSearchQuery,
3166
3309
  canonicalToolInput,
3167
3310
  buildContextMessages,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
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",