n8n-nodes-tembory 1.1.5 → 1.1.6

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.
@@ -399,275 +399,6 @@ const safeParseToolPayload = (value) => {
399
399
  return text;
400
400
  }
401
401
  };
402
- const parseNestedToolPayload = (value, depth = 0) => {
403
- if (depth > 8)
404
- return value;
405
- if (typeof value === 'string') {
406
- const text = value.trim();
407
- if (!text)
408
- return '';
409
- if (!/^[\[{]/.test(text))
410
- return value;
411
- try {
412
- return parseNestedToolPayload(JSON.parse(text), depth + 1);
413
- }
414
- catch {
415
- return value;
416
- }
417
- }
418
- if (Array.isArray(value))
419
- return value.map((item) => parseNestedToolPayload(item, depth + 1));
420
- if (!value || typeof value !== 'object')
421
- return value;
422
- const out = {};
423
- for (const [key, item] of Object.entries(value))
424
- out[key] = parseNestedToolPayload(item, depth + 1);
425
- return out;
426
- };
427
- const collectObjectsDeep = (value, out = [], seen = new Set()) => {
428
- if (!value || typeof value !== 'object' || seen.has(value))
429
- return out;
430
- seen.add(value);
431
- if (!Array.isArray(value))
432
- out.push(value);
433
- for (const item of Array.isArray(value) ? value : Object.values(value))
434
- collectObjectsDeep(item, out, seen);
435
- return out;
436
- };
437
- const compactObject = (value) => {
438
- if (Array.isArray(value)) {
439
- const arr = value.map(compactObject).filter((item) => item !== undefined);
440
- return arr.length ? arr : undefined;
441
- }
442
- if (!value || typeof value !== 'object')
443
- return value === '' || value === null || value === undefined ? undefined : value;
444
- const out = {};
445
- for (const [key, item] of Object.entries(value)) {
446
- const cleaned = compactObject(item);
447
- if (cleaned !== undefined)
448
- out[key] = cleaned;
449
- }
450
- return Object.keys(out).length ? out : undefined;
451
- };
452
- const normalizeFieldKey = (value = '') => String(value || '').toLowerCase().replace(/[^a-z0-9]/g, '');
453
- const hasFieldKey = (key, candidates) => candidates.map(normalizeFieldKey).includes(normalizeFieldKey(key));
454
- const findFieldDeep = (value, keys) => {
455
- const objects = collectObjectsDeep(value);
456
- for (const object of objects) {
457
- for (const [key, item] of Object.entries(object)) {
458
- if (hasFieldKey(key, keys) && item !== undefined && item !== null && item !== '')
459
- return item;
460
- }
461
- }
462
- return undefined;
463
- };
464
- const readPath = (value, path) => {
465
- let current = value;
466
- for (const segment of path) {
467
- if (!current || typeof current !== 'object')
468
- return undefined;
469
- current = current[segment];
470
- }
471
- return current;
472
- };
473
- const firstPath = (roots, paths) => {
474
- for (const root of roots) {
475
- for (const path of paths) {
476
- const value = readPath(root, path);
477
- if (value !== undefined && value !== null && value !== '')
478
- return value;
479
- }
480
- }
481
- return undefined;
482
- };
483
- const numberFrom = (value) => {
484
- if (value === undefined || value === null || value === '')
485
- return undefined;
486
- const match = String(value).match(/-?\d+(?:[.,]\d+)?/);
487
- if (!match)
488
- return undefined;
489
- const parsed = Number(match[0].replace(',', '.'));
490
- return Number.isFinite(parsed) ? parsed : undefined;
491
- };
492
- const integerFrom = (value) => {
493
- const parsed = numberFrom(value);
494
- return parsed === undefined ? undefined : Math.trunc(parsed);
495
- };
496
- const normalizeTimeValue = (value) => {
497
- const text = String(value || '').trim().toLowerCase();
498
- const match = /^(\d{1,2})(?:(?::|h)(\d{0,2}))?$/.exec(text);
499
- if (!match)
500
- return '';
501
- const hour = Number(match[1]);
502
- const minute = match[2] === '' || match[2] === undefined ? 0 : Number(match[2]);
503
- if (hour < 0 || hour > 23 || minute < 0 || minute > 59)
504
- return '';
505
- return `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;
506
- };
507
- const isoDateFromParts = (day, month, year, referenceDates = []) => {
508
- const dd = String(day || '').padStart(2, '0');
509
- const mm = String(month || '').padStart(2, '0');
510
- let yyyy = String(year || '');
511
- if (!yyyy) {
512
- const matched = (referenceDates || []).find((date) => String(date || '').slice(5, 10) === `${mm}-${dd}`);
513
- yyyy = matched ? String(matched).slice(0, 4) : String(new Date().getFullYear());
514
- }
515
- if (yyyy.length === 2)
516
- yyyy = `20${yyyy}`;
517
- return /^\d{4}$/.test(yyyy) && /^\d{2}$/.test(mm) && /^\d{2}$/.test(dd) ? `${yyyy}-${mm}-${dd}` : '';
518
- };
519
- const bookingToolName = (name = '') => String(name || '').toLowerCase();
520
- const serviceNameFromPageContent = (value) => {
521
- const content = String(value || '').trim();
522
- if (!content)
523
- return '';
524
- return content.split(/\r?\n/).map((line) => line.trim()).find(Boolean) || '';
525
- };
526
- const extractAvailabilitySlots = (parsedResult) => {
527
- const slots = [];
528
- const roots = Array.isArray(parsedResult) ? parsedResult : [parsedResult];
529
- for (const root of roots) {
530
- if (!root || typeof root !== 'object')
531
- continue;
532
- const availability = Array.isArray(root.disponibilidade) ? root.disponibilidade : [];
533
- for (const item of availability) {
534
- const date = item.dataDisponivel || item.date || item.data || '';
535
- const providers = Array.isArray(item.providers) ? item.providers : [];
536
- for (const provider of providers) {
537
- const providerId = integerFrom(provider.provider_id ?? provider.providerId ?? provider.id);
538
- const providerName = provider.provider_name || provider.providerName || provider.name || '';
539
- const horarios = Array.isArray(provider.horarios) ? provider.horarios : [];
540
- for (const horario of horarios) {
541
- const time = normalizeTimeValue(horario);
542
- if (date && time)
543
- slots.push(compactObject({ date, time, providerId, providerName }));
544
- }
545
- }
546
- }
547
- }
548
- return slots.filter(Boolean);
549
- };
550
- const extractToolBookingFacts = (toolName = '', input = '', rawResult = '') => {
551
- const name = bookingToolName(toolName);
552
- const inputObj = parseNestedToolPayload(safeParseToolPayload(input));
553
- const parsedResult = parseNestedToolPayload(safeParseToolPayload(rawResult));
554
- const roots = Array.isArray(parsedResult) ? parsedResult : [parsedResult];
555
- const objects = collectObjectsDeep(parsedResult);
556
- const facts = { source_tool: toolName };
557
- if (/check[_-]?availabilities|disponibilidade/i.test(name)) {
558
- facts.kind = 'availability';
559
- facts.locationId = integerFrom(firstPath(roots, [['locationId'], ['location_id']]) ?? findFieldDeep(parsedResult, ['locationId', 'location_id']));
560
- facts.locationName = inputObj && typeof inputObj === 'object' ? inputObj.location_name || inputObj.locationName : undefined;
561
- facts.serviceName = firstPath(roots, [['especialidade'], ['serviceName'], ['service_name']]) || (inputObj && typeof inputObj === 'object' ? inputObj.service_name || inputObj.serviceName : undefined);
562
- facts.serviceId = integerFrom(firstPath(roots, [['services', 'id'], ['service', 'id'], ['serviceId'], ['service_id']]) ?? findFieldDeep(parsedResult, ['serviceId', 'service_id']));
563
- facts.durationMinutes = integerFrom(firstPath(roots, [['services', 'duration'], ['duration'], ['durationMinutes']]) ?? findFieldDeep(parsedResult, ['duration', 'durationMinutes']));
564
- facts.price = firstPath(roots, [['services', 'price'], ['price']]) ?? findFieldDeep(parsedResult, ['price', 'price_num']);
565
- facts.providerId = integerFrom(firstPath(roots, [['provider', 'id'], ['providerId'], ['provider_id']]) ?? findFieldDeep(parsedResult, ['providerId', 'provider_id']));
566
- facts.availability_slots = extractAvailabilitySlots(parsedResult).slice(0, 80);
567
- }
568
- else if (/services?|veterinarios?/i.test(name)) {
569
- facts.kind = /veterinarios?/i.test(name) ? 'provider_service' : 'service';
570
- facts.serviceId = integerFrom(firstPath(roots, [['metadata', 'metadata', 'service_id'], ['metadata', 'service_id'], ['service_id'], ['serviceId']]) ?? findFieldDeep(parsedResult, ['service_id', 'serviceId']));
571
- facts.serviceName = firstPath(roots, [['pageContent']]) || (objects.map((object) => serviceNameFromPageContent(object.pageContent)).find(Boolean));
572
- facts.serviceName = serviceNameFromPageContent(facts.serviceName || '');
573
- facts.locationId = integerFrom(firstPath(roots, [['metadata', 'metadata', 'location_id'], ['metadata', 'location_id'], ['locationId'], ['local']]) ?? findFieldDeep(parsedResult, ['location_id', 'locationId', 'local']));
574
- facts.providerId = integerFrom(firstPath(roots, [['metadata', 'metadata', 'provider_id'], ['metadata', 'provider_id'], ['provider_id'], ['providerId']]) ?? findFieldDeep(parsedResult, ['provider_id', 'providerId']));
575
- facts.price = firstPath(roots, [['metadata', 'metadata', 'price_num'], ['metadata', 'price_num'], ['price']]) ?? findFieldDeep(parsedResult, ['price_num', 'price']);
576
- facts.durationMinutes = integerFrom(firstPath(roots, [['metadata', 'metadata', 'duration'], ['metadata', 'duration'], ['duration']]) ?? findFieldDeep(parsedResult, ['duration']));
577
- }
578
- else if (/anclivepa.*customer.*upsert|customer.*upsert/i.test(name)) {
579
- facts.kind = 'booking_customer';
580
- facts.customerId = integerFrom(firstPath(roots, [['customerId'], ['customer_id']]) ?? findFieldDeep(parsedResult, ['customerId', 'customer_id']));
581
- facts.petName = firstPath(roots, [['petChosen'], ['petName'], ['pet_name']]) || (inputObj && typeof inputObj === 'object' ? inputObj.petName || inputObj.pet_name : undefined);
582
- facts.readyForBooking = Boolean(firstPath(roots, [['readyForBooking']]) ?? findFieldDeep(parsedResult, ['readyForBooking']));
583
- }
584
- const compacted = compactObject(facts);
585
- return compacted && Object.keys(compacted).length > 2 ? compacted : undefined;
586
- };
587
- const extractBookingSelectionFromMessages = (recentMessages = [], referenceDates = []) => {
588
- const ordered = [...(recentMessages || [])].reverse();
589
- for (const msg of ordered) {
590
- const text = String(msg.content || '');
591
- const dateTime = /(\d{1,2})[/-](\d{1,2})(?:[/-](\d{2,4}))?[\s\S]{0,160}?(?:às|as|hor[aá]rio)\s*(\d{1,2})(?:(?::|h)(\d{2}))?/i.exec(text);
592
- if (dateTime) {
593
- return compactObject({
594
- date: isoDateFromParts(dateTime[1], dateTime[2], dateTime[3], referenceDates),
595
- time: normalizeTimeValue(`${dateTime[4]}:${dateTime[5] || '00'}`),
596
- source: 'recent_message',
597
- }) || {};
598
- }
599
- }
600
- const dateMsg = ordered.find((msg) => /(\d{1,2})[/-](\d{1,2})(?:[/-](\d{2,4}))?/.test(String(msg.content || '')));
601
- const timeMsg = ordered.find((msg) => /^(?:\s*(?:às|as)\s*)?\d{1,2}(?:(?::|h)\d{0,2})?\s*$/i.test(String(msg.content || '')));
602
- const dateMatch = dateMsg ? /(\d{1,2})[/-](\d{1,2})(?:[/-](\d{2,4}))?/.exec(String(dateMsg.content || '')) : null;
603
- return compactObject({
604
- date: dateMatch ? isoDateFromParts(dateMatch[1], dateMatch[2], dateMatch[3], referenceDates) : undefined,
605
- time: timeMsg ? normalizeTimeValue(timeMsg.content) : undefined,
606
- source: dateMatch || timeMsg ? 'recent_message_partial' : undefined,
607
- }) || {};
608
- };
609
- const addMinutesToSlot = (date, time, minutes = 60) => {
610
- if (!date || !time)
611
- return '';
612
- const start = new Date(`${date}T${time}:00Z`);
613
- if (!Number.isFinite(start.getTime()))
614
- return '';
615
- const end = new Date(start.getTime() + (Number(minutes) || 60) * 60000);
616
- return `${end.toISOString().slice(0, 10)} ${end.toISOString().slice(11, 19)}`;
617
- };
618
- const deriveBookingState = (toolHistory = [], recentMessages = []) => {
619
- const facts = (toolHistory || []).map((tool) => tool.booking_facts || extractToolBookingFacts(tool.name, tool.input, tool.result)).filter(Boolean);
620
- if (!facts.length)
621
- return undefined;
622
- const latest = (predicate) => [...facts].reverse().find(predicate) || {};
623
- const availability = latest((fact) => Array.isArray(fact.availability_slots) && fact.availability_slots.length);
624
- const service = latest((fact) => fact.serviceId);
625
- const customer = latest((fact) => fact.kind === 'booking_customer' && fact.customerId);
626
- const slots = availability.availability_slots || [];
627
- const referenceDates = Array.from(new Set(slots.map((slot) => slot.date).filter(Boolean)));
628
- const selection = extractBookingSelectionFromMessages(recentMessages, referenceDates);
629
- const selectedSlot = slots.find((slot) => slot.date === selection.date && slot.time === selection.time) || {};
630
- const uniqueProviderIds = Array.from(new Set(slots.map((slot) => slot.providerId).filter(Boolean)));
631
- const durationMinutes = availability.durationMinutes || service.durationMinutes || 60;
632
- const providerId = selectedSlot.providerId || (uniqueProviderIds.length === 1 ? uniqueProviderIds[0] : availability.providerId || service.providerId);
633
- const serviceId = availability.serviceId || service.serviceId;
634
- const locationId = availability.locationId || service.locationId;
635
- const customerId = customer.customerId;
636
- const start = selection.date && selection.time ? `${selection.date} ${selection.time}:00` : undefined;
637
- const end = start ? addMinutesToSlot(selection.date, selection.time, durationMinutes) : undefined;
638
- const bookingCandidate = compactObject({
639
- start,
640
- end,
641
- date: selection.date,
642
- time: selection.time,
643
- providerId,
644
- providerName: selectedSlot.providerName,
645
- serviceId,
646
- serviceName: availability.serviceName || service.serviceName,
647
- locationId,
648
- locationName: availability.locationName,
649
- customerId,
650
- petName: customer.petName,
651
- durationMinutes,
652
- price: availability.price || service.price,
653
- source: 'derived_from_tool_history',
654
- }) || {};
655
- const required = ['providerId', 'serviceId', 'locationId', 'customerId', 'date', 'time'];
656
- const missing = required.filter((key) => bookingCandidate[key] === undefined || bookingCandidate[key] === null || bookingCandidate[key] === '');
657
- const warnings = [];
658
- if (bookingCandidate.providerId && bookingCandidate.locationId && String(bookingCandidate.providerId) === String(bookingCandidate.locationId))
659
- warnings.push('providerId_equals_locationId');
660
- if (bookingCandidate.serviceId && bookingCandidate.locationId && String(bookingCandidate.serviceId) === String(bookingCandidate.locationId))
661
- warnings.push('serviceId_equals_locationId');
662
- return compactObject({
663
- booking_candidate: bookingCandidate,
664
- selected_slot: selectedSlot,
665
- missing,
666
- warnings,
667
- available_slot_count: slots.length || undefined,
668
- source_tools: Array.from(new Set(facts.map((fact) => fact.source_tool).filter(Boolean))),
669
- });
670
- };
671
402
  const compactToolPayload = (value) => truncate(typeof value === 'string' ? value : safeStringify(value), 900);
672
403
  const maybeToolResult = (tool, includeResults = true) => includeResults === false ? undefined : compactToolPayload(safeParseToolPayload(tool === null || tool === void 0 ? void 0 : tool.result));
673
404
  const isToolName = (value = '') => /^[A-Za-z_][A-Za-z0-9_.:-]{1,127}$/.test(String(value || ''));
@@ -707,7 +438,6 @@ const deriveOperationalState = (toolHistory = [], profileFacts = {}, recentMessa
707
438
  at: tool.at || null,
708
439
  input: compactInput,
709
440
  result: compactResult,
710
- booking_facts: tool.booking_facts,
711
441
  reason,
712
442
  source: tool.source || 'unknown',
713
443
  };
@@ -719,7 +449,6 @@ const deriveOperationalState = (toolHistory = [], profileFacts = {}, recentMessa
719
449
  reason,
720
450
  input: compactInput,
721
451
  output: compactResult,
722
- booking_facts: tool.booking_facts,
723
452
  }));
724
453
  if (tool.ok === false)
725
454
  failedByName[name] = (failedByName[name] || 0) + 1;
@@ -729,11 +458,9 @@ const deriveOperationalState = (toolHistory = [], profileFacts = {}, recentMessa
729
458
  const guidance = [
730
459
  'Use tool_state and action_ledger as the source of truth for prior tool calls, inputs, outputs, failures and decisions. Domain-specific tool policy must come from the agent prompt, not from memory.',
731
460
  ];
732
- const bookingState = deriveBookingState(tools, recentMessages);
733
461
  return {
734
462
  profile_complete: Boolean(profileFacts && profileFacts.name && profileFacts.company && profileFacts.email && profileFacts.phone),
735
463
  last_tool: lastTool ? { name: lastTool.name, ok: lastTool.ok, at: lastTool.at } : null,
736
- booking_state: bookingState,
737
464
  tool_counts: {
738
465
  total: tools.length,
739
466
  ok: successfulTools.length,
@@ -753,7 +480,6 @@ const deriveOperationalState = (toolHistory = [], profileFacts = {}, recentMessa
753
480
  name: successfulTools[successfulTools.length - 1].name,
754
481
  at: successfulTools[successfulTools.length - 1].at || null,
755
482
  result: maybeToolResult(successfulTools[successfulTools.length - 1], includeResults),
756
- booking_facts: successfulTools[successfulTools.length - 1].booking_facts,
757
483
  } : null,
758
484
  },
759
485
  blocked_without_context: Array.from(new Set(blockedWithoutContext)),
@@ -772,7 +498,6 @@ const deriveActionLedger = (toolHistory = [], maxItems = 20, includeResults = tr
772
498
  reason: truncate(String(tool.reason || tool.decision || tool.why || tool.source || 'recorded tool call'), 260),
773
499
  input: compactToolPayload(safeParseToolPayload(tool.input)),
774
500
  result: maybeToolResult(tool, includeResults),
775
- booking_facts: tool.booking_facts,
776
501
  at: tool.at || null,
777
502
  source: tool.source || 'unknown',
778
503
  })), maxItems || 20);
@@ -877,7 +602,6 @@ const encodeToolCall = (tool, threadId) => `${TOOL_HISTORY_MARKER}${safeStringif
877
602
  input: tool.input || '',
878
603
  ok: tool.ok !== false,
879
604
  result: tool.result || '',
880
- booking_facts: tool.booking_facts,
881
605
  at: tool.at || nowIso(),
882
606
  source: tool.source || 'n8n',
883
607
  thread_id: threadId,
@@ -897,7 +621,6 @@ const encodeToolLedger = (tools = [], threadId) => {
897
621
  input: tool.input || '',
898
622
  ok: tool.ok !== false,
899
623
  result: tool.result || '',
900
- booking_facts: tool.booking_facts,
901
624
  at: tool.at || nowIso(),
902
625
  source: tool.source || 'n8n',
903
626
  })),
@@ -924,7 +647,6 @@ const encodeTurnArchive = ({ threadId, messages = [], tools = [], workingMemory
924
647
  input: tool.input || '',
925
648
  ok: tool.ok !== false,
926
649
  output: tool.result || '',
927
- booking_facts: tool.booking_facts,
928
650
  at: tool.at || nowIso(),
929
651
  source: tool.source || 'n8n',
930
652
  })),
@@ -965,8 +687,7 @@ const parseToolHistoryMarker = (text) => {
965
687
  name: String(parsed.name),
966
688
  input: parsed.input === undefined ? '' : String(parsed.input),
967
689
  ok: parsed.ok !== false,
968
- result: truncate(parsed.result || '', 1000),
969
- booking_facts: parsed.booking_facts || parsed.bookingFacts,
690
+ result: parsed.result === undefined ? '' : String(parsed.result),
970
691
  at: parsed.at || nowIso(),
971
692
  source: parsed.source || 'tembory_marker',
972
693
  };
@@ -993,8 +714,7 @@ const parseToolLedgerMarker = (text) => {
993
714
  name: String(tool.name),
994
715
  input: tool.input === undefined ? '' : String(tool.input),
995
716
  ok: tool.ok !== false,
996
- result: truncate(tool.result || '', 1000),
997
- booking_facts: tool.booking_facts || tool.bookingFacts,
717
+ result: tool.result === undefined ? '' : String(tool.result),
998
718
  at: tool.at || parsed.generated_at || nowIso(),
999
719
  source: tool.source || 'tool_ledger_marker',
1000
720
  }));
@@ -1097,8 +817,7 @@ const toolHistoryFromMemory = (item) => {
1097
817
  name: factMatch[1],
1098
818
  input: truncate((factMatch[2] || '').trim(), 1000),
1099
819
  ok: true,
1100
- result: truncate((factMatch[3] || '').trim(), 1000),
1101
- booking_facts: meta.booking_facts || meta.bookingFacts,
820
+ result: (factMatch[3] || '').trim(),
1102
821
  at: meta.at || item.created_at || item.createdAt || nowIso(),
1103
822
  source: 'semantic_fact',
1104
823
  };
@@ -1127,8 +846,7 @@ const toolHistoryFromMemory = (item) => {
1127
846
  name: String(name),
1128
847
  input: meta.input === undefined ? '' : String(meta.input),
1129
848
  ok: meta.ok !== false,
1130
- result: truncate(meta.result || content || '', 1000),
1131
- booking_facts: meta.booking_facts || meta.bookingFacts,
849
+ result: meta.result === undefined ? String(content || '') : String(meta.result),
1132
850
  at: meta.at || item.created_at || item.createdAt || nowIso(),
1133
851
  source: meta.source || 'metadata',
1134
852
  };
@@ -1147,8 +865,7 @@ const explicitToolHistoryItemsFromMemory = (item) => {
1147
865
  name: String(tool.name),
1148
866
  input: tool.input === undefined ? '' : String(tool.input),
1149
867
  ok: tool.ok !== false,
1150
- result: truncate(tool.output || tool.result || '', 1000),
1151
- booking_facts: tool.booking_facts || tool.bookingFacts,
868
+ result: tool.output === undefined && tool.result === undefined ? '' : String(tool.output ?? tool.result),
1152
869
  at: tool.at || archive.generated_at || nowIso(),
1153
870
  source: tool.source || 'turn_archive',
1154
871
  }));
@@ -1213,9 +930,9 @@ const canonicalToolInput = (value) => {
1213
930
  const normalizeToolCall = (tool, sequence = 0, defaults = {}) => {
1214
931
  const at = tool.at || defaults.at || nowIso();
1215
932
  const input = canonicalToolInput(tool.input);
1216
- const rawResult = tool.result || tool.output || tool.observation || '';
1217
- const result = summarizeToolResult(rawResult);
1218
- const bookingFacts = tool.booking_facts || tool.bookingFacts || extractToolBookingFacts(tool.name || tool.tool || tool.toolName || '', input, rawResult);
933
+ const rawResult = tool.result !== undefined ? tool.result : tool.output !== undefined ? tool.output : tool.observation !== undefined ? tool.observation : '';
934
+ const result = typeof rawResult === 'string' ? rawResult : safeStringify(rawResult);
935
+ const resultSummary = summarizeToolResult(rawResult);
1219
936
  const normalized = {
1220
937
  id: tool.id || tool.callId || tool.call_id || '',
1221
938
  call_id: tool.id || tool.callId || tool.call_id || '',
@@ -1229,15 +946,12 @@ const normalizeToolCall = (tool, sequence = 0, defaults = {}) => {
1229
946
  normalized_args: input,
1230
947
  ok: tool.ok !== false,
1231
948
  result,
1232
- result_summary: result,
1233
- booking_facts: bookingFacts,
949
+ result_summary: resultSummary,
1234
950
  at,
1235
951
  timestamp: at,
1236
952
  source: tool.source || defaults.source || 'n8n',
1237
953
  status: tool.ok === false ? 'failed' : 'ok',
1238
954
  };
1239
- if (!normalized.booking_facts)
1240
- delete normalized.booking_facts;
1241
955
  if (!normalized.id)
1242
956
  normalized.id = makeToolEventId(normalized, normalized.sequence);
1243
957
  if (!normalized.call_id)
@@ -1315,11 +1029,8 @@ const extractToolCallsFromMessages = (messages = []) => {
1315
1029
  const existing = id ? toolCallById.get(String(id)) : null;
1316
1030
  if (existing) {
1317
1031
  const rawContent = messageContentOf(message);
1318
- existing.result = summarizeToolResult(rawContent);
1319
- existing.result_summary = existing.result;
1320
- existing.booking_facts = extractToolBookingFacts(existing.name, existing.input, rawContent) || existing.booking_facts;
1321
- if (!existing.booking_facts)
1322
- delete existing.booking_facts;
1032
+ existing.result = rawContent;
1033
+ existing.result_summary = summarizeToolResult(rawContent);
1323
1034
  existing.ok = true;
1324
1035
  existing.status = 'ok';
1325
1036
  existing.result_hash = stableHash(existing.result || '');
@@ -1357,7 +1068,7 @@ const extractToolCallsFromText = (text, at = nowIso()) => {
1357
1068
  name,
1358
1069
  input: match[2].trim(),
1359
1070
  ok: true,
1360
- result: summarizeToolResult(match[3].trim()),
1071
+ result: match[3].trim(),
1361
1072
  at,
1362
1073
  source: 'used_tools_text',
1363
1074
  }, calls.length + 1));
@@ -1377,7 +1088,7 @@ const extractToolCalls = (outputValues = {}) => {
1377
1088
  name: String(name),
1378
1089
  input: input === undefined ? '' : (typeof input === 'string' ? input : stableStringify(input)),
1379
1090
  ok,
1380
- result: summarizeToolResult(result),
1091
+ result,
1381
1092
  at,
1382
1093
  source: meta.source || 'intermediate_steps',
1383
1094
  }, calls.length + 1, { at }));
@@ -2320,7 +2031,6 @@ const compactToolHistoryForAgent = (toolHistory = [], maxItems = 6, includeResul
2320
2031
  reason: truncate(String(tool.reason || tool.decision || tool.why || tool.source || 'recorded tool call'), 140),
2321
2032
  input: truncate(String(tool.input || ''), 140) || undefined,
2322
2033
  result: includeResults ? compactToolResult(tool.result, 240) : undefined,
2323
- booking_facts: tool.booking_facts,
2324
2034
  }));
2325
2035
  const cleanContextValue = (value) => {
2326
2036
  if (Array.isArray(value)) {
@@ -2377,7 +2087,6 @@ const compactOperationalStateForAgent = (state = {}) => {
2377
2087
  const toolState = state.tool_state || {};
2378
2088
  return {
2379
2089
  last_tool: state.last_tool || null,
2380
- booking_state: state.booking_state,
2381
2090
  tool_counts: {
2382
2091
  total: counts.total || 0,
2383
2092
  ok: counts.ok || 0,
@@ -2406,7 +2115,6 @@ const compactActionLedgerForAgent = (ledger = [], maxItems = 6, includeResults =
2406
2115
  reason: item.reason,
2407
2116
  input: item.input,
2408
2117
  result: includeResults ? compactToolResult(item.result, 180) : undefined,
2409
- booking_facts: item.booking_facts,
2410
2118
  }));
2411
2119
  const compactEntityTimelineForAgent = (timeline = [], maxItems = 8) => pruneByLimit(timeline || [], maxItems).map((item) => cleanContextValue({
2412
2120
  entity: item.entity || item.source || item.name,
@@ -2715,7 +2423,6 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
2715
2423
  const vectorFacts = sectionValue('summary');
2716
2424
  const slmSummary = sectionValue('connected_model_summary') || sectionValue('active_summary');
2717
2425
  const directive = sectionValue('action_directive');
2718
- const bookingState = (operationalState || {}).booking_state;
2719
2426
  const inferredIntent = deriveUserIntentObservation({ query, workingMemory, decisionState, recentMessages });
2720
2427
  const minimalState = cleanContextValue({
2721
2428
  next_expected_action: directive ? undefined : workingMemory.next_expected_action,
@@ -2741,7 +2448,6 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
2741
2448
  slm: hasToolLedger ? undefined : slmSummary,
2742
2449
  },
2743
2450
  state: minimalState,
2744
- booking: bookingState,
2745
2451
  profile: sectionValue('profile_facts'),
2746
2452
  tools: compactToolLedger,
2747
2453
  });
@@ -3467,7 +3173,6 @@ class TemboryMemory {
3467
3173
  input: tool.input,
3468
3174
  ok: tool.ok,
3469
3175
  result: tool.result,
3470
- booking_facts: tool.booking_facts,
3471
3176
  at: tool.at,
3472
3177
  source: tool.source || 'tembory_transcript',
3473
3178
  thread_id: threadId,
@@ -4195,7 +3900,6 @@ class TemboryMemory {
4195
3900
  dedupe_key: tool.dedupe_key || toolEventKey(tool),
4196
3901
  result: adv.includeToolResults === false ? undefined : tool.result,
4197
3902
  result_summary: adv.includeToolResults === false ? undefined : (tool.result_summary || tool.result),
4198
- booking_facts: tool.booking_facts,
4199
3903
  })),
4200
3904
  },
4201
3905
  diagnostics,
@@ -4359,8 +4063,6 @@ exports.__private = {
4359
4063
  embedQueryCached,
4360
4064
  compactToolResult,
4361
4065
  compactToolHistoryForAgent,
4362
- extractToolBookingFacts,
4363
- deriveBookingState,
4364
4066
  compactVectorMemoriesForAgent,
4365
4067
  isConversationEchoMemory,
4366
4068
  compactOperationalStateForAgent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
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",