n8n-nodes-tembory 1.3.4 → 1.3.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.
package/README.md
CHANGED
|
@@ -2,7 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
Node de memoria operacional da Tembory para agentes de IA no n8n.
|
|
4
4
|
|
|
5
|
-
Versao atual: `1.3.
|
|
5
|
+
Versao atual: `1.3.6`.
|
|
6
|
+
|
|
7
|
+
## 1.3.6
|
|
8
|
+
|
|
9
|
+
- Fortalece o default recomendado para agentes mini/SLM em workflows reais.
|
|
10
|
+
- `Memoria Inteligente (Recomendado)` agora usa `productionBalanced` com contexto de 20000 caracteres, entrada do SLM em 12000 caracteres, resumo SLM em 3000 caracteres e active summary em 3500 caracteres.
|
|
11
|
+
- Mantem 30 tools recentes no contexto operacional e TTL de tool history em 86400 segundos.
|
|
12
|
+
- Alinha os defaults visiveis em `Ajustes Tecnicos` para nao mostrar configuracao mais fraca quando o usuario abre os grupos.
|
|
13
|
+
- Esclarece que o cache tecnico SLM usa segundos; 300 segundos equivalem a 5 minutos.
|
|
14
|
+
|
|
15
|
+
## 1.3.5
|
|
16
|
+
|
|
17
|
+
- Atualiza o `Tembory Agent Memory` para usuarios leigos: o padrao agora e `Modo da Memoria -> Memoria Inteligente (Recomendado)`.
|
|
18
|
+
- Esse modo aplica `productionBalanced` sem exigir que a pessoa abra ajustes tecnicos: contexto estruturado, active summary, tool history/results, action ledger, decision state, operational state e mensagens recentes ficam ligados por padrao.
|
|
19
|
+
- Renomeia campos visiveis para linguagem operacional: `Tamanho do Contexto`, `Mensagens Recentes`, `Mostrar Evidencias no Output` e `Mostrar Ajustes Tecnicos`.
|
|
20
|
+
- Mantem os controles brutos escondidos em `Ajustes Tecnicos Tembory`, para debug e casos avancados, sem tornar isso obrigatorio para o usuario comum.
|
|
6
21
|
|
|
7
22
|
## 1.3.4
|
|
8
23
|
|
|
@@ -213,13 +228,18 @@ No modo simples, o node aplica automaticamente:
|
|
|
213
228
|
|
|
214
229
|
- `Modo de Recuperacao`: operacional estruturado.
|
|
215
230
|
- `Formato do Contexto`: producao estruturado.
|
|
216
|
-
- `Preset Operacional`: producao
|
|
217
|
-
- `Fonte do Resumo do SLM`:
|
|
231
|
+
- `Preset Operacional`: producao balanceada.
|
|
232
|
+
- `Fonte do Resumo do SLM`: automatica.
|
|
233
|
+
- `Maximo de Caracteres do Contexto`: 20000.
|
|
234
|
+
- `Maximo de Caracteres de Entrada do SLM`: 12000.
|
|
235
|
+
- `Maximo de Caracteres do Resumo do SLM`: 3000.
|
|
236
|
+
- `Maximo de Caracteres do Active Summary`: 3500.
|
|
218
237
|
- Tool history, resultados de tools, action ledger, working memory, decision state, operational state e memory compression ligados.
|
|
219
238
|
- Persistencia no backend e active summary ligados.
|
|
220
239
|
- Diagnostico pesado, scores, semantic fallback e tool facts desligados.
|
|
221
|
-
-
|
|
222
|
-
-
|
|
240
|
+
- Cache tecnico do SLM em 300 segundos.
|
|
241
|
+
- TTL de tool history em 86400 segundos.
|
|
242
|
+
- Ultimas tools mantidas no contexto compacto: 30.
|
|
223
243
|
|
|
224
244
|
## Uso com `$fromAI()`
|
|
225
245
|
|
|
@@ -245,8 +265,8 @@ Exemplo de budget:
|
|
|
245
265
|
{
|
|
246
266
|
"agentContextBudget": {
|
|
247
267
|
"messages": 1,
|
|
248
|
-
"chars":
|
|
249
|
-
"approxTokens":
|
|
268
|
+
"chars": 12000,
|
|
269
|
+
"approxTokens": 3000,
|
|
250
270
|
"largestSections": [
|
|
251
271
|
{ "section": "tools", "chars": 1600, "approxTokens": 400 }
|
|
252
272
|
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.assertTemboryCredentials = assertTemboryCredentials;
|
|
4
3
|
exports.temboryApiRequest = temboryApiRequest;
|
|
4
|
+
exports.assertTemboryCredentials = assertTemboryCredentials;
|
|
5
5
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
6
|
async function getTemboryCredentials(ctx) {
|
|
7
7
|
try {
|
|
@@ -15,14 +15,10 @@ async function getTemboryCredentials(ctx) {
|
|
|
15
15
|
throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Credentials for Tembory are not set. Select a Tembory API credential and save the workflow.');
|
|
16
16
|
}
|
|
17
17
|
async function assertTemboryCredentials(ctx) {
|
|
18
|
-
|
|
19
|
-
if (!credentials || !credentials.apiKey) {
|
|
20
|
-
throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Tembory API credential is missing an API key. Configure a valid Tembory API credential before using this memory node.');
|
|
21
|
-
}
|
|
22
|
-
return credentials;
|
|
18
|
+
await getTemboryCredentials(ctx);
|
|
23
19
|
}
|
|
24
20
|
async function temboryApiRequest(method, endpoint, body = {}, qs = {}) {
|
|
25
|
-
const credentials = await
|
|
21
|
+
const credentials = await getTemboryCredentials(this);
|
|
26
22
|
const baseUrl = 'https://api.tembory.com';
|
|
27
23
|
const operation = resolveGatewayOperation(method, endpoint);
|
|
28
24
|
const payload = {
|
|
@@ -1333,8 +1333,8 @@ const mergeRemoteThreadState = (store, key, state) => {
|
|
|
1333
1333
|
store.activeSummary[key] = state.activeSummary;
|
|
1334
1334
|
};
|
|
1335
1335
|
const SIMPLE_MODE_OVERRIDES = {
|
|
1336
|
-
operationPreset: '
|
|
1337
|
-
summarySource: '
|
|
1336
|
+
operationPreset: 'productionBalanced',
|
|
1337
|
+
summarySource: 'auto',
|
|
1338
1338
|
includeContextHeader: true,
|
|
1339
1339
|
compactStateSections: true,
|
|
1340
1340
|
includeSummary: true,
|
|
@@ -1357,13 +1357,13 @@ const SIMPLE_MODE_OVERRIDES = {
|
|
|
1357
1357
|
includeDiagnostics: false,
|
|
1358
1358
|
persistToolFactsToTembory: false,
|
|
1359
1359
|
includeToolHistorySemanticFallback: false,
|
|
1360
|
-
contextMaxChars:
|
|
1361
|
-
toolHistoryLastN:
|
|
1362
|
-
toolHistoryTTLSeconds:
|
|
1360
|
+
contextMaxChars: 20000,
|
|
1361
|
+
toolHistoryLastN: 30,
|
|
1362
|
+
toolHistoryTTLSeconds: 86400,
|
|
1363
1363
|
recentMessagesLastN: 50,
|
|
1364
|
-
connectedModelSummaryInputMaxChars:
|
|
1365
|
-
connectedModelSummaryMaxChars:
|
|
1366
|
-
activeSummaryMaxChars:
|
|
1364
|
+
connectedModelSummaryInputMaxChars: 12000,
|
|
1365
|
+
connectedModelSummaryMaxChars: 3000,
|
|
1366
|
+
activeSummaryMaxChars: 3500,
|
|
1367
1367
|
activeSummaryRetentionDays: 30,
|
|
1368
1368
|
};
|
|
1369
1369
|
const applyOperationalPreset = (advanced = {}) => {
|
|
@@ -1445,7 +1445,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1445
1445
|
includeConnectedModelSummary: true,
|
|
1446
1446
|
includeActiveSummary: true,
|
|
1447
1447
|
persistActiveSummary: true,
|
|
1448
|
-
activeSummaryMaxChars:
|
|
1448
|
+
activeSummaryMaxChars: 3500,
|
|
1449
1449
|
activeSummaryRetentionDays: 30,
|
|
1450
1450
|
enableTransientSummaryCache: true,
|
|
1451
1451
|
transientSummaryCacheTTLSeconds: 300,
|
|
@@ -1471,12 +1471,14 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1471
1471
|
includeRecentHighlights: true,
|
|
1472
1472
|
topK: 6,
|
|
1473
1473
|
lastN: 8,
|
|
1474
|
-
toolHistoryLastN:
|
|
1474
|
+
toolHistoryLastN: 30,
|
|
1475
|
+
toolHistoryTTLSeconds: 86400,
|
|
1475
1476
|
recentMessagesLastN: 50,
|
|
1476
1477
|
vectorMemoryMaxChars: 360,
|
|
1477
|
-
contextMaxChars:
|
|
1478
|
-
connectedModelSummaryMaxChars:
|
|
1479
|
-
connectedModelSummaryInputMaxChars:
|
|
1478
|
+
contextMaxChars: 20000,
|
|
1479
|
+
connectedModelSummaryMaxChars: 3000,
|
|
1480
|
+
connectedModelSummaryInputMaxChars: 12000,
|
|
1481
|
+
summaryMaxFacts: 8,
|
|
1480
1482
|
},
|
|
1481
1483
|
productionCheap: {
|
|
1482
1484
|
summarySource: 'activeContext',
|
|
@@ -1648,6 +1650,7 @@ const readAdvancedOptions = (ctx, itemIndex) => {
|
|
|
1648
1650
|
};
|
|
1649
1651
|
readTopLevelOverride('contextMaxChars');
|
|
1650
1652
|
readTopLevelOverride('recentMessagesLastN');
|
|
1653
|
+
readTopLevelOverride('operationPreset');
|
|
1651
1654
|
try {
|
|
1652
1655
|
const debugVisualOutput = ctx.getNodeParameter('debugVisualOutput', itemIndex, undefined);
|
|
1653
1656
|
if (debugVisualOutput !== undefined) {
|
|
@@ -2054,7 +2057,7 @@ const turnBriefGuidanceForIntent = (intent = '') => {
|
|
|
2054
2057
|
return 'May require a tool. Use prompt policy. Prior tools are evidence only; do not claim new side effects without a current required tool call.';
|
|
2055
2058
|
if (intent === 'profile_update')
|
|
2056
2059
|
return 'Likely stable profile data. Save useful facts and continue; call tools only when prompt requires.';
|
|
2057
|
-
return '
|
|
2060
|
+
return 'Continue according to the agent prompt using conversation, tool history and operational state as read-only context.';
|
|
2058
2061
|
};
|
|
2059
2062
|
const buildTurnBriefForAgent = ({ query = '', recentMessages = [], toolHistory = [], operationalState = {}, workingMemory = {}, decisionState = {}, diagnostics = {} }) => {
|
|
2060
2063
|
const currentIntent = (decisionState || {}).current_intent || (workingMemory || {}).last_user_intent || inferUserIntent(query, recentMessages);
|
|
@@ -2182,7 +2185,7 @@ const inferUserIntent = (query = '', recentMessages = []) => {
|
|
|
2182
2185
|
};
|
|
2183
2186
|
const deriveNextExpectedAction = (intent, operationalState = {}) => {
|
|
2184
2187
|
if (['affirm', 'commit_or_continue', 'tool_action_candidate', 'selection_or_slot'].includes(intent))
|
|
2185
|
-
return '
|
|
2188
|
+
return 'current turn needs a tool; continue according to the agent prompt using conversation_frame, tool_state, tool_history and action_ledger; do not apply domain-specific memory rules';
|
|
2186
2189
|
if (intent === 'profile_update')
|
|
2187
2190
|
return 'save stable profile facts and continue the conversation';
|
|
2188
2191
|
if (intent === 'conversation_recall')
|
|
@@ -2191,7 +2194,7 @@ const deriveNextExpectedAction = (intent, operationalState = {}) => {
|
|
|
2191
2194
|
return 'answer status questions from tool_state, tool_history and action_ledger; do not call tools unless the agent prompt requires it';
|
|
2192
2195
|
return undefined;
|
|
2193
2196
|
};
|
|
2194
|
-
const isGenericMemoryNextAction = (value = '') => /answer using retrieved context and avoid unnecessary tool calls|continue according to the agent prompt using retrieved context
|
|
2197
|
+
const isGenericMemoryNextAction = (value = '') => /answer using retrieved context and avoid unnecessary tool calls|continue according to the agent prompt using retrieved context/i.test(String(value || ''));
|
|
2195
2198
|
const shouldCarryPreviousGoal = (intent = '', previousGoal = '') => {
|
|
2196
2199
|
if (!previousGoal || isGenericMemoryNextAction(previousGoal))
|
|
2197
2200
|
return false;
|
|
@@ -3231,14 +3234,6 @@ const buildAgentContextV2 = ({ query = '', userId = '', payloadFormat = 'structu
|
|
|
3231
3234
|
memory: cleanContextValue({
|
|
3232
3235
|
slmSummary: connectedModelSummary ? truncate(connectedModelSummary, Number(adv.connectedModelSummaryMaxChars || 900)) : undefined,
|
|
3233
3236
|
activeSummary: !connectedModelSummary && activeSummary ? truncate(activeSummary, Number(adv.activeSummaryMaxChars || 900)) : undefined,
|
|
3234
|
-
summaryStatus: diagnostics?.activeSummary ? cleanContextValue({
|
|
3235
|
-
source: diagnostics.activeSummary.source,
|
|
3236
|
-
generated: Boolean(connectedModelSummary),
|
|
3237
|
-
activeSummaryLoaded: Boolean(diagnostics.activeSummary.activeSummaryLoaded),
|
|
3238
|
-
activeSummaryUpdated: Boolean(diagnostics.activeSummary.activeSummaryUpdated),
|
|
3239
|
-
transientCacheHit: Boolean(diagnostics.activeSummary.transientCacheHit),
|
|
3240
|
-
chars: diagnostics.activeSummary.summaryChars,
|
|
3241
|
-
}) : undefined,
|
|
3242
3237
|
referenceFacts,
|
|
3243
3238
|
compression: adv.includeMemoryCompression === false ? undefined : compactMemoryCompressionForAgent(memoryCompression || {}),
|
|
3244
3239
|
}),
|
|
@@ -3360,7 +3355,7 @@ const invokeConnectedModelSummary = async (connectedLanguageModel, summaryInput,
|
|
|
3360
3355
|
const response = await connectedLanguageModel.invoke([
|
|
3361
3356
|
toBaseMessage({
|
|
3362
3357
|
role: 'user',
|
|
3363
|
-
content: `Update the Tembory active summary for the next agent turn. Return only concise Portuguese bullets, no JSON and no markdown table.
|
|
3358
|
+
content: `Update the Tembory active summary for the next agent turn. Return only concise Portuguese bullets, no JSON and no markdown table. Preserve IDs, dates, tool names, confirmed decisions, explicit pending actions, constraints, contradictions, and do-not-repeat instructions. Prefer durable useful context over raw logs. Do not invent facts. Treat inferred gaps or missing details as read-only observations, not action requirements, unless they are explicitly present in tool_state, action_ledger, working_memory.next_expected_action, or the current user message. Do not convert observations, guesses, or helpful suggestions into blocking pending actions. Do-not-repeat means avoiding duplicate prerequisite lookup calls; it never means a current side-effect action is completed without a successful tool call in the current turn.\n\nContext:\n${summaryInput}`,
|
|
3364
3359
|
}),
|
|
3365
3360
|
]);
|
|
3366
3361
|
return cleanModelSummaryText(response, Number(adv.connectedModelSummaryMaxChars || 1200));
|
|
@@ -3548,15 +3543,13 @@ const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory
|
|
|
3548
3543
|
const toolEvents = compactToolEventsForSideChannel(toolCalls, SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX);
|
|
3549
3544
|
const conversation = conversationDigestFromMessagesForSideChannel(chatHistory);
|
|
3550
3545
|
const timeline = conversationTimelineFromMessagesForSideChannel(chatHistory, 16);
|
|
3546
|
+
const toolLog = buildToolLogForSideChannel(toolEvents, toolCalls.length, SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX);
|
|
3551
3547
|
return cleanContextValue({
|
|
3552
3548
|
visualSchema: VISUAL_SCHEMA_VERSION,
|
|
3553
|
-
summary:
|
|
3554
|
-
action: 'saveContext',
|
|
3549
|
+
summary: {
|
|
3555
3550
|
messagesAfterSave: Array.isArray(chatHistory) ? chatHistory.length : 0,
|
|
3556
|
-
userInputPreview: inputMessage ? truncate(String(inputMessage), 220) : undefined,
|
|
3557
|
-
assistantOutputPreview: outputMessage ? truncate(String(outputMessage), 260) : undefined,
|
|
3558
3551
|
toolCallsCaptured: toolCalls.length,
|
|
3559
|
-
}
|
|
3552
|
+
},
|
|
3560
3553
|
conversation: cleanContextValue({
|
|
3561
3554
|
...conversation,
|
|
3562
3555
|
timeline,
|
|
@@ -3568,11 +3561,7 @@ const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory
|
|
|
3568
3561
|
tools: cleanContextValue({
|
|
3569
3562
|
captured: toolCalls.length,
|
|
3570
3563
|
capture: summarizeToolCaptureForSideChannel(output, toolCalls),
|
|
3571
|
-
log:
|
|
3572
|
-
}),
|
|
3573
|
-
save: cleanContextValue({
|
|
3574
|
-
messagesAfterSave: Array.isArray(chatHistory) ? chatHistory.length : 0,
|
|
3575
|
-
status: 'saved_to_memory_contract',
|
|
3564
|
+
log: toolLog,
|
|
3576
3565
|
}),
|
|
3577
3566
|
});
|
|
3578
3567
|
};
|
|
@@ -3597,14 +3586,12 @@ const compactMemoryEventPayload = (payload = {}) => {
|
|
|
3597
3586
|
compact[`${key}Chars`] = typeof compact[key] === 'string' ? compact[key].length : safeStringify(compact[key]).length;
|
|
3598
3587
|
delete compact[key];
|
|
3599
3588
|
}
|
|
3600
|
-
return
|
|
3589
|
+
return compact;
|
|
3601
3590
|
};
|
|
3602
3591
|
const compactVisualSummaryForMode = (summary = {}, configurationMode = 'advanced') => {
|
|
3603
3592
|
const compact = { ...(summary || {}) };
|
|
3604
3593
|
if (String(configurationMode || 'advanced') !== 'simple')
|
|
3605
3594
|
return compact;
|
|
3606
|
-
delete compact.toolNames;
|
|
3607
|
-
delete compact.toolEvents;
|
|
3608
3595
|
delete compact.savedMessages;
|
|
3609
3596
|
return compact;
|
|
3610
3597
|
};
|
|
@@ -3792,20 +3779,10 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3792
3779
|
toolCallsCaptured: parsed.captureHealth?.toolCallsCapturedLastSave,
|
|
3793
3780
|
captureSources: parsed.captureHealth?.captureSources,
|
|
3794
3781
|
} : {}));
|
|
3795
|
-
const summaryStatus = parsed.memory?.summaryStatus || parsed.diagnostics?.activeSummary || {};
|
|
3796
|
-
const slmPreview = parsed.memory?.slmSummary || parsed.memory?.activeSummary || summaryText || '';
|
|
3797
3782
|
const fullDedupeSummary = parsed.dedupeSummary || parsed.diagnostics?.dedupeSummary || undefined;
|
|
3798
3783
|
const loadedSections = loadedSectionsForSideChannel(parsed, memoryAudit);
|
|
3799
3784
|
const agentContextBudget = agentContextBudgetForSideChannel(list, parsed);
|
|
3800
3785
|
summary.visualSchema = VISUAL_SCHEMA_VERSION;
|
|
3801
|
-
summary.sentToAgent = cleanContextValue({
|
|
3802
|
-
messages: list.length,
|
|
3803
|
-
contextKind: parsed.kind,
|
|
3804
|
-
schemaVersion: parsed.schemaVersion,
|
|
3805
|
-
chars: agentContextBudget.chars,
|
|
3806
|
-
approxTokens: agentContextBudget.approxTokens,
|
|
3807
|
-
largestSections: agentContextBudget.largestSections,
|
|
3808
|
-
});
|
|
3809
3786
|
summary.userId = parsed.userId;
|
|
3810
3787
|
summary.project = parsed.project || undefined;
|
|
3811
3788
|
summary.retrievalMode = parsed.retrievalMode;
|
|
@@ -3813,12 +3790,13 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3813
3790
|
summary.intent = parsed.currentTurn?.intentHint || parsed.observations?.inferred_intent?.label || parsed.workingMemory?.last_user_intent || parsed.decisionState?.current_intent || undefined;
|
|
3814
3791
|
const parsedTurnBrief = parsed.turnBrief || parsed.turn_brief || undefined;
|
|
3815
3792
|
summary.currentTurn = parsed.currentTurn || parsed.current_turn || parsed.diagnostics?.currentTurn || undefined;
|
|
3816
|
-
|
|
3793
|
+
const currentUserMessage = conversation.current_user_message ? truncate(conversation.current_user_message, 180) : undefined;
|
|
3794
|
+
summary.currentUserMessage = undefined;
|
|
3817
3795
|
summary.recentMessages = chronological.length || undefined;
|
|
3818
3796
|
summary.conversation = cleanContextValue({
|
|
3819
3797
|
messages: chronological.length,
|
|
3820
3798
|
userMessages: allUserMessages.length,
|
|
3821
|
-
currentUserMessage
|
|
3799
|
+
currentUserMessage,
|
|
3822
3800
|
lastUser: lastUser ? {
|
|
3823
3801
|
at: lastUser.at || lastUser.timestamp || lastUser.created_at || lastUser.createdAt,
|
|
3824
3802
|
preview: truncate(String(lastUser.content || lastUser.text || lastUser.message || ''), 240),
|
|
@@ -3829,26 +3807,32 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3829
3807
|
} : undefined,
|
|
3830
3808
|
timeline: compactConversationTimelineForSideChannel(conversation, 16),
|
|
3831
3809
|
});
|
|
3832
|
-
summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 16);
|
|
3833
3810
|
const visibleToolEvents = compactToolEventsForSideChannel(toolItems, SIDE_CHANNEL_TOOL_EVENT_MAX);
|
|
3834
3811
|
summary.toolCount = toolItems.length || tools.count || parsed.operationalState?.tool_counts?.total || undefined;
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
summary.lastTool = tools.last_successful_tool
|
|
3812
|
+
const toolNames = toolItems.map((tool) => tool.name || tool.tool_name).filter(Boolean).slice(0, 12);
|
|
3813
|
+
const toolLog = buildToolLogForSideChannel(visibleToolEvents, toolItems.length || summary.toolCount || visibleToolEvents.length, SIDE_CHANNEL_TOOL_EVENT_MAX);
|
|
3814
|
+
const lastTool = tools.last_successful_tool
|
|
3839
3815
|
? {
|
|
3840
3816
|
name: tools.last_successful_tool.name,
|
|
3841
3817
|
at: tools.last_successful_tool.at,
|
|
3842
3818
|
}
|
|
3843
3819
|
: (toolItems.length ? { name: toolItems[toolItems.length - 1].name, at: toolItems[toolItems.length - 1].at } : undefined);
|
|
3820
|
+
summary.tools = cleanContextValue({
|
|
3821
|
+
names: toolNames,
|
|
3822
|
+
last: lastTool,
|
|
3823
|
+
log: toolLog,
|
|
3824
|
+
});
|
|
3825
|
+
summary.memory = cleanContextValue({
|
|
3826
|
+
conversation: summary.conversation,
|
|
3827
|
+
});
|
|
3844
3828
|
summary.turnBrief = typeof parsedTurnBrief === 'string'
|
|
3845
3829
|
? cleanContextValue({
|
|
3846
3830
|
brief: parsedTurnBrief,
|
|
3847
3831
|
intent: summary.intent,
|
|
3848
|
-
currentUserMessage
|
|
3832
|
+
currentUserMessage,
|
|
3849
3833
|
messages: summary.recentMessages,
|
|
3850
3834
|
toolCount: summary.toolCount,
|
|
3851
|
-
lastTool
|
|
3835
|
+
lastTool,
|
|
3852
3836
|
})
|
|
3853
3837
|
: parsedTurnBrief;
|
|
3854
3838
|
summary.counts = cleanContextValue({
|
|
@@ -3862,31 +3846,7 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3862
3846
|
recentHighlights: Array.isArray(parsed.recentHighlights) ? parsed.recentHighlights.length : undefined,
|
|
3863
3847
|
});
|
|
3864
3848
|
summary.loadedSections = loadedSections;
|
|
3865
|
-
summary.
|
|
3866
|
-
summary.slm = cleanContextValue({
|
|
3867
|
-
status: slmPreview ? 'available' : 'empty',
|
|
3868
|
-
source: summaryStatus.source || (parsed.memory?.slmSummary ? 'slm_summary' : parsed.memory?.activeSummary ? 'active_summary' : 'none'),
|
|
3869
|
-
generatedThisLoad: summaryStatus.source === 'fresh_slm',
|
|
3870
|
-
activeSummaryLoaded: summaryStatus.activeSummaryLoaded,
|
|
3871
|
-
activeSummaryUpdated: summaryStatus.activeSummaryUpdated,
|
|
3872
|
-
transientCacheHit: summaryStatus.transientCacheHit,
|
|
3873
|
-
chars: summaryStatus.chars || summaryStatus.summaryChars || (slmPreview ? String(slmPreview).length : 0),
|
|
3874
|
-
preview: slmPreview ? truncate(String(slmPreview), 500) : undefined,
|
|
3875
|
-
});
|
|
3876
|
-
summary.memory = cleanContextValue({
|
|
3877
|
-
conversation: summary.conversation,
|
|
3878
|
-
tools: {
|
|
3879
|
-
count: toolItems.length || summary.toolCount || 0,
|
|
3880
|
-
names: summary.toolNames,
|
|
3881
|
-
last: summary.lastTool,
|
|
3882
|
-
log: summary.toolLog,
|
|
3883
|
-
},
|
|
3884
|
-
compression: parsed.memory?.compression || parsed.memoryCompression,
|
|
3885
|
-
referenceFacts: parsed.memory?.referenceFacts,
|
|
3886
|
-
canonicalFacts: parsed.canonicalFacts,
|
|
3887
|
-
captureHealth: parsed.captureHealth,
|
|
3888
|
-
});
|
|
3889
|
-
summary.tools = summary.memory?.tools;
|
|
3849
|
+
summary.sentToAgent = agentContextBudget;
|
|
3890
3850
|
summary.lastSave = Object.keys(lastSave).length ? lastSave : undefined;
|
|
3891
3851
|
summary.dedupe = fullDedupeSummary ? compactDedupeForSideChannel(fullDedupeSummary) : undefined;
|
|
3892
3852
|
summary.workingMemory = cleanContextValue({
|
|
@@ -3923,6 +3883,10 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3923
3883
|
} : undefined),
|
|
3924
3884
|
});
|
|
3925
3885
|
summary.quality = parsed.contextHealth?.quality_score || parsed.contextQualityScore || undefined;
|
|
3886
|
+
summary.slm = summaryText ? {
|
|
3887
|
+
status: 'available',
|
|
3888
|
+
preview: truncate(typeof summaryText === 'string' ? summaryText : safeStringify(summaryText), 240),
|
|
3889
|
+
} : undefined;
|
|
3926
3890
|
summary.debug = includeDebug ? cleanContextValue({
|
|
3927
3891
|
options: parsed.options,
|
|
3928
3892
|
loadedSections,
|
|
@@ -3931,13 +3895,6 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3931
3895
|
dedupeSummary: fullDedupeSummary,
|
|
3932
3896
|
conversationTimelineFull: compactConversationTimelineForSideChannel(conversation, 12, true),
|
|
3933
3897
|
}) : undefined;
|
|
3934
|
-
delete summary.currentUserMessage;
|
|
3935
|
-
delete summary.toolNames;
|
|
3936
|
-
delete summary.toolEvents;
|
|
3937
|
-
delete summary.toolLog;
|
|
3938
|
-
delete summary.lastTool;
|
|
3939
|
-
delete summary.agentContextBudget;
|
|
3940
|
-
delete summary.conversationTimeline;
|
|
3941
3898
|
return Object.fromEntries(Object.entries(summary).filter(([, value]) => value !== undefined));
|
|
3942
3899
|
}
|
|
3943
3900
|
catch {
|
|
@@ -4131,7 +4088,7 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
4131
4088
|
latest_tool: ((decisionState || {}).latest_tool || (operationalState || {}).last_tool || undefined),
|
|
4132
4089
|
avoid_repeating_tools_unless_needed: ((decisionState || {}).avoid_repeating_tools_unless_needed || []).slice(0, 12),
|
|
4133
4090
|
do_not_repeat_tools_legacy: ((decisionState || {}).do_not_repeat_tools || []).slice(0, 12),
|
|
4134
|
-
instruction: actionDirective || workingMemory.next_expected_action ||
|
|
4091
|
+
instruction: actionDirective || workingMemory.next_expected_action || 'Continue according to the agent prompt.',
|
|
4135
4092
|
}),
|
|
4136
4093
|
});
|
|
4137
4094
|
const audit = {
|
|
@@ -4558,18 +4515,18 @@ class TemboryMemory {
|
|
|
4558
4515
|
options: [
|
|
4559
4516
|
{ name: 'Custom', value: 'custom' },
|
|
4560
4517
|
{ name: 'Diagnóstico Completo', value: 'diagnostic' },
|
|
4561
|
-
|
|
4562
|
-
|
|
4518
|
+
{ name: 'Produção Balanceada (Recomendado)', value: 'productionBalanced' },
|
|
4519
|
+
{ name: 'Produção Rápida (Thread + SLM)', value: 'productionFast' },
|
|
4563
4520
|
{ name: 'Produção Econômica', value: 'productionCheap' },
|
|
4564
4521
|
{ name: 'Produção Nano/SLM', value: 'productionNano' },
|
|
4565
4522
|
{ name: 'Auditoria', value: 'audit' },
|
|
4566
4523
|
],
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4524
|
+
default: 'productionBalanced',
|
|
4525
|
+
description: 'Preenche defaults seguros para contexto, historico de tools e memoria ativa.',
|
|
4526
|
+
},
|
|
4570
4527
|
{ displayName: 'Incluir Cabeçalho de Contexto', name: 'includeContextHeader', type: 'boolean', default: true },
|
|
4571
4528
|
{ displayName: 'Organizar Seções de Produção', name: 'compactStateSections', type: 'boolean', default: true },
|
|
4572
|
-
|
|
4529
|
+
{ displayName: 'Máximo de Caracteres do Contexto', name: 'contextMaxChars', type: 'number', default: 20000 },
|
|
4573
4530
|
{ displayName: 'Incluir Tool History', name: 'includeToolHistory', type: 'boolean', default: true },
|
|
4574
4531
|
{ displayName: 'Incluir Resultado Das Tools', name: 'includeToolResults', type: 'boolean', default: true },
|
|
4575
4532
|
{ displayName: 'Incluir Working Memory', name: 'includeWorkingMemory', type: 'boolean', default: true },
|
|
@@ -4607,16 +4564,16 @@ class TemboryMemory {
|
|
|
4607
4564
|
],
|
|
4608
4565
|
default: 'auto',
|
|
4609
4566
|
},
|
|
4610
|
-
|
|
4611
|
-
|
|
4567
|
+
{ displayName: 'Máximo de Caracteres de Entrada do SLM', name: 'connectedModelSummaryInputMaxChars', type: 'number', default: 12000 },
|
|
4568
|
+
{ displayName: 'Máximo de Caracteres do Resumo do SLM', name: 'connectedModelSummaryMaxChars', type: 'number', default: 3000 },
|
|
4612
4569
|
{ displayName: 'Incluir Active Summary', name: 'includeActiveSummary', type: 'boolean', default: true },
|
|
4613
4570
|
{ displayName: 'Persistir Active Summary', name: 'persistActiveSummary', type: 'boolean', default: true },
|
|
4614
|
-
|
|
4571
|
+
{ displayName: 'Máximo de Caracteres do Active Summary', name: 'activeSummaryMaxChars', type: 'number', default: 3500 },
|
|
4615
4572
|
{ displayName: 'Retenção do Active Summary (Dias)', name: 'activeSummaryRetentionDays', type: 'number', default: 30 },
|
|
4616
4573
|
{ displayName: 'Ativar Cache Técnico do Resumo SLM', name: 'enableTransientSummaryCache', type: 'boolean', default: true },
|
|
4617
4574
|
{ displayName: 'TTL do Cache Técnico SLM (Segundos)', name: 'transientSummaryCacheTTLSeconds', type: 'number', default: 300 },
|
|
4618
4575
|
{ displayName: 'Máximo de Itens no Cache Técnico SLM', name: 'transientSummaryCacheMaxItems', type: 'number', default: 50 },
|
|
4619
|
-
|
|
4576
|
+
{ displayName: 'Máximo de Fatos no Resumo', name: 'summaryMaxFacts', type: 'number', default: 8 },
|
|
4620
4577
|
],
|
|
4621
4578
|
},
|
|
4622
4579
|
{
|
|
@@ -4625,8 +4582,8 @@ class TemboryMemory {
|
|
|
4625
4582
|
values: [
|
|
4626
4583
|
{ displayName: 'Incluir Scores', name: 'includeScores', type: 'boolean', default: false },
|
|
4627
4584
|
{ displayName: 'Incluir Diagnóstico', name: 'includeDiagnostics', type: 'boolean', default: false },
|
|
4628
|
-
|
|
4629
|
-
|
|
4585
|
+
{ displayName: 'Últimas N Tools Mantidas no Contexto', name: 'toolHistoryLastN', type: 'number', default: 30 },
|
|
4586
|
+
{ displayName: 'TTL Das Tools (Segundos)', name: 'toolHistoryTTLSeconds', type: 'number', default: 86400 },
|
|
4630
4587
|
{ displayName: 'Persistir Tool Facts no Backend', name: 'persistToolFactsToTembory', type: 'boolean', default: false },
|
|
4631
4588
|
{ displayName: 'Fallback Semântico Para Tools', name: 'includeToolHistorySemanticFallback', type: 'boolean', default: false },
|
|
4632
4589
|
],
|
|
@@ -4785,7 +4742,6 @@ class TemboryMemory {
|
|
|
4785
4742
|
return { saved: false, input: inputValues, output: outputValues, toolCalls: toolContext };
|
|
4786
4743
|
}
|
|
4787
4744
|
async saveContextForItem(itemIndex, inputValues = {}, outputValues = {}) {
|
|
4788
|
-
await GenericFunctions_1.assertTemboryCredentials(this);
|
|
4789
4745
|
const threadId = this.getNodeParameter('threadId', itemIndex);
|
|
4790
4746
|
const project = this.getNodeParameter('project', itemIndex, '');
|
|
4791
4747
|
const adv = applyOperationalPreset(readAdvancedOptions(this, itemIndex));
|
|
@@ -5282,7 +5238,6 @@ class TemboryMemory {
|
|
|
5282
5238
|
}
|
|
5283
5239
|
async loadMemoryVariablesForItem(itemIndex, inputValues = {}) {
|
|
5284
5240
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
5285
|
-
await GenericFunctions_1.assertTemboryCredentials(this);
|
|
5286
5241
|
const memoryKey = resolveRuntimeMemoryKey(this, itemIndex);
|
|
5287
5242
|
const requestedRetrievalMode = this.getNodeParameter('retrievalMode', itemIndex, 'basic');
|
|
5288
5243
|
let payloadFormat = this.getNodeParameter('payloadFormat', itemIndex, 'structured');
|
|
@@ -5922,7 +5877,6 @@ class TemboryMemory {
|
|
|
5922
5877
|
return { response };
|
|
5923
5878
|
}
|
|
5924
5879
|
async execute() {
|
|
5925
|
-
await GenericFunctions_1.assertTemboryCredentials(this);
|
|
5926
5880
|
const items = this.getInputData();
|
|
5927
5881
|
const returnData = [];
|
|
5928
5882
|
const count = Math.max(items.length, 1);
|
|
@@ -6039,6 +5993,7 @@ exports.__private = {
|
|
|
6039
5993
|
currentInputJsonFromContext,
|
|
6040
5994
|
resolveCurrentTurnQueryWithSource,
|
|
6041
5995
|
resolveCurrentTurnQuery,
|
|
5996
|
+
readAdvancedOptions,
|
|
6042
5997
|
safePersistLegacyMemory,
|
|
6043
5998
|
stripThreadTestPrefix,
|
|
6044
5999
|
canonicalToolInput,
|
|
@@ -39,8 +39,8 @@ const buildAgentMemoryDescription = () => {
|
|
|
39
39
|
const payloadFormat = advancedOnly(cloneProperty(baseProperties, 'payloadFormat'));
|
|
40
40
|
const advancedGroups = advancedOnly(cloneProperty(baseProperties, 'advancedGroups'));
|
|
41
41
|
retrievalMode.description = 'Opcional. No v2 recomendado, o Tembory usa contexto operacional estruturado por padrão.';
|
|
42
|
-
advancedGroups.displayName = '
|
|
43
|
-
advancedGroups.description = 'Controles brutos para debug e casos avançados.
|
|
42
|
+
advancedGroups.displayName = 'Ajustes Técnicos Tembory';
|
|
43
|
+
advancedGroups.description = 'Controles brutos para debug e casos avançados. A Memória inteligente já ativa timeline, tool history, tool reuse guard, SLM analysis, dedupe e retenção segura.';
|
|
44
44
|
return {
|
|
45
45
|
...deepClone(base),
|
|
46
46
|
displayName: 'Tembory Agent Memory',
|
|
@@ -63,32 +63,61 @@ const buildAgentMemoryDescription = () => {
|
|
|
63
63
|
project,
|
|
64
64
|
query,
|
|
65
65
|
{
|
|
66
|
-
displayName: '
|
|
66
|
+
displayName: 'Modo da Memória',
|
|
67
|
+
name: 'operationPreset',
|
|
68
|
+
type: 'options',
|
|
69
|
+
options: [
|
|
70
|
+
{
|
|
71
|
+
name: 'Memória Inteligente (Recomendado)',
|
|
72
|
+
value: 'productionBalanced',
|
|
73
|
+
description: 'Melhor padrão para agentes reais: contexto estruturado, resumo ativo, histórico de tools, evidências e proteção contra repetir ferramentas.',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'Rápido e Econômico',
|
|
77
|
+
value: 'productionFast',
|
|
78
|
+
description: 'Usa menos contexto. Bom para fluxos simples, mas pode perder parte da inteligência operacional.',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'Mini/SLM Orientado',
|
|
82
|
+
value: 'productionNano',
|
|
83
|
+
description: 'Compacta o contexto para modelos mini/nano mantendo resumo ativo e histórico de tools.',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'Auditoria Completa',
|
|
87
|
+
value: 'audit',
|
|
88
|
+
description: 'Mais verboso, com diagnóstico e auditoria. Use para investigação e validação.',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
default: 'productionBalanced',
|
|
92
|
+
description: 'Escolha como o Tembory prepara o contexto para o agente. O recomendado já vem pronto para usuários leigos.',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
displayName: 'Tamanho do Contexto',
|
|
67
96
|
name: 'contextMaxChars',
|
|
68
97
|
type: 'number',
|
|
69
98
|
default: 20000,
|
|
70
|
-
description: 'Máximo aproximado de caracteres
|
|
99
|
+
description: 'Máximo aproximado de caracteres enviados ao agente. O padrão prioriza fluidez sem perder evidências importantes.',
|
|
71
100
|
},
|
|
72
101
|
{
|
|
73
|
-
displayName: '
|
|
102
|
+
displayName: 'Mensagens Recentes',
|
|
74
103
|
name: 'recentMessagesLastN',
|
|
75
104
|
type: 'number',
|
|
76
|
-
default:
|
|
105
|
+
default: 50,
|
|
77
106
|
description: 'Quantidade de mensagens recentes consideradas na timeline e no contexto operacional.',
|
|
78
107
|
},
|
|
79
108
|
{
|
|
80
|
-
displayName: '
|
|
109
|
+
displayName: 'Mostrar Evidências no Output',
|
|
81
110
|
name: 'debugVisualOutput',
|
|
82
111
|
type: 'boolean',
|
|
83
112
|
default: true,
|
|
84
|
-
description: '
|
|
113
|
+
description: 'Mostra evidências, tool history e saúde do contexto na execução. Ajuda usuários leigos a entender por que o agente respondeu daquela forma.',
|
|
85
114
|
},
|
|
86
115
|
{
|
|
87
|
-
displayName: '
|
|
116
|
+
displayName: 'Mostrar Ajustes Técnicos',
|
|
88
117
|
name: 'showAdvanced',
|
|
89
118
|
type: 'boolean',
|
|
90
119
|
default: false,
|
|
91
|
-
description: 'Mostra controles brutos de memória, auditoria, TTL e payload.
|
|
120
|
+
description: 'Mostra controles brutos de memória, auditoria, TTL e payload. Normalmente não precisa ativar.',
|
|
92
121
|
},
|
|
93
122
|
retrievalMode,
|
|
94
123
|
memoryKey,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
2
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
-
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
3
|
+
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
4
4
|
viewBox="0 0 460 460" xml:space="preserve">
|
|
5
5
|
<g>
|
|
6
6
|
<path style="fill:#FF926E;" d="M230,203.06h-29.375v50h-31.25v-50H85.04v-30H120V133.1h30v39.96h109.375v50h31.25v-50h84.335v-30
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<path style="fill:#FFB76E;" d="M329.01,283.06h-99c0,47.828,33.909,87.729,79,96.979V460h40v-79.961
|
|
15
15
|
c-6.459,1.325-13.148,2.021-20,2.021V283.06z"/>
|
|
16
16
|
<rect x="180.04" y="77.06" style="fill:#FFB76E;" width="50" height="30"/>
|
|
17
|
-
<polygon style="fill:#FFB76E;" points="150,133.1 120,133.1 120,173.06 85.04,173.06 85.04,203.06 169.375,203.06 169.375,253.06
|
|
17
|
+
<polygon style="fill:#FFB76E;" points="150,133.1 120,133.1 120,173.06 85.04,173.06 85.04,203.06 169.375,203.06 169.375,253.06
|
|
18
18
|
200.625,253.06 200.625,203.06 230,203.06 230,173.06 150,173.06 "/>
|
|
19
19
|
<rect x="230.04" y="77.06" style="fill:#FF926E;" width="50" height="30"/>
|
|
20
20
|
<rect x="363.51" y="223.06" style="fill:#FF926E;" width="30" height="30"/>
|
package/package.json
CHANGED