n8n-nodes-tembory 1.1.36 → 1.1.38

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,19 @@
2
2
 
3
3
  Node de memoria operacional da Tembory para agentes de IA no n8n.
4
4
 
5
- Versao atual: `1.1.36`.
5
+ Versao atual: `1.1.38`.
6
+
7
+ ## 1.1.38
8
+
9
+ - Torna o resumo visual independente do tipo da mensagem LangChain, procurando o contexto Tembory em qualquer mensagem carregada.
10
+ - Enriquece eventos `chatHistory.addMessage(s)` com `savedMessages`, input/output resumidos e tool events quando esse for o caminho usado pelo Agent.
11
+ - Mantem a separacao entre contexto interno do Agent e output compacto para humano.
12
+
13
+ ## 1.1.37
14
+
15
+ - Normaliza `chatHistory` legado para `chat_history` no modo simples, evitando que historico bruto vaze no output final do Agent.
16
+ - Mantem `chatHistory` apenas como alias nao enumeravel no contrato interno de memoria.
17
+ - O caminho de execucao normal do node passa a retornar resumo visual compacto, nao o array bruto de mensagens.
6
18
 
7
19
  ## 1.1.36
8
20
 
@@ -10,6 +10,21 @@ try {
10
10
  catch { }
11
11
  const MAX_TEXT = 12000;
12
12
  const DEFAULT_MEMORY_KEY = 'chat_history';
13
+ const resolveRuntimeMemoryKey = (ctx, itemIndex = 0) => {
14
+ let configurationMode = 'simple';
15
+ try {
16
+ configurationMode = String(ctx.getNodeParameter('configurationMode', itemIndex, 'simple') || 'simple');
17
+ }
18
+ catch { }
19
+ if (configurationMode !== 'advanced')
20
+ return DEFAULT_MEMORY_KEY;
21
+ let key = DEFAULT_MEMORY_KEY;
22
+ try {
23
+ key = String(ctx.getNodeParameter('memoryKey', itemIndex, DEFAULT_MEMORY_KEY) || DEFAULT_MEMORY_KEY);
24
+ }
25
+ catch { }
26
+ return key === 'chatHistory' ? DEFAULT_MEMORY_KEY : key;
27
+ };
13
28
  const nowIso = () => new Date().toISOString();
14
29
  const safeStringify = (value) => {
15
30
  try {
@@ -3012,10 +3027,11 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
3012
3027
  const type = messageTypeOf(message);
3013
3028
  return type === 'system' || /system/i.test(String(message?.role || ''));
3014
3029
  });
3015
- if (!firstSystem)
3030
+ const contextMessage = firstSystem || list.find((message) => messageContentOf(message).includes('tembory.agent_context.v1')) || list[0];
3031
+ if (!contextMessage)
3016
3032
  return summary;
3017
3033
  try {
3018
- const rawContent = messageContentOf(firstSystem);
3034
+ const rawContent = messageContentOf(contextMessage);
3019
3035
  let parsed;
3020
3036
  try {
3021
3037
  parsed = JSON.parse(rawContent);
@@ -3135,7 +3151,7 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
3135
3151
  return Object.fromEntries(Object.entries(summary).filter(([, value]) => value !== undefined));
3136
3152
  }
3137
3153
  catch {
3138
- const content = messageContentOf(firstSystem);
3154
+ const content = messageContentOf(contextMessage);
3139
3155
  return cleanContextValue({
3140
3156
  ...summary,
3141
3157
  contextChars: content.length || undefined,
@@ -3812,7 +3828,7 @@ class TemboryMemory {
3812
3828
  // For AI connections, n8n reads from supplyData. The AI Agent expects a
3813
3829
  // memory-like object, not raw JSON, so expose the LangChain memory contract.
3814
3830
  async supplyData(itemIndex) {
3815
- const memoryKey = this.getNodeParameter('memoryKey', itemIndex, DEFAULT_MEMORY_KEY);
3831
+ const memoryKey = resolveRuntimeMemoryKey(this, itemIndex);
3816
3832
  let currentMessages = [];
3817
3833
  const loadCache = new Map();
3818
3834
  const recordMemoryEvent = (action, payload = {}, error) => {
@@ -3837,24 +3853,40 @@ class TemboryMemory {
3837
3853
  addMessage: async (message) => {
3838
3854
  currentMessages.push(message);
3839
3855
  const saved = await TemboryMemory.prototype.saveMessagesForItem.call(this, itemIndex, [message]);
3840
- recordMemoryEvent('chatHistory.addMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
3856
+ recordMemoryEvent('chatHistory.addMessage', {
3857
+ saved: Boolean(saved && saved.saved),
3858
+ messages: 1,
3859
+ ...summarizeSaveContextForSideChannel((saved && saved.input) || {}, (saved && saved.output) || {}, currentMessages),
3860
+ });
3841
3861
  },
3842
3862
  addUserMessage: async (message) => {
3843
3863
  const baseMessage = toBaseMessage({ role: 'user', content: message });
3844
3864
  currentMessages.push(baseMessage);
3845
3865
  const saved = await TemboryMemory.prototype.saveMessagesForItem.call(this, itemIndex, [baseMessage]);
3846
- recordMemoryEvent('chatHistory.addUserMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
3866
+ recordMemoryEvent('chatHistory.addUserMessage', {
3867
+ saved: Boolean(saved && saved.saved),
3868
+ messages: 1,
3869
+ ...summarizeSaveContextForSideChannel((saved && saved.input) || {}, (saved && saved.output) || {}, currentMessages),
3870
+ });
3847
3871
  },
3848
3872
  addAIChatMessage: async (message) => {
3849
3873
  const baseMessage = toBaseMessage({ role: 'assistant', content: message });
3850
3874
  currentMessages.push(baseMessage);
3851
3875
  const saved = await TemboryMemory.prototype.saveMessagesForItem.call(this, itemIndex, [baseMessage]);
3852
- recordMemoryEvent('chatHistory.addAIChatMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
3876
+ recordMemoryEvent('chatHistory.addAIChatMessage', {
3877
+ saved: Boolean(saved && saved.saved),
3878
+ messages: 1,
3879
+ ...summarizeSaveContextForSideChannel((saved && saved.input) || {}, (saved && saved.output) || {}, currentMessages),
3880
+ });
3853
3881
  },
3854
3882
  addMessages: async (messages) => {
3855
3883
  currentMessages.push(...messages);
3856
3884
  const saved = await TemboryMemory.prototype.saveMessagesForItem.call(this, itemIndex, messages);
3857
- recordMemoryEvent('chatHistory.addMessages', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: Array.isArray(messages) ? messages.length : 0 });
3885
+ recordMemoryEvent('chatHistory.addMessages', {
3886
+ saved: Boolean(saved && saved.saved),
3887
+ messages: Array.isArray(messages) ? messages.length : 0,
3888
+ ...summarizeSaveContextForSideChannel((saved && saved.input) || {}, (saved && saved.output) || {}, currentMessages),
3889
+ });
3858
3890
  },
3859
3891
  clear: async () => {
3860
3892
  currentMessages = [];
@@ -4436,7 +4468,7 @@ class TemboryMemory {
4436
4468
  }
4437
4469
  async loadMemoryVariablesForItem(itemIndex, inputValues = {}) {
4438
4470
  var _a, _b, _c, _d, _e, _f, _g;
4439
- const memoryKey = this.getNodeParameter('memoryKey', itemIndex, DEFAULT_MEMORY_KEY);
4471
+ const memoryKey = resolveRuntimeMemoryKey(this, itemIndex);
4440
4472
  const requestedRetrievalMode = this.getNodeParameter('retrievalMode', itemIndex, 'basic');
4441
4473
  let payloadFormat = this.getNodeParameter('payloadFormat', itemIndex, 'structured');
4442
4474
  const threadId = this.getNodeParameter('threadId', itemIndex);
@@ -5066,20 +5098,20 @@ class TemboryMemory {
5066
5098
  diagnostics,
5067
5099
  dedupeSummary: diagnostics.dedupeSummary,
5068
5100
  };
5069
- return {
5070
- response: {
5071
- [memoryKey]: payload,
5072
- chat_history: payload,
5073
- chatHistory: payload,
5074
- },
5075
- };
5101
+ const response = { [memoryKey]: payload, chat_history: payload };
5102
+ Object.defineProperty(response, 'chatHistory', {
5103
+ value: payload,
5104
+ enumerable: false,
5105
+ configurable: true,
5106
+ });
5107
+ return { response };
5076
5108
  }
5077
5109
  async execute() {
5078
5110
  const items = this.getInputData();
5079
5111
  const returnData = [];
5080
5112
  const count = Math.max(items.length, 1);
5081
5113
  for (let i = 0; i < count; i++) {
5082
- const memoryKey = this.getNodeParameter('memoryKey', i, DEFAULT_MEMORY_KEY);
5114
+ const memoryKey = resolveRuntimeMemoryKey(this, i);
5083
5115
  const requestedRetrievalMode = this.getNodeParameter('retrievalMode', i, 'basic');
5084
5116
  const threadId = this.getNodeParameter('threadId', i);
5085
5117
  const project = this.getNodeParameter('project', i, '');
@@ -5142,10 +5174,14 @@ class TemboryMemory {
5142
5174
  payload = memories.map((m) => { var _a, _b; return ({ role: 'system', content: (_b = (_a = m.memory) !== null && _a !== void 0 ? _a : m.text) !== null && _b !== void 0 ? _b : JSON.stringify(m) }); });
5143
5175
  }
5144
5176
  }
5145
- const json = {};
5146
- json[memoryKey] = payload;
5147
- json.chat_history = payload;
5148
- json.chatHistory = payload;
5177
+ const json = {
5178
+ action: 'loadMemoryVariables',
5179
+ messages: Array.isArray(payload) ? payload.length : 0,
5180
+ memorySummary: summarizeMemoryMessagesForSideChannel(payload),
5181
+ };
5182
+ if (adv.includeDiagnostics === true) {
5183
+ json.contextMessages = payload;
5184
+ }
5149
5185
  returnData.push({ json });
5150
5186
  }
5151
5187
  return [returnData];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.36",
3
+ "version": "1.1.38",
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",