n8n-nodes-tembory 1.1.27 → 1.1.28

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.
@@ -153,38 +153,39 @@ const currentInputJsonFromContext = (ctx, itemIndex = 0) => {
153
153
  return {};
154
154
  }
155
155
  };
156
- const resolveCurrentTurnQuery = (ctx, itemIndex = 0, inputValues = {}, queryParam = '') => {
156
+ const resolveCurrentTurnQueryWithSource = (ctx, itemIndex = 0, inputValues = {}, queryParam = '') => {
157
157
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
158
158
  const inputJson = currentInputJsonFromContext(ctx, itemIndex);
159
159
  const candidates = [
160
- queryParam,
161
- inputValues.query,
162
- inputValues.input,
163
- inputValues.chatInput,
164
- inputValues.text,
165
- inputValues.question,
166
- inputValues.message,
167
- inputJson.query,
168
- inputJson.lastUserMessage,
169
- inputJson.chatInput,
170
- inputJson.input,
171
- inputJson.text,
172
- inputJson.message,
173
- (_a = inputJson.body) === null || _a === void 0 ? void 0 : _a.consolidated_text,
174
- (_b = inputJson.body) === null || _b === void 0 ? void 0 : _b.chatInput,
175
- (_c = inputJson.body) === null || _c === void 0 ? void 0 : _c.message,
176
- (_d = inputJson.body) === null || _d === void 0 ? void 0 : _d.text,
177
- (_e = inputJson.body) === null || _e === void 0 ? void 0 : _e.input,
178
- (_h = (_g = (_f = inputJson.body) === null || _f === void 0 ? void 0 : _f.messages) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.text,
179
- (_k = (_j = inputJson.body) === null || _j === void 0 ? void 0 : _j.messages) === null || _k === void 0 ? void 0 : _k[0],
160
+ ['query_param', queryParam],
161
+ ['input_values.query', inputValues.query],
162
+ ['input_values.input', inputValues.input],
163
+ ['input_values.chatInput', inputValues.chatInput],
164
+ ['input_values.text', inputValues.text],
165
+ ['input_values.question', inputValues.question],
166
+ ['input_values.message', inputValues.message],
167
+ ['input_json.query', inputJson.query],
168
+ ['input_json.lastUserMessage', inputJson.lastUserMessage],
169
+ ['input_json.chatInput', inputJson.chatInput],
170
+ ['input_json.input', inputJson.input],
171
+ ['input_json.text', inputJson.text],
172
+ ['input_json.message', inputJson.message],
173
+ ['input_json.body.consolidated_text', (_a = inputJson.body) === null || _a === void 0 ? void 0 : _a.consolidated_text],
174
+ ['input_json.body.chatInput', (_b = inputJson.body) === null || _b === void 0 ? void 0 : _b.chatInput],
175
+ ['input_json.body.message', (_c = inputJson.body) === null || _c === void 0 ? void 0 : _c.message],
176
+ ['input_json.body.text', (_d = inputJson.body) === null || _d === void 0 ? void 0 : _d.text],
177
+ ['input_json.body.input', (_e = inputJson.body) === null || _e === void 0 ? void 0 : _e.input],
178
+ ['input_json.body.messages.0.text', (_h = (_g = (_f = inputJson.body) === null || _f === void 0 ? void 0 : _f.messages) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.text],
179
+ ['input_json.body.messages.0', (_k = (_j = inputJson.body) === null || _j === void 0 ? void 0 : _j.messages) === null || _k === void 0 ? void 0 : _k[0]],
180
180
  ];
181
- for (const candidate of candidates) {
181
+ for (const [source, candidate] of candidates) {
182
182
  const query = asSearchQuery(candidate).trim();
183
183
  if (query)
184
- return stripThreadTestPrefix(query);
184
+ return { query: stripThreadTestPrefix(query), source };
185
185
  }
186
- return '';
186
+ return { query: '', source: 'missing' };
187
187
  };
188
+ const resolveCurrentTurnQuery = (ctx, itemIndex = 0, inputValues = {}, queryParam = '') => resolveCurrentTurnQueryWithSource(ctx, itemIndex, inputValues, queryParam).query;
188
189
  const memoryText = (memory) => {
189
190
  if (!memory)
190
191
  return '';
@@ -2625,8 +2626,8 @@ const compactToolAuditForSideChannel = (tool = {}) => cleanContextValue({
2625
2626
  status: tool.status || (tool.ok === false ? 'failed' : 'ok'),
2626
2627
  at: tool.at || tool.timestamp,
2627
2628
  timestamp: tool.timestamp || tool.at,
2628
- input: truncate(String(tool.input || tool.tool_args || tool.normalized_args || ''), 500) || undefined,
2629
- output: compactToolResult(tool.result !== undefined ? tool.result : tool.output !== undefined ? tool.output : tool.observation, 1200),
2629
+ input: truncate(String(tool.input || tool.tool_args || tool.normalized_args || ''), 300) || undefined,
2630
+ output: compactToolResult(tool.result !== undefined ? tool.result : tool.output !== undefined ? tool.output : tool.observation, 800),
2630
2631
  });
2631
2632
  const compactMessageForSideChannel = (message = {}) => {
2632
2633
  const type = messageTypeOf(message) || String(message.role || 'message').toLowerCase();
@@ -2650,7 +2651,7 @@ const normalizeConversationRoleForSideChannel = (role = '') => {
2650
2651
  return 'tool';
2651
2652
  return normalized || 'message';
2652
2653
  };
2653
- const compactConversationTimelineForSideChannel = (conversation = {}, maxItems = 12) => {
2654
+ const compactConversationTimelineForSideChannel = (conversation = {}, maxItems = 4, includeFull = false) => {
2654
2655
  const chronological = Array.isArray(conversation.conversation_history_chronological)
2655
2656
  ? conversation.conversation_history_chronological
2656
2657
  : [];
@@ -2666,13 +2667,12 @@ const compactConversationTimelineForSideChannel = (conversation = {}, maxItems =
2666
2667
  at,
2667
2668
  chars: content.length,
2668
2669
  preview,
2669
- content: preview,
2670
- message: {
2670
+ message: includeFull ? {
2671
2671
  role,
2672
2672
  at,
2673
2673
  content: role === 'system' ? '[system context hidden]' : truncate(content, 2000),
2674
2674
  truncated: content.length > 2000,
2675
- },
2675
+ } : undefined,
2676
2676
  });
2677
2677
  });
2678
2678
  };
@@ -2702,11 +2702,11 @@ const compactMemoryEventPayload = (payload = {}) => {
2702
2702
  compact.toolNames = compact.toolCalls
2703
2703
  .map((tool) => (tool && (tool.name || tool.tool_name || tool.tool)) || '')
2704
2704
  .filter(Boolean)
2705
- .slice(0, 20);
2705
+ .slice(0, 12);
2706
2706
  compact.toolEvents = compact.toolCalls
2707
2707
  .map((tool) => compactToolAuditForSideChannel(tool || {}))
2708
2708
  .filter((tool) => tool && Object.keys(tool).length)
2709
- .slice(0, 20);
2709
+ .slice(0, 8);
2710
2710
  delete compact.toolCalls;
2711
2711
  }
2712
2712
  for (const key of ['input', 'output', 'values', 'chatHistory', 'context', 'contextText', 'diagnostics']) {
@@ -2716,6 +2716,49 @@ const compactMemoryEventPayload = (payload = {}) => {
2716
2716
  }
2717
2717
  return compact;
2718
2718
  };
2719
+ const compactLastSaveForSideChannel = (lastSave = {}) => cleanContextValue({
2720
+ saved: lastSave.saved,
2721
+ status: lastSave.status,
2722
+ at: lastSave.at,
2723
+ inputChars: lastSave.input_chars,
2724
+ outputChars: lastSave.output_chars,
2725
+ toolCallsCaptured: lastSave.tool_calls_captured,
2726
+ toolNames: lastSave.tool_names,
2727
+ conversationMessagesAfterSave: lastSave.conversation_messages_after_save,
2728
+ toolHistoryAfterSave: lastSave.tool_history_after_save,
2729
+ threadStateSaved: lastSave.thread_state_saved,
2730
+ backendPersistence: lastSave.backend_memory_persistence,
2731
+ });
2732
+ const compactDedupeForSideChannel = (dedupe = {}) => {
2733
+ const load = dedupe.load || {};
2734
+ const removedOnLoad = Object.values(load).reduce((sum, item) => sum + Number((item || {}).removed || 0), 0);
2735
+ const write = dedupe.lastSave?.write || dedupe.write || {};
2736
+ return cleanContextValue({
2737
+ enabled: dedupe.enabled,
2738
+ removedOnLoad,
2739
+ skippedWrites: Number(write.skipped || 0),
2740
+ persistedWrites: Number(write.persisted || 0),
2741
+ candidates: Number(write.candidates || 0),
2742
+ });
2743
+ };
2744
+ const loadedSectionsForSideChannel = (parsed = {}, memoryAudit = {}) => cleanContextValue({
2745
+ conversation: Boolean(parsed.conversation),
2746
+ summary: Boolean(parsed.summary),
2747
+ activeSummary: Boolean(parsed.activeSummary),
2748
+ connectedModelSummary: Boolean(parsed.connectedModelSummary),
2749
+ workingMemory: Boolean(parsed.workingMemory),
2750
+ decisionState: Boolean(parsed.decisionState),
2751
+ memoryCompression: Boolean(parsed.memoryCompression),
2752
+ operationalState: Boolean(parsed.operationalState),
2753
+ actionLedger: Array.isArray(parsed.actionLedger),
2754
+ turnBrief: Boolean(parsed.turnBrief || parsed.turn_brief),
2755
+ memoryAudit: Boolean(memoryAudit && Object.keys(memoryAudit).length),
2756
+ entityTimeline: Array.isArray(parsed.entityTimeline),
2757
+ vectorMemories: Array.isArray(parsed.vectorMemories),
2758
+ graph: Array.isArray(parsed.graph),
2759
+ recentHighlights: Array.isArray(parsed.recentHighlights),
2760
+ contextHealth: Boolean(parsed.contextHealth),
2761
+ });
2719
2762
  const summarizeMemoryMessagesForSideChannel = (messages = []) => {
2720
2763
  const list = Array.isArray(messages) ? messages : [];
2721
2764
  const summary = { messages: list.length };
@@ -2732,20 +2775,45 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
2732
2775
  const toolItems = Array.isArray(tools.items) ? tools.items : [];
2733
2776
  const memoryAudit = parsed.memoryAudit || parsed.memory_audit || {};
2734
2777
  const summaryText = parsed.summary?.slm || parsed.summary || parsed.connectedModelSummary || parsed.activeSummary || '';
2778
+ const chronological = Array.isArray(conversation.conversation_history_chronological)
2779
+ ? conversation.conversation_history_chronological
2780
+ : [];
2781
+ const allUserMessages = Array.isArray(conversation.all_user_messages_chronological)
2782
+ ? conversation.all_user_messages_chronological
2783
+ : chronological.filter((message) => normalizeConversationRoleForSideChannel(message.role || message.type) === 'user');
2784
+ const lastUser = [...chronological].reverse().find((message) => normalizeConversationRoleForSideChannel(message.role || message.type) === 'user');
2785
+ const lastAgent = [...chronological].reverse().find((message) => normalizeConversationRoleForSideChannel(message.role || message.type) === 'agent');
2786
+ const includeDebug = Boolean(parsed.options?.includeDiagnostics || parsed.diagnostics?.includeDiagnostics || parsed.diagnostics?.include_diagnostics);
2787
+ const lastSave = compactLastSaveForSideChannel(memoryAudit.last_save || parsed.state?.last_save || {});
2788
+ const fullDedupeSummary = parsed.dedupeSummary || parsed.diagnostics?.dedupeSummary || undefined;
2789
+ const loadedSections = loadedSectionsForSideChannel(parsed, memoryAudit);
2735
2790
  summary.userId = parsed.userId;
2736
2791
  summary.project = parsed.project || undefined;
2737
2792
  summary.retrievalMode = parsed.retrievalMode;
2738
2793
  summary.payloadFormat = parsed.payloadFormat;
2739
- summary.options = cleanContextValue(parsed.options || {});
2740
2794
  summary.intent = parsed.observations?.inferred_intent?.label || parsed.workingMemory?.last_user_intent || parsed.decisionState?.current_intent || undefined;
2741
2795
  const parsedTurnBrief = parsed.turnBrief || parsed.turn_brief || undefined;
2796
+ summary.currentTurn = parsed.currentTurn || parsed.current_turn || parsed.diagnostics?.currentTurn || undefined;
2742
2797
  summary.currentUserMessage = conversation.current_user_message ? truncate(conversation.current_user_message, 180) : undefined;
2743
- summary.recentMessages = Array.isArray(conversation.conversation_history_chronological) ? conversation.conversation_history_chronological.length : undefined;
2744
- summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 12);
2798
+ summary.recentMessages = chronological.length || undefined;
2799
+ summary.conversation = cleanContextValue({
2800
+ messages: chronological.length,
2801
+ userMessages: allUserMessages.length,
2802
+ currentUserMessage: summary.currentUserMessage,
2803
+ lastUser: lastUser ? {
2804
+ at: lastUser.at || lastUser.timestamp || lastUser.created_at || lastUser.createdAt,
2805
+ preview: truncate(String(lastUser.content || lastUser.text || lastUser.message || ''), 240),
2806
+ } : undefined,
2807
+ lastAgent: lastAgent ? {
2808
+ at: lastAgent.at || lastAgent.timestamp || lastAgent.created_at || lastAgent.createdAt,
2809
+ preview: truncate(String(lastAgent.content || lastAgent.text || lastAgent.message || ''), 240),
2810
+ } : undefined,
2811
+ });
2812
+ summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 4);
2745
2813
  summary.toolCount = toolItems.length || tools.count || parsed.operationalState?.tool_counts?.total || undefined;
2746
- summary.toolNames = toolItems.map((tool) => tool.name || tool.tool_name).filter(Boolean).slice(0, 20);
2814
+ summary.toolNames = toolItems.map((tool) => tool.name || tool.tool_name).filter(Boolean).slice(0, 12);
2747
2815
  summary.toolEvents = toolItems
2748
- .slice(-6)
2816
+ .slice(-3)
2749
2817
  .map((tool) => compactToolAuditForSideChannel(tool || {}))
2750
2818
  .filter((tool) => tool && Object.keys(tool).length);
2751
2819
  summary.lastTool = tools.last_successful_tool
@@ -2765,8 +2833,8 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
2765
2833
  })
2766
2834
  : parsedTurnBrief;
2767
2835
  summary.counts = cleanContextValue({
2768
- conversationMessages: Array.isArray(conversation.conversation_history_chronological) ? conversation.conversation_history_chronological.length : undefined,
2769
- userMessages: Array.isArray(conversation.all_user_messages_chronological) ? conversation.all_user_messages_chronological.length : undefined,
2836
+ conversationMessages: chronological.length || undefined,
2837
+ userMessages: allUserMessages.length || undefined,
2770
2838
  toolHistory: toolItems.length,
2771
2839
  actionLedger: Array.isArray(parsed.actionLedger) ? parsed.actionLedger.length : undefined,
2772
2840
  entityTimeline: Array.isArray(parsed.entityTimeline) ? parsed.entityTimeline.length : undefined,
@@ -2774,26 +2842,8 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
2774
2842
  graph: Array.isArray(parsed.graph) ? parsed.graph.length : undefined,
2775
2843
  recentHighlights: Array.isArray(parsed.recentHighlights) ? parsed.recentHighlights.length : undefined,
2776
2844
  });
2777
- summary.lastSave = memoryAudit.last_save || parsed.state?.last_save || undefined;
2778
- summary.dedupeSummary = parsed.dedupeSummary || parsed.diagnostics?.dedupeSummary || undefined;
2779
- summary.loadedSections = cleanContextValue({
2780
- conversation: Boolean(parsed.conversation),
2781
- summary: Boolean(parsed.summary),
2782
- activeSummary: Boolean(parsed.activeSummary),
2783
- connectedModelSummary: Boolean(parsed.connectedModelSummary),
2784
- workingMemory: Boolean(parsed.workingMemory),
2785
- decisionState: Boolean(parsed.decisionState),
2786
- memoryCompression: Boolean(parsed.memoryCompression),
2787
- operationalState: Boolean(parsed.operationalState),
2788
- actionLedger: Array.isArray(parsed.actionLedger),
2789
- turnBrief: Boolean(parsed.turnBrief || parsed.turn_brief),
2790
- memoryAudit: Boolean(memoryAudit && Object.keys(memoryAudit).length),
2791
- entityTimeline: Array.isArray(parsed.entityTimeline),
2792
- vectorMemories: Array.isArray(parsed.vectorMemories),
2793
- graph: Array.isArray(parsed.graph),
2794
- recentHighlights: Array.isArray(parsed.recentHighlights),
2795
- contextHealth: Boolean(parsed.contextHealth),
2796
- });
2845
+ summary.lastSave = Object.keys(lastSave).length ? lastSave : undefined;
2846
+ summary.dedupe = fullDedupeSummary ? compactDedupeForSideChannel(fullDedupeSummary) : undefined;
2797
2847
  summary.workingMemory = cleanContextValue({
2798
2848
  currentGoal: parsed.workingMemory?.current_goal,
2799
2849
  currentGoalReason: parsed.workingMemory?.current_goal_reason,
@@ -2814,8 +2864,14 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
2814
2864
  doNotRepeatTools: parsed.decisionState?.do_not_repeat_tools,
2815
2865
  });
2816
2866
  summary.quality = parsed.contextHealth?.quality_score || parsed.contextQualityScore || undefined;
2817
- summary.contextSize = parsed.diagnostics?.contextSize || undefined;
2818
- summary.summaryChars = typeof summaryText === 'string' ? summaryText.length : safeStringify(summaryText).length;
2867
+ summary.debug = includeDebug ? cleanContextValue({
2868
+ options: parsed.options,
2869
+ loadedSections,
2870
+ contextSize: parsed.diagnostics?.contextSize,
2871
+ summaryChars: typeof summaryText === 'string' ? summaryText.length : safeStringify(summaryText).length,
2872
+ dedupeSummary: fullDedupeSummary,
2873
+ conversationTimelineFull: compactConversationTimelineForSideChannel(conversation, 12, true),
2874
+ }) : undefined;
2819
2875
  return Object.fromEntries(Object.entries(summary).filter(([, value]) => value !== undefined));
2820
2876
  }
2821
2877
  catch {
@@ -3032,6 +3088,7 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
3032
3088
  current_user_request: focus.current_user_request,
3033
3089
  instruction: focus.instruction,
3034
3090
  }),
3091
+ currentTurn: diagnostics?.currentTurn,
3035
3092
  action_directive: directive ? cleanContextValue({
3036
3093
  required_tool: directive.required_tool,
3037
3094
  next_expected_action: directive.next_expected_action,
@@ -4070,7 +4127,8 @@ class TemboryMemory {
4070
4127
  const store = getMemoryStore(this);
4071
4128
  const key = userKeyFrom(threadId, adv, project);
4072
4129
  const queryParam = this.getNodeParameter('query', itemIndex, '');
4073
- const query = resolveCurrentTurnQuery(this, itemIndex, inputValues, queryParam);
4130
+ const currentTurn = resolveCurrentTurnQueryWithSource(this, itemIndex, inputValues, queryParam);
4131
+ const query = currentTurn.query;
4074
4132
  const remoteThreadState = await loadThreadState(this, key, threadId, project);
4075
4133
  mergeRemoteThreadState(store, key, remoteThreadState);
4076
4134
  let connectedLanguageModel;
@@ -4099,6 +4157,7 @@ class TemboryMemory {
4099
4157
  retrievalMode,
4100
4158
  requestedRetrievalMode,
4101
4159
  hasQuery: String(query || '').trim().length > 0,
4160
+ querySource: currentTurn.source,
4102
4161
  connectedAi,
4103
4162
  });
4104
4163
  }
@@ -4542,6 +4601,7 @@ class TemboryMemory {
4542
4601
  connectedAi,
4543
4602
  activeSummary: summaryDiagnostics,
4544
4603
  dedupeSummary: cleanContextValue(loadDedupeSummary),
4604
+ currentTurn,
4545
4605
  };
4546
4606
  const contextHealth = deriveContextHealth({
4547
4607
  userId: key,
@@ -4613,6 +4673,7 @@ class TemboryMemory {
4613
4673
  userId: key,
4614
4674
  project: project || undefined,
4615
4675
  query,
4676
+ currentTurn,
4616
4677
  retrievalMode,
4617
4678
  requestedRetrievalMode: requestedRetrievalMode === retrievalMode ? undefined : requestedRetrievalMode,
4618
4679
  payloadFormat,
@@ -4798,6 +4859,7 @@ exports.__private = {
4798
4859
  flattenAdvancedGroups,
4799
4860
  asSearchQuery,
4800
4861
  currentInputJsonFromContext,
4862
+ resolveCurrentTurnQueryWithSource,
4801
4863
  resolveCurrentTurnQuery,
4802
4864
  safePersistLegacyMemory,
4803
4865
  stripThreadTestPrefix,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.27",
3
+ "version": "1.1.28",
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",