n8n-nodes-tembory 1.3.0 → 1.3.2
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 +13 -1
- package/dist/nodes/Tembory/TemboryMemory.node.js +81 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,19 @@
|
|
|
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.2`.
|
|
6
|
+
|
|
7
|
+
## 1.3.2
|
|
8
|
+
|
|
9
|
+
- Remodela o output visual para debug simples no n8n com `sentToAgent`, `slm`, `memory`, `conversation`, `tools`, `io` e `save`.
|
|
10
|
+
- Remove duplicacoes visuais de `saveContext`: `savedMessages`, `conversationTimeline`, `toolNames` e `toolEvents` deixam de aparecer como blocos paralelos no topo.
|
|
11
|
+
- Expõe o status real da SLM no visual: fonte, geração no load atual, cache técnico, active summary carregado/atualizado, chars e preview.
|
|
12
|
+
- Mantem o contexto enviado ao Agent como `tembory.agent_context.v2`; a mudança é no side channel visual e na instrução da SLM para resumir objetivo, próxima ação e evidências operacionais.
|
|
13
|
+
|
|
14
|
+
## 1.3.1
|
|
15
|
+
|
|
16
|
+
- Republica o pacote como `latest` sem a marcacao deprecated aplicada por engano na `1.3.0`.
|
|
17
|
+
- Mantem o mesmo contrato da `1.3.0`: node legado `Tembory` e node opt in `Tembory Agent Memory`.
|
|
6
18
|
|
|
7
19
|
## 1.3.0
|
|
8
20
|
|
|
@@ -3231,6 +3231,14 @@ const buildAgentContextV2 = ({ query = '', userId = '', payloadFormat = 'structu
|
|
|
3231
3231
|
memory: cleanContextValue({
|
|
3232
3232
|
slmSummary: connectedModelSummary ? truncate(connectedModelSummary, Number(adv.connectedModelSummaryMaxChars || 900)) : undefined,
|
|
3233
3233
|
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,
|
|
3234
3242
|
referenceFacts,
|
|
3235
3243
|
compression: adv.includeMemoryCompression === false ? undefined : compactMemoryCompressionForAgent(memoryCompression || {}),
|
|
3236
3244
|
}),
|
|
@@ -3352,13 +3360,13 @@ const invokeConnectedModelSummary = async (connectedLanguageModel, summaryInput,
|
|
|
3352
3360
|
const response = await connectedLanguageModel.invoke([
|
|
3353
3361
|
toBaseMessage({
|
|
3354
3362
|
role: 'user',
|
|
3355
|
-
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}`,
|
|
3363
|
+
content: `Update the Tembory active summary for the next agent turn. Return only concise Portuguese bullets, no JSON and no markdown table. Include what the agent is doing now, the current objective, the next expected action, useful tool evidence, pending confirmations, durable user facts, constraints, contradictions, and do-not-repeat guidance when present. 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}`,
|
|
3356
3364
|
}),
|
|
3357
3365
|
]);
|
|
3358
3366
|
return cleanModelSummaryText(response, Number(adv.connectedModelSummaryMaxChars || 1200));
|
|
3359
3367
|
};
|
|
3360
|
-
const VISUAL_SCHEMA_VERSION = 'tembory.visual.
|
|
3361
|
-
const TOOL_LOG_VISUAL_SCHEMA_VERSION = 'tembory.visual.
|
|
3368
|
+
const VISUAL_SCHEMA_VERSION = 'tembory.visual.v2';
|
|
3369
|
+
const TOOL_LOG_VISUAL_SCHEMA_VERSION = 'tembory.visual.v2.toolLog';
|
|
3362
3370
|
const SIDE_CHANNEL_TOOL_EVENT_MAX = 12;
|
|
3363
3371
|
const SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX = 20;
|
|
3364
3372
|
const compactParsedToolInputForSideChannel = (input) => {
|
|
@@ -3538,22 +3546,35 @@ const summarizeSaveContextForSideChannel = (input = {}, output = {}, chatHistory
|
|
|
3538
3546
|
const outputMessage = output?.output || output?.response || output?.text || output?.message || output?.answer || '';
|
|
3539
3547
|
const toolCalls = extractToolCalls(output || {});
|
|
3540
3548
|
const toolEvents = compactToolEventsForSideChannel(toolCalls, SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX);
|
|
3541
|
-
|
|
3549
|
+
const conversation = conversationDigestFromMessagesForSideChannel(chatHistory);
|
|
3550
|
+
const timeline = conversationTimelineFromMessagesForSideChannel(chatHistory, 16);
|
|
3551
|
+
return cleanContextValue({
|
|
3542
3552
|
visualSchema: VISUAL_SCHEMA_VERSION,
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
?
|
|
3548
|
-
:
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3553
|
+
summary: cleanContextValue({
|
|
3554
|
+
action: 'saveContext',
|
|
3555
|
+
messagesAfterSave: Array.isArray(chatHistory) ? chatHistory.length : 0,
|
|
3556
|
+
userInputPreview: inputMessage ? truncate(String(inputMessage), 220) : undefined,
|
|
3557
|
+
assistantOutputPreview: outputMessage ? truncate(String(outputMessage), 260) : undefined,
|
|
3558
|
+
toolCallsCaptured: toolCalls.length,
|
|
3559
|
+
}),
|
|
3560
|
+
conversation: cleanContextValue({
|
|
3561
|
+
...conversation,
|
|
3562
|
+
timeline,
|
|
3563
|
+
}),
|
|
3564
|
+
io: cleanContextValue({
|
|
3565
|
+
userInput: inputMessage ? truncate(String(inputMessage), 500) : undefined,
|
|
3566
|
+
assistantOutput: outputMessage ? truncate(String(outputMessage), 700) : undefined,
|
|
3567
|
+
}),
|
|
3568
|
+
tools: cleanContextValue({
|
|
3569
|
+
captured: toolCalls.length,
|
|
3570
|
+
capture: summarizeToolCaptureForSideChannel(output, toolCalls),
|
|
3571
|
+
log: buildToolLogForSideChannel(toolEvents, toolCalls.length, SIDE_CHANNEL_SAVE_TOOL_EVENT_MAX),
|
|
3572
|
+
}),
|
|
3573
|
+
save: cleanContextValue({
|
|
3574
|
+
messagesAfterSave: Array.isArray(chatHistory) ? chatHistory.length : 0,
|
|
3575
|
+
status: 'saved_to_memory_contract',
|
|
3576
|
+
}),
|
|
3577
|
+
});
|
|
3557
3578
|
};
|
|
3558
3579
|
const compactMemoryEventPayload = (payload = {}) => {
|
|
3559
3580
|
const compact = { ...(payload || {}) };
|
|
@@ -3771,10 +3792,20 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3771
3792
|
toolCallsCaptured: parsed.captureHealth?.toolCallsCapturedLastSave,
|
|
3772
3793
|
captureSources: parsed.captureHealth?.captureSources,
|
|
3773
3794
|
} : {}));
|
|
3795
|
+
const summaryStatus = parsed.memory?.summaryStatus || parsed.diagnostics?.activeSummary || {};
|
|
3796
|
+
const slmPreview = parsed.memory?.slmSummary || parsed.memory?.activeSummary || summaryText || '';
|
|
3774
3797
|
const fullDedupeSummary = parsed.dedupeSummary || parsed.diagnostics?.dedupeSummary || undefined;
|
|
3775
3798
|
const loadedSections = loadedSectionsForSideChannel(parsed, memoryAudit);
|
|
3776
3799
|
const agentContextBudget = agentContextBudgetForSideChannel(list, parsed);
|
|
3777
3800
|
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
|
+
});
|
|
3778
3809
|
summary.userId = parsed.userId;
|
|
3779
3810
|
summary.project = parsed.project || undefined;
|
|
3780
3811
|
summary.retrievalMode = parsed.retrievalMode;
|
|
@@ -3796,6 +3827,7 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3796
3827
|
at: lastAgent.at || lastAgent.timestamp || lastAgent.created_at || lastAgent.createdAt,
|
|
3797
3828
|
preview: truncate(String(lastAgent.content || lastAgent.text || lastAgent.message || ''), 240),
|
|
3798
3829
|
} : undefined,
|
|
3830
|
+
timeline: compactConversationTimelineForSideChannel(conversation, 16),
|
|
3799
3831
|
});
|
|
3800
3832
|
summary.conversationTimeline = compactConversationTimelineForSideChannel(conversation, 16);
|
|
3801
3833
|
const visibleToolEvents = compactToolEventsForSideChannel(toolItems, SIDE_CHANNEL_TOOL_EVENT_MAX);
|
|
@@ -3831,6 +3863,30 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3831
3863
|
});
|
|
3832
3864
|
summary.loadedSections = loadedSections;
|
|
3833
3865
|
summary.agentContextBudget = agentContextBudget;
|
|
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;
|
|
3834
3890
|
summary.lastSave = Object.keys(lastSave).length ? lastSave : undefined;
|
|
3835
3891
|
summary.dedupe = fullDedupeSummary ? compactDedupeForSideChannel(fullDedupeSummary) : undefined;
|
|
3836
3892
|
summary.workingMemory = cleanContextValue({
|
|
@@ -3875,6 +3931,13 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3875
3931
|
dedupeSummary: fullDedupeSummary,
|
|
3876
3932
|
conversationTimelineFull: compactConversationTimelineForSideChannel(conversation, 12, true),
|
|
3877
3933
|
}) : 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;
|
|
3878
3941
|
return Object.fromEntries(Object.entries(summary).filter(([, value]) => value !== undefined));
|
|
3879
3942
|
}
|
|
3880
3943
|
catch {
|
package/package.json
CHANGED