n8n-nodes-tembory 1.0.57 → 1.1.0
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 +1 -1
- package/dist/credentials/{Mem0Api.credentials.d.ts → TemboryApi.credentials.d.ts} +1 -1
- package/dist/credentials/{Mem0Api.credentials.js → TemboryApi.credentials.js} +4 -4
- package/dist/nodes/Tembory/GenericFunctions.d.ts +3 -0
- package/dist/nodes/{Mem0 → Tembory}/GenericFunctions.js +3 -3
- package/dist/nodes/{Mem0/Mem0Memory.node.d.ts → Tembory/TemboryMemory.node.d.ts} +1 -1
- package/dist/nodes/{Mem0/Mem0Memory.node.js → Tembory/TemboryMemory.node.js} +49 -56
- package/package.json +6 -6
- package/scripts/simulate-agent-context.js +1 -1
- package/scripts/simulate-n8n-agent-agenda.js +1 -1
- package/scripts/smoke-n8n-multiturn-tools.js +1 -1
- package/dist/nodes/Mem0/GenericFunctions.d.ts +0 -3
- /package/dist/nodes/{Mem0 → Tembory}/tembory-brain.svg +0 -0
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ Versao atual: `1.0.31`.
|
|
|
62
62
|
## 1.0.22
|
|
63
63
|
|
|
64
64
|
- Corrige persistencia do transcript quando ha embedding conectado: mensagens recentes tambem sao gravadas como markers estruturados em `/v1/memories/`.
|
|
65
|
-
- Persiste tool history estruturado por padrao quando `includeToolHistory` esta ativo, mesmo sem `
|
|
65
|
+
- Persiste tool history estruturado por padrao quando `includeToolHistory` esta ativo, mesmo sem `persistToolFactsToTembory`.
|
|
66
66
|
- Resolve falha real em n8n onde cada execucao carregava apenas a mensagem atual no `Conversation frame`.
|
|
67
67
|
|
|
68
68
|
## 1.0.21
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
-
export declare class
|
|
2
|
+
export declare class TemboryApi implements ICredentialType {
|
|
3
3
|
name: string;
|
|
4
4
|
displayName: string;
|
|
5
5
|
documentationUrl: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
class
|
|
3
|
+
exports.TemboryApi = void 0;
|
|
4
|
+
class TemboryApi {
|
|
5
5
|
constructor() {
|
|
6
|
-
this.name = '
|
|
6
|
+
this.name = 'temboryApi';
|
|
7
7
|
this.displayName = 'Tembory API';
|
|
8
8
|
this.documentationUrl = 'https://tembory.com';
|
|
9
9
|
this.properties = [
|
|
@@ -34,4 +34,4 @@ class Mem0Api {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
exports.
|
|
37
|
+
exports.TemboryApi = TemboryApi;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { IExecuteFunctions, ILoadOptionsFunctions, IHookFunctions, IWebhookFunctions, IHttpRequestMethods } from 'n8n-workflow';
|
|
2
|
+
export declare function temboryApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions | IWebhookFunctions, method: IHttpRequestMethods, endpoint: string, body?: any, qs?: any): Promise<any>;
|
|
3
|
+
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.temboryApiRequest = temboryApiRequest;
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
-
async function
|
|
6
|
-
const credentials = await this.getCredentials('
|
|
5
|
+
async function temboryApiRequest(method, endpoint, body = {}, qs = {}) {
|
|
6
|
+
const credentials = await this.getCredentials('temboryApi');
|
|
7
7
|
const baseUrl = 'https://api.tembory.com';
|
|
8
8
|
const operation = resolveGatewayOperation(method, endpoint);
|
|
9
9
|
const payload = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ISupplyDataFunctions, IExecuteFunctions, INodeType, INodeTypeDescription, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
-
export declare class
|
|
2
|
+
export declare class TemboryMemory implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<{
|
|
5
5
|
response: any;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.TemboryMemory = void 0;
|
|
4
4
|
const GenericFunctions_1 = require("./GenericFunctions");
|
|
5
5
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
6
|
let LangChainMessages = {};
|
|
@@ -53,7 +53,7 @@ const saveClientVectorMemories = async (ctx, memories, ids = {}) => {
|
|
|
53
53
|
const valid = memories.filter((memory) => String(memory === null || memory === void 0 ? void 0 : memory.text || '').trim());
|
|
54
54
|
if (!valid.length)
|
|
55
55
|
return null;
|
|
56
|
-
return GenericFunctions_1.
|
|
56
|
+
return GenericFunctions_1.temboryApiRequest.call(ctx, 'POST', '/tembory/v1/vector-memories', {
|
|
57
57
|
memories: valid,
|
|
58
58
|
user_id: ids.user_id,
|
|
59
59
|
agent_id: ids.agent_id,
|
|
@@ -64,7 +64,7 @@ const searchClientVectorMemories = async (ctx, embedding, query, body = {}) => {
|
|
|
64
64
|
const text = String(query || '').trim();
|
|
65
65
|
if (!text)
|
|
66
66
|
return { results: [] };
|
|
67
|
-
return GenericFunctions_1.
|
|
67
|
+
return GenericFunctions_1.temboryApiRequest.call(ctx, 'POST', '/tembory/v1/vector-memories/search', {
|
|
68
68
|
...body,
|
|
69
69
|
query: text,
|
|
70
70
|
embedding: await embedQueryCached(embedding, text),
|
|
@@ -72,7 +72,7 @@ const searchClientVectorMemories = async (ctx, embedding, query, body = {}) => {
|
|
|
72
72
|
};
|
|
73
73
|
const safePersistLegacyMemory = async (ctx, body, diagnostics = {}) => {
|
|
74
74
|
try {
|
|
75
|
-
return await GenericFunctions_1.
|
|
75
|
+
return await GenericFunctions_1.temboryApiRequest.call(ctx, 'POST', '/v1/memories/', body);
|
|
76
76
|
}
|
|
77
77
|
catch (error) {
|
|
78
78
|
try {
|
|
@@ -695,7 +695,7 @@ const parseToolHistoryMarker = (text) => {
|
|
|
695
695
|
ok: parsed.ok !== false,
|
|
696
696
|
result: truncate(parsed.result || '', 1000),
|
|
697
697
|
at: parsed.at || nowIso(),
|
|
698
|
-
source: parsed.source || '
|
|
698
|
+
source: parsed.source || 'tembory_marker',
|
|
699
699
|
};
|
|
700
700
|
}
|
|
701
701
|
catch {
|
|
@@ -1187,7 +1187,7 @@ const userKeyFrom = (threadId, adv, project = '') => {
|
|
|
1187
1187
|
};
|
|
1188
1188
|
const loadThreadState = async (ctx, key, threadId, project) => {
|
|
1189
1189
|
try {
|
|
1190
|
-
const res = await GenericFunctions_1.
|
|
1190
|
+
const res = await GenericFunctions_1.temboryApiRequest.call(ctx, 'GET', '/v1/tembory/thread-state/load', {}, {
|
|
1191
1191
|
user_id: key,
|
|
1192
1192
|
thread_id: threadId,
|
|
1193
1193
|
project: project || undefined,
|
|
@@ -1200,7 +1200,7 @@ const loadThreadState = async (ctx, key, threadId, project) => {
|
|
|
1200
1200
|
};
|
|
1201
1201
|
const saveThreadState = async (ctx, key, threadId, project, state) => {
|
|
1202
1202
|
try {
|
|
1203
|
-
await GenericFunctions_1.
|
|
1203
|
+
await GenericFunctions_1.temboryApiRequest.call(ctx, 'POST', '/v1/tembory/thread-state', {
|
|
1204
1204
|
user_id: key,
|
|
1205
1205
|
thread_id: threadId,
|
|
1206
1206
|
project: project || undefined,
|
|
@@ -1255,7 +1255,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1255
1255
|
includeRelations: false,
|
|
1256
1256
|
includeToolHistory: true,
|
|
1257
1257
|
includeToolResults: true,
|
|
1258
|
-
|
|
1258
|
+
persistToolFactsToTembory: false,
|
|
1259
1259
|
includeToolHistorySemanticFallback: false,
|
|
1260
1260
|
includeProfileFacts: true,
|
|
1261
1261
|
includeOperationalState: true,
|
|
@@ -1286,7 +1286,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1286
1286
|
includeRelations: false,
|
|
1287
1287
|
includeToolHistory: true,
|
|
1288
1288
|
includeToolResults: true,
|
|
1289
|
-
|
|
1289
|
+
persistToolFactsToTembory: true,
|
|
1290
1290
|
includeToolHistorySemanticFallback: true,
|
|
1291
1291
|
includeProfileFacts: true,
|
|
1292
1292
|
includeOperationalState: true,
|
|
@@ -1320,7 +1320,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1320
1320
|
includeRelations: false,
|
|
1321
1321
|
includeToolHistory: true,
|
|
1322
1322
|
includeToolResults: true,
|
|
1323
|
-
|
|
1323
|
+
persistToolFactsToTembory: false,
|
|
1324
1324
|
includeToolHistorySemanticFallback: false,
|
|
1325
1325
|
includeProfileFacts: true,
|
|
1326
1326
|
includeOperationalState: true,
|
|
@@ -1358,7 +1358,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1358
1358
|
includeRelations: false,
|
|
1359
1359
|
includeToolHistory: true,
|
|
1360
1360
|
includeToolResults: false,
|
|
1361
|
-
|
|
1361
|
+
persistToolFactsToTembory: false,
|
|
1362
1362
|
includeToolHistorySemanticFallback: false,
|
|
1363
1363
|
includeProfileFacts: true,
|
|
1364
1364
|
includeOperationalState: true,
|
|
@@ -1395,7 +1395,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1395
1395
|
includeRelations: false,
|
|
1396
1396
|
includeToolHistory: true,
|
|
1397
1397
|
includeToolResults: true,
|
|
1398
|
-
|
|
1398
|
+
persistToolFactsToTembory: false,
|
|
1399
1399
|
includeToolHistorySemanticFallback: false,
|
|
1400
1400
|
includeProfileFacts: true,
|
|
1401
1401
|
includeOperationalState: true,
|
|
@@ -1426,7 +1426,7 @@ const applyOperationalPreset = (advanced = {}) => {
|
|
|
1426
1426
|
includeRelations: false,
|
|
1427
1427
|
includeToolHistory: true,
|
|
1428
1428
|
includeToolResults: true,
|
|
1429
|
-
|
|
1429
|
+
persistToolFactsToTembory: true,
|
|
1430
1430
|
includeToolHistorySemanticFallback: true,
|
|
1431
1431
|
includeProfileFacts: true,
|
|
1432
1432
|
includeOperationalState: true,
|
|
@@ -2637,7 +2637,7 @@ const buildContextMessages = ({ payloadFormat, query, userId, profileFacts, work
|
|
|
2637
2637
|
}
|
|
2638
2638
|
return [{ role: 'system', content: truncate(text, maxChars) }];
|
|
2639
2639
|
};
|
|
2640
|
-
class
|
|
2640
|
+
class TemboryMemory {
|
|
2641
2641
|
constructor() {
|
|
2642
2642
|
this.description = {
|
|
2643
2643
|
displayName: 'Tembory',
|
|
@@ -2645,7 +2645,7 @@ class Mem0Memory {
|
|
|
2645
2645
|
icon: 'file:tembory-brain.svg',
|
|
2646
2646
|
group: ['transform'],
|
|
2647
2647
|
version: 1,
|
|
2648
|
-
description: '
|
|
2648
|
+
description: 'Operational memory for AI agents with profile, tools, actions, summaries and decision state',
|
|
2649
2649
|
defaults: {
|
|
2650
2650
|
name: 'Tembory',
|
|
2651
2651
|
},
|
|
@@ -2656,24 +2656,17 @@ class Mem0Memory {
|
|
|
2656
2656
|
type: n8n_workflow_1.NodeConnectionTypes.AiLanguageModel,
|
|
2657
2657
|
required: false,
|
|
2658
2658
|
},
|
|
2659
|
-
{
|
|
2660
|
-
displayName: 'Embed',
|
|
2661
|
-
maxConnections: 1,
|
|
2662
|
-
type: n8n_workflow_1.NodeConnectionTypes.AiEmbedding,
|
|
2663
|
-
required: false,
|
|
2664
|
-
},
|
|
2665
2659
|
],
|
|
2666
2660
|
outputs: [n8n_workflow_1.NodeConnectionTypes.AiMemory],
|
|
2667
2661
|
outputNames: ['Mem'],
|
|
2668
2662
|
builderHint: {
|
|
2669
2663
|
inputs: {
|
|
2670
2664
|
ai_languageModel: { required: false },
|
|
2671
|
-
ai_embedding: { required: false },
|
|
2672
2665
|
},
|
|
2673
2666
|
},
|
|
2674
2667
|
credentials: [
|
|
2675
2668
|
{
|
|
2676
|
-
name: '
|
|
2669
|
+
name: 'temboryApi',
|
|
2677
2670
|
required: true,
|
|
2678
2671
|
},
|
|
2679
2672
|
],
|
|
@@ -2853,7 +2846,7 @@ class Mem0Memory {
|
|
|
2853
2846
|
{ displayName: 'Incluir Diagnóstico', name: 'includeDiagnostics', type: 'boolean', default: false },
|
|
2854
2847
|
{ displayName: 'Últimas N Tools', name: 'toolHistoryLastN', type: 'number', default: 10 },
|
|
2855
2848
|
{ displayName: 'TTL Das Tools (Segundos)', name: 'toolHistoryTTLSeconds', type: 'number', default: 3600 },
|
|
2856
|
-
{ displayName: 'Persistir Tool Facts no Backend', name: '
|
|
2849
|
+
{ displayName: 'Persistir Tool Facts no Backend', name: 'persistToolFactsToTembory', type: 'boolean', default: false },
|
|
2857
2850
|
{ displayName: 'Fallback Semântico Para Tools', name: 'includeToolHistorySemanticFallback', type: 'boolean', default: false },
|
|
2858
2851
|
],
|
|
2859
2852
|
},
|
|
@@ -2937,7 +2930,7 @@ class Mem0Memory {
|
|
|
2937
2930
|
{ displayName: 'Incluir Resultado Das Tools', name: 'includeToolResults', type: 'boolean', default: true },
|
|
2938
2931
|
{ displayName: 'Últimas N Tools', name: 'toolHistoryLastN', type: 'number', default: 15 },
|
|
2939
2932
|
{ displayName: 'TTL Das Tools (Segundos)', name: 'toolHistoryTTLSeconds', type: 'number', default: 3600 },
|
|
2940
|
-
{ displayName: 'Persistir Tool Facts no Backend', name: '
|
|
2933
|
+
{ displayName: 'Persistir Tool Facts no Backend', name: 'persistToolFactsToTembory', type: 'boolean', default: false },
|
|
2941
2934
|
{ displayName: 'Fallback Semântico Para Tools', name: 'includeToolHistorySemanticFallback', type: 'boolean', default: false, description: 'Usa memórias vetoriais para tentar inferir histórico de tools quando não houver eventos estruturados. Útil em laboratório, não recomendado como fonte primária em produção.' },
|
|
2942
2935
|
{ displayName: 'Incluir Profile Facts', name: 'includeProfileFacts', type: 'boolean', default: true, description: 'Extrai e injeta fatos estáveis do lead/cliente como nome, empresa, email, telefone, preferências, interesses e contexto comercial.' },
|
|
2943
2936
|
{ displayName: 'Incluir Working Memory', name: 'includeWorkingMemory', type: 'boolean', default: true, description: 'Injeta objetivo atual, intenção recente, entidades ativas, último erro e próxima ação esperada.' },
|
|
@@ -2982,24 +2975,24 @@ class Mem0Memory {
|
|
|
2982
2975
|
getMessages: async () => currentMessages,
|
|
2983
2976
|
addMessage: async (message) => {
|
|
2984
2977
|
currentMessages.push(message);
|
|
2985
|
-
const saved = await
|
|
2978
|
+
const saved = await TemboryMemory.prototype.saveMessagesForItem.call(this, itemIndex, [message]);
|
|
2986
2979
|
recordMemoryEvent('chatHistory.addMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
|
|
2987
2980
|
},
|
|
2988
2981
|
addUserMessage: async (message) => {
|
|
2989
2982
|
const baseMessage = toBaseMessage({ role: 'user', content: message });
|
|
2990
2983
|
currentMessages.push(baseMessage);
|
|
2991
|
-
const saved = await
|
|
2984
|
+
const saved = await TemboryMemory.prototype.saveMessagesForItem.call(this, itemIndex, [baseMessage]);
|
|
2992
2985
|
recordMemoryEvent('chatHistory.addUserMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
|
|
2993
2986
|
},
|
|
2994
2987
|
addAIChatMessage: async (message) => {
|
|
2995
2988
|
const baseMessage = toBaseMessage({ role: 'assistant', content: message });
|
|
2996
2989
|
currentMessages.push(baseMessage);
|
|
2997
|
-
const saved = await
|
|
2990
|
+
const saved = await TemboryMemory.prototype.saveMessagesForItem.call(this, itemIndex, [baseMessage]);
|
|
2998
2991
|
recordMemoryEvent('chatHistory.addAIChatMessage', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: 1 });
|
|
2999
2992
|
},
|
|
3000
2993
|
addMessages: async (messages) => {
|
|
3001
2994
|
currentMessages.push(...messages);
|
|
3002
|
-
const saved = await
|
|
2995
|
+
const saved = await TemboryMemory.prototype.saveMessagesForItem.call(this, itemIndex, messages);
|
|
3003
2996
|
recordMemoryEvent('chatHistory.addMessages', { saved: Boolean(saved && saved.saved), toolCalls: (saved && saved.toolCalls) || [], messages: Array.isArray(messages) ? messages.length : 0 });
|
|
3004
2997
|
},
|
|
3005
2998
|
clear: async () => {
|
|
@@ -3032,7 +3025,7 @@ class Mem0Memory {
|
|
|
3032
3025
|
delete result.response.temboryContextText;
|
|
3033
3026
|
}
|
|
3034
3027
|
else {
|
|
3035
|
-
result = await
|
|
3028
|
+
result = await TemboryMemory.prototype.loadMemoryVariablesForItem.call(this, itemIndex, inputValues);
|
|
3036
3029
|
loadCache.set(cacheKey, snapshotJson(result));
|
|
3037
3030
|
if (loadCache.size > 20) {
|
|
3038
3031
|
const firstKey = loadCache.keys().next().value;
|
|
@@ -3057,7 +3050,7 @@ class Mem0Memory {
|
|
|
3057
3050
|
currentMessages.push(toBaseMessage({ role: 'user', content: input }));
|
|
3058
3051
|
if (output)
|
|
3059
3052
|
currentMessages.push(toBaseMessage({ role: 'assistant', content: output }));
|
|
3060
|
-
await
|
|
3053
|
+
await TemboryMemory.prototype.saveContextForItem.call(this, itemIndex, inputValues, outputValues);
|
|
3061
3054
|
},
|
|
3062
3055
|
};
|
|
3063
3056
|
return { response: wrapTemboryMemory(memory, this, memoryKey) };
|
|
@@ -3086,7 +3079,7 @@ class Mem0Memory {
|
|
|
3086
3079
|
if (toolContext.length)
|
|
3087
3080
|
outputValues.__temboryToolCalls = toolContext;
|
|
3088
3081
|
if (inputValues.input || outputValues.output || toolContext.length) {
|
|
3089
|
-
await
|
|
3082
|
+
await TemboryMemory.prototype.saveContextForItem.call(this, itemIndex, inputValues, outputValues);
|
|
3090
3083
|
return { saved: true, input: inputValues, output: outputValues, toolCalls: toolContext };
|
|
3091
3084
|
}
|
|
3092
3085
|
return { saved: false, input: inputValues, output: outputValues, toolCalls: toolContext };
|
|
@@ -3109,7 +3102,7 @@ class Mem0Memory {
|
|
|
3109
3102
|
last_save_tool_names: toolCalls.map((tool) => tool.name).filter(Boolean).slice(0, 20),
|
|
3110
3103
|
last_save_capture_sources: Array.from(new Set(toolCalls.map((tool) => tool.source).filter(Boolean))),
|
|
3111
3104
|
};
|
|
3112
|
-
const
|
|
3105
|
+
const recentForTembory = [];
|
|
3113
3106
|
const profileFromTurn = extractProfileFactsFromText(input, 'user_message', nowIso());
|
|
3114
3107
|
if (Object.keys(profileFromTurn).length) {
|
|
3115
3108
|
store.profileFacts[key] = mergeProfileFacts(store.profileFacts[key], profileFromTurn);
|
|
@@ -3133,12 +3126,12 @@ class Mem0Memory {
|
|
|
3133
3126
|
if (input) {
|
|
3134
3127
|
const item = { role: 'user', content: truncate(input, 2000), at: nowIso() };
|
|
3135
3128
|
recent.push(item);
|
|
3136
|
-
|
|
3129
|
+
recentForTembory.push(item);
|
|
3137
3130
|
}
|
|
3138
3131
|
if (output) {
|
|
3139
3132
|
const item = { role: 'assistant', content: truncate(output, 2000), at: nowIso() };
|
|
3140
3133
|
recent.push(item);
|
|
3141
|
-
|
|
3134
|
+
recentForTembory.push(item);
|
|
3142
3135
|
}
|
|
3143
3136
|
store.recentMessages[key] = pruneByLimit(recent, adv.recentMessagesLastN || 8);
|
|
3144
3137
|
try {
|
|
@@ -3238,8 +3231,8 @@ class Mem0Memory {
|
|
|
3238
3231
|
latest_tool: toolHistoryForTurn.at(-1)?.name || null,
|
|
3239
3232
|
}, ids),
|
|
3240
3233
|
], ids);
|
|
3241
|
-
if (adv.includeRecentMessages !== false &&
|
|
3242
|
-
for (const recent of
|
|
3234
|
+
if (adv.includeRecentMessages !== false && recentForTembory.length) {
|
|
3235
|
+
for (const recent of recentForTembory) {
|
|
3243
3236
|
await safePersistLegacyMemory(this, {
|
|
3244
3237
|
messages: [{ role: 'system', content: encodeRecentMessage(recent, threadId) }],
|
|
3245
3238
|
infer: false,
|
|
@@ -3327,10 +3320,10 @@ class Mem0Memory {
|
|
|
3327
3320
|
return;
|
|
3328
3321
|
}
|
|
3329
3322
|
if (messages.length)
|
|
3330
|
-
await GenericFunctions_1.
|
|
3331
|
-
if (adv.includeRecentMessages !== false &&
|
|
3332
|
-
for (const recent of
|
|
3333
|
-
await GenericFunctions_1.
|
|
3323
|
+
await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', body);
|
|
3324
|
+
if (adv.includeRecentMessages !== false && recentForTembory.length) {
|
|
3325
|
+
for (const recent of recentForTembory) {
|
|
3326
|
+
await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
|
|
3334
3327
|
messages: [{ role: 'system', content: encodeRecentMessage(recent, threadId) }],
|
|
3335
3328
|
infer: false,
|
|
3336
3329
|
user_id: body.user_id,
|
|
@@ -3346,7 +3339,7 @@ class Mem0Memory {
|
|
|
3346
3339
|
},
|
|
3347
3340
|
});
|
|
3348
3341
|
}
|
|
3349
|
-
await GenericFunctions_1.
|
|
3342
|
+
await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
|
|
3350
3343
|
messages: [{ role: 'system', content: encodeConversationLedger(recentForTurn, threadId) }],
|
|
3351
3344
|
infer: false,
|
|
3352
3345
|
user_id: body.user_id,
|
|
@@ -3361,9 +3354,9 @@ class Mem0Memory {
|
|
|
3361
3354
|
},
|
|
3362
3355
|
});
|
|
3363
3356
|
}
|
|
3364
|
-
if (adv.includeToolHistory !== false && !adv.
|
|
3357
|
+
if (adv.includeToolHistory !== false && !adv.persistToolFactsToTembory && toolCalls.length) {
|
|
3365
3358
|
for (const tool of toolCalls) {
|
|
3366
|
-
await GenericFunctions_1.
|
|
3359
|
+
await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
|
|
3367
3360
|
messages: [{ role: 'system', content: encodeToolCall(tool, threadId) }],
|
|
3368
3361
|
infer: false,
|
|
3369
3362
|
user_id: body.user_id,
|
|
@@ -3385,7 +3378,7 @@ class Mem0Memory {
|
|
|
3385
3378
|
},
|
|
3386
3379
|
});
|
|
3387
3380
|
}
|
|
3388
|
-
await GenericFunctions_1.
|
|
3381
|
+
await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
|
|
3389
3382
|
messages: [{ role: 'system', content: encodeToolLedger(toolHistoryForTurn, threadId) }],
|
|
3390
3383
|
infer: false,
|
|
3391
3384
|
user_id: body.user_id,
|
|
@@ -3400,16 +3393,16 @@ class Mem0Memory {
|
|
|
3400
3393
|
},
|
|
3401
3394
|
});
|
|
3402
3395
|
}
|
|
3403
|
-
if (adv.
|
|
3396
|
+
if (adv.persistToolFactsToTembory && toolCalls.length) {
|
|
3404
3397
|
const facts = toolCalls.map((tool) => `Tool ${tool.name} input=${tool.input}${tool.result ? ` result=${tool.result}` : ''}`).join('\n');
|
|
3405
|
-
await GenericFunctions_1.
|
|
3398
|
+
await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
|
|
3406
3399
|
messages: [{ role: 'system', content: `Tool facts (read-only):\n${truncate(facts, 2000)}` }],
|
|
3407
3400
|
infer: false,
|
|
3408
3401
|
user_id: body.user_id,
|
|
3409
3402
|
metadata: { kind: 'tool_facts' },
|
|
3410
3403
|
});
|
|
3411
3404
|
for (const tool of toolCalls) {
|
|
3412
|
-
await GenericFunctions_1.
|
|
3405
|
+
await GenericFunctions_1.temboryApiRequest.call(this, 'POST', '/v1/memories/', {
|
|
3413
3406
|
messages: [{ role: 'system', content: encodeToolCall(tool, threadId) }],
|
|
3414
3407
|
infer: false,
|
|
3415
3408
|
user_id: body.user_id,
|
|
@@ -3520,7 +3513,7 @@ class Mem0Memory {
|
|
|
3520
3513
|
const semRes = hasQuery && connectedEmbedding
|
|
3521
3514
|
? await searchClientVectorMemories(this, connectedEmbedding, query, body)
|
|
3522
3515
|
: hasQuery
|
|
3523
|
-
? await GenericFunctions_1.
|
|
3516
|
+
? await GenericFunctions_1.temboryApiRequest.call(this, 'POST', url, body)
|
|
3524
3517
|
: { results: [] };
|
|
3525
3518
|
let semMemories = normalizeResults(semRes);
|
|
3526
3519
|
if (retrievalMode === 'hybrid' || !hasQuery) {
|
|
@@ -3533,7 +3526,7 @@ class Mem0Memory {
|
|
|
3533
3526
|
qs.app_id = String(adv.appId);
|
|
3534
3527
|
if (adv.runId)
|
|
3535
3528
|
qs.run_id = String(adv.runId);
|
|
3536
|
-
const recRes = await GenericFunctions_1.
|
|
3529
|
+
const recRes = await GenericFunctions_1.temboryApiRequest.call(this, 'GET', '/v1/memories/', {}, qs);
|
|
3537
3530
|
let recents = normalizeResults(recRes);
|
|
3538
3531
|
const lastN = Number((_a = adv.lastN) !== null && _a !== void 0 ? _a : 20);
|
|
3539
3532
|
if (lastN > 0)
|
|
@@ -3635,7 +3628,7 @@ class Mem0Memory {
|
|
|
3635
3628
|
qs.app_id = String(adv.appId);
|
|
3636
3629
|
if (adv.runId)
|
|
3637
3630
|
qs.run_id = String(adv.runId);
|
|
3638
|
-
const res = await GenericFunctions_1.
|
|
3631
|
+
const res = await GenericFunctions_1.temboryApiRequest.call(this, 'GET', '/v1/memories/', {}, qs);
|
|
3639
3632
|
let memories = normalizeResults(res);
|
|
3640
3633
|
// lastN limit
|
|
3641
3634
|
if (adv.lastN && Number(adv.lastN) > 0)
|
|
@@ -3655,7 +3648,7 @@ class Mem0Memory {
|
|
|
3655
3648
|
let graph = [];
|
|
3656
3649
|
if (adv.includeRelations !== false) {
|
|
3657
3650
|
try {
|
|
3658
|
-
const entityRes = await GenericFunctions_1.
|
|
3651
|
+
const entityRes = await GenericFunctions_1.temboryApiRequest.call(this, 'GET', '/entities/relations', {}, { user_id: key, agent_id: adv.agentId || undefined, run_id: adv.runId || undefined, limit: Number(adv.maxRelations || 10) });
|
|
3659
3652
|
graph = normalizeResults(entityRes).slice(0, Number(adv.maxRelations || 10));
|
|
3660
3653
|
}
|
|
3661
3654
|
catch (error) {
|
|
@@ -3742,7 +3735,7 @@ class Mem0Memory {
|
|
|
3742
3735
|
qs.agent_id = String(adv.agentId);
|
|
3743
3736
|
if (adv.runId)
|
|
3744
3737
|
qs.run_id = String(adv.runId);
|
|
3745
|
-
const persistedRes = await GenericFunctions_1.
|
|
3738
|
+
const persistedRes = await GenericFunctions_1.temboryApiRequest.call(this, 'GET', '/v1/memories/', {}, qs);
|
|
3746
3739
|
persistedMemoryItems = normalizeResults(persistedRes);
|
|
3747
3740
|
}
|
|
3748
3741
|
catch (error) {
|
|
@@ -4099,7 +4092,7 @@ class Mem0Memory {
|
|
|
4099
4092
|
const url = retrievalMode === 'semanticV2' ? '/v2/memories/search/' : '/v1/memories/search/';
|
|
4100
4093
|
const res = connectedEmbedding
|
|
4101
4094
|
? await searchClientVectorMemories(this, connectedEmbedding, query, body)
|
|
4102
|
-
: await GenericFunctions_1.
|
|
4095
|
+
: await GenericFunctions_1.temboryApiRequest.call(this, 'POST', url, body);
|
|
4103
4096
|
const memories = Array.isArray(res) ? res : [res];
|
|
4104
4097
|
payload = memories.map((m) => { var _a, _b; return ({ role: 'system', content: (_b = (_a = m.memory) !== null && _a !== void 0 ? _a : m.text) !== null && _b !== void 0 ? _b : JSON.stringify(m) }); });
|
|
4105
4098
|
}
|
|
@@ -4112,7 +4105,7 @@ class Mem0Memory {
|
|
|
4112
4105
|
qs.app_id = String(adv.appId);
|
|
4113
4106
|
if (adv.runId)
|
|
4114
4107
|
qs.run_id = String(adv.runId);
|
|
4115
|
-
const res = await GenericFunctions_1.
|
|
4108
|
+
const res = await GenericFunctions_1.temboryApiRequest.call(this, 'GET', '/v1/memories/', {}, qs);
|
|
4116
4109
|
let memories = Array.isArray(res) ? res : [res];
|
|
4117
4110
|
if (adv.lastN && Number(adv.lastN) > 0)
|
|
4118
4111
|
memories = memories.slice(-Number(adv.lastN));
|
|
@@ -4134,7 +4127,7 @@ class Mem0Memory {
|
|
|
4134
4127
|
return [returnData];
|
|
4135
4128
|
}
|
|
4136
4129
|
}
|
|
4137
|
-
exports.
|
|
4130
|
+
exports.TemboryMemory = TemboryMemory;
|
|
4138
4131
|
exports.__private = {
|
|
4139
4132
|
extractToolCallsFromText,
|
|
4140
4133
|
extractToolCalls,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-tembory",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Tembory node for n8n AI Agents with
|
|
3
|
+
"version": "1.1.0",
|
|
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",
|
|
7
7
|
"author": {
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"n8n": {
|
|
39
39
|
"n8nNodesApiVersion": 1,
|
|
40
40
|
"credentials": [
|
|
41
|
-
"dist/credentials/
|
|
41
|
+
"dist/credentials/TemboryApi.credentials.js"
|
|
42
42
|
],
|
|
43
43
|
"nodes": [
|
|
44
|
-
"dist/nodes/
|
|
44
|
+
"dist/nodes/Tembory/TemboryMemory.node.js"
|
|
45
45
|
]
|
|
46
46
|
},
|
|
47
47
|
"keywords": [
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
"ai",
|
|
54
54
|
"llm",
|
|
55
55
|
"long-term-memory",
|
|
56
|
-
"
|
|
57
|
-
"
|
|
56
|
+
"operational-memory",
|
|
57
|
+
"tool-history"
|
|
58
58
|
],
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^18.16.0",
|
|
@@ -23,7 +23,7 @@ Module._load = function patchedLoad(request, parent, isMain) {
|
|
|
23
23
|
return originalLoad.call(this, request, parent, isMain);
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
const core = require('../dist/nodes/
|
|
26
|
+
const core = require('../dist/nodes/Tembory/TemboryMemory.node.js').__private;
|
|
27
27
|
|
|
28
28
|
const toolHistory = [
|
|
29
29
|
{
|
|
@@ -26,7 +26,7 @@ Module._load = function patchedLoad(request, parent, isMain) {
|
|
|
26
26
|
return originalLoad.call(this, request, parent, isMain);
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
const core = require('../dist/nodes/
|
|
29
|
+
const core = require('../dist/nodes/Tembory/TemboryMemory.node.js').__private;
|
|
30
30
|
|
|
31
31
|
const BASE_TIME = Date.parse('2026-05-16T12:00:00.000Z');
|
|
32
32
|
|
|
@@ -26,7 +26,7 @@ Module._load = function patchedLoad(request, parent, isMain) {
|
|
|
26
26
|
return originalLoad.call(this, request, parent, isMain);
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
const core = require('../dist/nodes/
|
|
29
|
+
const core = require('../dist/nodes/Tembory/TemboryMemory.node.js').__private;
|
|
30
30
|
|
|
31
31
|
const turns = [
|
|
32
32
|
{
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { IExecuteFunctions, ILoadOptionsFunctions, IHookFunctions, IWebhookFunctions, IHttpRequestMethods } from 'n8n-workflow';
|
|
2
|
-
export declare function mem0ApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions | IWebhookFunctions, method: IHttpRequestMethods, endpoint: string, body?: any, qs?: any): Promise<any>;
|
|
3
|
-
|
|
File without changes
|