n8n-nodes-tembory 1.1.41 → 1.1.42

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,13 @@
2
2
 
3
3
  Node de memoria operacional da Tembory para agentes de IA no n8n.
4
4
 
5
- Versao atual: `1.1.41`.
5
+ Versao atual: `1.1.42`.
6
+
7
+ ## 1.1.42
8
+
9
+ - Explicita `conversation` e `conversationTimeline` tambem no payload visual de `saveContext`.
10
+ - Aumenta a timeline visual de conversa do `loadMemoryVariables` para ate 16 mensagens recentes.
11
+ - Parseia resultados de tools de busca vetorial em `outputParsed.documents`, preservando `pageContent`, `metadata`, `id`, `source` e `score` quando existirem.
6
12
 
7
13
  ## 1.1.41
8
14
 
@@ -2680,9 +2680,44 @@ const extractToolOperationalFacts = (tool = {}) => {
2680
2680
  const facts = mergeOperationalFactObjects(outputFacts, inputFacts);
2681
2681
  return Object.keys(facts || {}).length ? facts : undefined;
2682
2682
  };
2683
+ const compactVectorDocumentForSideChannel = (value) => {
2684
+ const original = value;
2685
+ let parsed = value;
2686
+ if (typeof parsed === 'string')
2687
+ parsed = tryParseJsonValue(parsed) || parsed;
2688
+ if (parsed && typeof parsed === 'object' && typeof parsed.text === 'string') {
2689
+ const textParsed = tryParseJsonValue(parsed.text);
2690
+ if (textParsed && typeof textParsed === 'object')
2691
+ parsed = { ...parsed, ...textParsed };
2692
+ }
2693
+ if (!parsed || typeof parsed !== 'object')
2694
+ return undefined;
2695
+ const pageContent = parsed.pageContent || parsed.content || parsed.document || (original && original.type === 'text' ? parsed.text : undefined);
2696
+ const rawMetadata = parsed.metadata && typeof parsed.metadata === 'object' ? parsed.metadata : undefined;
2697
+ const metadata = rawMetadata ? stripNoisyToolFields(rawMetadata) : undefined;
2698
+ if (!pageContent && !metadata)
2699
+ return undefined;
2700
+ return cleanContextValue({
2701
+ pageContent: pageContent ? truncate(String(pageContent), 1200) : undefined,
2702
+ metadata,
2703
+ id: parsed.id || metadata?.id,
2704
+ source: parsed.source || rawMetadata?.source,
2705
+ score: parsed.score || metadata?.score,
2706
+ });
2707
+ };
2708
+ const compactVectorDocumentsForSideChannel = (value) => {
2709
+ const items = Array.isArray(value) ? value : [value];
2710
+ return items
2711
+ .map((item) => compactVectorDocumentForSideChannel(item))
2712
+ .filter((item) => item && Object.keys(item).length)
2713
+ .slice(0, 8);
2714
+ };
2683
2715
  const compactParsedToolOutputForSideChannel = (parsed) => {
2684
2716
  if (parsed === undefined || parsed === null)
2685
2717
  return undefined;
2718
+ const vectorDocuments = compactVectorDocumentsForSideChannel(parsed);
2719
+ if (vectorDocuments.length)
2720
+ return cleanContextValue({ documents: vectorDocuments, count: vectorDocuments.length });
2686
2721
  if (Array.isArray(parsed))
2687
2722
  return cleanContextValue(parsed.map((item) => compactParsedToolOutputForSideChannel(item)));
2688
2723
  if (typeof parsed !== 'object')
@@ -3081,17 +3116,19 @@ const normalizeConversationRoleForSideChannel = (role = '') => {
3081
3116
  return 'tool';
3082
3117
  return normalized || 'message';
3083
3118
  };
3084
- const compactConversationTimelineForSideChannel = (conversation = {}, maxItems = 4, includeFull = false) => {
3119
+ const compactConversationTimelineForSideChannel = (conversation = {}, maxItems = 16, includeFull = false) => {
3085
3120
  const chronological = Array.isArray(conversation.conversation_history_chronological)
3086
3121
  ? conversation.conversation_history_chronological
3087
3122
  : [];
3088
- return pruneByLimit(chronological, maxItems).map((message, index) => {
3123
+ const visible = pruneByLimit(chronological, maxItems);
3124
+ const offset = Math.max(0, chronological.length - visible.length);
3125
+ return visible.map((message, index) => {
3089
3126
  const role = normalizeConversationRoleForSideChannel(message.role || message.type);
3090
3127
  const content = String(message.content || message.text || message.message || '');
3091
3128
  const at = message.at || message.timestamp || message.created_at || message.createdAt;
3092
3129
  const preview = role === 'system' ? '[system context hidden]' : truncate(content, 180);
3093
3130
  return cleanContextValue({
3094
- index,
3131
+ index: offset + index,
3095
3132
  role,
3096
3133
  speaker: role,
3097
3134
  at,
@@ -3106,6 +3143,50 @@ const compactConversationTimelineForSideChannel = (conversation = {}, maxItems =
3106
3143
  });
3107
3144
  });
3108
3145
  };
3146
+ const conversationEntriesFromMessagesForSideChannel = (messages = []) => (Array.isArray(messages) ? messages : [])
3147
+ .map((message) => {
3148
+ const type = messageTypeOf(message) || String(message.role || 'message').toLowerCase();
3149
+ const role = type === 'human' || type === 'user' ? 'user' : type === 'ai' || type === 'assistant' ? 'agent' : type === 'tool' ? 'tool' : type === 'system' ? 'system' : 'message';
3150
+ const content = messageContentOf(message);
3151
+ return {
3152
+ role,
3153
+ speaker: role,
3154
+ at: message.at || message.timestamp || message.created_at || message.createdAt,
3155
+ content,
3156
+ };
3157
+ })
3158
+ .filter((message) => message.role !== 'system' && message.content);
3159
+ const conversationDigestFromMessagesForSideChannel = (messages = []) => {
3160
+ const entries = conversationEntriesFromMessagesForSideChannel(messages);
3161
+ const lastUser = [...entries].reverse().find((message) => message.role === 'user');
3162
+ const lastAgent = [...entries].reverse().find((message) => message.role === 'agent');
3163
+ return cleanContextValue({
3164
+ messages: entries.length,
3165
+ userMessages: entries.filter((message) => message.role === 'user').length,
3166
+ assistantMessages: entries.filter((message) => message.role === 'agent').length,
3167
+ lastUser: lastUser ? {
3168
+ at: lastUser.at,
3169
+ preview: truncate(lastUser.content, 240),
3170
+ } : undefined,
3171
+ lastAgent: lastAgent ? {
3172
+ at: lastAgent.at,
3173
+ preview: truncate(lastAgent.content, 240),
3174
+ } : undefined,
3175
+ });
3176
+ };
3177
+ const conversationTimelineFromMessagesForSideChannel = (messages = [], maxItems = 16) => {
3178
+ const entries = conversationEntriesFromMessagesForSideChannel(messages);
3179
+ const visible = pruneByLimit(entries, maxItems);
3180
+ const offset = Math.max(0, entries.length - visible.length);
3181
+ return visible.map((message, index) => cleanContextValue({
3182
+ index: offset + index,
3183
+ role: message.role,
3184
+ speaker: message.speaker,
3185
+ at: message.at,
3186
+ chars: message.content.length,
3187
+ preview: truncate(message.content, 180),
3188
+ }));
3189
+ };
3109
3190
  const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory = []) => {
3110
3191
  const inputMessage = input?.input || input?.chatInput || input?.query || input?.question || input?.text || input?.message || '';
3111
3192
  const outputMessage = output?.output || output?.response || output?.text || output?.message || output?.answer || '';
@@ -3114,6 +3195,8 @@ const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory
3114
3195
  return keepVisibleToolLogArrays(cleanContextValue({
3115
3196
  visualSchema: VISUAL_SCHEMA_VERSION,
3116
3197
  messagesAfterSave: Array.isArray(chatHistory) ? chatHistory.length : 0,
3198
+ conversation: conversationDigestFromMessagesForSideChannel(chatHistory),
3199
+ conversationTimeline: conversationTimelineFromMessagesForSideChannel(chatHistory, 16),
3117
3200
  savedMessages: Array.isArray(chatHistory)
3118
3201
  ? chatHistory.slice(-6).map((message) => compactMessageForSideChannel(message))
3119
3202
  : undefined,
@@ -3320,7 +3403,7 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
3320
3403
  preview: truncate(String(lastAgent.content || lastAgent.text || lastAgent.message || ''), 240),
3321
3404
  } : undefined,
3322
3405
  });
3323
- summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 4);
3406
+ summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 16);
3324
3407
  const visibleToolEvents = compactToolEventsForSideChannel(toolItems, SIDE_CHANNEL_TOOL_EVENT_MAX);
3325
3408
  summary.toolCount = toolItems.length || tools.count || parsed.operationalState?.tool_counts?.total || undefined;
3326
3409
  summary.toolNames = toolItems.map((tool) => tool.name || tool.tool_name).filter(Boolean).slice(0, 12);
@@ -5501,6 +5584,7 @@ exports.__private = {
5501
5584
  compactToolResult,
5502
5585
  compactToolAuditForSideChannel,
5503
5586
  buildToolLogForSideChannel,
5587
+ compactParsedToolOutputForSideChannel,
5504
5588
  compactToolHistoryForAgent,
5505
5589
  compactVectorMemoriesForAgent,
5506
5590
  isConversationEchoMemory,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.41",
3
+ "version": "1.1.42",
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",