n8n-nodes-tembory 1.1.18 → 1.1.20

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.
@@ -2403,7 +2403,7 @@ const contextSizeOfMessages = (messages = []) => {
2403
2403
  const chars = perMessage.reduce((sum, item) => sum + item.chars, 0);
2404
2404
  return { chars, approx_tokens: approxTokenCount((messages || []).map((m) => m.content || '').join('\n')), messages: perMessage };
2405
2405
  };
2406
- const wrapTemboryMemory = (memory, ctx, memoryKey) => new Proxy(memory, {
2406
+ const wrapTemboryMemory = (memory, ctx, memoryKey, itemIndex = 0) => new Proxy(memory, {
2407
2407
  get(target, prop) {
2408
2408
  if (prop === 'loadMemoryVariables') {
2409
2409
  return async (values = {}) => {
@@ -2462,14 +2462,38 @@ const wrapTemboryMemory = (memory, ctx, memoryKey) => new Proxy(memory, {
2462
2462
  }
2463
2463
  catch (error) {
2464
2464
  const message = error && error.message ? error.message : String(error);
2465
+ const safeInput = stripThreadTestPrefix(pickText(input, ['input', 'chatInput', 'text', 'query', 'question']));
2466
+ const safeOutput = cleanAssistantTranscriptText(pickText(output, ['output', 'response', 'text', 'answer']));
2467
+ let fallbackSaved = false;
2468
+ let fallbackError;
2469
+ let chatHistory = [];
2470
+ if (safeInput || safeOutput) {
2471
+ try {
2472
+ await TemboryMemory.prototype.saveContextForItem.call(ctx, itemIndex, safeInput ? { input: safeInput } : {}, safeOutput ? { output: safeOutput } : {});
2473
+ fallbackSaved = true;
2474
+ try {
2475
+ chatHistory = snapshotJson(await target.chatHistory.getMessages());
2476
+ }
2477
+ catch {
2478
+ chatHistory = [];
2479
+ }
2480
+ }
2481
+ catch (fallback) {
2482
+ fallbackError = fallback && fallback.message ? fallback.message : String(fallback);
2483
+ }
2484
+ }
2465
2485
  ctx.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, [
2466
2486
  [{
2467
2487
  json: {
2468
2488
  action: 'saveContext',
2469
- saved: false,
2489
+ saved: fallbackSaved,
2490
+ fallback: true,
2470
2491
  inputChars: JSON.stringify(input || {}).length,
2471
2492
  outputChars: JSON.stringify(output || {}).length,
2472
- error: truncate(message, 500),
2493
+ messages: Array.isArray(chatHistory) ? chatHistory.length : 0,
2494
+ savedSummary: fallbackSaved ? summarizeSaveContextForSideChannel({ input: safeInput }, { output: safeOutput }, chatHistory) : undefined,
2495
+ originalError: truncate(message, 500),
2496
+ error: fallbackSaved ? undefined : truncate(fallbackError || message, 500),
2473
2497
  },
2474
2498
  }],
2475
2499
  ]);
@@ -3083,7 +3107,7 @@ class TemboryMemory {
3083
3107
  await TemboryMemory.prototype.saveContextForItem.call(this, itemIndex, inputValues, outputValues);
3084
3108
  },
3085
3109
  };
3086
- return { response: wrapTemboryMemory(memory, this, memoryKey) };
3110
+ return { response: wrapTemboryMemory(memory, this, memoryKey, itemIndex) };
3087
3111
  }
3088
3112
  async saveMessagesForItem(itemIndex, messages = []) {
3089
3113
  const inputValues = {};
@@ -3350,10 +3374,13 @@ class TemboryMemory {
3350
3374
  return;
3351
3375
  }
3352
3376
  if (messages.length)
3353
- await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', body);
3377
+ await safePersistLegacyMemory(this, body, {
3378
+ kind: 'conversation_messages',
3379
+ user_id: body.user_id,
3380
+ });
3354
3381
  if (adv.includeRecentMessages !== false && recentForTembory.length) {
3355
3382
  for (const recent of recentForTembory) {
3356
- await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
3383
+ await safePersistLegacyMemory(this, {
3357
3384
  messages: [{ role: 'system', content: encodeRecentMessage(recent, threadId) }],
3358
3385
  infer: false,
3359
3386
  user_id: body.user_id,
@@ -3367,9 +3394,12 @@ class TemboryMemory {
3367
3394
  thread_id: threadId,
3368
3395
  project: project || undefined,
3369
3396
  },
3397
+ }, {
3398
+ kind: 'recent_message',
3399
+ user_id: body.user_id,
3370
3400
  });
3371
3401
  }
3372
- await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
3402
+ await safePersistLegacyMemory(this, {
3373
3403
  messages: [{ role: 'system', content: encodeConversationLedger(recentForTurn, threadId) }],
3374
3404
  infer: false,
3375
3405
  user_id: body.user_id,
@@ -3382,11 +3412,14 @@ class TemboryMemory {
3382
3412
  source: 'tembory_transcript',
3383
3413
  generated_at: nowIso(),
3384
3414
  },
3415
+ }, {
3416
+ kind: 'conversation_ledger',
3417
+ user_id: body.user_id,
3385
3418
  });
3386
3419
  }
3387
3420
  if (adv.includeToolHistory !== false && !adv.persistToolFactsToTembory && toolCalls.length) {
3388
3421
  for (const tool of toolCalls) {
3389
- await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
3422
+ await safePersistLegacyMemory(this, {
3390
3423
  messages: [{ role: 'system', content: encodeToolCall(tool, threadId) }],
3391
3424
  infer: false,
3392
3425
  user_id: body.user_id,
@@ -3406,9 +3439,13 @@ class TemboryMemory {
3406
3439
  thread_id: threadId,
3407
3440
  project: project || undefined,
3408
3441
  },
3442
+ }, {
3443
+ kind: 'tool_history',
3444
+ user_id: body.user_id,
3445
+ tool: tool.name,
3409
3446
  });
3410
3447
  }
3411
- await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
3448
+ await safePersistLegacyMemory(this, {
3412
3449
  messages: [{ role: 'system', content: encodeToolLedger(toolHistoryForTurn, threadId) }],
3413
3450
  infer: false,
3414
3451
  user_id: body.user_id,
@@ -3421,18 +3458,24 @@ class TemboryMemory {
3421
3458
  source: 'tembory_transcript',
3422
3459
  generated_at: nowIso(),
3423
3460
  },
3461
+ }, {
3462
+ kind: 'tool_ledger',
3463
+ user_id: body.user_id,
3424
3464
  });
3425
3465
  }
3426
3466
  if (adv.persistToolFactsToTembory && toolCalls.length) {
3427
3467
  const facts = toolCalls.map((tool) => `Tool ${tool.name} input=${tool.input}${tool.result ? ` result=${tool.result}` : ''}`).join('\n');
3428
- await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
3468
+ await safePersistLegacyMemory(this, {
3429
3469
  messages: [{ role: 'system', content: `Tool facts (read-only):\n${truncate(facts, 2000)}` }],
3430
3470
  infer: false,
3431
3471
  user_id: body.user_id,
3432
3472
  metadata: { kind: 'tool_facts' },
3473
+ }, {
3474
+ kind: 'tool_facts',
3475
+ user_id: body.user_id,
3433
3476
  });
3434
3477
  for (const tool of toolCalls) {
3435
- await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
3478
+ await safePersistLegacyMemory(this, {
3436
3479
  messages: [{ role: 'system', content: encodeToolCall(tool, threadId) }],
3437
3480
  infer: false,
3438
3481
  user_id: body.user_id,
@@ -3451,6 +3494,10 @@ class TemboryMemory {
3451
3494
  source: tool.source,
3452
3495
  thread_id: threadId,
3453
3496
  },
3497
+ }, {
3498
+ kind: 'tool_history',
3499
+ user_id: body.user_id,
3500
+ tool: tool.name,
3454
3501
  });
3455
3502
  }
3456
3503
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.18",
3
+ "version": "1.1.20",
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",