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 +13 -1
- package/dist/nodes/Tembory/TemboryMemory.node.js +86 -20
- package/package.json +1 -1
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.
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
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
|
|
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
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
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