n8n-nodes-tembory 1.1.11 → 1.1.13

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.
@@ -1679,6 +1679,7 @@ const buildCurrentTurnFocus = ({ query = '', recentMessages = [], operationalSta
1679
1679
  });
1680
1680
  return focus;
1681
1681
  };
1682
+ const SIDE_EFFECT_SAFETY_INSTRUCTION = 'Previous tool calls are evidence only. Never tell the user that a new side-effect action is done, confirmed, booked, created, updated, cancelled, sent, charged, assigned, or executed from memory alone. If the current user turn asks to commit a side-effect and the agent prompt requires a tool, call the appropriate tool in the current turn before saying it is done. Use prior tool outputs only to avoid repeating prerequisite lookup tools and to fill inputs for the required tool call.';
1682
1683
  const intentConfidence = (intent = '') => {
1683
1684
  if (['conversation_recall', 'operational_status_question'].includes(intent))
1684
1685
  return 0.94;
@@ -2248,11 +2249,28 @@ const invokeConnectedModelSummary = async (connectedLanguageModel, summaryInput,
2248
2249
  const response = await connectedLanguageModel.invoke([
2249
2250
  toBaseMessage({
2250
2251
  role: 'user',
2251
- 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.\n\nContext:\n${summaryInput}`,
2252
+ 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}`,
2252
2253
  }),
2253
2254
  ]);
2254
2255
  return cleanModelSummaryText(response, Number(adv.connectedModelSummaryMaxChars || 1200));
2255
2256
  };
2257
+ const compactMemoryEventPayload = (payload = {}) => {
2258
+ const compact = { ...(payload || {}) };
2259
+ if (Array.isArray(compact.toolCalls)) {
2260
+ compact.toolCallsCaptured = compact.toolCalls.length;
2261
+ compact.toolNames = compact.toolCalls
2262
+ .map((tool) => (tool && (tool.name || tool.tool_name || tool.tool)) || '')
2263
+ .filter(Boolean)
2264
+ .slice(0, 20);
2265
+ delete compact.toolCalls;
2266
+ }
2267
+ for (const key of ['input', 'output', 'values', 'chatHistory', 'context', 'contextText', 'diagnostics']) {
2268
+ if (compact[key] !== undefined)
2269
+ compact[`${key}Chars`] = typeof compact[key] === 'string' ? compact[key].length : safeStringify(compact[key]).length;
2270
+ delete compact[key];
2271
+ }
2272
+ return compact;
2273
+ };
2256
2274
  const contextSizeOfMessages = (messages = []) => {
2257
2275
  const perMessage = (messages || []).map((message, index) => {
2258
2276
  const content = String(message.content || '');
@@ -2335,8 +2353,8 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
2335
2353
  section: 'context_header',
2336
2354
  title: 'Tembory context',
2337
2355
  value: compactForAgent || compactStateSections
2338
- ? 'Read-only operational memory. Conversation frame is authoritative for user/assistant transcript. Tool history/action ledger are authoritative for tool calls, reasons, inputs, outputs, status and timestamps. The agent prompt owns domain policy and decides which tool to call.'
2339
- : 'Use this context as read-only operational memory. Do not mention internal section names to the user. Conversation frame is authoritative for the chronological user/assistant transcript. Tool history and action ledger are authoritative for what tools were called, why they were called, what input was sent, what output returned, whether they failed, and when they ran. Memory must not invent domain-specific tool rules; the agent prompt owns tool orchestration policy.',
2356
+ ? `Read-only operational memory. Conversation frame is authoritative for user/assistant transcript. Tool history/action ledger are authoritative for prior tool calls, reasons, inputs, outputs, status and timestamps. The agent prompt owns domain policy and decides which tool to call. ${SIDE_EFFECT_SAFETY_INSTRUCTION}`
2357
+ : `Use this context as read-only operational memory. Do not mention internal section names to the user. Conversation frame is authoritative for the chronological user/assistant transcript. Tool history and action ledger are authoritative for what tools were called, why they were called, what input was sent, what output returned, whether they failed, and when they ran. Memory must not invent domain-specific tool rules; the agent prompt owns tool orchestration policy. ${SIDE_EFFECT_SAFETY_INSTRUCTION}`,
2340
2358
  });
2341
2359
  }
2342
2360
  sections.push({
@@ -2850,7 +2868,7 @@ class TemboryMemory {
2850
2868
  return;
2851
2869
  }
2852
2870
  this.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiMemory, index, [
2853
- [{ json: { action, ...payload } }],
2871
+ [{ json: { action, ...compactMemoryEventPayload(payload) } }],
2854
2872
  ]);
2855
2873
  };
2856
2874
  const memory = {
@@ -4041,4 +4059,5 @@ exports.__private = {
4041
4059
  buildConnectedModelSummaryInput,
4042
4060
  cleanModelSummaryText,
4043
4061
  invokeConnectedModelSummary,
4062
+ compactMemoryEventPayload,
4044
4063
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-tembory",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "description": "Tembory node for n8n AI Agents with operational memory, tool history and decision state",
5
5
  "license": "MIT",
6
6
  "homepage": "https://tembory.com",