n8n-nodes-tembory 1.3.6 → 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 CHANGED
@@ -247,6 +247,27 @@ Em tools conectadas ao AI Agent, o n8n permite que o modelo preencha parametros
247
247
 
248
248
  Referencia oficial do n8n: https://docs.n8n.io/advanced-ai/examples/using-the-fromai-function/
249
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
+
250
271
  ## Payload visual do n8n
251
272
 
252
273
  No output do node durante uma execucao, o Tembory mostra um resumo compacto para humano:
@@ -1250,32 +1250,18 @@ const extractToolCalls = (outputValues = {}) => {
1250
1250
  return Array.from(byKey.values());
1251
1251
  };
1252
1252
  const getMemoryStore = (ctx) => {
1253
- try {
1254
- const data = ctx.getWorkflowStaticData('global');
1255
- data.tembory = data.tembory || {};
1256
- data.tembory.toolHistory = data.tembory.toolHistory || {};
1257
- data.tembory.recentMessages = data.tembory.recentMessages || {};
1258
- data.tembory.profileFacts = data.tembory.profileFacts || {};
1259
- data.tembory.workingMemory = data.tembory.workingMemory || {};
1260
- data.tembory.decisionState = data.tembory.decisionState || {};
1261
- data.tembory.memoryCompression = data.tembory.memoryCompression || {};
1262
- data.tembory.activeSummary = data.tembory.activeSummary || {};
1263
- data.tembory.connectedModelSummaryCache = data.tembory.connectedModelSummaryCache || {};
1264
- data.tembory.captureState = data.tembory.captureState || {};
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 = '') => {
@@ -4823,20 +4809,10 @@ class TemboryMemory {
4823
4809
  const profileFromTurn = extractProfileFactsFromText(input, 'user_message', nowIso());
4824
4810
  if (Object.keys(profileFromTurn).length) {
4825
4811
  store.profileFacts[key] = mergeProfileFacts(store.profileFacts[key], profileFromTurn);
4826
- try {
4827
- const globalData = this.getWorkflowStaticData('global');
4828
- globalData.__dataChanged = true;
4829
- }
4830
- catch { }
4831
4812
  }
4832
4813
  if (toolCalls.length) {
4833
4814
  const existing = store.toolHistory[key] || [];
4834
4815
  store.toolHistory[key] = applyToolHistoryWindow(existing.concat(toolCalls), adv.toolHistoryTTLSeconds, adv.toolHistoryLastN || 15);
4835
- try {
4836
- const globalData = this.getWorkflowStaticData('global');
4837
- globalData.__dataChanged = true;
4838
- }
4839
- catch { }
4840
4816
  }
4841
4817
  if (adv.includeRecentMessages !== false) {
4842
4818
  const recent = store.recentMessages[key] || [];
@@ -4851,11 +4827,6 @@ class TemboryMemory {
4851
4827
  recentForTembory.push(item);
4852
4828
  }
4853
4829
  store.recentMessages[key] = pruneByLimit(recent, adv.recentMessagesLastN || 8);
4854
- try {
4855
- const globalData = this.getWorkflowStaticData('global');
4856
- globalData.__dataChanged = true;
4857
- }
4858
- catch { }
4859
4830
  }
4860
4831
  const renderedProfileForTurn = renderProfileFacts(store.profileFacts[key] || {});
4861
4832
  const recentForTurn = store.recentMessages[key] || [];
@@ -4886,11 +4857,6 @@ class TemboryMemory {
4886
4857
  store.workingMemory[key] = workingMemoryForTurn;
4887
4858
  store.decisionState[key] = decisionStateForTurn;
4888
4859
  store.memoryCompression[key] = compressionForTurn;
4889
- try {
4890
- const globalData = this.getWorkflowStaticData('global');
4891
- globalData.__dataChanged = true;
4892
- }
4893
- catch { }
4894
4860
  const messages = [];
4895
4861
  if (input)
4896
4862
  messages.push({ role: 'user', content: input });
@@ -4940,11 +4906,6 @@ class TemboryMemory {
4940
4906
  ...nextCaptureState,
4941
4907
  last_save_thread_state_saved: threadStateSaved,
4942
4908
  });
4943
- try {
4944
- const globalData = this.getWorkflowStaticData('global');
4945
- globalData.__dataChanged = true;
4946
- }
4947
- catch { }
4948
4909
  if (adv.persistBackendMemories === false) {
4949
4910
  await finalizeDedupeSummary();
4950
4911
  return;
@@ -5599,11 +5560,6 @@ class TemboryMemory {
5599
5560
  const profileFacts = adv.includeProfileFacts === false ? {} : mergeProfileFacts(store.profileFacts[key], profileFactsFromMessages(allRecentMessages), profileFactsFromMemories(vectorMemories));
5600
5561
  if (adv.includeProfileFacts !== false && Object.keys(profileFacts).length) {
5601
5562
  store.profileFacts[key] = mergeProfileFacts(store.profileFacts[key], profileFacts);
5602
- try {
5603
- const globalData = this.getWorkflowStaticData('global');
5604
- globalData.__dataChanged = true;
5605
- }
5606
- catch { }
5607
5563
  }
5608
5564
  const includeToolResults = adv.includeToolResults !== false;
5609
5565
  const operationalState = deriveOperationalState(toolHistory, renderProfileFacts(profileFacts), recentMessages, includeToolResults);
@@ -5743,11 +5699,6 @@ class TemboryMemory {
5743
5699
  store.workingMemory[key] = workingMemory;
5744
5700
  store.decisionState[key] = decisionState;
5745
5701
  store.memoryCompression[key] = memoryCompression;
5746
- try {
5747
- const globalData = this.getWorkflowStaticData('global');
5748
- globalData.__dataChanged = true;
5749
- }
5750
- catch { }
5751
5702
  payload = buildContextMessages({
5752
5703
  payloadFormat,
5753
5704
  query,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.3.6",
3
+ "version": "1.3.7",
4
4
  "description": "Tembory node for n8n AI Agents with operational memory, tool history and decision state",
5
5
  "license": "MIT",
6
6
  "homepage": "https://tembory.com",