n8n-nodes-tembory 1.1.22 → 1.1.24

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.
@@ -143,6 +143,48 @@ const asSearchQuery = (value) => {
143
143
  return String(value);
144
144
  return pickText(value, ['query', 'input', 'chatInput', 'text', 'message', 'consolidated_text', 'lastUserMessage']);
145
145
  };
146
+ const currentInputJsonFromContext = (ctx, itemIndex = 0) => {
147
+ try {
148
+ const inputData = typeof (ctx === null || ctx === void 0 ? void 0 : ctx.getInputData) === 'function' ? ctx.getInputData() : [];
149
+ const item = (Array.isArray(inputData) && (inputData[itemIndex] || inputData[0])) || {};
150
+ return item && typeof item.json === 'object' && item.json ? item.json : {};
151
+ }
152
+ catch {
153
+ return {};
154
+ }
155
+ };
156
+ const resolveCurrentTurnQuery = (ctx, itemIndex = 0, inputValues = {}, queryParam = '') => {
157
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
158
+ const inputJson = currentInputJsonFromContext(ctx, itemIndex);
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],
180
+ ];
181
+ for (const candidate of candidates) {
182
+ const query = asSearchQuery(candidate).trim();
183
+ if (query)
184
+ return stripThreadTestPrefix(query);
185
+ }
186
+ return '';
187
+ };
146
188
  const memoryText = (memory) => {
147
189
  if (!memory)
148
190
  return '';
@@ -1224,6 +1266,8 @@ const mergeRemoteThreadState = (store, key, state) => {
1224
1266
  store.decisionState[key] = { ...(store.decisionState[key] || {}), ...state.decisionState };
1225
1267
  if (state.memoryCompression && typeof state.memoryCompression === 'object')
1226
1268
  store.memoryCompression[key] = state.memoryCompression;
1269
+ if (state.captureState && typeof state.captureState === 'object')
1270
+ store.captureState[key] = { ...(store.captureState[key] || {}), ...state.captureState };
1227
1271
  if (typeof state.activeSummary === 'string' && state.activeSummary)
1228
1272
  store.activeSummary[key] = state.activeSummary;
1229
1273
  };
@@ -2292,6 +2336,35 @@ const compactMessageForSideChannel = (message = {}) => {
2292
2336
  preview: role === 'system' ? '[system context hidden]' : truncate(content, 280),
2293
2337
  });
2294
2338
  };
2339
+ const normalizeConversationRoleForSideChannel = (role = '') => {
2340
+ const normalized = String(role || '').toLowerCase();
2341
+ if (normalized === 'human' || normalized === 'user')
2342
+ return 'user';
2343
+ if (normalized === 'ai' || normalized === 'assistant' || normalized === 'agent')
2344
+ return 'agent';
2345
+ if (normalized === 'system')
2346
+ return 'system';
2347
+ if (normalized === 'tool')
2348
+ return 'tool';
2349
+ return normalized || 'message';
2350
+ };
2351
+ const compactConversationTimelineForSideChannel = (conversation = {}, maxItems = 12) => {
2352
+ const chronological = Array.isArray(conversation.conversation_history_chronological)
2353
+ ? conversation.conversation_history_chronological
2354
+ : [];
2355
+ return pruneByLimit(chronological, maxItems).map((message, index) => {
2356
+ const role = normalizeConversationRoleForSideChannel(message.role || message.type);
2357
+ const content = String(message.content || message.text || message.message || '');
2358
+ return cleanContextValue({
2359
+ index,
2360
+ role,
2361
+ speaker: role,
2362
+ at: message.at || message.timestamp || message.created_at || message.createdAt,
2363
+ chars: content.length,
2364
+ content: truncate(content, 700),
2365
+ });
2366
+ });
2367
+ };
2295
2368
  const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory = []) => {
2296
2369
  const inputMessage = input?.input || input?.chatInput || input?.query || input?.question || input?.text || input?.message || '';
2297
2370
  const outputMessage = output?.output || output?.response || output?.text || output?.message || output?.answer || '';
@@ -2356,6 +2429,7 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
2356
2429
  summary.intent = parsed.observations?.inferred_intent?.label || parsed.workingMemory?.last_user_intent || parsed.decisionState?.current_intent || undefined;
2357
2430
  summary.currentUserMessage = conversation.current_user_message ? truncate(conversation.current_user_message, 180) : undefined;
2358
2431
  summary.recentMessages = Array.isArray(conversation.conversation_history_chronological) ? conversation.conversation_history_chronological.length : undefined;
2432
+ summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 12);
2359
2433
  summary.toolCount = toolItems.length || tools.count || parsed.operationalState?.tool_counts?.total || undefined;
2360
2434
  summary.toolNames = toolItems.map((tool) => tool.name || tool.tool_name).filter(Boolean).slice(0, 20);
2361
2435
  summary.toolEvents = toolItems
@@ -2902,12 +2976,7 @@ class TemboryMemory {
2902
2976
  name: 'query',
2903
2977
  type: 'string',
2904
2978
  default: '={{ $json.query || $json.lastUserMessage || $json.chatInput || $json.body?.consolidated_text || $json.body?.message || $json.body?.text || "" }}',
2905
- description: 'Consulta em linguagem natural para recuperar memórias relevantes',
2906
- displayOptions: {
2907
- show: {
2908
- retrievalMode: ['semantic', 'semanticV2', 'hybrid'],
2909
- },
2910
- },
2979
+ description: 'Mensagem atual usada para montar o contexto operacional, inferir intenção e recuperar memórias relevantes. Em AI Agent, mantenha a expressão padrão para ler o chatInput do item.',
2911
2980
  },
2912
2981
  {
2913
2982
  displayName: 'Chave de Memória',
@@ -3264,6 +3333,19 @@ class TemboryMemory {
3264
3333
  body.app_id = String(adv.appId);
3265
3334
  if (adv.runId)
3266
3335
  body.run_id = String(adv.runId);
3336
+ const nextCaptureState = cleanContextValue({
3337
+ ...(store.captureState[key] || {}),
3338
+ last_save_status: 'saved',
3339
+ last_save_saved: true,
3340
+ last_save_conversation_messages_after_save: recentForTurn.length,
3341
+ last_save_tool_history_after_save: toolHistoryForTurn.length,
3342
+ last_save_thread_state_saved: true,
3343
+ last_save_backend_memory_persistence: adv.persistBackendMemories === false
3344
+ ? 'disabled'
3345
+ : adv.useVectorMemory === false
3346
+ ? 'thread_state_only'
3347
+ : 'enabled',
3348
+ });
3267
3349
  const threadStateSaved = await saveThreadState(this, key, threadId, project, {
3268
3350
  kind: 'tembory.thread_state.v1',
3269
3351
  threadId,
@@ -3276,20 +3358,12 @@ class TemboryMemory {
3276
3358
  decisionState: decisionStateForTurn,
3277
3359
  memoryCompression: compressionForTurn,
3278
3360
  operationalState: operationalStateForTurn,
3361
+ captureState: nextCaptureState,
3279
3362
  activeSummary: store.activeSummary[key] || '',
3280
3363
  });
3281
3364
  store.captureState[key] = cleanContextValue({
3282
- ...(store.captureState[key] || {}),
3283
- last_save_status: 'saved',
3284
- last_save_saved: true,
3285
- last_save_conversation_messages_after_save: recentForTurn.length,
3286
- last_save_tool_history_after_save: toolHistoryForTurn.length,
3365
+ ...nextCaptureState,
3287
3366
  last_save_thread_state_saved: threadStateSaved,
3288
- last_save_backend_memory_persistence: adv.persistBackendMemories === false
3289
- ? 'disabled'
3290
- : adv.useVectorMemory === false
3291
- ? 'thread_state_only'
3292
- : 'enabled',
3293
3367
  });
3294
3368
  try {
3295
3369
  const globalData = this.getWorkflowStaticData('global');
@@ -3556,7 +3630,7 @@ class TemboryMemory {
3556
3630
  const store = getMemoryStore(this);
3557
3631
  const key = userKeyFrom(threadId, adv, project);
3558
3632
  const queryParam = this.getNodeParameter('query', itemIndex, '');
3559
- const query = stripThreadTestPrefix(asSearchQuery(queryParam) || asSearchQuery(inputValues.query) || asSearchQuery(inputValues.input) || asSearchQuery(inputValues.chatInput));
3633
+ const query = resolveCurrentTurnQuery(this, itemIndex, inputValues, queryParam);
3560
3634
  const remoteThreadState = await loadThreadState(this, key, threadId, project);
3561
3635
  mergeRemoteThreadState(store, key, remoteThreadState);
3562
3636
  let connectedLanguageModel;
@@ -4000,7 +4074,7 @@ class TemboryMemory {
4000
4074
  last_save_conversation_messages_after_save: 0,
4001
4075
  last_save_tool_history_after_save: 0,
4002
4076
  last_save_thread_state_saved: false,
4003
- last_save_backend_memory_persistence: backendPersistenceEnabled ? 'enabled' : 'disabled',
4077
+ last_save_backend_memory_persistence: backendPersistenceEnabled ? (vectorMemoryEnabled ? 'enabled' : 'thread_state_only') : 'disabled',
4004
4078
  },
4005
4079
  connectedAi,
4006
4080
  activeSummary: summaryDiagnostics,
@@ -4258,6 +4332,8 @@ exports.__private = {
4258
4332
  applyOperationalPreset,
4259
4333
  flattenAdvancedGroups,
4260
4334
  asSearchQuery,
4335
+ currentInputJsonFromContext,
4336
+ resolveCurrentTurnQuery,
4261
4337
  safePersistLegacyMemory,
4262
4338
  stripThreadTestPrefix,
4263
4339
  canonicalToolInput,
@@ -4295,6 +4371,7 @@ exports.__private = {
4295
4371
  cleanModelSummaryText,
4296
4372
  invokeConnectedModelSummary,
4297
4373
  compactMemoryEventPayload,
4374
+ compactConversationTimelineForSideChannel,
4298
4375
  summarizeMemoryMessagesForSideChannel,
4299
4376
  summarizeSaveContextForSideChannel,
4300
4377
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.22",
3
+ "version": "1.1.24",
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",