n8n-nodes-tembory 1.0.7 → 1.0.8
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.
|
@@ -928,6 +928,34 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
928
928
|
toolHistoryLastN: 5,
|
|
929
929
|
recentMessagesLastN: 4,
|
|
930
930
|
},
|
|
931
|
+
productionNano: {
|
|
932
|
+
compactForAgent: true,
|
|
933
|
+
includeContextHeader: true,
|
|
934
|
+
includeSummary: true,
|
|
935
|
+
includeScores: false,
|
|
936
|
+
includeDiagnostics: false,
|
|
937
|
+
includeRelations: false,
|
|
938
|
+
includeToolHistory: true,
|
|
939
|
+
includeToolResults: true,
|
|
940
|
+
persistToolFactsToMem0: false,
|
|
941
|
+
includeToolHistorySemanticFallback: false,
|
|
942
|
+
includeProfileFacts: true,
|
|
943
|
+
includeOperationalState: true,
|
|
944
|
+
includeActionLedger: false,
|
|
945
|
+
includeEntityTimeline: false,
|
|
946
|
+
includeWorkingMemory: true,
|
|
947
|
+
includeDecisionState: true,
|
|
948
|
+
includeMemoryCompression: true,
|
|
949
|
+
includeRecentMessages: false,
|
|
950
|
+
includeRecentHighlights: false,
|
|
951
|
+
topK: 4,
|
|
952
|
+
lastN: 4,
|
|
953
|
+
maxReturn: 6,
|
|
954
|
+
toolHistoryLastN: 6,
|
|
955
|
+
recentMessagesLastN: 2,
|
|
956
|
+
vectorMemoryMaxChars: 220,
|
|
957
|
+
contextMaxChars: 6000,
|
|
958
|
+
},
|
|
931
959
|
audit: {
|
|
932
960
|
includeContextHeader: true,
|
|
933
961
|
includeSummary: true,
|
|
@@ -1308,6 +1336,105 @@ const contextMemoryText = (memory, max = 700) => {
|
|
|
1308
1336
|
}
|
|
1309
1337
|
return truncate(text, max);
|
|
1310
1338
|
};
|
|
1339
|
+
const approxTokenCount = (text) => Math.ceil(String(text || '').length / 4);
|
|
1340
|
+
const importantJsonFields = ['reservation_id', 'confirmation_id', 'selected_from_message', 'status', 'next_step', 'available_slots', 'timezone', 'error'];
|
|
1341
|
+
const pickImportantFields = (value) => {
|
|
1342
|
+
if (value === null || value === undefined)
|
|
1343
|
+
return {};
|
|
1344
|
+
const out = {};
|
|
1345
|
+
const visit = (item) => {
|
|
1346
|
+
if (!item || typeof item !== 'object')
|
|
1347
|
+
return;
|
|
1348
|
+
if (Array.isArray(item)) {
|
|
1349
|
+
item.slice(0, 3).forEach(visit);
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
for (const key of importantJsonFields) {
|
|
1353
|
+
if (item[key] !== undefined && out[key] === undefined)
|
|
1354
|
+
out[key] = item[key];
|
|
1355
|
+
}
|
|
1356
|
+
if (item.args)
|
|
1357
|
+
visit(item.args);
|
|
1358
|
+
if (item.result)
|
|
1359
|
+
visit(item.result);
|
|
1360
|
+
};
|
|
1361
|
+
visit(value);
|
|
1362
|
+
return out;
|
|
1363
|
+
};
|
|
1364
|
+
const compactToolResult = (result, max = 360) => {
|
|
1365
|
+
const text = String(result || '');
|
|
1366
|
+
if (!text.trim())
|
|
1367
|
+
return undefined;
|
|
1368
|
+
try {
|
|
1369
|
+
const parsed = JSON.parse(text);
|
|
1370
|
+
const picked = pickImportantFields(parsed);
|
|
1371
|
+
if (Object.keys(picked).length)
|
|
1372
|
+
return truncate(safeStringify(picked), max);
|
|
1373
|
+
}
|
|
1374
|
+
catch { }
|
|
1375
|
+
const picked = {};
|
|
1376
|
+
for (const key of importantJsonFields) {
|
|
1377
|
+
const re = new RegExp(`["']?${key}["']?\\s*[:=]\\s*["']?([^"',}\\]]+)`, 'i');
|
|
1378
|
+
const match = re.exec(text);
|
|
1379
|
+
if (match)
|
|
1380
|
+
picked[key] = match[1];
|
|
1381
|
+
}
|
|
1382
|
+
if (Object.keys(picked).length)
|
|
1383
|
+
return truncate(safeStringify(picked), max);
|
|
1384
|
+
return truncate(text, max);
|
|
1385
|
+
};
|
|
1386
|
+
const compactToolHistoryForAgent = (toolHistory = [], maxItems = 6, includeResults = true) => pruneByLimit(toolHistory || [], maxItems).map((tool) => ({
|
|
1387
|
+
name: tool.name,
|
|
1388
|
+
status: tool.ok === false ? 'failed' : 'ok',
|
|
1389
|
+
at: tool.at,
|
|
1390
|
+
input: truncate(String(tool.input || ''), 180) || undefined,
|
|
1391
|
+
result: includeResults ? compactToolResult(tool.result, 360) : undefined,
|
|
1392
|
+
}));
|
|
1393
|
+
const compactOperationalStateForAgent = (state = {}) => {
|
|
1394
|
+
const agenda = state.agenda_state || {};
|
|
1395
|
+
return {
|
|
1396
|
+
last_tool: state.last_tool || null,
|
|
1397
|
+
tool_counts: state.tool_counts || {},
|
|
1398
|
+
agenda_state: {
|
|
1399
|
+
has_availability: Boolean(agenda.has_availability),
|
|
1400
|
+
has_pre_reservation: Boolean(agenda.has_pre_reservation),
|
|
1401
|
+
has_confirmation: Boolean(agenda.has_confirmation),
|
|
1402
|
+
has_pending_pre_reservation: Boolean(agenda.has_pending_pre_reservation),
|
|
1403
|
+
latest_availability: compactToolResult(agenda.latest_availability_result),
|
|
1404
|
+
latest_pre_reservation: compactToolResult(agenda.latest_pre_reservation_result),
|
|
1405
|
+
latest_confirmation: compactToolResult(agenda.latest_confirmation_result),
|
|
1406
|
+
},
|
|
1407
|
+
blocked_without_context: state.blocked_without_context || [],
|
|
1408
|
+
guidance: (state.guidance || []).slice(0, 3),
|
|
1409
|
+
};
|
|
1410
|
+
};
|
|
1411
|
+
const compactMemoryCompressionForAgent = (compression = {}) => ({
|
|
1412
|
+
turn_summary: (compression.turn_summary || []).slice(-3),
|
|
1413
|
+
session_tools: (((compression.session_summary || {}).tools) || []).slice(-6),
|
|
1414
|
+
agenda_state: ((compression.session_summary || {}).agenda_state) ? {
|
|
1415
|
+
has_availability: Boolean(compression.session_summary.agenda_state.has_availability),
|
|
1416
|
+
has_pre_reservation: Boolean(compression.session_summary.agenda_state.has_pre_reservation),
|
|
1417
|
+
has_confirmation: Boolean(compression.session_summary.agenda_state.has_confirmation),
|
|
1418
|
+
has_pending_pre_reservation: Boolean(compression.session_summary.agenda_state.has_pending_pre_reservation),
|
|
1419
|
+
} : undefined,
|
|
1420
|
+
active_memory_count: ((compression.workflow_summary || {}).active_memory_count) || 0,
|
|
1421
|
+
});
|
|
1422
|
+
const compactVectorMemoriesForAgent = (vectorMemories = [], toolHistory = [], maxItems = 3) => {
|
|
1423
|
+
const hasStructuredTools = Array.isArray(toolHistory) && toolHistory.length > 0;
|
|
1424
|
+
return (vectorMemories || [])
|
|
1425
|
+
.map((memory) => contextMemoryText(memory, 220))
|
|
1426
|
+
.filter(Boolean)
|
|
1427
|
+
.filter((text) => !hasStructuredTools || !/^\[tool_events_extracted\]/i.test(text))
|
|
1428
|
+
.slice(0, maxItems);
|
|
1429
|
+
};
|
|
1430
|
+
const contextSizeOfMessages = (messages = []) => {
|
|
1431
|
+
const perMessage = (messages || []).map((message, index) => {
|
|
1432
|
+
const content = String(message.content || '');
|
|
1433
|
+
return { index, role: message.role || 'system', chars: content.length, approx_tokens: approxTokenCount(content) };
|
|
1434
|
+
});
|
|
1435
|
+
const chars = perMessage.reduce((sum, item) => sum + item.chars, 0);
|
|
1436
|
+
return { chars, approx_tokens: approxTokenCount((messages || []).map((m) => m.content || '').join('\n')), messages: perMessage };
|
|
1437
|
+
};
|
|
1311
1438
|
const wrapElefaiMemory = (memory, ctx, memoryKey) => new Proxy(memory, {
|
|
1312
1439
|
get(target, prop) {
|
|
1313
1440
|
if (prop === 'loadMemoryVariables') {
|
|
@@ -1377,13 +1504,80 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
1377
1504
|
const includeHeader = adv.includeContextHeader !== false;
|
|
1378
1505
|
const includeSummary = adv.includeSummary !== false;
|
|
1379
1506
|
const includeScores = adv.includeScores !== false;
|
|
1507
|
+
const compactForAgent = Boolean(adv.compactForAgent);
|
|
1380
1508
|
const sections = [];
|
|
1381
1509
|
if (includeHeader) {
|
|
1382
1510
|
sections.push({
|
|
1383
1511
|
section: 'context_header',
|
|
1384
1512
|
title: 'Tembory context',
|
|
1385
|
-
value:
|
|
1513
|
+
value: compactForAgent
|
|
1514
|
+
? '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
|
+
: '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
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
if (compactForAgent) {
|
|
1519
|
+
if (includeSummary) {
|
|
1520
|
+
const summary = compactVectorMemoriesForAgent(vectorMemories, toolHistory, Number(adv.summaryMaxFacts || 3));
|
|
1521
|
+
sections.push({ section: 'summary', title: 'Summary', value: summary.length ? summary : null, why_null: summary.length ? undefined : 'no non-tool vector memories to summarize' });
|
|
1522
|
+
}
|
|
1523
|
+
sections.push({
|
|
1524
|
+
section: 'working_memory',
|
|
1525
|
+
title: 'Working memory',
|
|
1526
|
+
value: adv.includeWorkingMemory === false ? null : (workingMemory || {}),
|
|
1527
|
+
why_null: adv.includeWorkingMemory === false ? 'working memory disabled' : undefined,
|
|
1386
1528
|
});
|
|
1529
|
+
sections.push({
|
|
1530
|
+
section: 'decision_state',
|
|
1531
|
+
title: 'Decision state',
|
|
1532
|
+
value: adv.includeDecisionState === false ? null : (decisionState || {}),
|
|
1533
|
+
why_null: adv.includeDecisionState === false ? 'decision state disabled' : undefined,
|
|
1534
|
+
});
|
|
1535
|
+
sections.push({
|
|
1536
|
+
section: 'operational_state',
|
|
1537
|
+
title: 'Operational state',
|
|
1538
|
+
value: adv.includeOperationalState === false ? null : compactOperationalStateForAgent(operationalState || {}),
|
|
1539
|
+
why_null: adv.includeOperationalState === false ? 'operational state disabled' : undefined,
|
|
1540
|
+
});
|
|
1541
|
+
sections.push({
|
|
1542
|
+
section: 'tool_history',
|
|
1543
|
+
title: 'Tool history',
|
|
1544
|
+
value: {
|
|
1545
|
+
enabled: adv.includeToolHistory !== false,
|
|
1546
|
+
items: adv.includeToolHistory === false ? [] : compactToolHistoryForAgent(toolHistory, adv.toolHistoryLastN || 6, adv.includeToolResults !== false),
|
|
1547
|
+
},
|
|
1548
|
+
});
|
|
1549
|
+
sections.push({
|
|
1550
|
+
section: 'profile_facts',
|
|
1551
|
+
title: 'Profile facts',
|
|
1552
|
+
value: adv.includeProfileFacts === false ? null : renderProfileFacts(profileFacts),
|
|
1553
|
+
why_null: adv.includeProfileFacts === false ? 'profile facts disabled' : undefined,
|
|
1554
|
+
});
|
|
1555
|
+
sections.push({
|
|
1556
|
+
section: 'memory_compression',
|
|
1557
|
+
title: 'Memory compression',
|
|
1558
|
+
value: adv.includeMemoryCompression === false ? null : compactMemoryCompressionForAgent(memoryCompression || {}),
|
|
1559
|
+
why_null: adv.includeMemoryCompression === false ? 'memory compression disabled' : undefined,
|
|
1560
|
+
});
|
|
1561
|
+
const audit = {
|
|
1562
|
+
kind: 'elefai.brain.context.v1',
|
|
1563
|
+
meta: { user_id: userId, payloadFormat, query, compact_for_agent: true },
|
|
1564
|
+
sections,
|
|
1565
|
+
diagnostics,
|
|
1566
|
+
};
|
|
1567
|
+
const renderCompactSection = (section) => {
|
|
1568
|
+
if (section.value === null || section.value === undefined)
|
|
1569
|
+
return `## ${section.title}\n${section.why_null || 'empty'}`;
|
|
1570
|
+
if (typeof section.value === 'string')
|
|
1571
|
+
return `## ${section.title}\n${section.value}`;
|
|
1572
|
+
if (Array.isArray(section.value))
|
|
1573
|
+
return `## ${section.title}\n${section.value.length ? section.value.map((item) => typeof item === 'string' ? `- ${item}` : `- ${truncate(safeStringify(item), 420)}`).join('\n') : '(empty)'}`;
|
|
1574
|
+
return `## ${section.title}\n${truncate(safeStringify(section.value), 900)}`;
|
|
1575
|
+
};
|
|
1576
|
+
if (payloadFormat === 'auditJson')
|
|
1577
|
+
return [{ role: 'system', content: JSON.stringify(audit, null, 2) }];
|
|
1578
|
+
if (payloadFormat === 'auditBlocks')
|
|
1579
|
+
return sections.map((section) => ({ role: 'system', content: renderCompactSection(section) }));
|
|
1580
|
+
return [{ role: 'system', content: truncate(sections.map(renderCompactSection).join('\n\n'), Number(adv.contextMaxChars || 6000)) }];
|
|
1387
1581
|
}
|
|
1388
1582
|
if (includeSummary) {
|
|
1389
1583
|
const summary = vectorMemories.slice(0, Number(adv.summaryMaxFacts || 4)).map((memory) => contextMemoryText(memory, 360)).filter(Boolean);
|
|
@@ -1654,6 +1848,7 @@ class Mem0Memory {
|
|
|
1654
1848
|
{ name: 'Diagnóstico Completo', value: 'diagnostic' },
|
|
1655
1849
|
{ name: 'Produção Balanceada', value: 'productionBalanced' },
|
|
1656
1850
|
{ name: 'Produção Econômica', value: 'productionCheap' },
|
|
1851
|
+
{ name: 'Produção Nano/SLM', value: 'productionNano' },
|
|
1657
1852
|
{ name: 'Auditoria', value: 'audit' },
|
|
1658
1853
|
],
|
|
1659
1854
|
default: 'custom',
|
|
@@ -1673,6 +1868,8 @@ class Mem0Memory {
|
|
|
1673
1868
|
{ displayName: 'MMR (diversidade)', name: 'mmr', type: 'boolean', default: true, description: 'Aplicar diversidade de resultados (Maximal Marginal Relevance)', displayOptions: { show: { '/retrievalMode': ['hybrid'] } } },
|
|
1674
1869
|
{ 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'] } } },
|
|
1675
1870
|
{ displayName: 'Incluir Cabeçalho de Contexto', name: 'includeContextHeader', type: 'boolean', default: true },
|
|
1871
|
+
{ 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: 'Máximo de Caracteres do Contexto', name: 'contextMaxChars', type: 'number', default: 6000, description: 'Limite final aplicado quando Compactar Contexto Para Agente estiver ativo.' },
|
|
1676
1873
|
{ displayName: 'Incluir Resumo', name: 'includeSummary', type: 'boolean', default: true },
|
|
1677
1874
|
{ displayName: 'Máximo de Fatos no Resumo', name: 'summaryMaxFacts', type: 'number', default: 4 },
|
|
1678
1875
|
{ displayName: 'Incluir Scores', name: 'includeScores', type: 'boolean', default: true },
|
|
@@ -2362,6 +2559,7 @@ class Mem0Memory {
|
|
|
2362
2559
|
diagnostics,
|
|
2363
2560
|
adv,
|
|
2364
2561
|
});
|
|
2562
|
+
diagnostics.contextSize = contextSizeOfMessages(payload);
|
|
2365
2563
|
const normalizedVectorMemories = vectorMemories.map((m) => {
|
|
2366
2564
|
const scoreMeta = scoreMetaOf(m);
|
|
2367
2565
|
const rawScore = scoreOf(m);
|
|
@@ -2404,6 +2602,7 @@ class Mem0Memory {
|
|
|
2404
2602
|
includeOperationalState: adv.includeOperationalState !== false,
|
|
2405
2603
|
includeActionLedger: adv.includeActionLedger !== false,
|
|
2406
2604
|
includeEntityTimeline: adv.includeEntityTimeline !== false,
|
|
2605
|
+
compactForAgent: Boolean(adv.compactForAgent),
|
|
2407
2606
|
includeWorkingMemory: adv.includeWorkingMemory !== false,
|
|
2408
2607
|
includeDecisionState: adv.includeDecisionState !== false,
|
|
2409
2608
|
includeMemoryCompression: adv.includeMemoryCompression !== false,
|
|
@@ -2587,4 +2786,9 @@ exports.__private = {
|
|
|
2587
2786
|
mergeProfileFacts,
|
|
2588
2787
|
renderProfileFacts,
|
|
2589
2788
|
isNoisyProfileValue,
|
|
2789
|
+
approxTokenCount,
|
|
2790
|
+
contextSizeOfMessages,
|
|
2791
|
+
compactToolResult,
|
|
2792
|
+
compactToolHistoryForAgent,
|
|
2793
|
+
compactOperationalStateForAgent,
|
|
2590
2794
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-tembory",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Tembory node for n8n AI Agents with profile, tools, timeline, graph and semantic memory",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://tembory.com",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"lintfix": "tslint --fix -p tsconfig.json -c tslint.json",
|
|
25
25
|
"test": "node --test test/*.test.js",
|
|
26
26
|
"smoke:n8n:multiturn": "node scripts/smoke-n8n-multiturn-tools.js",
|
|
27
|
-
"
|
|
27
|
+
"simulate:agent-context": "node scripts/simulate-agent-context.js",
|
|
28
|
+
"prepublishOnly": "npm test"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
30
31
|
"dist",
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const Module = require('node:module');
|
|
3
|
+
|
|
4
|
+
const originalLoad = Module._load;
|
|
5
|
+
Module._load = function patchedLoad(request, parent, isMain) {
|
|
6
|
+
if (request === 'n8n-workflow') {
|
|
7
|
+
return {
|
|
8
|
+
NodeConnectionTypes: {
|
|
9
|
+
AiMemory: 'ai_memory',
|
|
10
|
+
AiLanguageModel: 'ai_languageModel',
|
|
11
|
+
AiEmbedding: 'ai_embedding',
|
|
12
|
+
},
|
|
13
|
+
NodeApiError: class NodeApiError extends Error {},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (request === '@langchain/core/messages') {
|
|
17
|
+
return {
|
|
18
|
+
HumanMessage: class HumanMessage { constructor(content) { this.content = content; } _getType() { return 'human'; } },
|
|
19
|
+
AIMessage: class AIMessage { constructor(content) { this.content = content; } _getType() { return 'ai'; } },
|
|
20
|
+
SystemMessage: class SystemMessage { constructor(content) { this.content = content; } _getType() { return 'system'; } },
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return originalLoad.call(this, request, parent, isMain);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const core = require('../dist/nodes/Mem0/Mem0Memory.node.js').__private;
|
|
27
|
+
|
|
28
|
+
const toolHistory = [
|
|
29
|
+
{
|
|
30
|
+
id: 'tool_ry3twg',
|
|
31
|
+
name: 'agenda_consultar_disponibilidade',
|
|
32
|
+
input: '',
|
|
33
|
+
ok: true,
|
|
34
|
+
at: '2026-05-14T05:34:12.460Z',
|
|
35
|
+
source: 'used_tools_text',
|
|
36
|
+
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"}}]',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'tool_mu9qd2',
|
|
40
|
+
name: 'agenda_pre_reservar_horario',
|
|
41
|
+
input: '',
|
|
42
|
+
ok: true,
|
|
43
|
+
at: '2026-05-14T05:34:34.017Z',
|
|
44
|
+
source: 'used_tools_text',
|
|
45
|
+
result: '[{"args":{"tool":"agenda_pre_reservar_horario","reservation_id":"RES-ELEFAI-LAB-001","selected_from_message":"dia 13","status":"pre_reserved","next_step":"confirmar_agendamento"}}]',
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
const vectorMemories = [
|
|
50
|
+
{
|
|
51
|
+
memory: '[Used tools: Tool: agenda_pre_reservar_horario, Input: , Result: [{"args":{"tool":"agenda_pre_reservar_horario","reservation_id":"RES-ELEFAI-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
|
+
created_at: '2026-05-14T05:34:35.373020Z',
|
|
53
|
+
elefaiScore: { semanticScore: 0.71, recencyScore: 0.99, hybridScore: 0.81, source: 'semantic' },
|
|
54
|
+
},
|
|
55
|
+
{
|
|
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
|
+
created_at: '2026-05-14T05:34:14.717988Z',
|
|
58
|
+
elefaiScore: { semanticScore: 0.7, recencyScore: 0.99, hybridScore: 0.8, source: 'semantic' },
|
|
59
|
+
},
|
|
60
|
+
{ memory: 'Oi! Como posso ajudar?', created_at: '2026-05-14T05:33:47.194630Z' },
|
|
61
|
+
{ memory: 'oi', created_at: '2026-05-14T05:33:47.194355Z' },
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const operationalState = core.deriveOperationalState(toolHistory, {}, [], true);
|
|
65
|
+
const workingMemory = {
|
|
66
|
+
current_goal: 'call agenda_confirmar_agendamento now; do not ask the same confirmation question again',
|
|
67
|
+
current_task: 'call agenda_confirmar_agendamento now; do not ask the same confirmation question again',
|
|
68
|
+
last_user_intent: 'affirm',
|
|
69
|
+
last_user_message: 'ok',
|
|
70
|
+
next_expected_action: 'call agenda_confirmar_agendamento now; do not ask the same confirmation question again',
|
|
71
|
+
};
|
|
72
|
+
const decisionState = core.deriveDecisionState({ query: 'ok', toolHistory, operationalState, workingMemory });
|
|
73
|
+
const memoryCompression = core.deriveMemoryCompression({ toolHistory, operationalState, vectorMemories });
|
|
74
|
+
const common = {
|
|
75
|
+
payloadFormat: 'structured',
|
|
76
|
+
query: 'ok',
|
|
77
|
+
userId: 'd48292bd4c9f4eccb9120092e3acd073',
|
|
78
|
+
profileFacts: {},
|
|
79
|
+
workingMemory,
|
|
80
|
+
decisionState,
|
|
81
|
+
memoryCompression,
|
|
82
|
+
operationalState,
|
|
83
|
+
actionLedger: core.deriveActionLedger(toolHistory, 20, true),
|
|
84
|
+
entityTimeline: core.deriveEntityTimeline({}, [], [], toolHistory),
|
|
85
|
+
vectorMemories,
|
|
86
|
+
recentMessages: [],
|
|
87
|
+
toolHistory,
|
|
88
|
+
highlights: [
|
|
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-ELEFAI-LAB-001","status":"pre_reserved"}}]',
|
|
91
|
+
],
|
|
92
|
+
graph: [],
|
|
93
|
+
diagnostics: {},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const modes = [
|
|
97
|
+
['productionBalanced', core.applyOperationalPreset({ operationPreset: 'productionBalanced' })],
|
|
98
|
+
['productionNano', core.applyOperationalPreset({ operationPreset: 'productionNano' })],
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
for (const [name, adv] of modes) {
|
|
102
|
+
const messages = core.buildContextMessages({ ...common, adv });
|
|
103
|
+
const text = messages.map((message) => message.content).join('\n\n');
|
|
104
|
+
console.log(JSON.stringify({
|
|
105
|
+
mode: name,
|
|
106
|
+
size: core.contextSizeOfMessages(messages),
|
|
107
|
+
has_next_expected_action: /next_expected_action/.test(text),
|
|
108
|
+
has_do_not_repeat_tools: /do_not_repeat_tools/.test(text),
|
|
109
|
+
has_reservation_id: /RES-ELEFAI-LAB-001/.test(text),
|
|
110
|
+
has_available_slots: /available_slots/.test(text),
|
|
111
|
+
has_duplicate_calling_text: /Calling agenda_pre_reservar_horario/.test(text),
|
|
112
|
+
}, null, 2));
|
|
113
|
+
}
|