n8n-nodes-tembory 1.1.38 → 1.1.39
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,13 @@
|
|
|
2
2
|
|
|
3
3
|
Node de memoria operacional da Tembory para agentes de IA no n8n.
|
|
4
4
|
|
|
5
|
-
Versao atual: `1.1.
|
|
5
|
+
Versao atual: `1.1.39`.
|
|
6
|
+
|
|
7
|
+
## 1.1.39
|
|
8
|
+
|
|
9
|
+
- Ajusta a semantica de repeticao de tools: `do_not_repeat_tools` fica restrito a turnos de recall, status operacional ou pedido explicito para nao chamar tools.
|
|
10
|
+
- Em turnos normais, o Agent recebe `repeat_tool_policy` e `avoid_repeating_tools_unless_needed`, deixando claro que tools anteriores sao evidencia reutilizavel, nao ferramentas proibidas.
|
|
11
|
+
- Compacta `decisionState.tool_decision_state` para evitar duplicar outputs longos de tools no contexto balanceado.
|
|
6
12
|
|
|
7
13
|
## 1.1.38
|
|
8
14
|
|
|
@@ -2046,6 +2046,8 @@ const buildTurnBriefForAgent = ({ query = '', recentMessages = [], toolHistory =
|
|
|
2046
2046
|
status: lastTool.status || (lastTool.ok === false ? 'failed' : 'ok'),
|
|
2047
2047
|
at: lastTool.at || lastTool.timestamp,
|
|
2048
2048
|
} : undefined,
|
|
2049
|
+
repeat_tool_policy: (decisionState || {}).repeat_tool_policy,
|
|
2050
|
+
avoid_repeating_tools_unless_needed: ((decisionState || {}).avoid_repeating_tools_unless_needed || []).slice(0, 12),
|
|
2049
2051
|
do_not_repeat_tools: ((decisionState || {}).do_not_repeat_tools || []).slice(0, 12),
|
|
2050
2052
|
guidance: turnBriefGuidanceForIntent(currentIntent),
|
|
2051
2053
|
});
|
|
@@ -2151,6 +2153,19 @@ const shouldCarryPreviousGoal = (intent = '', previousGoal = '') => {
|
|
|
2151
2153
|
return false;
|
|
2152
2154
|
return ['general_message', 'profile_update', 'unknown'].includes(intent);
|
|
2153
2155
|
};
|
|
2156
|
+
const toolNameSuggestsSideEffect = (name = '') => /(?:^|[_\-. ])(book|booking|reserv\w*|agend\w*|confirm\w*|cancel\w*|cri\w*|create|update|upsert|set|send|enviar|registr\w*|cadastr\w*|charge|cobran\w*|pagamento|ticket)(?:$|[_\-. ])/i.test(String(name || ''));
|
|
2157
|
+
const deriveToolRepeatPolicy = ({ intent = '', query = '', executedTools = [], toolState = {} }) => {
|
|
2158
|
+
const tools = Array.from(new Set(executedTools.filter(Boolean)));
|
|
2159
|
+
const strictMemoryOnlyTurn = intent === 'conversation_recall' || intent === 'operational_status_question' || hasNoToolRequested(query);
|
|
2160
|
+
const sideEffectToolCandidates = tools.filter(toolNameSuggestsSideEffect);
|
|
2161
|
+
return cleanContextValue({
|
|
2162
|
+
mode: strictMemoryOnlyTurn ? 'answer_from_memory_when_possible' : 'conditional_reuse',
|
|
2163
|
+
avoid_repeating_tools_unless_needed: tools,
|
|
2164
|
+
legacy_do_not_repeat_applies: strictMemoryOnlyTurn,
|
|
2165
|
+
side_effect_tool_candidates: sideEffectToolCandidates,
|
|
2166
|
+
instruction: 'Prior tools are evidence, not forbidden tools. Reuse outputs when sufficient; call tools for fresh data, new scope, or current side effects.',
|
|
2167
|
+
});
|
|
2168
|
+
};
|
|
2154
2169
|
const deriveWorkingMemory = ({ query = '', profileFacts = {}, recentMessages = [], toolHistory = [], operationalState = {}, previous = {} }) => {
|
|
2155
2170
|
const intent = inferUserIntent(query, recentMessages);
|
|
2156
2171
|
const chronological = sortConversationChronological(recentMessages || []);
|
|
@@ -2225,7 +2240,6 @@ const deriveWorkingMemory = ({ query = '', profileFacts = {}, recentMessages = [
|
|
|
2225
2240
|
};
|
|
2226
2241
|
const deriveDecisionState = ({ query = '', toolHistory = [], operationalState = {}, workingMemory = {} }) => {
|
|
2227
2242
|
const decisions = [];
|
|
2228
|
-
const doNotRepeatTools = [];
|
|
2229
2243
|
const intent = workingMemory.last_user_intent || inferUserIntent(query, []);
|
|
2230
2244
|
const now = nowIso();
|
|
2231
2245
|
const toolState = operationalState.tool_state || {};
|
|
@@ -2244,9 +2258,9 @@ const deriveDecisionState = ({ query = '', toolHistory = [], operationalState =
|
|
|
2244
2258
|
tool: extra.tool,
|
|
2245
2259
|
});
|
|
2246
2260
|
};
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2261
|
+
const executedTools = Array.from(new Set(Object.keys(toolState.counts_by_name || {})));
|
|
2262
|
+
const toolRepeatPolicy = deriveToolRepeatPolicy({ intent, query, executedTools, toolState });
|
|
2263
|
+
const doNotRepeatTools = toolRepeatPolicy.legacy_do_not_repeat_applies ? executedTools : [];
|
|
2250
2264
|
if (toolState.last_successful_tool)
|
|
2251
2265
|
pushDecision('last_successful_tool_recorded', `latest successful tool is ${toolState.last_successful_tool.name}`, 'tool_state records successful tool execution', 'tool_orchestration', { confidence: 0.9, tool: toolState.last_successful_tool.name });
|
|
2252
2266
|
for (const [name, count] of Object.entries(toolState.failed_by_name || {}))
|
|
@@ -2254,15 +2268,18 @@ const deriveDecisionState = ({ query = '', toolHistory = [], operationalState =
|
|
|
2254
2268
|
return {
|
|
2255
2269
|
active_decisions: decisions,
|
|
2256
2270
|
do_not_repeat_tools: Array.from(new Set(doNotRepeatTools)),
|
|
2271
|
+
repeat_tool_policy: toolRepeatPolicy,
|
|
2272
|
+
avoid_repeating_tools_unless_needed: toolRepeatPolicy.avoid_repeating_tools_unless_needed,
|
|
2257
2273
|
current_intent: intent,
|
|
2258
2274
|
tool_decision_state: {
|
|
2259
|
-
executed_tools:
|
|
2275
|
+
executed_tools: executedTools,
|
|
2260
2276
|
failed_tools: Object.keys(toolState.failed_by_name || {}),
|
|
2261
2277
|
last_successful_tool: toolState.last_successful_tool || null,
|
|
2262
2278
|
do_not_repeat_tools: Array.from(new Set(doNotRepeatTools)),
|
|
2279
|
+
repeat_tool_policy: toolRepeatPolicy,
|
|
2263
2280
|
evaluated_at: now,
|
|
2264
2281
|
},
|
|
2265
|
-
conflict_policy: 'prefer active decisions
|
|
2282
|
+
conflict_policy: 'prefer newer active decisions; ignore superseded or expired memories unless auditing',
|
|
2266
2283
|
decision_count: decisions.length,
|
|
2267
2284
|
latest_tool: toolHistory && toolHistory.length ? {
|
|
2268
2285
|
name: toolHistory[toolHistory.length - 1].name,
|
|
@@ -2580,6 +2597,26 @@ const compactWorkingMemoryForAgent = (memory = {}) => cleanContextValue({
|
|
|
2580
2597
|
next_expected_action: memory.next_expected_action,
|
|
2581
2598
|
updated_at: memory.updated_at,
|
|
2582
2599
|
});
|
|
2600
|
+
const compactToolDecisionStateForAgent = (toolDecisionState = {}) => {
|
|
2601
|
+
const lastTool = toolDecisionState.last_successful_tool || null;
|
|
2602
|
+
return cleanContextValue({
|
|
2603
|
+
executed_tools: (toolDecisionState.executed_tools || []).slice(0, 12),
|
|
2604
|
+
failed_tools: (toolDecisionState.failed_tools || []).slice(0, 12),
|
|
2605
|
+
last_successful_tool: lastTool ? cleanContextValue({
|
|
2606
|
+
name: lastTool.name || lastTool.tool_name || lastTool.tool,
|
|
2607
|
+
status: lastTool.status || (lastTool.ok === false ? 'failed' : 'ok'),
|
|
2608
|
+
at: lastTool.at || lastTool.timestamp,
|
|
2609
|
+
}) : undefined,
|
|
2610
|
+
do_not_repeat_tools: (toolDecisionState.do_not_repeat_tools || []).slice(0, 12),
|
|
2611
|
+
evaluated_at: toolDecisionState.evaluated_at,
|
|
2612
|
+
});
|
|
2613
|
+
};
|
|
2614
|
+
const compactRepeatToolPolicyForAgent = (policy = {}) => cleanContextValue({
|
|
2615
|
+
mode: policy.mode,
|
|
2616
|
+
legacy_do_not_repeat_applies: policy.legacy_do_not_repeat_applies,
|
|
2617
|
+
side_effect_tool_candidates: (policy.side_effect_tool_candidates || []).slice(0, 12),
|
|
2618
|
+
instruction: policy.instruction,
|
|
2619
|
+
});
|
|
2583
2620
|
const compactDecisionStateForAgent = (state = {}) => cleanContextValue({
|
|
2584
2621
|
current_intent: state.current_intent,
|
|
2585
2622
|
active_decisions: (state.active_decisions || []).slice(-4).map((decision) => cleanContextValue({
|
|
@@ -2592,13 +2629,14 @@ const compactDecisionStateForAgent = (state = {}) => cleanContextValue({
|
|
|
2592
2629
|
at: decision.at || decision.updated_at,
|
|
2593
2630
|
})),
|
|
2594
2631
|
do_not_repeat_tools: state.do_not_repeat_tools,
|
|
2595
|
-
|
|
2632
|
+
repeat_tool_policy: state.repeat_tool_policy ? compactRepeatToolPolicyForAgent(state.repeat_tool_policy) : undefined,
|
|
2633
|
+
avoid_repeating_tools_unless_needed: state.avoid_repeating_tools_unless_needed,
|
|
2634
|
+
tool_decision_state: state.tool_decision_state ? compactToolDecisionStateForAgent(state.tool_decision_state) : undefined,
|
|
2596
2635
|
latest_tool: state.latest_tool ? cleanContextValue({
|
|
2597
2636
|
name: state.latest_tool.name,
|
|
2598
2637
|
status: state.latest_tool.status || (state.latest_tool.ok === false ? 'failed' : 'ok'),
|
|
2599
2638
|
at: state.latest_tool.at,
|
|
2600
2639
|
}) : undefined,
|
|
2601
|
-
conflict_policy: state.conflict_policy,
|
|
2602
2640
|
});
|
|
2603
2641
|
const compactOperationalStateForAgent = (state = {}) => {
|
|
2604
2642
|
const counts = state.tool_counts || {};
|
|
@@ -3138,6 +3176,12 @@ const summarizeMemoryMessagesForSideChannel = (messages = []) => {
|
|
|
3138
3176
|
decisionCount: parsed.decisionState?.decision_count,
|
|
3139
3177
|
latestTool: parsed.decisionState?.latest_tool,
|
|
3140
3178
|
doNotRepeatTools: parsed.decisionState?.do_not_repeat_tools,
|
|
3179
|
+
avoidRepeatingToolsUnlessNeeded: parsed.decisionState?.avoid_repeating_tools_unless_needed,
|
|
3180
|
+
repeatToolPolicy: parsed.decisionState?.repeat_tool_policy ? {
|
|
3181
|
+
mode: parsed.decisionState.repeat_tool_policy.mode,
|
|
3182
|
+
legacyDoNotRepeatApplies: parsed.decisionState.repeat_tool_policy.legacy_do_not_repeat_applies,
|
|
3183
|
+
sideEffectToolCandidates: parsed.decisionState.repeat_tool_policy.side_effect_tool_candidates,
|
|
3184
|
+
} : undefined,
|
|
3141
3185
|
});
|
|
3142
3186
|
summary.quality = parsed.contextHealth?.quality_score || parsed.contextQualityScore || undefined;
|
|
3143
3187
|
summary.debug = includeDebug ? cleanContextValue({
|
|
@@ -3338,7 +3382,9 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
3338
3382
|
value: cleanContextValue({
|
|
3339
3383
|
current_intent: (decisionState || {}).current_intent || workingMemory.last_user_intent,
|
|
3340
3384
|
latest_tool: ((decisionState || {}).latest_tool || (operationalState || {}).last_tool || undefined),
|
|
3341
|
-
|
|
3385
|
+
repeat_tool_policy: (decisionState || {}).repeat_tool_policy,
|
|
3386
|
+
avoid_repeating_tools_unless_needed: ((decisionState || {}).avoid_repeating_tools_unless_needed || []).slice(0, 12),
|
|
3387
|
+
do_not_repeat_tools_legacy: ((decisionState || {}).do_not_repeat_tools || []).slice(0, 12),
|
|
3342
3388
|
instruction: actionDirective || workingMemory.next_expected_action || 'Continue according to the agent prompt.',
|
|
3343
3389
|
}),
|
|
3344
3390
|
});
|
package/package.json
CHANGED