n8n-nodes-tembory 1.1.40 → 1.1.41

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.40`.
5
+ Versao atual: `1.1.41`.
6
+
7
+ ## 1.1.41
8
+
9
+ - Padroniza a saida visual do node com `visualSchema`, `memorySummary` e `toolLog` tanto no `loadMemoryVariables` quanto no `saveContext`.
10
+ - Mantem `toolEvents` para compatibilidade, mas agora tambem mostra `inputParsed`, `outputParsed`, timestamps e `facts` com IDs operacionais quando existirem.
11
+ - Aumenta a visibilidade do historico recente de tools no resumo visual para evitar esconder eventos importantes no debug humano.
6
12
 
7
13
  ## 1.1.40
8
14
 
@@ -3006,6 +3006,16 @@ const invokeConnectedModelSummary = async (connectedLanguageModel, summaryInput,
3006
3006
  ]);
3007
3007
  return cleanModelSummaryText(response, Number(adv.connectedModelSummaryMaxChars || 1200));
3008
3008
  };
3009
+ const VISUAL_SCHEMA_VERSION = 'tembory.visual.v1';
3010
+ const TOOL_LOG_VISUAL_SCHEMA_VERSION = 'tembory.visual.v1.toolLog';
3011
+ const SIDE_CHANNEL_TOOL_EVENT_MAX = 12;
3012
+ const SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX = 20;
3013
+ const compactParsedToolInputForSideChannel = (input) => {
3014
+ const parsed = safeParseToolPayload(input);
3015
+ if (!parsed || typeof parsed !== 'object')
3016
+ return undefined;
3017
+ return cleanContextValue(stripNoisyToolFields(parsed));
3018
+ };
3009
3019
  const compactToolAuditForSideChannel = (tool = {}) => {
3010
3020
  const capturedAt = tool.at || tool.timestamp;
3011
3021
  const rawResult = tool.result !== undefined ? tool.result : tool.output !== undefined ? tool.output : tool.observation;
@@ -3019,10 +3029,36 @@ const compactToolAuditForSideChannel = (tool = {}) => {
3019
3029
  toolTimestamp: toolResultTimestampFromParsed(parsedResult),
3020
3030
  toolStatus: parsedResult && typeof parsedResult === 'object' && !Array.isArray(parsedResult) ? parsedResult.status : undefined,
3021
3031
  input: truncate(String(tool.input || tool.tool_args || tool.normalized_args || ''), 300) || undefined,
3032
+ inputParsed: compactParsedToolInputForSideChannel(tool.input || tool.tool_args || tool.normalized_args),
3022
3033
  output: compactToolResult(rawResult, 800),
3023
3034
  outputParsed: compactParsedToolOutputForSideChannel(parsedResult),
3035
+ facts: extractToolOperationalFacts(tool),
3024
3036
  });
3025
3037
  };
3038
+ const compactToolEventsForSideChannel = (toolItems = [], maxItems = SIDE_CHANNEL_TOOL_EVENT_MAX) => pruneByLimit(toolItems || [], maxItems)
3039
+ .map((tool) => compactToolAuditForSideChannel(tool || {}))
3040
+ .filter((tool) => tool && Object.keys(tool).length);
3041
+ const buildToolLogForSideChannel = (toolEvents = [], totalCount, maxItems = SIDE_CHANNEL_TOOL_EVENT_MAX) => {
3042
+ const events = Array.isArray(toolEvents) ? toolEvents : [];
3043
+ const count = typeof totalCount === 'number' ? totalCount : events.length;
3044
+ return {
3045
+ schema: TOOL_LOG_VISUAL_SCHEMA_VERSION,
3046
+ count,
3047
+ names: events.map((tool) => tool.name).filter(Boolean).slice(0, maxItems),
3048
+ events,
3049
+ truncated: count > events.length,
3050
+ maxEvents: maxItems,
3051
+ };
3052
+ };
3053
+ const keepVisibleToolLogArrays = (payload = {}) => {
3054
+ if (payload.toolLog) {
3055
+ if (!Array.isArray(payload.toolLog.names))
3056
+ payload.toolLog.names = [];
3057
+ if (!Array.isArray(payload.toolLog.events))
3058
+ payload.toolLog.events = [];
3059
+ }
3060
+ return payload;
3061
+ };
3026
3062
  const compactMessageForSideChannel = (message = {}) => {
3027
3063
  const type = messageTypeOf(message) || String(message.role || 'message').toLowerCase();
3028
3064
  const role = type === 'human' ? 'user' : type === 'ai' ? 'assistant' : type || 'message';
@@ -3073,21 +3109,21 @@ const compactConversationTimelineForSideChannel = (conversation = {}, maxItems =
3073
3109
  const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory = []) => {
3074
3110
  const inputMessage = input?.input || input?.chatInput || input?.query || input?.question || input?.text || input?.message || '';
3075
3111
  const outputMessage = output?.output || output?.response || output?.text || output?.message || output?.answer || '';
3076
- const toolEvents = extractToolCalls(output || {})
3077
- .map((tool) => compactToolAuditForSideChannel(tool || {}))
3078
- .filter((tool) => tool && Object.keys(tool).length)
3079
- .slice(0, 20);
3080
- return cleanContextValue({
3112
+ const toolCalls = extractToolCalls(output || {});
3113
+ const toolEvents = compactToolEventsForSideChannel(toolCalls, SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX);
3114
+ return keepVisibleToolLogArrays(cleanContextValue({
3115
+ visualSchema: VISUAL_SCHEMA_VERSION,
3081
3116
  messagesAfterSave: Array.isArray(chatHistory) ? chatHistory.length : 0,
3082
3117
  savedMessages: Array.isArray(chatHistory)
3083
3118
  ? chatHistory.slice(-6).map((message) => compactMessageForSideChannel(message))
3084
3119
  : undefined,
3085
3120
  userInput: inputMessage ? truncate(String(inputMessage), 500) : undefined,
3086
3121
  assistantOutput: outputMessage ? truncate(String(outputMessage), 700) : undefined,
3087
- toolCallsCaptured: toolEvents.length || undefined,
3122
+ toolCallsCaptured: toolCalls.length,
3088
3123
  toolNames: toolEvents.map((tool) => tool.name).filter(Boolean),
3124
+ toolLog: buildToolLogForSideChannel(toolEvents, toolCalls.length, SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX),
3089
3125
  toolEvents,
3090
- });
3126
+ }));
3091
3127
  };
3092
3128
  const compactMemoryEventPayload = (payload = {}) => {
3093
3129
  const compact = { ...(payload || {}) };
@@ -3097,18 +3133,20 @@ const compactMemoryEventPayload = (payload = {}) => {
3097
3133
  .map((tool) => (tool && (tool.name || tool.tool_name || tool.tool)) || '')
3098
3134
  .filter(Boolean)
3099
3135
  .slice(0, 12);
3100
- compact.toolEvents = compact.toolCalls
3101
- .map((tool) => compactToolAuditForSideChannel(tool || {}))
3102
- .filter((tool) => tool && Object.keys(tool).length)
3103
- .slice(0, 8);
3136
+ compact.toolEvents = compactToolEventsForSideChannel(compact.toolCalls, SIDE_CHANNEL_TOOL_EVENT_MAX);
3137
+ compact.toolLog = buildToolLogForSideChannel(compact.toolEvents, compact.toolCalls.length, SIDE_CHANNEL_TOOL_EVENT_MAX);
3104
3138
  delete compact.toolCalls;
3105
3139
  }
3140
+ if (!compact.visualSchema)
3141
+ compact.visualSchema = VISUAL_SCHEMA_VERSION;
3142
+ if (Array.isArray(compact.toolEvents) && !compact.toolLog)
3143
+ compact.toolLog = buildToolLogForSideChannel(compact.toolEvents, compact.toolCallsCaptured, SIDE_CHANNEL_TOOL_EVENT_MAX);
3106
3144
  for (const key of ['input', 'output', 'values', 'chatHistory', 'context', 'contextText', 'diagnostics']) {
3107
3145
  if (compact[key] !== undefined)
3108
3146
  compact[`${key}Chars`] = typeof compact[key] === 'string' ? compact[key].length : safeStringify(compact[key]).length;
3109
3147
  delete compact[key];
3110
3148
  }
3111
- return compact;
3149
+ return keepVisibleToolLogArrays(compact);
3112
3150
  };
3113
3151
  const compactLastSaveForSideChannel = (lastSave = {}) => cleanContextValue({
3114
3152
  saved: lastSave.saved,
@@ -3259,6 +3297,7 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
3259
3297
  const fullDedupeSummary = parsed.dedupeSummary || parsed.diagnostics?.dedupeSummary || undefined;
3260
3298
  const loadedSections = loadedSectionsForSideChannel(parsed, memoryAudit);
3261
3299
  const agentContextBudget = agentContextBudgetForSideChannel(list, parsed);
3300
+ summary.visualSchema = VISUAL_SCHEMA_VERSION;
3262
3301
  summary.userId = parsed.userId;
3263
3302
  summary.project = parsed.project || undefined;
3264
3303
  summary.retrievalMode = parsed.retrievalMode;
@@ -3282,12 +3321,11 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
3282
3321
  } : undefined,
3283
3322
  });
3284
3323
  summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 4);
3324
+ const visibleToolEvents = compactToolEventsForSideChannel(toolItems, SIDE_CHANNEL_TOOL_EVENT_MAX);
3285
3325
  summary.toolCount = toolItems.length || tools.count || parsed.operationalState?.tool_counts?.total || undefined;
3286
3326
  summary.toolNames = toolItems.map((tool) => tool.name || tool.tool_name).filter(Boolean).slice(0, 12);
3287
- summary.toolEvents = toolItems
3288
- .slice(-3)
3289
- .map((tool) => compactToolAuditForSideChannel(tool || {}))
3290
- .filter((tool) => tool && Object.keys(tool).length);
3327
+ summary.toolLog = buildToolLogForSideChannel(visibleToolEvents, toolItems.length || summary.toolCount || visibleToolEvents.length, SIDE_CHANNEL_TOOL_EVENT_MAX);
3328
+ summary.toolEvents = visibleToolEvents;
3291
3329
  summary.lastTool = tools.last_successful_tool
3292
3330
  ? {
3293
3331
  name: tools.last_successful_tool.name,
@@ -3377,7 +3415,7 @@ const wrapTemboryMemory = (memory, ctx, memoryKey, itemIndex = 0) => new Proxy(m
3377
3415
  if (prop === 'loadMemoryVariables') {
3378
3416
  return async (values = {}) => {
3379
3417
  const { index } = ctx.addInputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, [
3380
- [{ json: { action: 'loadMemoryVariables', valuesChars: JSON.stringify(values || {}).length } }],
3418
+ [{ json: { action: 'loadMemoryVariables', visualSchema: VISUAL_SCHEMA_VERSION, valuesChars: JSON.stringify(values || {}).length } }],
3381
3419
  ]);
3382
3420
  try {
3383
3421
  const response = await target.loadMemoryVariables(values);
@@ -3387,6 +3425,7 @@ const wrapTemboryMemory = (memory, ctx, memoryKey, itemIndex = 0) => new Proxy(m
3387
3425
  [{
3388
3426
  json: {
3389
3427
  action: 'loadMemoryVariables',
3428
+ visualSchema: VISUAL_SCHEMA_VERSION,
3390
3429
  messages,
3391
3430
  memorySummary: summarizeMemoryMessagesForSideChannel(memoryMessages),
3392
3431
  },
@@ -4039,14 +4078,15 @@ class TemboryMemory {
4039
4078
  const loadCache = new Map();
4040
4079
  const recordMemoryEvent = (action, payload = {}, error) => {
4041
4080
  const { index } = this.addInputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, [
4042
- [{ json: { action } }],
4081
+ [{ json: { action, visualSchema: VISUAL_SCHEMA_VERSION } }],
4043
4082
  ]);
4044
4083
  if (error) {
4045
4084
  this.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, error);
4046
4085
  return;
4047
4086
  }
4087
+ const compactPayload = compactMemoryEventPayload(payload);
4048
4088
  this.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, [
4049
- [{ json: { action, ...compactMemoryEventPayload(payload) } }],
4089
+ [{ json: { action, visualSchema: VISUAL_SCHEMA_VERSION, memorySummary: compactPayload, ...compactPayload } }],
4050
4090
  ]);
4051
4091
  };
4052
4092
  const memory = {
@@ -5382,6 +5422,7 @@ class TemboryMemory {
5382
5422
  }
5383
5423
  const json = {
5384
5424
  action: 'loadMemoryVariables',
5425
+ visualSchema: VISUAL_SCHEMA_VERSION,
5385
5426
  messages: Array.isArray(payload) ? payload.length : 0,
5386
5427
  memorySummary: summarizeMemoryMessagesForSideChannel(payload),
5387
5428
  };
@@ -5458,6 +5499,8 @@ exports.__private = {
5458
5499
  contextSizeOfMessages,
5459
5500
  embedQueryCached,
5460
5501
  compactToolResult,
5502
+ compactToolAuditForSideChannel,
5503
+ buildToolLogForSideChannel,
5461
5504
  compactToolHistoryForAgent,
5462
5505
  compactVectorMemoriesForAgent,
5463
5506
  isConversationEchoMemory,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.40",
3
+ "version": "1.1.41",
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",