n8n-nodes-tembory 1.1.34 → 1.1.36

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.34`.
5
+ Versao atual: `1.1.36`.
6
+
7
+ ## 1.1.36
8
+
9
+ - Mantem o comportamento funcional da `1.1.35`.
10
+ - Corrige o resumo visual do n8n para mensagens LangChain serializadas, incluindo objetos com `kwargs.content`.
11
+ - Evita o fallback pobre `{ action, messages }` quando o contexto foi carregado corretamente mas o output humano nao conseguiu parsear o `SystemMessage`.
12
+
13
+ ## 1.1.35
14
+
15
+ - Corrige a chave default de memoria do runtime para `chat_history`, que e o placeholder usado pelo AI Agent do n8n.
16
+ - Mantem compatibilidade com `chatHistory`, devolvendo aliases para workflows antigos.
17
+ - Faz o contexto operacional do Tembory entrar no prompt principal do Agent em modo simples.
6
18
 
7
19
  ## 1.1.34
8
20
 
@@ -9,6 +9,7 @@ try {
9
9
  }
10
10
  catch { }
11
11
  const MAX_TEXT = 12000;
12
+ const DEFAULT_MEMORY_KEY = 'chat_history';
12
13
  const nowIso = () => new Date().toISOString();
13
14
  const safeStringify = (value) => {
14
15
  try {
@@ -932,8 +933,8 @@ const toolHistoryItemsFromMemory = (item) => {
932
933
  return single ? [single] : [];
933
934
  };
934
935
  const toBaseMessage = (message) => {
935
- const role = String((message === null || message === void 0 ? void 0 : message.role) || 'system').toLowerCase();
936
- const content = typeof message === 'string' ? message : String((message === null || message === void 0 ? void 0 : message.content) || '');
936
+ const role = String(messageTypeOf(message) || (message === null || message === void 0 ? void 0 : message.role) || 'system').toLowerCase();
937
+ const content = messageContentOf(message);
937
938
  const MessageClass = role === 'human' || role === 'user'
938
939
  ? LangChainMessages.HumanMessage
939
940
  : role === 'ai' || role === 'assistant'
@@ -1028,9 +1029,39 @@ const readDeep = (value, visitor, seen = new Set()) => {
1028
1029
  const messageTypeOf = (message) => {
1029
1030
  if (typeof (message === null || message === void 0 ? void 0 : message._getType) === 'function')
1030
1031
  return String(message._getType() || '');
1031
- return String((message === null || message === void 0 ? void 0 : message.role) || (message === null || message === void 0 ? void 0 : message.type) || (message === null || message === void 0 ? void 0 : message.lc_kwargs && message.lc_kwargs.type) || '').toLowerCase();
1032
+ const serializedId = Array.isArray(message === null || message === void 0 ? void 0 : message.id) ? message.id.join('.') : '';
1033
+ if (/SystemMessage/i.test(serializedId))
1034
+ return 'system';
1035
+ if (/HumanMessage/i.test(serializedId))
1036
+ return 'human';
1037
+ if (/AIMessage/i.test(serializedId))
1038
+ return 'ai';
1039
+ return String((message === null || message === void 0 ? void 0 : message.role) || (message === null || message === void 0 ? void 0 : message.type) || (message === null || message === void 0 ? void 0 : message.kwargs && message.kwargs.type) || (message === null || message === void 0 ? void 0 : message.lc_kwargs && message.lc_kwargs.type) || '').toLowerCase();
1040
+ };
1041
+ const messageContentOf = (message) => {
1042
+ if (typeof message === 'string')
1043
+ return message;
1044
+ const content = (message === null || message === void 0 ? void 0 : message.content) !== undefined
1045
+ ? message.content
1046
+ : (message === null || message === void 0 ? void 0 : message.kwargs && message.kwargs.content) !== undefined
1047
+ ? message.kwargs.content
1048
+ : (message === null || message === void 0 ? void 0 : message.lc_kwargs && message.lc_kwargs.content) !== undefined
1049
+ ? message.lc_kwargs.content
1050
+ : (message === null || message === void 0 ? void 0 : message.data && message.data.content) !== undefined
1051
+ ? message.data.content
1052
+ : undefined;
1053
+ if (typeof content === 'string')
1054
+ return content;
1055
+ if (Array.isArray(content)) {
1056
+ const joined = content
1057
+ .map((part) => typeof part === 'string' ? part : (part && typeof part.text === 'string' ? part.text : safeStringify(part)))
1058
+ .filter(Boolean)
1059
+ .join('\n');
1060
+ if (joined)
1061
+ return joined;
1062
+ }
1063
+ return content === undefined ? '' : safeStringify(content);
1032
1064
  };
1033
- const messageContentOf = (message) => typeof (message === null || message === void 0 ? void 0 : message.content) === 'string' ? message.content : safeStringify(message === null || message === void 0 ? void 0 : message.content);
1034
1065
  const extractToolCallsFromMessages = (messages = []) => {
1035
1066
  const calls = [];
1036
1067
  const toolCallById = new Map();
@@ -2984,7 +3015,18 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
2984
3015
  if (!firstSystem)
2985
3016
  return summary;
2986
3017
  try {
2987
- const parsed = JSON.parse(messageContentOf(firstSystem));
3018
+ const rawContent = messageContentOf(firstSystem);
3019
+ let parsed;
3020
+ try {
3021
+ parsed = JSON.parse(rawContent);
3022
+ }
3023
+ catch {
3024
+ const start = rawContent.indexOf('{');
3025
+ const end = rawContent.lastIndexOf('}');
3026
+ if (start < 0 || end <= start)
3027
+ throw new Error('Tembory visual summary could not find JSON context');
3028
+ parsed = JSON.parse(rawContent.slice(start, end + 1));
3029
+ }
2988
3030
  const conversation = parsed.conversation || {};
2989
3031
  const tools = parsed.tools || {};
2990
3032
  const toolItems = Array.isArray(tools.items) ? tools.items : [];
@@ -3093,7 +3135,13 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
3093
3135
  return Object.fromEntries(Object.entries(summary).filter(([, value]) => value !== undefined));
3094
3136
  }
3095
3137
  catch {
3096
- return summary;
3138
+ const content = messageContentOf(firstSystem);
3139
+ return cleanContextValue({
3140
+ ...summary,
3141
+ contextChars: content.length || undefined,
3142
+ contextPreview: content ? truncate(content, 260) : undefined,
3143
+ visualSummaryStatus: 'unparsed',
3144
+ });
3097
3145
  }
3098
3146
  };
3099
3147
  const contextSizeOfMessages = (messages = []) => {
@@ -3113,7 +3161,7 @@ const wrapTemboryMemory = (memory, ctx, memoryKey, itemIndex = 0) => new Proxy(m
3113
3161
  ]);
3114
3162
  try {
3115
3163
  const response = await target.loadMemoryVariables(values);
3116
- const memoryMessages = response[memoryKey] || response.chatHistory || [];
3164
+ const memoryMessages = response[memoryKey] || response.chat_history || response.chatHistory || [];
3117
3165
  const messages = Array.isArray(memoryMessages) ? memoryMessages.length : 0;
3118
3166
  ctx.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, [
3119
3167
  [{
@@ -3764,7 +3812,7 @@ class TemboryMemory {
3764
3812
  // For AI connections, n8n reads from supplyData. The AI Agent expects a
3765
3813
  // memory-like object, not raw JSON, so expose the LangChain memory contract.
3766
3814
  async supplyData(itemIndex) {
3767
- const memoryKey = this.getNodeParameter('memoryKey', itemIndex, 'chatHistory');
3815
+ const memoryKey = this.getNodeParameter('memoryKey', itemIndex, DEFAULT_MEMORY_KEY);
3768
3816
  let currentMessages = [];
3769
3817
  const loadCache = new Map();
3770
3818
  const recordMemoryEvent = (action, payload = {}, error) => {
@@ -3780,7 +3828,7 @@ class TemboryMemory {
3780
3828
  ]);
3781
3829
  };
3782
3830
  const memory = {
3783
- memoryKeys: [memoryKey],
3831
+ memoryKeys: Array.from(new Set([memoryKey, DEFAULT_MEMORY_KEY])),
3784
3832
  inputKey: 'input',
3785
3833
  outputKey: 'output',
3786
3834
  returnMessages: true,
@@ -3827,11 +3875,18 @@ class TemboryMemory {
3827
3875
  loadCache.delete(firstKey);
3828
3876
  }
3829
3877
  }
3830
- const chatHistory = (result.response[memoryKey] || []).map(toBaseMessage);
3878
+ const chatHistory = (result.response[memoryKey] || result.response.chat_history || result.response.chatHistory || []).map(toBaseMessage);
3831
3879
  currentMessages = chatHistory;
3832
3880
  const variables = {
3833
3881
  [memoryKey]: chatHistory,
3834
3882
  };
3883
+ if (memoryKey !== DEFAULT_MEMORY_KEY) {
3884
+ Object.defineProperty(variables, DEFAULT_MEMORY_KEY, {
3885
+ value: chatHistory,
3886
+ enumerable: true,
3887
+ configurable: true,
3888
+ });
3889
+ }
3835
3890
  if (memoryKey !== 'chatHistory') {
3836
3891
  Object.defineProperty(variables, 'chatHistory', {
3837
3892
  value: chatHistory,
@@ -4381,7 +4436,7 @@ class TemboryMemory {
4381
4436
  }
4382
4437
  async loadMemoryVariablesForItem(itemIndex, inputValues = {}) {
4383
4438
  var _a, _b, _c, _d, _e, _f, _g;
4384
- const memoryKey = this.getNodeParameter('memoryKey', itemIndex, 'chatHistory');
4439
+ const memoryKey = this.getNodeParameter('memoryKey', itemIndex, DEFAULT_MEMORY_KEY);
4385
4440
  const requestedRetrievalMode = this.getNodeParameter('retrievalMode', itemIndex, 'basic');
4386
4441
  let payloadFormat = this.getNodeParameter('payloadFormat', itemIndex, 'structured');
4387
4442
  const threadId = this.getNodeParameter('threadId', itemIndex);
@@ -5014,6 +5069,7 @@ class TemboryMemory {
5014
5069
  return {
5015
5070
  response: {
5016
5071
  [memoryKey]: payload,
5072
+ chat_history: payload,
5017
5073
  chatHistory: payload,
5018
5074
  },
5019
5075
  };
@@ -5023,7 +5079,7 @@ class TemboryMemory {
5023
5079
  const returnData = [];
5024
5080
  const count = Math.max(items.length, 1);
5025
5081
  for (let i = 0; i < count; i++) {
5026
- const memoryKey = this.getNodeParameter('memoryKey', i, 'chatHistory');
5082
+ const memoryKey = this.getNodeParameter('memoryKey', i, DEFAULT_MEMORY_KEY);
5027
5083
  const requestedRetrievalMode = this.getNodeParameter('retrievalMode', i, 'basic');
5028
5084
  const threadId = this.getNodeParameter('threadId', i);
5029
5085
  const project = this.getNodeParameter('project', i, '');
@@ -5088,6 +5144,8 @@ class TemboryMemory {
5088
5144
  }
5089
5145
  const json = {};
5090
5146
  json[memoryKey] = payload;
5147
+ json.chat_history = payload;
5148
+ json.chatHistory = payload;
5091
5149
  returnData.push({ json });
5092
5150
  }
5093
5151
  return [returnData];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.34",
3
+ "version": "1.1.36",
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",