n8n-nodes-tembory 1.0.8 → 1.0.11
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 +3 -1
- package/dist/nodes/Mem0/Mem0Memory.node.js +253 -95
- package/package.json +1 -1
- package/scripts/simulate-agent-context.js +6 -6
package/README.md
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Node de memoria operacional da Tembory para agentes de IA no n8n.
|
|
4
4
|
|
|
5
|
-
Versao atual: `1.0.
|
|
5
|
+
Versao atual: `1.0.11`.
|
|
6
6
|
|
|
7
7
|
O Tembory entrega contexto rico para o AI Agent sem depender apenas do historico textual da conversa. Ele combina memoria semantica, working memory, decision state, fatos estaveis do lead, historico de tools, estado operacional, action ledger, timeline de entidades, compressao de memoria, grafo, mensagens recentes e diagnosticos.
|
|
8
8
|
|
|
9
|
+
Nos presets de producao, o contexto e organizado como um pacote acionavel: secoes vazias sao removidas, evidencias de tools ficam canonicas em `tool_history`/`operational_state`, e blocos como `decision_state`, `working_memory` e `memory_compression` sao compactados sem perder IDs, proximas acoes, slots, reservas, confirmacoes e bloqueios de repeticao.
|
|
10
|
+
|
|
9
11
|
## Smoke tecnico
|
|
10
12
|
|
|
11
13
|
Antes de publicar uma versao, rode:
|
|
@@ -27,7 +27,7 @@ const snapshotJson = (value) => {
|
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
const truncate = (value, max = MAX_TEXT) => {
|
|
30
|
-
const text = typeof value === 'string' ? value : safeStringify(value);
|
|
30
|
+
const text = value === undefined || value === null ? '' : (typeof value === 'string' ? value : safeStringify(value));
|
|
31
31
|
if (text.length <= max)
|
|
32
32
|
return text;
|
|
33
33
|
return `${text.slice(0, max)}\n... [truncated ${text.length - max} chars]`;
|
|
@@ -43,7 +43,7 @@ const getConnectedEmbedding = async (ctx, itemIndex) => {
|
|
|
43
43
|
};
|
|
44
44
|
const createClientVectorMemory = async (embedding, text, metadata, ids = {}) => ({
|
|
45
45
|
text: truncate(text, 4000),
|
|
46
|
-
embedding: await embedding
|
|
46
|
+
embedding: await embedQueryCached(embedding, String(text || '')),
|
|
47
47
|
user_id: ids.user_id,
|
|
48
48
|
agent_id: ids.agent_id,
|
|
49
49
|
run_id: ids.run_id,
|
|
@@ -53,7 +53,7 @@ const saveClientVectorMemories = async (ctx, memories, ids = {}) => {
|
|
|
53
53
|
const valid = memories.filter((memory) => String(memory === null || memory === void 0 ? void 0 : memory.text || '').trim());
|
|
54
54
|
if (!valid.length)
|
|
55
55
|
return null;
|
|
56
|
-
return GenericFunctions_1.mem0ApiRequest.call(ctx, 'POST', '/
|
|
56
|
+
return GenericFunctions_1.mem0ApiRequest.call(ctx, 'POST', '/tembory/v1/vector-memories', {
|
|
57
57
|
memories: valid,
|
|
58
58
|
user_id: ids.user_id,
|
|
59
59
|
agent_id: ids.agent_id,
|
|
@@ -64,10 +64,10 @@ const searchClientVectorMemories = async (ctx, embedding, query, body = {}) => {
|
|
|
64
64
|
const text = String(query || '').trim();
|
|
65
65
|
if (!text)
|
|
66
66
|
return { results: [] };
|
|
67
|
-
return GenericFunctions_1.mem0ApiRequest.call(ctx, 'POST', '/
|
|
67
|
+
return GenericFunctions_1.mem0ApiRequest.call(ctx, 'POST', '/tembory/v1/vector-memories/search', {
|
|
68
68
|
...body,
|
|
69
69
|
query: text,
|
|
70
|
-
embedding: await embedding
|
|
70
|
+
embedding: await embedQueryCached(embedding, text),
|
|
71
71
|
});
|
|
72
72
|
};
|
|
73
73
|
const stableStringify = (value) => {
|
|
@@ -87,6 +87,31 @@ const hashString = (value) => {
|
|
|
87
87
|
return (hash >>> 0).toString(36);
|
|
88
88
|
};
|
|
89
89
|
const stableHash = (value) => hashString(typeof value === 'string' ? value : stableStringify(value));
|
|
90
|
+
const embeddingCacheByModel = new WeakMap();
|
|
91
|
+
const MAX_EMBEDDING_CACHE_ITEMS = 500;
|
|
92
|
+
const embedQueryCached = async (embedding, text) => {
|
|
93
|
+
const query = String(text || '');
|
|
94
|
+
if (!embedding || typeof embedding.embedQuery !== 'function')
|
|
95
|
+
return undefined;
|
|
96
|
+
let cache = embeddingCacheByModel.get(embedding);
|
|
97
|
+
if (!cache) {
|
|
98
|
+
cache = new Map();
|
|
99
|
+
embeddingCacheByModel.set(embedding, cache);
|
|
100
|
+
}
|
|
101
|
+
const key = stableHash(query);
|
|
102
|
+
if (cache.has(key))
|
|
103
|
+
return cache.get(key);
|
|
104
|
+
const promise = Promise.resolve(embedding.embedQuery(query)).catch((error) => {
|
|
105
|
+
cache.delete(key);
|
|
106
|
+
throw error;
|
|
107
|
+
});
|
|
108
|
+
cache.set(key, promise);
|
|
109
|
+
if (cache.size > MAX_EMBEDDING_CACHE_ITEMS) {
|
|
110
|
+
const firstKey = cache.keys().next().value;
|
|
111
|
+
cache.delete(firstKey);
|
|
112
|
+
}
|
|
113
|
+
return promise;
|
|
114
|
+
};
|
|
90
115
|
const pickText = (values, preferredKeys) => {
|
|
91
116
|
for (const key of preferredKeys) {
|
|
92
117
|
const value = values === null || values === void 0 ? void 0 : values[key];
|
|
@@ -142,11 +167,11 @@ const scoreOf = (m) => {
|
|
|
142
167
|
var _a, _b, _c, _d;
|
|
143
168
|
return (_d = (_c = (_b = (_a = m === null || m === void 0 ? void 0 : m.score) !== null && _a !== void 0 ? _a : m === null || m === void 0 ? void 0 : m.similarity) !== null && _b !== void 0 ? _b : m === null || m === void 0 ? void 0 : m.relevance) !== null && _c !== void 0 ? _c : m === null || m === void 0 ? void 0 : m.distance) !== null && _d !== void 0 ? _d : undefined;
|
|
144
169
|
};
|
|
145
|
-
const scoreMetaOf = (m) => (m && typeof m === 'object' && (m.
|
|
146
|
-
const
|
|
170
|
+
const scoreMetaOf = (m) => (m && typeof m === 'object' && (m.temboryScore || m._temboryScore)) || {};
|
|
171
|
+
const withTemboryScore = (m, temboryScore) => {
|
|
147
172
|
if (!m || typeof m !== 'object')
|
|
148
173
|
return m;
|
|
149
|
-
return { ...m,
|
|
174
|
+
return { ...m, temboryScore };
|
|
150
175
|
};
|
|
151
176
|
const normalizeFactValue = (value) => String(value || '').replace(/\*\*/g, '').replace(/\s+/g, ' ').replace(/[.,;:]+$/g, '').trim();
|
|
152
177
|
const profileSourceRank = (source = '') => {
|
|
@@ -479,8 +504,8 @@ const deriveEntityTimeline = (profileFacts = {}, graph = [], recentMessages = []
|
|
|
479
504
|
}
|
|
480
505
|
return pruneByLimit(deduped.sort((a, b) => String(a.at || '').localeCompare(String(b.at || ''))), maxItems || 24);
|
|
481
506
|
};
|
|
482
|
-
const RECENT_MESSAGE_MARKER = '
|
|
483
|
-
const TOOL_HISTORY_MARKER = '
|
|
507
|
+
const RECENT_MESSAGE_MARKER = '__tembory_recent_message_v1__';
|
|
508
|
+
const TOOL_HISTORY_MARKER = '__tembory_tool_history_v1__';
|
|
484
509
|
const encodeRecentMessage = (recent, threadId) => `${RECENT_MESSAGE_MARKER}${safeStringify({
|
|
485
510
|
role: recent.role || 'user',
|
|
486
511
|
content: recent.content || '',
|
|
@@ -830,21 +855,21 @@ const extractToolCalls = (outputValues = {}) => {
|
|
|
830
855
|
const getMemoryStore = (ctx) => {
|
|
831
856
|
try {
|
|
832
857
|
const data = ctx.getWorkflowStaticData('global');
|
|
833
|
-
data.
|
|
834
|
-
data.
|
|
835
|
-
data.
|
|
836
|
-
data.
|
|
837
|
-
data.
|
|
838
|
-
data.
|
|
839
|
-
data.
|
|
840
|
-
return data.
|
|
858
|
+
data.tembory = data.tembory || {};
|
|
859
|
+
data.tembory.toolHistory = data.tembory.toolHistory || {};
|
|
860
|
+
data.tembory.recentMessages = data.tembory.recentMessages || {};
|
|
861
|
+
data.tembory.profileFacts = data.tembory.profileFacts || {};
|
|
862
|
+
data.tembory.workingMemory = data.tembory.workingMemory || {};
|
|
863
|
+
data.tembory.decisionState = data.tembory.decisionState || {};
|
|
864
|
+
data.tembory.memoryCompression = data.tembory.memoryCompression || {};
|
|
865
|
+
return data.tembory;
|
|
841
866
|
}
|
|
842
867
|
catch {
|
|
843
|
-
global.
|
|
844
|
-
global.
|
|
845
|
-
global.
|
|
846
|
-
global.
|
|
847
|
-
return global.
|
|
868
|
+
global.__temboryMemory = global.__temboryMemory || { toolHistory: {}, recentMessages: {}, profileFacts: {}, workingMemory: {}, decisionState: {}, memoryCompression: {} };
|
|
869
|
+
global.__temboryMemory.workingMemory = global.__temboryMemory.workingMemory || {};
|
|
870
|
+
global.__temboryMemory.decisionState = global.__temboryMemory.decisionState || {};
|
|
871
|
+
global.__temboryMemory.memoryCompression = global.__temboryMemory.memoryCompression || {};
|
|
872
|
+
return global.__temboryMemory;
|
|
848
873
|
}
|
|
849
874
|
};
|
|
850
875
|
const namespacePart = (value) => String(value || '').trim().replace(/\s+/g, '_').replace(/[:|]+/g, '-');
|
|
@@ -881,6 +906,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
881
906
|
recentMessagesLastN: 8,
|
|
882
907
|
},
|
|
883
908
|
productionBalanced: {
|
|
909
|
+
compactStateSections: true,
|
|
884
910
|
includeContextHeader: true,
|
|
885
911
|
includeSummary: true,
|
|
886
912
|
includeScores: false,
|
|
@@ -903,8 +929,11 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
903
929
|
lastN: 8,
|
|
904
930
|
toolHistoryLastN: 10,
|
|
905
931
|
recentMessagesLastN: 6,
|
|
932
|
+
vectorMemoryMaxChars: 360,
|
|
933
|
+
contextMaxChars: 10000,
|
|
906
934
|
},
|
|
907
935
|
productionCheap: {
|
|
936
|
+
compactStateSections: true,
|
|
908
937
|
includeContextHeader: true,
|
|
909
938
|
includeSummary: false,
|
|
910
939
|
includeScores: false,
|
|
@@ -927,6 +956,8 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
927
956
|
lastN: 4,
|
|
928
957
|
toolHistoryLastN: 5,
|
|
929
958
|
recentMessagesLastN: 4,
|
|
959
|
+
vectorMemoryMaxChars: 260,
|
|
960
|
+
contextMaxChars: 7000,
|
|
930
961
|
},
|
|
931
962
|
productionNano: {
|
|
932
963
|
compactForAgent: true,
|
|
@@ -1303,7 +1334,7 @@ const deriveContextHealth = ({ userId = '', project = '', vectorMemories = [], r
|
|
|
1303
1334
|
const missing = Object.entries(checks).filter(([, ok]) => !ok).map(([key]) => key);
|
|
1304
1335
|
const agenda = operationalState.agenda_state || {};
|
|
1305
1336
|
return {
|
|
1306
|
-
kind: '
|
|
1337
|
+
kind: 'tembory.context_health.v1',
|
|
1307
1338
|
namespace: userId || null,
|
|
1308
1339
|
project: project || null,
|
|
1309
1340
|
quality_score: Math.max(0, Math.min(1000, score)),
|
|
@@ -1384,12 +1415,63 @@ const compactToolResult = (result, max = 360) => {
|
|
|
1384
1415
|
return truncate(text, max);
|
|
1385
1416
|
};
|
|
1386
1417
|
const compactToolHistoryForAgent = (toolHistory = [], maxItems = 6, includeResults = true) => pruneByLimit(toolHistory || [], maxItems).map((tool) => ({
|
|
1418
|
+
id: tool.call_id || tool.id,
|
|
1387
1419
|
name: tool.name,
|
|
1388
1420
|
status: tool.ok === false ? 'failed' : 'ok',
|
|
1389
1421
|
at: tool.at,
|
|
1390
1422
|
input: truncate(String(tool.input || ''), 180) || undefined,
|
|
1391
1423
|
result: includeResults ? compactToolResult(tool.result, 360) : undefined,
|
|
1392
1424
|
}));
|
|
1425
|
+
const cleanContextValue = (value) => {
|
|
1426
|
+
if (Array.isArray(value)) {
|
|
1427
|
+
return value.map(cleanContextValue).filter((item) => item !== undefined && item !== null && !(Array.isArray(item) && item.length === 0) && !(typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0));
|
|
1428
|
+
}
|
|
1429
|
+
if (!value || typeof value !== 'object')
|
|
1430
|
+
return value === '' ? undefined : value;
|
|
1431
|
+
const out = {};
|
|
1432
|
+
for (const [key, item] of Object.entries(value)) {
|
|
1433
|
+
const cleaned = cleanContextValue(item);
|
|
1434
|
+
if (cleaned === undefined || cleaned === null)
|
|
1435
|
+
continue;
|
|
1436
|
+
if (Array.isArray(cleaned) && cleaned.length === 0)
|
|
1437
|
+
continue;
|
|
1438
|
+
if (typeof cleaned === 'object' && !Array.isArray(cleaned) && Object.keys(cleaned).length === 0)
|
|
1439
|
+
continue;
|
|
1440
|
+
out[key] = cleaned;
|
|
1441
|
+
}
|
|
1442
|
+
return out;
|
|
1443
|
+
};
|
|
1444
|
+
const compactWorkingMemoryForAgent = (memory = {}) => cleanContextValue({
|
|
1445
|
+
current_goal: memory.current_goal,
|
|
1446
|
+
current_task: memory.current_task,
|
|
1447
|
+
last_user_intent: memory.last_user_intent,
|
|
1448
|
+
last_user_message: truncate(memory.last_user_message, 220),
|
|
1449
|
+
active_entities: memory.active_entities,
|
|
1450
|
+
open_decisions: memory.open_decisions,
|
|
1451
|
+
last_error: memory.last_error,
|
|
1452
|
+
next_expected_action: memory.next_expected_action,
|
|
1453
|
+
updated_at: memory.updated_at,
|
|
1454
|
+
});
|
|
1455
|
+
const compactDecisionStateForAgent = (state = {}) => cleanContextValue({
|
|
1456
|
+
current_intent: state.current_intent,
|
|
1457
|
+
active_decisions: (state.active_decisions || []).slice(-4).map((decision) => cleanContextValue({
|
|
1458
|
+
id: decision.id,
|
|
1459
|
+
status: decision.status,
|
|
1460
|
+
decision: truncate(decision.decision || decision.summary || decision.reason, 260),
|
|
1461
|
+
tool: decision.tool || decision.next_tool || decision.required_tool,
|
|
1462
|
+
reservation_id: decision.reservation_id,
|
|
1463
|
+
confirmation_id: decision.confirmation_id,
|
|
1464
|
+
at: decision.at || decision.updated_at,
|
|
1465
|
+
})),
|
|
1466
|
+
do_not_repeat_tools: state.do_not_repeat_tools,
|
|
1467
|
+
agenda_decision_state: state.agenda_decision_state,
|
|
1468
|
+
latest_tool: state.latest_tool ? cleanContextValue({
|
|
1469
|
+
name: state.latest_tool.name,
|
|
1470
|
+
status: state.latest_tool.status || (state.latest_tool.ok === false ? 'failed' : 'ok'),
|
|
1471
|
+
at: state.latest_tool.at,
|
|
1472
|
+
}) : undefined,
|
|
1473
|
+
conflict_policy: state.conflict_policy,
|
|
1474
|
+
});
|
|
1393
1475
|
const compactOperationalStateForAgent = (state = {}) => {
|
|
1394
1476
|
const agenda = state.agenda_state || {};
|
|
1395
1477
|
return {
|
|
@@ -1419,6 +1501,21 @@ const compactMemoryCompressionForAgent = (compression = {}) => ({
|
|
|
1419
1501
|
} : undefined,
|
|
1420
1502
|
active_memory_count: ((compression.workflow_summary || {}).active_memory_count) || 0,
|
|
1421
1503
|
});
|
|
1504
|
+
const compactActionLedgerForAgent = (ledger = [], maxItems = 6, includeResults = true) => pruneByLimit(ledger || [], maxItems).map((item) => cleanContextValue({
|
|
1505
|
+
action_id: item.action_id,
|
|
1506
|
+
kind: item.kind,
|
|
1507
|
+
tool: item.tool || item.name,
|
|
1508
|
+
status: item.status,
|
|
1509
|
+
at: item.at,
|
|
1510
|
+
result: includeResults ? compactToolResult(item.result, 260) : undefined,
|
|
1511
|
+
}));
|
|
1512
|
+
const compactEntityTimelineForAgent = (timeline = [], maxItems = 8) => pruneByLimit(timeline || [], maxItems).map((item) => cleanContextValue({
|
|
1513
|
+
entity: item.entity || item.source || item.name,
|
|
1514
|
+
event: truncate(item.event || item.fact || item.relation || item.kind || item.value, 220),
|
|
1515
|
+
target: item.target,
|
|
1516
|
+
at: item.at,
|
|
1517
|
+
source: item.source_type || item.source,
|
|
1518
|
+
}));
|
|
1422
1519
|
const compactVectorMemoriesForAgent = (vectorMemories = [], toolHistory = [], maxItems = 3) => {
|
|
1423
1520
|
const hasStructuredTools = Array.isArray(toolHistory) && toolHistory.length > 0;
|
|
1424
1521
|
return (vectorMemories || [])
|
|
@@ -1435,7 +1532,7 @@ const contextSizeOfMessages = (messages = []) => {
|
|
|
1435
1532
|
const chars = perMessage.reduce((sum, item) => sum + item.chars, 0);
|
|
1436
1533
|
return { chars, approx_tokens: approxTokenCount((messages || []).map((m) => m.content || '').join('\n')), messages: perMessage };
|
|
1437
1534
|
};
|
|
1438
|
-
const
|
|
1535
|
+
const wrapTemboryMemory = (memory, ctx, memoryKey) => new Proxy(memory, {
|
|
1439
1536
|
get(target, prop) {
|
|
1440
1537
|
if (prop === 'loadMemoryVariables') {
|
|
1441
1538
|
return async (values = {}) => {
|
|
@@ -1444,29 +1541,33 @@ const wrapElefaiMemory = (memory, ctx, memoryKey) => new Proxy(memory, {
|
|
|
1444
1541
|
]);
|
|
1445
1542
|
try {
|
|
1446
1543
|
const response = await target.loadMemoryVariables(values);
|
|
1447
|
-
const
|
|
1544
|
+
const cacheHit = Boolean(response.temboryDiagnostics && response.temboryDiagnostics.cacheHit);
|
|
1545
|
+
const chatHistory = cacheHit
|
|
1546
|
+
? [{ cached: true, messages: Array.isArray(response[memoryKey] || response.chatHistory) ? (response[memoryKey] || response.chatHistory).length : 0 }]
|
|
1547
|
+
: snapshotJson(response[memoryKey] || response.chatHistory || []);
|
|
1448
1548
|
ctx.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, [
|
|
1449
1549
|
[{
|
|
1450
1550
|
json: {
|
|
1451
1551
|
action: 'loadMemoryVariables',
|
|
1552
|
+
cached: cacheHit || undefined,
|
|
1452
1553
|
chatHistory,
|
|
1453
|
-
context: response.
|
|
1454
|
-
contextText: response.
|
|
1455
|
-
summary: response.
|
|
1456
|
-
connectedModelSummary: response.
|
|
1457
|
-
workingMemory: response.
|
|
1458
|
-
decisionState: response.
|
|
1459
|
-
memoryCompression: response.
|
|
1460
|
-
profileFacts: response.
|
|
1461
|
-
operationalState: response.
|
|
1462
|
-
actionLedger: response.
|
|
1463
|
-
entityTimeline: response.
|
|
1464
|
-
vectorMemories: response.
|
|
1465
|
-
graph: response.
|
|
1466
|
-
recentMessages: response.
|
|
1467
|
-
recentHighlights: response.
|
|
1468
|
-
toolHistory: response.
|
|
1469
|
-
diagnostics: response.
|
|
1554
|
+
context: response.temboryContext,
|
|
1555
|
+
contextText: response.temboryContextText,
|
|
1556
|
+
summary: response.temborySummary,
|
|
1557
|
+
connectedModelSummary: response.temboryConnectedModelSummary,
|
|
1558
|
+
workingMemory: response.temboryWorkingMemory,
|
|
1559
|
+
decisionState: response.temboryDecisionState,
|
|
1560
|
+
memoryCompression: response.temboryMemoryCompression,
|
|
1561
|
+
profileFacts: response.temboryProfileFacts,
|
|
1562
|
+
operationalState: response.temboryOperationalState,
|
|
1563
|
+
actionLedger: response.temboryActionLedger,
|
|
1564
|
+
entityTimeline: response.temboryEntityTimeline,
|
|
1565
|
+
vectorMemories: response.temboryVectorMemories,
|
|
1566
|
+
graph: response.temboryGraph,
|
|
1567
|
+
recentMessages: response.temboryRecentMessages,
|
|
1568
|
+
recentHighlights: response.temboryRecentHighlights,
|
|
1569
|
+
toolHistory: response.temboryToolHistory,
|
|
1570
|
+
diagnostics: response.temboryDiagnostics,
|
|
1470
1571
|
},
|
|
1471
1572
|
}],
|
|
1472
1573
|
]);
|
|
@@ -1505,12 +1606,13 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1505
1606
|
const includeSummary = adv.includeSummary !== false;
|
|
1506
1607
|
const includeScores = adv.includeScores !== false;
|
|
1507
1608
|
const compactForAgent = Boolean(adv.compactForAgent);
|
|
1609
|
+
const compactStateSections = Boolean(adv.compactStateSections);
|
|
1508
1610
|
const sections = [];
|
|
1509
1611
|
if (includeHeader) {
|
|
1510
1612
|
sections.push({
|
|
1511
1613
|
section: 'context_header',
|
|
1512
1614
|
title: 'Tembory context',
|
|
1513
|
-
value: compactForAgent
|
|
1615
|
+
value: compactForAgent || compactStateSections
|
|
1514
1616
|
? 'Read-only memory. Follow next_expected_action when present. Before calling downstream tools, verify required prior tool context in tool_history or operational_state. Do not repeat tools listed in do_not_repeat_tools.'
|
|
1515
1617
|
: 'Use this context as read-only memory. Prefer it over guessing. Do not mention internal section names to the user. Treat next_expected_action as an instruction, not as a suggestion. If it says to call a tool now, call that tool instead of asking the user the same question again. If the user asks to continue, chooses a slot, says ok/sim, reserve, confirm, update, cancel, or performs any downstream action that depends on a prior tool result, first verify the required prior result in tool_history, recent_messages, or vector memories. If the required prior result is absent, do not call the downstream tool; ask for the missing context or call the appropriate prerequisite tool.',
|
|
1516
1618
|
});
|
|
@@ -1559,7 +1661,7 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1559
1661
|
why_null: adv.includeMemoryCompression === false ? 'memory compression disabled' : undefined,
|
|
1560
1662
|
});
|
|
1561
1663
|
const audit = {
|
|
1562
|
-
kind: '
|
|
1664
|
+
kind: 'tembory.context.v1',
|
|
1563
1665
|
meta: { user_id: userId, payloadFormat, query, compact_for_agent: true },
|
|
1564
1666
|
sections,
|
|
1565
1667
|
diagnostics,
|
|
@@ -1580,13 +1682,15 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1580
1682
|
return [{ role: 'system', content: truncate(sections.map(renderCompactSection).join('\n\n'), Number(adv.contextMaxChars || 6000)) }];
|
|
1581
1683
|
}
|
|
1582
1684
|
if (includeSummary) {
|
|
1583
|
-
const summary =
|
|
1685
|
+
const summary = compactStateSections
|
|
1686
|
+
? compactVectorMemoriesForAgent(vectorMemories, toolHistory, Number(adv.summaryMaxFacts || 4))
|
|
1687
|
+
: vectorMemories.slice(0, Number(adv.summaryMaxFacts || 4)).map((memory) => contextMemoryText(memory, 360)).filter(Boolean);
|
|
1584
1688
|
sections.push({ section: 'summary', title: 'Summary', value: summary.length ? summary : null, why_null: summary.length ? undefined : 'no vector memories to summarize' });
|
|
1585
1689
|
}
|
|
1586
1690
|
sections.push({
|
|
1587
1691
|
section: 'working_memory',
|
|
1588
1692
|
title: 'Working memory',
|
|
1589
|
-
value: adv.includeWorkingMemory === false ? null : (workingMemory || {}),
|
|
1693
|
+
value: adv.includeWorkingMemory === false ? null : (compactStateSections ? compactWorkingMemoryForAgent(workingMemory || {}) : (workingMemory || {})),
|
|
1590
1694
|
why_null: adv.includeWorkingMemory === false ? 'working memory disabled' : undefined,
|
|
1591
1695
|
});
|
|
1592
1696
|
sections.push({
|
|
@@ -1610,31 +1714,31 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1610
1714
|
sections.push({
|
|
1611
1715
|
section: 'decision_state',
|
|
1612
1716
|
title: 'Decision state',
|
|
1613
|
-
value: adv.includeDecisionState === false ? null : (decisionState || {}),
|
|
1717
|
+
value: adv.includeDecisionState === false ? null : (compactStateSections ? compactDecisionStateForAgent(decisionState || {}) : (decisionState || {})),
|
|
1614
1718
|
why_null: adv.includeDecisionState === false ? 'decision state disabled' : undefined,
|
|
1615
1719
|
});
|
|
1616
1720
|
sections.push({
|
|
1617
1721
|
section: 'operational_state',
|
|
1618
1722
|
title: 'Operational state',
|
|
1619
|
-
value: adv.includeOperationalState === false ? null : operationalState,
|
|
1723
|
+
value: adv.includeOperationalState === false ? null : (compactStateSections ? compactOperationalStateForAgent(operationalState || {}) : operationalState),
|
|
1620
1724
|
why_null: adv.includeOperationalState === false ? 'operational state disabled' : undefined,
|
|
1621
1725
|
});
|
|
1622
1726
|
sections.push({
|
|
1623
1727
|
section: 'action_ledger',
|
|
1624
1728
|
title: 'Action ledger',
|
|
1625
|
-
value: adv.includeActionLedger === false ? null : (actionLedger || []),
|
|
1729
|
+
value: adv.includeActionLedger === false ? null : (compactStateSections ? compactActionLedgerForAgent(actionLedger || [], adv.actionLedgerMaxItems || 6, adv.includeToolResults !== false) : (actionLedger || [])),
|
|
1626
1730
|
why_null: adv.includeActionLedger === false ? 'action ledger disabled' : undefined,
|
|
1627
1731
|
});
|
|
1628
1732
|
sections.push({
|
|
1629
1733
|
section: 'entity_timeline',
|
|
1630
1734
|
title: 'Entity timeline',
|
|
1631
|
-
value: adv.includeEntityTimeline === false ? null : (entityTimeline || []),
|
|
1735
|
+
value: adv.includeEntityTimeline === false ? null : (compactStateSections ? compactEntityTimelineForAgent(entityTimeline || [], adv.entityTimelineMaxItems || 8) : (entityTimeline || [])),
|
|
1632
1736
|
why_null: adv.includeEntityTimeline === false ? 'entity timeline disabled' : undefined,
|
|
1633
1737
|
});
|
|
1634
1738
|
sections.push({
|
|
1635
1739
|
section: 'vector',
|
|
1636
1740
|
title: 'Vector memories',
|
|
1637
|
-
value: vectorMemories.map((m) => {
|
|
1741
|
+
value: compactStateSections ? compactVectorMemoriesForAgent(vectorMemories, toolHistory, Number(adv.maxReturn || adv.topK || 4)) : vectorMemories.map((m) => {
|
|
1638
1742
|
const scoreMeta = scoreMetaOf(m);
|
|
1639
1743
|
const rawScore = scoreOf(m);
|
|
1640
1744
|
return {
|
|
@@ -1652,7 +1756,7 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1652
1756
|
sections.push({
|
|
1653
1757
|
section: 'memory_compression',
|
|
1654
1758
|
title: 'Memory compression',
|
|
1655
|
-
value: adv.includeMemoryCompression === false ? null : (memoryCompression || {}),
|
|
1759
|
+
value: adv.includeMemoryCompression === false ? null : (compactStateSections ? compactMemoryCompressionForAgent(memoryCompression || {}) : (memoryCompression || {})),
|
|
1656
1760
|
why_null: adv.includeMemoryCompression === false ? 'memory compression disabled' : undefined,
|
|
1657
1761
|
});
|
|
1658
1762
|
sections.push({
|
|
@@ -1664,7 +1768,11 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1664
1768
|
sections.push({
|
|
1665
1769
|
section: 'recent_messages',
|
|
1666
1770
|
title: 'Recent messages',
|
|
1667
|
-
value: recentMessages || [],
|
|
1771
|
+
value: compactStateSections ? pruneByLimit(recentMessages || [], adv.recentMessagesLastN || 4).map((message) => cleanContextValue({
|
|
1772
|
+
role: message.role,
|
|
1773
|
+
content: truncate(message.content, 260),
|
|
1774
|
+
at: message.at,
|
|
1775
|
+
})) : recentMessages || [],
|
|
1668
1776
|
});
|
|
1669
1777
|
sections.push({
|
|
1670
1778
|
section: 'recent_highlights',
|
|
@@ -1675,18 +1783,18 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1675
1783
|
section: 'tool_history',
|
|
1676
1784
|
title: 'Tool history',
|
|
1677
1785
|
value: {
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1786
|
+
enabled: adv.includeToolHistory !== false,
|
|
1787
|
+
items: adv.includeToolHistory === false ? [] : (compactStateSections ? compactToolHistoryForAgent(toolHistory, adv.toolHistoryLastN || 8, adv.includeToolResults !== false) : toolHistory.map((tool) => ({
|
|
1788
|
+
id: tool.id,
|
|
1789
|
+
turnId: tool.turnId,
|
|
1790
|
+
sequence: tool.sequence,
|
|
1683
1791
|
name: tool.name,
|
|
1684
1792
|
input: tool.input,
|
|
1685
1793
|
ok: tool.ok,
|
|
1686
1794
|
at: tool.at,
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
})),
|
|
1795
|
+
source: tool.source,
|
|
1796
|
+
result: adv.includeToolResults === false ? undefined : tool.result,
|
|
1797
|
+
}))),
|
|
1690
1798
|
},
|
|
1691
1799
|
});
|
|
1692
1800
|
if (adv.includeDiagnostics) {
|
|
@@ -1697,7 +1805,7 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1697
1805
|
});
|
|
1698
1806
|
}
|
|
1699
1807
|
const audit = {
|
|
1700
|
-
kind: '
|
|
1808
|
+
kind: 'tembory.context.v1',
|
|
1701
1809
|
meta: { user_id: userId, payloadFormat, query },
|
|
1702
1810
|
sections,
|
|
1703
1811
|
diagnostics,
|
|
@@ -1711,17 +1819,32 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1711
1819
|
return `## ${section.title}\n${section.value.length ? section.value.map((item) => typeof item === 'string' ? `- ${item}` : `- ${truncate(safeStringify(item), 900)}`).join('\n') : '(empty)'}`;
|
|
1712
1820
|
return `## ${section.title}\n${truncate(safeStringify(section.value), 1600)}`;
|
|
1713
1821
|
};
|
|
1822
|
+
const sectionIsEmpty = (section) => {
|
|
1823
|
+
if (!compactStateSections)
|
|
1824
|
+
return false;
|
|
1825
|
+
if (section.section === 'context_header' || section.section === 'tool_guard' || section.section === 'working_memory' || section.section === 'decision_state' || section.section === 'operational_state' || section.section === 'tool_history')
|
|
1826
|
+
return false;
|
|
1827
|
+
if (section.value === null || section.value === undefined)
|
|
1828
|
+
return true;
|
|
1829
|
+
if (Array.isArray(section.value) && section.value.length === 0)
|
|
1830
|
+
return true;
|
|
1831
|
+
if (typeof section.value === 'object' && !Array.isArray(section.value) && Object.keys(section.value).length === 0)
|
|
1832
|
+
return true;
|
|
1833
|
+
return false;
|
|
1834
|
+
};
|
|
1835
|
+
const renderableSections = compactStateSections ? sections.filter((section) => !sectionIsEmpty(section)) : sections;
|
|
1714
1836
|
if (payloadFormat === 'auditJson') {
|
|
1715
1837
|
return [{ role: 'system', content: JSON.stringify(audit, null, 2) }];
|
|
1716
1838
|
}
|
|
1717
1839
|
if (payloadFormat === 'auditBlocks') {
|
|
1718
|
-
return
|
|
1840
|
+
return renderableSections.map((section) => ({ role: 'system', content: renderSection(section) }));
|
|
1719
1841
|
}
|
|
1720
|
-
const text =
|
|
1842
|
+
const text = renderableSections.map(renderSection).join('\n\n');
|
|
1843
|
+
const maxChars = Number(adv.contextMaxChars || 16000);
|
|
1721
1844
|
if (payloadFormat === 'auditText' || payloadFormat === 'singleSystemMessage' || payloadFormat === 'structured') {
|
|
1722
|
-
return [{ role: 'system', content: truncate(text,
|
|
1845
|
+
return [{ role: 'system', content: truncate(text, maxChars) }];
|
|
1723
1846
|
}
|
|
1724
|
-
return [{ role: 'system', content: truncate(text,
|
|
1847
|
+
return [{ role: 'system', content: truncate(text, maxChars) }];
|
|
1725
1848
|
};
|
|
1726
1849
|
class Mem0Memory {
|
|
1727
1850
|
constructor() {
|
|
@@ -1869,7 +1992,8 @@ class Mem0Memory {
|
|
|
1869
1992
|
{ displayName: 'MMR Lambda', name: 'mmrLambda', type: 'number', typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2 }, default: 0.5, description: 'Equilíbrio entre relevância e diversidade no MMR', displayOptions: { show: { '/retrievalMode': ['hybrid'] } } },
|
|
1870
1993
|
{ displayName: 'Incluir Cabeçalho de Contexto', name: 'includeContextHeader', type: 'boolean', default: true },
|
|
1871
1994
|
{ displayName: 'Compactar Contexto Para Agente', name: 'compactForAgent', type: 'boolean', default: false, description: 'Entrega ao agente apenas o estado acionável: working memory, decisões, estado operacional e histórico de tools compacto. Mantém detalhes completos no audit/debug.' },
|
|
1872
|
-
{ displayName: '
|
|
1995
|
+
{ displayName: 'Organizar Seções de Produção', name: 'compactStateSections', type: 'boolean', default: false, description: 'Renderiza blocos de produção com campos canônicos, remove seções vazias e evita duplicar evidências já presentes em tool_history/operational_state.' },
|
|
1996
|
+
{ displayName: 'Máximo de Caracteres do Contexto', name: 'contextMaxChars', type: 'number', default: 6000, description: 'Limite final aplicado ao contexto entregue ao agente em modos estruturados de produção.' },
|
|
1873
1997
|
{ displayName: 'Incluir Resumo', name: 'includeSummary', type: 'boolean', default: true },
|
|
1874
1998
|
{ displayName: 'Máximo de Fatos no Resumo', name: 'summaryMaxFacts', type: 'number', default: 4 },
|
|
1875
1999
|
{ displayName: 'Incluir Scores', name: 'includeScores', type: 'boolean', default: true },
|
|
@@ -1903,6 +2027,7 @@ class Mem0Memory {
|
|
|
1903
2027
|
async supplyData(itemIndex) {
|
|
1904
2028
|
const memoryKey = this.getNodeParameter('memoryKey', itemIndex);
|
|
1905
2029
|
let currentMessages = [];
|
|
2030
|
+
const loadCache = new Map();
|
|
1906
2031
|
const memory = {
|
|
1907
2032
|
memoryKeys: [memoryKey],
|
|
1908
2033
|
inputKey: 'input',
|
|
@@ -1933,7 +2058,38 @@ class Mem0Memory {
|
|
|
1933
2058
|
},
|
|
1934
2059
|
},
|
|
1935
2060
|
loadMemoryVariables: async (inputValues = {}) => {
|
|
1936
|
-
const
|
|
2061
|
+
const cacheKey = stableHash({ itemIndex, inputValues, memoryKey });
|
|
2062
|
+
let result;
|
|
2063
|
+
if (loadCache.has(cacheKey)) {
|
|
2064
|
+
result = snapshotJson(loadCache.get(cacheKey));
|
|
2065
|
+
result.response = result.response || {};
|
|
2066
|
+
result.response.temboryDiagnostics = {
|
|
2067
|
+
...(result.response.temboryDiagnostics || {}),
|
|
2068
|
+
cacheHit: true,
|
|
2069
|
+
cacheScope: 'supplyData.loadMemoryVariables',
|
|
2070
|
+
};
|
|
2071
|
+
if (result.response.temboryContext) {
|
|
2072
|
+
result.response.temboryContext = {
|
|
2073
|
+
kind: result.response.temboryContext.kind,
|
|
2074
|
+
userId: result.response.temboryContext.userId,
|
|
2075
|
+
project: result.response.temboryContext.project,
|
|
2076
|
+
query: result.response.temboryContext.query,
|
|
2077
|
+
retrievalMode: result.response.temboryContext.retrievalMode,
|
|
2078
|
+
payloadFormat: result.response.temboryContext.payloadFormat,
|
|
2079
|
+
contextQualityScore: result.response.temboryContext.contextQualityScore,
|
|
2080
|
+
cacheHit: true,
|
|
2081
|
+
};
|
|
2082
|
+
}
|
|
2083
|
+
delete result.response.temboryContextText;
|
|
2084
|
+
}
|
|
2085
|
+
else {
|
|
2086
|
+
result = await Mem0Memory.prototype.loadMemoryVariablesForItem.call(this, itemIndex, inputValues);
|
|
2087
|
+
loadCache.set(cacheKey, snapshotJson(result));
|
|
2088
|
+
if (loadCache.size > 20) {
|
|
2089
|
+
const firstKey = loadCache.keys().next().value;
|
|
2090
|
+
loadCache.delete(firstKey);
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
1937
2093
|
const chatHistory = (result.response[memoryKey] || []).map(toBaseMessage);
|
|
1938
2094
|
const extra = { ...(result.response || {}) };
|
|
1939
2095
|
delete extra[memoryKey];
|
|
@@ -1945,6 +2101,7 @@ class Mem0Memory {
|
|
|
1945
2101
|
};
|
|
1946
2102
|
},
|
|
1947
2103
|
saveContext: async (inputValues = {}, outputValues = {}) => {
|
|
2104
|
+
loadCache.clear();
|
|
1948
2105
|
const input = pickText(inputValues, ['input', 'chatInput', 'text', 'query', 'question']);
|
|
1949
2106
|
const output = pickText(outputValues, ['output', 'response', 'text', 'answer']);
|
|
1950
2107
|
if (input)
|
|
@@ -1954,7 +2111,7 @@ class Mem0Memory {
|
|
|
1954
2111
|
await Mem0Memory.prototype.saveContextForItem.call(this, itemIndex, inputValues, outputValues);
|
|
1955
2112
|
},
|
|
1956
2113
|
};
|
|
1957
|
-
return { response:
|
|
2114
|
+
return { response: wrapTemboryMemory(memory, this, memoryKey) };
|
|
1958
2115
|
}
|
|
1959
2116
|
async saveMessagesForItem(itemIndex, messages = []) {
|
|
1960
2117
|
const inputValues = {};
|
|
@@ -2227,7 +2384,7 @@ class Mem0Memory {
|
|
|
2227
2384
|
}
|
|
2228
2385
|
if (connectedEmbedding && typeof connectedEmbedding.embedQuery === 'function' && String(query || '').trim()) {
|
|
2229
2386
|
try {
|
|
2230
|
-
await connectedEmbedding
|
|
2387
|
+
await embedQueryCached(connectedEmbedding, String(query));
|
|
2231
2388
|
connectedAi.embeddingQuery = true;
|
|
2232
2389
|
}
|
|
2233
2390
|
catch (error) {
|
|
@@ -2365,7 +2522,7 @@ class Mem0Memory {
|
|
|
2365
2522
|
}
|
|
2366
2523
|
ranked = selected;
|
|
2367
2524
|
}
|
|
2368
|
-
const finalMemories = ranked.slice(0, maxReturn).map((r) =>
|
|
2525
|
+
const finalMemories = ranked.slice(0, maxReturn).map((r) => withTemboryScore(r.m, {
|
|
2369
2526
|
semanticScore: r.semanticScore,
|
|
2370
2527
|
recencyScore: r.recencyScore,
|
|
2371
2528
|
hybridScore: r.hybrid,
|
|
@@ -2375,7 +2532,7 @@ class Mem0Memory {
|
|
|
2375
2532
|
payload = finalMemories.map((m) => { var _a, _b; return ({ role: 'system', content: (_b = (_a = m.memory) !== null && _a !== void 0 ? _a : m.text) !== null && _b !== void 0 ? _b : JSON.stringify(m) }); });
|
|
2376
2533
|
}
|
|
2377
2534
|
else {
|
|
2378
|
-
vectorMemories = semMemories.map((m) =>
|
|
2535
|
+
vectorMemories = semMemories.map((m) => withTemboryScore(m, {
|
|
2379
2536
|
semanticScore: scoreOf(m),
|
|
2380
2537
|
source: 'semantic',
|
|
2381
2538
|
}));
|
|
@@ -2467,10 +2624,10 @@ class Mem0Memory {
|
|
|
2467
2624
|
catch { }
|
|
2468
2625
|
}
|
|
2469
2626
|
let connectedModelSummary = '';
|
|
2470
|
-
if (connectedLanguageModel && typeof connectedLanguageModel.invoke === 'function' &&
|
|
2627
|
+
if (connectedLanguageModel && typeof connectedLanguageModel.invoke === 'function' && vectorMemories.length && adv.includeSummary !== false) {
|
|
2471
2628
|
try {
|
|
2472
2629
|
const facts = vectorMemories.slice(0, Number(adv.summaryMaxFacts || 4)).map((memory) => contextMemoryText(memory, 500)).filter(Boolean).join('\n') || '(no vector memories found)';
|
|
2473
|
-
if (facts
|
|
2630
|
+
if (facts) {
|
|
2474
2631
|
const response = await connectedLanguageModel.invoke([
|
|
2475
2632
|
toBaseMessage({
|
|
2476
2633
|
role: 'user',
|
|
@@ -2583,7 +2740,7 @@ class Mem0Memory {
|
|
|
2583
2740
|
const summary = vectorMemories.slice(0, Number(adv.summaryMaxFacts || 4)).map((memory) => contextMemoryText(memory, 360)).filter(Boolean);
|
|
2584
2741
|
const contextText = payload.map((message) => String(message.content || '')).join('\n\n');
|
|
2585
2742
|
const audit = {
|
|
2586
|
-
kind: '
|
|
2743
|
+
kind: 'tembory.context.v1',
|
|
2587
2744
|
userId: key,
|
|
2588
2745
|
project: project || undefined,
|
|
2589
2746
|
query,
|
|
@@ -2654,25 +2811,25 @@ class Mem0Memory {
|
|
|
2654
2811
|
return {
|
|
2655
2812
|
response: {
|
|
2656
2813
|
[memoryKey]: payload,
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2814
|
+
temboryContext: audit,
|
|
2815
|
+
temboryContextText: contextText,
|
|
2816
|
+
temborySummary: summary,
|
|
2817
|
+
temboryConnectedModelSummary: connectedModelSummary,
|
|
2818
|
+
temboryContextHealth: contextHealth,
|
|
2819
|
+
temboryContextQualityScore: contextHealth.quality_score,
|
|
2820
|
+
temboryWorkingMemory: workingMemory,
|
|
2821
|
+
temboryDecisionState: decisionState,
|
|
2822
|
+
temboryMemoryCompression: memoryCompression,
|
|
2823
|
+
temboryProfileFacts: renderProfileFacts(profileFacts),
|
|
2824
|
+
temboryOperationalState: operationalState,
|
|
2825
|
+
temboryActionLedger: actionLedger,
|
|
2826
|
+
temboryEntityTimeline: entityTimeline,
|
|
2827
|
+
temboryVectorMemories: normalizedVectorMemories,
|
|
2828
|
+
temboryGraph: graph,
|
|
2829
|
+
temboryRecentMessages: recentMessages,
|
|
2830
|
+
temboryRecentHighlights: highlights,
|
|
2831
|
+
temboryToolHistory: audit.toolHistory,
|
|
2832
|
+
temboryDiagnostics: diagnostics,
|
|
2676
2833
|
},
|
|
2677
2834
|
};
|
|
2678
2835
|
}
|
|
@@ -2788,6 +2945,7 @@ exports.__private = {
|
|
|
2788
2945
|
isNoisyProfileValue,
|
|
2789
2946
|
approxTokenCount,
|
|
2790
2947
|
contextSizeOfMessages,
|
|
2948
|
+
embedQueryCached,
|
|
2791
2949
|
compactToolResult,
|
|
2792
2950
|
compactToolHistoryForAgent,
|
|
2793
2951
|
compactOperationalStateForAgent,
|
package/package.json
CHANGED
|
@@ -42,20 +42,20 @@ const toolHistory = [
|
|
|
42
42
|
ok: true,
|
|
43
43
|
at: '2026-05-14T05:34:34.017Z',
|
|
44
44
|
source: 'used_tools_text',
|
|
45
|
-
result: '[{"args":{"tool":"agenda_pre_reservar_horario","reservation_id":"RES-
|
|
45
|
+
result: '[{"args":{"tool":"agenda_pre_reservar_horario","reservation_id":"RES-TEMBORY-LAB-001","selected_from_message":"dia 13","status":"pre_reserved","next_step":"confirmar_agendamento"}}]',
|
|
46
46
|
},
|
|
47
47
|
];
|
|
48
48
|
|
|
49
49
|
const vectorMemories = [
|
|
50
50
|
{
|
|
51
|
-
memory: '[Used tools: Tool: agenda_pre_reservar_horario, Input: , Result: [{"args":{"tool":"agenda_pre_reservar_horario","reservation_id":"RES-
|
|
51
|
+
memory: '[Used tools: Tool: agenda_pre_reservar_horario, Input: , Result: [{"args":{"tool":"agenda_pre_reservar_horario","reservation_id":"RES-TEMBORY-LAB-001","selected_from_message":"dia 13","status":"pre_reserved","next_step":"confirmar_agendamento"}}]] Calling agenda_pre_reservar_horario with input: {"id":"call_bfHlltcjI1vCagRkav0fj8Ha"}\nPré-reserva feita para o dia 13.\nSe quiser, posso confirmar agora.',
|
|
52
52
|
created_at: '2026-05-14T05:34:35.373020Z',
|
|
53
|
-
|
|
53
|
+
temboryScore: { semanticScore: 0.71, recencyScore: 0.99, hybridScore: 0.81, source: 'semantic' },
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
memory: '[Used tools: Tool: agenda_consultar_disponibilidade, Input: , Result: [{"args":{"tool":"agenda_consultar_disponibilidade","available_slots":"2026-05-12T09:00,2026-05-12T14:00,2026-05-13T10:30","timezone":"America/Sao_Paulo","next_step":"escolher_um_horario"}}]] Temos estes horários vagos:\n- 12/05 às 09:00\n- 12/05 às 14:00\n- 13/05 às 10:30',
|
|
57
57
|
created_at: '2026-05-14T05:34:14.717988Z',
|
|
58
|
-
|
|
58
|
+
temboryScore: { semanticScore: 0.7, recencyScore: 0.99, hybridScore: 0.8, source: 'semantic' },
|
|
59
59
|
},
|
|
60
60
|
{ memory: 'Oi! Como posso ajudar?', created_at: '2026-05-14T05:33:47.194630Z' },
|
|
61
61
|
{ memory: 'oi', created_at: '2026-05-14T05:33:47.194355Z' },
|
|
@@ -87,7 +87,7 @@ const common = {
|
|
|
87
87
|
toolHistory,
|
|
88
88
|
highlights: [
|
|
89
89
|
'tool agenda_consultar_disponibilidade: [{"args":{"available_slots":"2026-05-12T09:00,2026-05-12T14:00,2026-05-13T10:30"}}]',
|
|
90
|
-
'tool agenda_pre_reservar_horario: [{"args":{"reservation_id":"RES-
|
|
90
|
+
'tool agenda_pre_reservar_horario: [{"args":{"reservation_id":"RES-TEMBORY-LAB-001","status":"pre_reserved"}}]',
|
|
91
91
|
],
|
|
92
92
|
graph: [],
|
|
93
93
|
diagnostics: {},
|
|
@@ -106,7 +106,7 @@ for (const [name, adv] of modes) {
|
|
|
106
106
|
size: core.contextSizeOfMessages(messages),
|
|
107
107
|
has_next_expected_action: /next_expected_action/.test(text),
|
|
108
108
|
has_do_not_repeat_tools: /do_not_repeat_tools/.test(text),
|
|
109
|
-
has_reservation_id: /RES-
|
|
109
|
+
has_reservation_id: /RES-TEMBORY-LAB-001/.test(text),
|
|
110
110
|
has_available_slots: /available_slots/.test(text),
|
|
111
111
|
has_duplicate_calling_text: /Calling agenda_pre_reservar_horario/.test(text),
|
|
112
112
|
}, null, 2));
|