n8n-nodes-tembory 1.1.41 → 1.1.43
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 +127 -7
- 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.43`.
|
|
6
|
+
|
|
7
|
+
## 1.1.43
|
|
8
|
+
|
|
9
|
+
- Adiciona `toolCapture` no payload visual de `saveContext`, deixando explicito quando nenhuma execucao de tool chegou para a memoria.
|
|
10
|
+
- Suporta tambem `intermediate_steps` em snake case, alem de `intermediateSteps`.
|
|
11
|
+
- Quando `toolCallsCaptured` for `0`, o payload informa que e necessario o AI Agent entregar `intermediateSteps`, `__temboryToolCalls` ou tool messages para a memoria conseguir salvar a tool.
|
|
12
|
+
|
|
13
|
+
## 1.1.42
|
|
14
|
+
|
|
15
|
+
- Explicita `conversation` e `conversationTimeline` tambem no payload visual de `saveContext`.
|
|
16
|
+
- Aumenta a timeline visual de conversa do `loadMemoryVariables` para ate 16 mensagens recentes.
|
|
17
|
+
- Parseia resultados de tools de busca vetorial em `outputParsed.documents`, preservando `pageContent`, `metadata`, `id`, `source` e `score` quando existirem.
|
|
6
18
|
|
|
7
19
|
## 1.1.41
|
|
8
20
|
|
|
@@ -1210,9 +1210,14 @@ const extractToolCalls = (outputValues = {}) => {
|
|
|
1210
1210
|
source: 'tool_object',
|
|
1211
1211
|
});
|
|
1212
1212
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1213
|
+
const intermediateSteps = Array.isArray(obj.intermediateSteps)
|
|
1214
|
+
? obj.intermediateSteps
|
|
1215
|
+
: Array.isArray(obj.intermediate_steps)
|
|
1216
|
+
? obj.intermediate_steps
|
|
1217
|
+
: undefined;
|
|
1218
|
+
if (Array.isArray(intermediateSteps)) {
|
|
1219
|
+
for (let index = 0; index < intermediateSteps.length; index++) {
|
|
1220
|
+
const step = intermediateSteps[index];
|
|
1216
1221
|
if (Array.isArray(step) && step.length >= 1) {
|
|
1217
1222
|
const action = step[0] || {};
|
|
1218
1223
|
push(action.tool || action.name, action.toolInput || action.input || action.args, step[1], true, {
|
|
@@ -2680,9 +2685,44 @@ const extractToolOperationalFacts = (tool = {}) => {
|
|
|
2680
2685
|
const facts = mergeOperationalFactObjects(outputFacts, inputFacts);
|
|
2681
2686
|
return Object.keys(facts || {}).length ? facts : undefined;
|
|
2682
2687
|
};
|
|
2688
|
+
const compactVectorDocumentForSideChannel = (value) => {
|
|
2689
|
+
const original = value;
|
|
2690
|
+
let parsed = value;
|
|
2691
|
+
if (typeof parsed === 'string')
|
|
2692
|
+
parsed = tryParseJsonValue(parsed) || parsed;
|
|
2693
|
+
if (parsed && typeof parsed === 'object' && typeof parsed.text === 'string') {
|
|
2694
|
+
const textParsed = tryParseJsonValue(parsed.text);
|
|
2695
|
+
if (textParsed && typeof textParsed === 'object')
|
|
2696
|
+
parsed = { ...parsed, ...textParsed };
|
|
2697
|
+
}
|
|
2698
|
+
if (!parsed || typeof parsed !== 'object')
|
|
2699
|
+
return undefined;
|
|
2700
|
+
const pageContent = parsed.pageContent || parsed.content || parsed.document || (original && original.type === 'text' ? parsed.text : undefined);
|
|
2701
|
+
const rawMetadata = parsed.metadata && typeof parsed.metadata === 'object' ? parsed.metadata : undefined;
|
|
2702
|
+
const metadata = rawMetadata ? stripNoisyToolFields(rawMetadata) : undefined;
|
|
2703
|
+
if (!pageContent && !metadata)
|
|
2704
|
+
return undefined;
|
|
2705
|
+
return cleanContextValue({
|
|
2706
|
+
pageContent: pageContent ? truncate(String(pageContent), 1200) : undefined,
|
|
2707
|
+
metadata,
|
|
2708
|
+
id: parsed.id || metadata?.id,
|
|
2709
|
+
source: parsed.source || rawMetadata?.source,
|
|
2710
|
+
score: parsed.score || metadata?.score,
|
|
2711
|
+
});
|
|
2712
|
+
};
|
|
2713
|
+
const compactVectorDocumentsForSideChannel = (value) => {
|
|
2714
|
+
const items = Array.isArray(value) ? value : [value];
|
|
2715
|
+
return items
|
|
2716
|
+
.map((item) => compactVectorDocumentForSideChannel(item))
|
|
2717
|
+
.filter((item) => item && Object.keys(item).length)
|
|
2718
|
+
.slice(0, 8);
|
|
2719
|
+
};
|
|
2683
2720
|
const compactParsedToolOutputForSideChannel = (parsed) => {
|
|
2684
2721
|
if (parsed === undefined || parsed === null)
|
|
2685
2722
|
return undefined;
|
|
2723
|
+
const vectorDocuments = compactVectorDocumentsForSideChannel(parsed);
|
|
2724
|
+
if (vectorDocuments.length)
|
|
2725
|
+
return cleanContextValue({ documents: vectorDocuments, count: vectorDocuments.length });
|
|
2686
2726
|
if (Array.isArray(parsed))
|
|
2687
2727
|
return cleanContextValue(parsed.map((item) => compactParsedToolOutputForSideChannel(item)));
|
|
2688
2728
|
if (typeof parsed !== 'object')
|
|
@@ -3081,17 +3121,19 @@ const normalizeConversationRoleForSideChannel = (role = '') => {
|
|
|
3081
3121
|
return 'tool';
|
|
3082
3122
|
return normalized || 'message';
|
|
3083
3123
|
};
|
|
3084
|
-
const compactConversationTimelineForSideChannel = (conversation = {}, maxItems =
|
|
3124
|
+
const compactConversationTimelineForSideChannel = (conversation = {}, maxItems = 16, includeFull = false) => {
|
|
3085
3125
|
const chronological = Array.isArray(conversation.conversation_history_chronological)
|
|
3086
3126
|
? conversation.conversation_history_chronological
|
|
3087
3127
|
: [];
|
|
3088
|
-
|
|
3128
|
+
const visible = pruneByLimit(chronological, maxItems);
|
|
3129
|
+
const offset = Math.max(0, chronological.length - visible.length);
|
|
3130
|
+
return visible.map((message, index) => {
|
|
3089
3131
|
const role = normalizeConversationRoleForSideChannel(message.role || message.type);
|
|
3090
3132
|
const content = String(message.content || message.text || message.message || '');
|
|
3091
3133
|
const at = message.at || message.timestamp || message.created_at || message.createdAt;
|
|
3092
3134
|
const preview = role === 'system' ? '[system context hidden]' : truncate(content, 180);
|
|
3093
3135
|
return cleanContextValue({
|
|
3094
|
-
index,
|
|
3136
|
+
index: offset + index,
|
|
3095
3137
|
role,
|
|
3096
3138
|
speaker: role,
|
|
3097
3139
|
at,
|
|
@@ -3106,6 +3148,80 @@ const compactConversationTimelineForSideChannel = (conversation = {}, maxItems =
|
|
|
3106
3148
|
});
|
|
3107
3149
|
});
|
|
3108
3150
|
};
|
|
3151
|
+
const conversationEntriesFromMessagesForSideChannel = (messages = []) => (Array.isArray(messages) ? messages : [])
|
|
3152
|
+
.map((message) => {
|
|
3153
|
+
const type = messageTypeOf(message) || String(message.role || 'message').toLowerCase();
|
|
3154
|
+
const role = type === 'human' || type === 'user' ? 'user' : type === 'ai' || type === 'assistant' ? 'agent' : type === 'tool' ? 'tool' : type === 'system' ? 'system' : 'message';
|
|
3155
|
+
const content = messageContentOf(message);
|
|
3156
|
+
return {
|
|
3157
|
+
role,
|
|
3158
|
+
speaker: role,
|
|
3159
|
+
at: message.at || message.timestamp || message.created_at || message.createdAt,
|
|
3160
|
+
content,
|
|
3161
|
+
};
|
|
3162
|
+
})
|
|
3163
|
+
.filter((message) => message.role !== 'system' && message.content);
|
|
3164
|
+
const conversationDigestFromMessagesForSideChannel = (messages = []) => {
|
|
3165
|
+
const entries = conversationEntriesFromMessagesForSideChannel(messages);
|
|
3166
|
+
const lastUser = [...entries].reverse().find((message) => message.role === 'user');
|
|
3167
|
+
const lastAgent = [...entries].reverse().find((message) => message.role === 'agent');
|
|
3168
|
+
return cleanContextValue({
|
|
3169
|
+
messages: entries.length,
|
|
3170
|
+
userMessages: entries.filter((message) => message.role === 'user').length,
|
|
3171
|
+
assistantMessages: entries.filter((message) => message.role === 'agent').length,
|
|
3172
|
+
lastUser: lastUser ? {
|
|
3173
|
+
at: lastUser.at,
|
|
3174
|
+
preview: truncate(lastUser.content, 240),
|
|
3175
|
+
} : undefined,
|
|
3176
|
+
lastAgent: lastAgent ? {
|
|
3177
|
+
at: lastAgent.at,
|
|
3178
|
+
preview: truncate(lastAgent.content, 240),
|
|
3179
|
+
} : undefined,
|
|
3180
|
+
});
|
|
3181
|
+
};
|
|
3182
|
+
const conversationTimelineFromMessagesForSideChannel = (messages = [], maxItems = 16) => {
|
|
3183
|
+
const entries = conversationEntriesFromMessagesForSideChannel(messages);
|
|
3184
|
+
const visible = pruneByLimit(entries, maxItems);
|
|
3185
|
+
const offset = Math.max(0, entries.length - visible.length);
|
|
3186
|
+
return visible.map((message, index) => cleanContextValue({
|
|
3187
|
+
index: offset + index,
|
|
3188
|
+
role: message.role,
|
|
3189
|
+
speaker: message.speaker,
|
|
3190
|
+
at: message.at,
|
|
3191
|
+
chars: message.content.length,
|
|
3192
|
+
preview: truncate(message.content, 180),
|
|
3193
|
+
}));
|
|
3194
|
+
};
|
|
3195
|
+
const hasToolCaptureSignal = (output = {}) => {
|
|
3196
|
+
let hasIntermediateSteps = false;
|
|
3197
|
+
let hasExplicitToolCalls = false;
|
|
3198
|
+
let hasToolObject = false;
|
|
3199
|
+
readDeep(output || {}, (obj) => {
|
|
3200
|
+
if (Array.isArray(obj.intermediateSteps) || Array.isArray(obj.intermediate_steps))
|
|
3201
|
+
hasIntermediateSteps = true;
|
|
3202
|
+
if (Array.isArray(obj.__temboryToolCalls) || Array.isArray(obj.toolCalls) || Array.isArray(obj.tool_calls))
|
|
3203
|
+
hasExplicitToolCalls = true;
|
|
3204
|
+
const name = obj.tool || obj.toolName || obj.name;
|
|
3205
|
+
const hasInput = obj.toolInput !== undefined || obj.input !== undefined || obj.args !== undefined;
|
|
3206
|
+
const hasResult = obj.observation !== undefined || obj.result !== undefined || obj.output !== undefined || obj.error !== undefined;
|
|
3207
|
+
if (name && hasInput && hasResult)
|
|
3208
|
+
hasToolObject = true;
|
|
3209
|
+
});
|
|
3210
|
+
return { hasIntermediateSteps, hasExplicitToolCalls, hasToolObject };
|
|
3211
|
+
};
|
|
3212
|
+
const summarizeToolCaptureForSideChannel = (output = {}, toolCalls = []) => {
|
|
3213
|
+
const signals = hasToolCaptureSignal(output);
|
|
3214
|
+
const sources = Array.from(new Set((toolCalls || []).map((tool) => tool.source).filter(Boolean)));
|
|
3215
|
+
return cleanContextValue({
|
|
3216
|
+
status: toolCalls.length ? 'captured' : 'no_tool_payload_received',
|
|
3217
|
+
captured: toolCalls.length,
|
|
3218
|
+
sources,
|
|
3219
|
+
signals,
|
|
3220
|
+
note: toolCalls.length
|
|
3221
|
+
? undefined
|
|
3222
|
+
: 'No tool execution data was received by memory in this saveContext call. If a tool ran, enable AI Agent Return Intermediate Steps or pass tool messages to memory.',
|
|
3223
|
+
});
|
|
3224
|
+
};
|
|
3109
3225
|
const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory = []) => {
|
|
3110
3226
|
const inputMessage = input?.input || input?.chatInput || input?.query || input?.question || input?.text || input?.message || '';
|
|
3111
3227
|
const outputMessage = output?.output || output?.response || output?.text || output?.message || output?.answer || '';
|
|
@@ -3114,6 +3230,8 @@ const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory
|
|
|
3114
3230
|
return keepVisibleToolLogArrays(cleanContextValue({
|
|
3115
3231
|
visualSchema: VISUAL_SCHEMA_VERSION,
|
|
3116
3232
|
messagesAfterSave: Array.isArray(chatHistory) ? chatHistory.length : 0,
|
|
3233
|
+
conversation: conversationDigestFromMessagesForSideChannel(chatHistory),
|
|
3234
|
+
conversationTimeline: conversationTimelineFromMessagesForSideChannel(chatHistory, 16),
|
|
3117
3235
|
savedMessages: Array.isArray(chatHistory)
|
|
3118
3236
|
? chatHistory.slice(-6).map((message) => compactMessageForSideChannel(message))
|
|
3119
3237
|
: undefined,
|
|
@@ -3121,6 +3239,7 @@ const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory
|
|
|
3121
3239
|
assistantOutput: outputMessage ? truncate(String(outputMessage), 700) : undefined,
|
|
3122
3240
|
toolCallsCaptured: toolCalls.length,
|
|
3123
3241
|
toolNames: toolEvents.map((tool) => tool.name).filter(Boolean),
|
|
3242
|
+
toolCapture: summarizeToolCaptureForSideChannel(output, toolCalls),
|
|
3124
3243
|
toolLog: buildToolLogForSideChannel(toolEvents, toolCalls.length, SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX),
|
|
3125
3244
|
toolEvents,
|
|
3126
3245
|
}));
|
|
@@ -3320,7 +3439,7 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3320
3439
|
preview: truncate(String(lastAgent.content || lastAgent.text || lastAgent.message || ''), 240),
|
|
3321
3440
|
} : undefined,
|
|
3322
3441
|
});
|
|
3323
|
-
summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation,
|
|
3442
|
+
summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 16);
|
|
3324
3443
|
const visibleToolEvents = compactToolEventsForSideChannel(toolItems, SIDE_CHANNEL_TOOL_EVENT_MAX);
|
|
3325
3444
|
summary.toolCount = toolItems.length || tools.count || parsed.operationalState?.tool_counts?.total || undefined;
|
|
3326
3445
|
summary.toolNames = toolItems.map((tool) => tool.name || tool.tool_name).filter(Boolean).slice(0, 12);
|
|
@@ -5501,6 +5620,7 @@ exports.__private = {
|
|
|
5501
5620
|
compactToolResult,
|
|
5502
5621
|
compactToolAuditForSideChannel,
|
|
5503
5622
|
buildToolLogForSideChannel,
|
|
5623
|
+
compactParsedToolOutputForSideChannel,
|
|
5504
5624
|
compactToolHistoryForAgent,
|
|
5505
5625
|
compactVectorMemoriesForAgent,
|
|
5506
5626
|
isConversationEchoMemory,
|
package/package.json
CHANGED