n8n-nodes-tembory 1.3.5 → 1.3.7
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 +41 -7
- package/dist/nodes/Tembory/TemboryMemory.node.js +39 -86
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Node de memoria operacional da Tembory para agentes de IA no n8n.
|
|
4
4
|
|
|
5
|
-
Versao atual: `1.3.
|
|
5
|
+
Versao atual: `1.3.6`.
|
|
6
|
+
|
|
7
|
+
## 1.3.6
|
|
8
|
+
|
|
9
|
+
- Fortalece o default recomendado para agentes mini/SLM em workflows reais.
|
|
10
|
+
- `Memoria Inteligente (Recomendado)` agora usa `productionBalanced` com contexto de 20000 caracteres, entrada do SLM em 12000 caracteres, resumo SLM em 3000 caracteres e active summary em 3500 caracteres.
|
|
11
|
+
- Mantem 30 tools recentes no contexto operacional e TTL de tool history em 86400 segundos.
|
|
12
|
+
- Alinha os defaults visiveis em `Ajustes Tecnicos` para nao mostrar configuracao mais fraca quando o usuario abre os grupos.
|
|
13
|
+
- Esclarece que o cache tecnico SLM usa segundos; 300 segundos equivalem a 5 minutos.
|
|
6
14
|
|
|
7
15
|
## 1.3.5
|
|
8
16
|
|
|
@@ -220,13 +228,18 @@ No modo simples, o node aplica automaticamente:
|
|
|
220
228
|
|
|
221
229
|
- `Modo de Recuperacao`: operacional estruturado.
|
|
222
230
|
- `Formato do Contexto`: producao estruturado.
|
|
223
|
-
- `Preset Operacional`: producao
|
|
224
|
-
- `Fonte do Resumo do SLM`:
|
|
231
|
+
- `Preset Operacional`: producao balanceada.
|
|
232
|
+
- `Fonte do Resumo do SLM`: automatica.
|
|
233
|
+
- `Maximo de Caracteres do Contexto`: 20000.
|
|
234
|
+
- `Maximo de Caracteres de Entrada do SLM`: 12000.
|
|
235
|
+
- `Maximo de Caracteres do Resumo do SLM`: 3000.
|
|
236
|
+
- `Maximo de Caracteres do Active Summary`: 3500.
|
|
225
237
|
- Tool history, resultados de tools, action ledger, working memory, decision state, operational state e memory compression ligados.
|
|
226
238
|
- Persistencia no backend e active summary ligados.
|
|
227
239
|
- Diagnostico pesado, scores, semantic fallback e tool facts desligados.
|
|
228
|
-
-
|
|
229
|
-
-
|
|
240
|
+
- Cache tecnico do SLM em 300 segundos.
|
|
241
|
+
- TTL de tool history em 86400 segundos.
|
|
242
|
+
- Ultimas tools mantidas no contexto compacto: 30.
|
|
230
243
|
|
|
231
244
|
## Uso com `$fromAI()`
|
|
232
245
|
|
|
@@ -234,6 +247,27 @@ Em tools conectadas ao AI Agent, o n8n permite que o modelo preencha parametros
|
|
|
234
247
|
|
|
235
248
|
Referencia oficial do n8n: https://docs.n8n.io/advanced-ai/examples/using-the-fromai-function/
|
|
236
249
|
|
|
250
|
+
## Prompt recomendado para AI Agent
|
|
251
|
+
|
|
252
|
+
O Tembory entrega memoria operacional, mas o Agent ainda precisa de politica clara para decidir quando usar memoria e quando chamar tool. Em workflows com muitas tools, adicione um bloco como este no `System Message` do AI Agent:
|
|
253
|
+
|
|
254
|
+
```text
|
|
255
|
+
Antes de chamar uma ferramenta, consulte a memoria Tembory: tool_state, tool_history, action_ledger, decision_state, operational_state, active_summary e conversation_frame.
|
|
256
|
+
Use a memoria para evitar repeticao, mas nao substitua verificacao operacional nova por inferencia.
|
|
257
|
+
Se o usuario pedir para verificar, validar, consultar, checar, confirmar status, criar, atualizar, registrar ou acionar algo que ainda nao esteja confirmado por uma tool recente no tool_history, chame a tool correta.
|
|
258
|
+
Nao repita uma tool se a memoria ja trouxer evidencia suficiente para a pergunta atual.
|
|
259
|
+
Nunca declare uma acao como confirmada, criada, atualizada, enviada ou reservada sem uma tool de side effect bem-sucedida no turno atual.
|
|
260
|
+
Se uma tool retornar dado incoerente com a pergunta, aponte a inconsistencia em vez de inventar.
|
|
261
|
+
Quando responder sobre historico operacional, use os outputs e timestamps das tools salvas pela memoria.
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Regras praticas:
|
|
265
|
+
|
|
266
|
+
- Perguntas de recall/status podem usar memoria sem chamar tools.
|
|
267
|
+
- Pedidos novos de verificacao, consulta, atualizacao ou registro devem chamar a tool correta quando ainda nao houver evidencia recente.
|
|
268
|
+
- Acoes laterais como confirmar, reservar, enviar, criar ou atualizar so podem ser declaradas como concluidas depois de uma tool de side effect bem-sucedida.
|
|
269
|
+
- Outputs incoerentes de tools devem ser tratados como inconsistencia, nao como fato confirmado.
|
|
270
|
+
|
|
237
271
|
## Payload visual do n8n
|
|
238
272
|
|
|
239
273
|
No output do node durante uma execucao, o Tembory mostra um resumo compacto para humano:
|
|
@@ -252,8 +286,8 @@ Exemplo de budget:
|
|
|
252
286
|
{
|
|
253
287
|
"agentContextBudget": {
|
|
254
288
|
"messages": 1,
|
|
255
|
-
"chars":
|
|
256
|
-
"approxTokens":
|
|
289
|
+
"chars": 12000,
|
|
290
|
+
"approxTokens": 3000,
|
|
257
291
|
"largestSections": [
|
|
258
292
|
{ "section": "tools", "chars": 1600, "approxTokens": 400 }
|
|
259
293
|
]
|
|
@@ -1250,32 +1250,18 @@ const extractToolCalls = (outputValues = {}) => {
|
|
|
1250
1250
|
return Array.from(byKey.values());
|
|
1251
1251
|
};
|
|
1252
1252
|
const getMemoryStore = (ctx) => {
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
data.tembory.memoryDedupe = data.tembory.memoryDedupe || {};
|
|
1266
|
-
return data.tembory;
|
|
1267
|
-
}
|
|
1268
|
-
catch {
|
|
1269
|
-
global.__temboryMemory = global.__temboryMemory || { toolHistory: {}, recentMessages: {}, profileFacts: {}, workingMemory: {}, decisionState: {}, memoryCompression: {}, activeSummary: {}, connectedModelSummaryCache: {}, captureState: {}, memoryDedupe: {} };
|
|
1270
|
-
global.__temboryMemory.workingMemory = global.__temboryMemory.workingMemory || {};
|
|
1271
|
-
global.__temboryMemory.decisionState = global.__temboryMemory.decisionState || {};
|
|
1272
|
-
global.__temboryMemory.memoryCompression = global.__temboryMemory.memoryCompression || {};
|
|
1273
|
-
global.__temboryMemory.activeSummary = global.__temboryMemory.activeSummary || {};
|
|
1274
|
-
global.__temboryMemory.connectedModelSummaryCache = global.__temboryMemory.connectedModelSummaryCache || {};
|
|
1275
|
-
global.__temboryMemory.captureState = global.__temboryMemory.captureState || {};
|
|
1276
|
-
global.__temboryMemory.memoryDedupe = global.__temboryMemory.memoryDedupe || {};
|
|
1277
|
-
return global.__temboryMemory;
|
|
1278
|
-
}
|
|
1253
|
+
global.__temboryMemory = global.__temboryMemory || { toolHistory: {}, recentMessages: {}, profileFacts: {}, workingMemory: {}, decisionState: {}, memoryCompression: {}, activeSummary: {}, connectedModelSummaryCache: {}, captureState: {}, memoryDedupe: {} };
|
|
1254
|
+
global.__temboryMemory.toolHistory = global.__temboryMemory.toolHistory || {};
|
|
1255
|
+
global.__temboryMemory.recentMessages = global.__temboryMemory.recentMessages || {};
|
|
1256
|
+
global.__temboryMemory.profileFacts = global.__temboryMemory.profileFacts || {};
|
|
1257
|
+
global.__temboryMemory.workingMemory = global.__temboryMemory.workingMemory || {};
|
|
1258
|
+
global.__temboryMemory.decisionState = global.__temboryMemory.decisionState || {};
|
|
1259
|
+
global.__temboryMemory.memoryCompression = global.__temboryMemory.memoryCompression || {};
|
|
1260
|
+
global.__temboryMemory.activeSummary = global.__temboryMemory.activeSummary || {};
|
|
1261
|
+
global.__temboryMemory.connectedModelSummaryCache = global.__temboryMemory.connectedModelSummaryCache || {};
|
|
1262
|
+
global.__temboryMemory.captureState = global.__temboryMemory.captureState || {};
|
|
1263
|
+
global.__temboryMemory.memoryDedupe = global.__temboryMemory.memoryDedupe || {};
|
|
1264
|
+
return global.__temboryMemory;
|
|
1279
1265
|
};
|
|
1280
1266
|
const namespacePart = (value) => String(value || '').trim().replace(/\s+/g, '_').replace(/[:|]+/g, '-');
|
|
1281
1267
|
const userKeyFrom = (threadId, adv, project = '') => {
|
|
@@ -1333,8 +1319,8 @@ const mergeRemoteThreadState = (store, key, state) => {
|
|
|
1333
1319
|
store.activeSummary[key] = state.activeSummary;
|
|
1334
1320
|
};
|
|
1335
1321
|
const SIMPLE_MODE_OVERRIDES = {
|
|
1336
|
-
operationPreset: '
|
|
1337
|
-
summarySource: '
|
|
1322
|
+
operationPreset: 'productionBalanced',
|
|
1323
|
+
summarySource: 'auto',
|
|
1338
1324
|
includeContextHeader: true,
|
|
1339
1325
|
compactStateSections: true,
|
|
1340
1326
|
includeSummary: true,
|
|
@@ -1357,13 +1343,13 @@ const SIMPLE_MODE_OVERRIDES = {
|
|
|
1357
1343
|
includeDiagnostics: false,
|
|
1358
1344
|
persistToolFactsToTembory: false,
|
|
1359
1345
|
includeToolHistorySemanticFallback: false,
|
|
1360
|
-
contextMaxChars:
|
|
1361
|
-
toolHistoryLastN:
|
|
1362
|
-
toolHistoryTTLSeconds:
|
|
1346
|
+
contextMaxChars: 20000,
|
|
1347
|
+
toolHistoryLastN: 30,
|
|
1348
|
+
toolHistoryTTLSeconds: 86400,
|
|
1363
1349
|
recentMessagesLastN: 50,
|
|
1364
|
-
connectedModelSummaryInputMaxChars:
|
|
1365
|
-
connectedModelSummaryMaxChars:
|
|
1366
|
-
activeSummaryMaxChars:
|
|
1350
|
+
connectedModelSummaryInputMaxChars: 12000,
|
|
1351
|
+
connectedModelSummaryMaxChars: 3000,
|
|
1352
|
+
activeSummaryMaxChars: 3500,
|
|
1367
1353
|
activeSummaryRetentionDays: 30,
|
|
1368
1354
|
};
|
|
1369
1355
|
const applyOperationalPreset = (advanced = {}) => {
|
|
@@ -1445,7 +1431,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1445
1431
|
includeConnectedModelSummary: true,
|
|
1446
1432
|
includeActiveSummary: true,
|
|
1447
1433
|
persistActiveSummary: true,
|
|
1448
|
-
activeSummaryMaxChars:
|
|
1434
|
+
activeSummaryMaxChars: 3500,
|
|
1449
1435
|
activeSummaryRetentionDays: 30,
|
|
1450
1436
|
enableTransientSummaryCache: true,
|
|
1451
1437
|
transientSummaryCacheTTLSeconds: 300,
|
|
@@ -1471,12 +1457,14 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1471
1457
|
includeRecentHighlights: true,
|
|
1472
1458
|
topK: 6,
|
|
1473
1459
|
lastN: 8,
|
|
1474
|
-
toolHistoryLastN:
|
|
1460
|
+
toolHistoryLastN: 30,
|
|
1461
|
+
toolHistoryTTLSeconds: 86400,
|
|
1475
1462
|
recentMessagesLastN: 50,
|
|
1476
1463
|
vectorMemoryMaxChars: 360,
|
|
1477
|
-
contextMaxChars:
|
|
1478
|
-
connectedModelSummaryMaxChars:
|
|
1479
|
-
connectedModelSummaryInputMaxChars:
|
|
1464
|
+
contextMaxChars: 20000,
|
|
1465
|
+
connectedModelSummaryMaxChars: 3000,
|
|
1466
|
+
connectedModelSummaryInputMaxChars: 12000,
|
|
1467
|
+
summaryMaxFacts: 8,
|
|
1480
1468
|
},
|
|
1481
1469
|
productionCheap: {
|
|
1482
1470
|
summarySource: 'activeContext',
|
|
@@ -4513,18 +4501,18 @@ class TemboryMemory {
|
|
|
4513
4501
|
options: [
|
|
4514
4502
|
{ name: 'Custom', value: 'custom' },
|
|
4515
4503
|
{ name: 'Diagnóstico Completo', value: 'diagnostic' },
|
|
4516
|
-
|
|
4517
|
-
|
|
4504
|
+
{ name: 'Produção Balanceada (Recomendado)', value: 'productionBalanced' },
|
|
4505
|
+
{ name: 'Produção Rápida (Thread + SLM)', value: 'productionFast' },
|
|
4518
4506
|
{ name: 'Produção Econômica', value: 'productionCheap' },
|
|
4519
4507
|
{ name: 'Produção Nano/SLM', value: 'productionNano' },
|
|
4520
4508
|
{ name: 'Auditoria', value: 'audit' },
|
|
4521
4509
|
],
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4510
|
+
default: 'productionBalanced',
|
|
4511
|
+
description: 'Preenche defaults seguros para contexto, historico de tools e memoria ativa.',
|
|
4512
|
+
},
|
|
4525
4513
|
{ displayName: 'Incluir Cabeçalho de Contexto', name: 'includeContextHeader', type: 'boolean', default: true },
|
|
4526
4514
|
{ displayName: 'Organizar Seções de Produção', name: 'compactStateSections', type: 'boolean', default: true },
|
|
4527
|
-
|
|
4515
|
+
{ displayName: 'Máximo de Caracteres do Contexto', name: 'contextMaxChars', type: 'number', default: 20000 },
|
|
4528
4516
|
{ displayName: 'Incluir Tool History', name: 'includeToolHistory', type: 'boolean', default: true },
|
|
4529
4517
|
{ displayName: 'Incluir Resultado Das Tools', name: 'includeToolResults', type: 'boolean', default: true },
|
|
4530
4518
|
{ displayName: 'Incluir Working Memory', name: 'includeWorkingMemory', type: 'boolean', default: true },
|
|
@@ -4562,16 +4550,16 @@ class TemboryMemory {
|
|
|
4562
4550
|
],
|
|
4563
4551
|
default: 'auto',
|
|
4564
4552
|
},
|
|
4565
|
-
|
|
4566
|
-
|
|
4553
|
+
{ displayName: 'Máximo de Caracteres de Entrada do SLM', name: 'connectedModelSummaryInputMaxChars', type: 'number', default: 12000 },
|
|
4554
|
+
{ displayName: 'Máximo de Caracteres do Resumo do SLM', name: 'connectedModelSummaryMaxChars', type: 'number', default: 3000 },
|
|
4567
4555
|
{ displayName: 'Incluir Active Summary', name: 'includeActiveSummary', type: 'boolean', default: true },
|
|
4568
4556
|
{ displayName: 'Persistir Active Summary', name: 'persistActiveSummary', type: 'boolean', default: true },
|
|
4569
|
-
|
|
4557
|
+
{ displayName: 'Máximo de Caracteres do Active Summary', name: 'activeSummaryMaxChars', type: 'number', default: 3500 },
|
|
4570
4558
|
{ displayName: 'Retenção do Active Summary (Dias)', name: 'activeSummaryRetentionDays', type: 'number', default: 30 },
|
|
4571
4559
|
{ displayName: 'Ativar Cache Técnico do Resumo SLM', name: 'enableTransientSummaryCache', type: 'boolean', default: true },
|
|
4572
4560
|
{ displayName: 'TTL do Cache Técnico SLM (Segundos)', name: 'transientSummaryCacheTTLSeconds', type: 'number', default: 300 },
|
|
4573
4561
|
{ displayName: 'Máximo de Itens no Cache Técnico SLM', name: 'transientSummaryCacheMaxItems', type: 'number', default: 50 },
|
|
4574
|
-
|
|
4562
|
+
{ displayName: 'Máximo de Fatos no Resumo', name: 'summaryMaxFacts', type: 'number', default: 8 },
|
|
4575
4563
|
],
|
|
4576
4564
|
},
|
|
4577
4565
|
{
|
|
@@ -4580,8 +4568,8 @@ class TemboryMemory {
|
|
|
4580
4568
|
values: [
|
|
4581
4569
|
{ displayName: 'Incluir Scores', name: 'includeScores', type: 'boolean', default: false },
|
|
4582
4570
|
{ displayName: 'Incluir Diagnóstico', name: 'includeDiagnostics', type: 'boolean', default: false },
|
|
4583
|
-
|
|
4584
|
-
|
|
4571
|
+
{ displayName: 'Últimas N Tools Mantidas no Contexto', name: 'toolHistoryLastN', type: 'number', default: 30 },
|
|
4572
|
+
{ displayName: 'TTL Das Tools (Segundos)', name: 'toolHistoryTTLSeconds', type: 'number', default: 86400 },
|
|
4585
4573
|
{ displayName: 'Persistir Tool Facts no Backend', name: 'persistToolFactsToTembory', type: 'boolean', default: false },
|
|
4586
4574
|
{ displayName: 'Fallback Semântico Para Tools', name: 'includeToolHistorySemanticFallback', type: 'boolean', default: false },
|
|
4587
4575
|
],
|
|
@@ -4821,20 +4809,10 @@ class TemboryMemory {
|
|
|
4821
4809
|
const profileFromTurn = extractProfileFactsFromText(input, 'user_message', nowIso());
|
|
4822
4810
|
if (Object.keys(profileFromTurn).length) {
|
|
4823
4811
|
store.profileFacts[key] = mergeProfileFacts(store.profileFacts[key], profileFromTurn);
|
|
4824
|
-
try {
|
|
4825
|
-
const globalData = this.getWorkflowStaticData('global');
|
|
4826
|
-
globalData.__dataChanged = true;
|
|
4827
|
-
}
|
|
4828
|
-
catch { }
|
|
4829
4812
|
}
|
|
4830
4813
|
if (toolCalls.length) {
|
|
4831
4814
|
const existing = store.toolHistory[key] || [];
|
|
4832
4815
|
store.toolHistory[key] = applyToolHistoryWindow(existing.concat(toolCalls), adv.toolHistoryTTLSeconds, adv.toolHistoryLastN || 15);
|
|
4833
|
-
try {
|
|
4834
|
-
const globalData = this.getWorkflowStaticData('global');
|
|
4835
|
-
globalData.__dataChanged = true;
|
|
4836
|
-
}
|
|
4837
|
-
catch { }
|
|
4838
4816
|
}
|
|
4839
4817
|
if (adv.includeRecentMessages !== false) {
|
|
4840
4818
|
const recent = store.recentMessages[key] || [];
|
|
@@ -4849,11 +4827,6 @@ class TemboryMemory {
|
|
|
4849
4827
|
recentForTembory.push(item);
|
|
4850
4828
|
}
|
|
4851
4829
|
store.recentMessages[key] = pruneByLimit(recent, adv.recentMessagesLastN || 8);
|
|
4852
|
-
try {
|
|
4853
|
-
const globalData = this.getWorkflowStaticData('global');
|
|
4854
|
-
globalData.__dataChanged = true;
|
|
4855
|
-
}
|
|
4856
|
-
catch { }
|
|
4857
4830
|
}
|
|
4858
4831
|
const renderedProfileForTurn = renderProfileFacts(store.profileFacts[key] || {});
|
|
4859
4832
|
const recentForTurn = store.recentMessages[key] || [];
|
|
@@ -4884,11 +4857,6 @@ class TemboryMemory {
|
|
|
4884
4857
|
store.workingMemory[key] = workingMemoryForTurn;
|
|
4885
4858
|
store.decisionState[key] = decisionStateForTurn;
|
|
4886
4859
|
store.memoryCompression[key] = compressionForTurn;
|
|
4887
|
-
try {
|
|
4888
|
-
const globalData = this.getWorkflowStaticData('global');
|
|
4889
|
-
globalData.__dataChanged = true;
|
|
4890
|
-
}
|
|
4891
|
-
catch { }
|
|
4892
4860
|
const messages = [];
|
|
4893
4861
|
if (input)
|
|
4894
4862
|
messages.push({ role: 'user', content: input });
|
|
@@ -4938,11 +4906,6 @@ class TemboryMemory {
|
|
|
4938
4906
|
...nextCaptureState,
|
|
4939
4907
|
last_save_thread_state_saved: threadStateSaved,
|
|
4940
4908
|
});
|
|
4941
|
-
try {
|
|
4942
|
-
const globalData = this.getWorkflowStaticData('global');
|
|
4943
|
-
globalData.__dataChanged = true;
|
|
4944
|
-
}
|
|
4945
|
-
catch { }
|
|
4946
4909
|
if (adv.persistBackendMemories === false) {
|
|
4947
4910
|
await finalizeDedupeSummary();
|
|
4948
4911
|
return;
|
|
@@ -5597,11 +5560,6 @@ class TemboryMemory {
|
|
|
5597
5560
|
const profileFacts = adv.includeProfileFacts === false ? {} : mergeProfileFacts(store.profileFacts[key], profileFactsFromMessages(allRecentMessages), profileFactsFromMemories(vectorMemories));
|
|
5598
5561
|
if (adv.includeProfileFacts !== false && Object.keys(profileFacts).length) {
|
|
5599
5562
|
store.profileFacts[key] = mergeProfileFacts(store.profileFacts[key], profileFacts);
|
|
5600
|
-
try {
|
|
5601
|
-
const globalData = this.getWorkflowStaticData('global');
|
|
5602
|
-
globalData.__dataChanged = true;
|
|
5603
|
-
}
|
|
5604
|
-
catch { }
|
|
5605
5563
|
}
|
|
5606
5564
|
const includeToolResults = adv.includeToolResults !== false;
|
|
5607
5565
|
const operationalState = deriveOperationalState(toolHistory, renderProfileFacts(profileFacts), recentMessages, includeToolResults);
|
|
@@ -5741,11 +5699,6 @@ class TemboryMemory {
|
|
|
5741
5699
|
store.workingMemory[key] = workingMemory;
|
|
5742
5700
|
store.decisionState[key] = decisionState;
|
|
5743
5701
|
store.memoryCompression[key] = memoryCompression;
|
|
5744
|
-
try {
|
|
5745
|
-
const globalData = this.getWorkflowStaticData('global');
|
|
5746
|
-
globalData.__dataChanged = true;
|
|
5747
|
-
}
|
|
5748
|
-
catch { }
|
|
5749
5702
|
payload = buildContextMessages({
|
|
5750
5703
|
payloadFormat,
|
|
5751
5704
|
query,
|
package/package.json
CHANGED