n8n-nodes-tembory 1.1.35 → 1.1.37

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.35`.
5
+ Versao atual: `1.1.37`.
6
+
7
+ ## 1.1.37
8
+
9
+ - Normaliza `chatHistory` legado para `chat_history` no modo simples, evitando que historico bruto vaze no output final do Agent.
10
+ - Mantem `chatHistory` apenas como alias nao enumeravel no contrato interno de memoria.
11
+ - O caminho de execucao normal do node passa a retornar resumo visual compacto, nao o array bruto de mensagens.
12
+
13
+ ## 1.1.36
14
+
15
+ - Mantem o comportamento funcional da `1.1.35`.
16
+ - Corrige o resumo visual do n8n para mensagens LangChain serializadas, incluindo objetos com `kwargs.content`.
17
+ - Evita o fallback pobre `{ action, messages }` quando o contexto foi carregado corretamente mas o output humano nao conseguiu parsear o `SystemMessage`.
6
18
 
7
19
  ## 1.1.35
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 {
@@ -933,8 +948,8 @@ const toolHistoryItemsFromMemory = (item) => {
933
948
  return single ? [single] : [];
934
949
  };
935
950
  const toBaseMessage = (message) => {
936
- const role = String((message === null || message === void 0 ? void 0 : message.role) || 'system').toLowerCase();
937
- const content = typeof message === 'string' ? message : String((message === null || message === void 0 ? void 0 : message.content) || '');
951
+ const role = String(messageTypeOf(message) || (message === null || message === void 0 ? void 0 : message.role) || 'system').toLowerCase();
952
+ const content = messageContentOf(message);
938
953
  const MessageClass = role === 'human' || role === 'user'
939
954
  ? LangChainMessages.HumanMessage
940
955
  : role === 'ai' || role === 'assistant'
@@ -1029,9 +1044,39 @@ const readDeep = (value, visitor, seen = new Set()) => {
1029
1044
  const messageTypeOf = (message) => {
1030
1045
  if (typeof (message === null || message === void 0 ? void 0 : message._getType) === 'function')
1031
1046
  return String(message._getType() || '');
1032
- 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();
1047
+ const serializedId = Array.isArray(message === null || message === void 0 ? void 0 : message.id) ? message.id.join('.') : '';
1048
+ if (/SystemMessage/i.test(serializedId))
1049
+ return 'system';
1050
+ if (/HumanMessage/i.test(serializedId))
1051
+ return 'human';
1052
+ if (/AIMessage/i.test(serializedId))
1053
+ return 'ai';
1054
+ 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();
1055
+ };
1056
+ const messageContentOf = (message) => {
1057
+ if (typeof message === 'string')
1058
+ return message;
1059
+ const content = (message === null || message === void 0 ? void 0 : message.content) !== undefined
1060
+ ? message.content
1061
+ : (message === null || message === void 0 ? void 0 : message.kwargs && message.kwargs.content) !== undefined
1062
+ ? message.kwargs.content
1063
+ : (message === null || message === void 0 ? void 0 : message.lc_kwargs && message.lc_kwargs.content) !== undefined
1064
+ ? message.lc_kwargs.content
1065
+ : (message === null || message === void 0 ? void 0 : message.data && message.data.content) !== undefined
1066
+ ? message.data.content
1067
+ : undefined;
1068
+ if (typeof content === 'string')
1069
+ return content;
1070
+ if (Array.isArray(content)) {
1071
+ const joined = content
1072
+ .map((part) => typeof part === 'string' ? part : (part && typeof part.text === 'string' ? part.text : safeStringify(part)))
1073
+ .filter(Boolean)
1074
+ .join('\n');
1075
+ if (joined)
1076
+ return joined;
1077
+ }
1078
+ return content === undefined ? '' : safeStringify(content);
1033
1079
  };
1034
- 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);
1035
1080
  const extractToolCallsFromMessages = (messages = []) => {
1036
1081
  const calls = [];
1037
1082
  const toolCallById = new Map();
@@ -2985,7 +3030,18 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
2985
3030
  if (!firstSystem)
2986
3031
  return summary;
2987
3032
  try {
2988
- const parsed = JSON.parse(messageContentOf(firstSystem));
3033
+ const rawContent = messageContentOf(firstSystem);
3034
+ let parsed;
3035
+ try {
3036
+ parsed = JSON.parse(rawContent);
3037
+ }
3038
+ catch {
3039
+ const start = rawContent.indexOf('{');
3040
+ const end = rawContent.lastIndexOf('}');
3041
+ if (start < 0 || end <= start)
3042
+ throw new Error('Tembory visual summary could not find JSON context');
3043
+ parsed = JSON.parse(rawContent.slice(start, end + 1));
3044
+ }
2989
3045
  const conversation = parsed.conversation || {};
2990
3046
  const tools = parsed.tools || {};
2991
3047
  const toolItems = Array.isArray(tools.items) ? tools.items : [];
@@ -3094,7 +3150,13 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
3094
3150
  return Object.fromEntries(Object.entries(summary).filter(([, value]) => value !== undefined));
3095
3151
  }
3096
3152
  catch {
3097
- return summary;
3153
+ const content = messageContentOf(firstSystem);
3154
+ return cleanContextValue({
3155
+ ...summary,
3156
+ contextChars: content.length || undefined,
3157
+ contextPreview: content ? truncate(content, 260) : undefined,
3158
+ visualSummaryStatus: 'unparsed',
3159
+ });
3098
3160
  }
3099
3161
  };
3100
3162
  const contextSizeOfMessages = (messages = []) => {
@@ -3765,7 +3827,7 @@ class TemboryMemory {
3765
3827
  // For AI connections, n8n reads from supplyData. The AI Agent expects a
3766
3828
  // memory-like object, not raw JSON, so expose the LangChain memory contract.
3767
3829
  async supplyData(itemIndex) {
3768
- const memoryKey = this.getNodeParameter('memoryKey', itemIndex, DEFAULT_MEMORY_KEY);
3830
+ const memoryKey = resolveRuntimeMemoryKey(this, itemIndex);
3769
3831
  let currentMessages = [];
3770
3832
  const loadCache = new Map();
3771
3833
  const recordMemoryEvent = (action, payload = {}, error) => {
@@ -4389,7 +4451,7 @@ class TemboryMemory {
4389
4451
  }
4390
4452
  async loadMemoryVariablesForItem(itemIndex, inputValues = {}) {
4391
4453
  var _a, _b, _c, _d, _e, _f, _g;
4392
- const memoryKey = this.getNodeParameter('memoryKey', itemIndex, DEFAULT_MEMORY_KEY);
4454
+ const memoryKey = resolveRuntimeMemoryKey(this, itemIndex);
4393
4455
  const requestedRetrievalMode = this.getNodeParameter('retrievalMode', itemIndex, 'basic');
4394
4456
  let payloadFormat = this.getNodeParameter('payloadFormat', itemIndex, 'structured');
4395
4457
  const threadId = this.getNodeParameter('threadId', itemIndex);
@@ -5019,20 +5081,20 @@ class TemboryMemory {
5019
5081
  diagnostics,
5020
5082
  dedupeSummary: diagnostics.dedupeSummary,
5021
5083
  };
5022
- return {
5023
- response: {
5024
- [memoryKey]: payload,
5025
- chat_history: payload,
5026
- chatHistory: payload,
5027
- },
5028
- };
5084
+ const response = { [memoryKey]: payload, chat_history: payload };
5085
+ Object.defineProperty(response, 'chatHistory', {
5086
+ value: payload,
5087
+ enumerable: false,
5088
+ configurable: true,
5089
+ });
5090
+ return { response };
5029
5091
  }
5030
5092
  async execute() {
5031
5093
  const items = this.getInputData();
5032
5094
  const returnData = [];
5033
5095
  const count = Math.max(items.length, 1);
5034
5096
  for (let i = 0; i < count; i++) {
5035
- const memoryKey = this.getNodeParameter('memoryKey', i, DEFAULT_MEMORY_KEY);
5097
+ const memoryKey = resolveRuntimeMemoryKey(this, i);
5036
5098
  const requestedRetrievalMode = this.getNodeParameter('retrievalMode', i, 'basic');
5037
5099
  const threadId = this.getNodeParameter('threadId', i);
5038
5100
  const project = this.getNodeParameter('project', i, '');
@@ -5095,10 +5157,14 @@ class TemboryMemory {
5095
5157
  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) }); });
5096
5158
  }
5097
5159
  }
5098
- const json = {};
5099
- json[memoryKey] = payload;
5100
- json.chat_history = payload;
5101
- json.chatHistory = payload;
5160
+ const json = {
5161
+ action: 'loadMemoryVariables',
5162
+ messages: Array.isArray(payload) ? payload.length : 0,
5163
+ memorySummary: summarizeMemoryMessagesForSideChannel(payload),
5164
+ };
5165
+ if (adv.includeDiagnostics === true) {
5166
+ json.contextMessages = payload;
5167
+ }
5102
5168
  returnData.push({ json });
5103
5169
  }
5104
5170
  return [returnData];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.35",
3
+ "version": "1.1.37",
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",