n8n-nodes-tembory-agent-memory-v2 2.0.0-rc.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 ADDED
@@ -0,0 +1,28 @@
1
+ # Tembory Agent Memory for n8n
2
+
3
+ Release candidate público: `2.0.0-rc.2`. Instale-o lado a lado com o pacote legado para validação controlada, sem migrar workflows existentes automaticamente.
4
+
5
+ O node tem identidade exclusiva `temboryAgentMemoryV2`, contrato fixo `agent-context/2`, persistência PostgreSQL obrigatória por padrão, revisão otimista e recibos de gravação. Ele não substitui nem migra o node antigo.
6
+
7
+ O pacote reutiliza o runtime testado por meio de `npm run sync:standalone` no pacote canônico. Durante o canário, referencia a credencial `temboryApi` já registrada pelo pacote antigo, sem duplicar definição nem copiar segredos.
8
+
9
+ This is a public side-by-side release candidate, not a GA release.
10
+
11
+ Install it only beside `n8n-nodes-tembory`; the old package supplies the shared credential type while both node identities remain distinct.
12
+
13
+ ## Package identity
14
+
15
+ - npm package: `n8n-nodes-tembory-agent-memory-v2`
16
+ - n8n node display name: `Tembory Agent Memory v2 (Canary)`
17
+ - n8n node internal name: `temboryAgentMemoryV2`
18
+ - guard internal name: `temboryActionGuardV2`
19
+ - credential dependency: `temboryApi` from the legacy package
20
+
21
+ ## Why separate
22
+
23
+ The legacy package remains available as `n8n-nodes-tembory`.
24
+ This package is the opt-in ElefAI LAB path for the next Agent Memory experience without changing existing workflows.
25
+
26
+ ## Release candidate use
27
+
28
+ Use this release candidate only in explicitly selected workflows. Do not migrate customer workflows during this validation phase.
@@ -0,0 +1,9 @@
1
+ import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class TemboryAgentApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate: IAuthenticateGeneric;
8
+ test: ICredentialTestRequest;
9
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TemboryAgentApi = void 0;
4
+ class TemboryAgentApi {
5
+ constructor() {
6
+ this.name = 'temboryAgentApi';
7
+ this.displayName = 'Tembory Agent API';
8
+ this.documentationUrl = 'https://tembory.com';
9
+ this.properties = [
10
+ {
11
+ displayName: 'API Key',
12
+ name: 'apiKey',
13
+ type: 'string',
14
+ typeOptions: { password: true },
15
+ default: '',
16
+ required: true,
17
+ description: 'API key generated in the Tembory SaaS dashboard. It already identifies the account and project.',
18
+ },
19
+ ];
20
+ this.authenticate = {
21
+ type: 'generic',
22
+ properties: {
23
+ headers: {
24
+ 'x-tembory-api-key': '={{$credentials.apiKey}}',
25
+ },
26
+ },
27
+ };
28
+ this.test = {
29
+ request: {
30
+ baseURL: 'https://api.tembory.com',
31
+ url: '/healthz',
32
+ method: 'GET',
33
+ },
34
+ };
35
+ }
36
+ }
37
+ exports.TemboryAgentApi = TemboryAgentApi;
@@ -0,0 +1,2 @@
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>;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.temboryApiRequest = temboryApiRequest;
4
+ exports.assertTemboryCredentials = assertTemboryCredentials;
5
+ const n8n_workflow_1 = require("n8n-workflow");
6
+ async function getTemboryCredentials(ctx) {
7
+ try {
8
+ return await ctx.getCredentials('temboryApi');
9
+ }
10
+ catch { }
11
+ try {
12
+ return await ctx.getCredentials('mem0Api');
13
+ }
14
+ catch { }
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
+ }
17
+ async function assertTemboryCredentials(ctx) {
18
+ await getTemboryCredentials(ctx);
19
+ }
20
+ async function temboryApiRequest(method, endpoint, body = {}, qs = {}) {
21
+ const credentials = await getTemboryCredentials(this);
22
+ const baseUrl = 'https://api.tembory.com';
23
+ const operation = resolveGatewayOperation(method, endpoint);
24
+ const payload = {
25
+ ...(qs && typeof qs === 'object' ? qs : {}),
26
+ ...(body && typeof body === 'object' ? body : {}),
27
+ operation,
28
+ nodePackage: 'n8n-nodes-tembory-agent-memory-v2/2.0.0-rc.2',
29
+ contextContract: 'agent-context/2',
30
+ };
31
+ const options = {
32
+ method: 'POST',
33
+ body: payload,
34
+ url: `${baseUrl}/api/tembory/memory`,
35
+ json: true,
36
+ };
37
+ if (credentials.apiKey) {
38
+ options.headers = {
39
+ 'x-tembory-api-key': credentials.apiKey,
40
+ };
41
+ }
42
+ try {
43
+ const response = await this.helpers.request(options);
44
+ return unwrapGatewayResponse(response);
45
+ }
46
+ catch (error) {
47
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
48
+ }
49
+ }
50
+ function resolveGatewayOperation(method, endpoint) {
51
+ const normalizedMethod = String(method || '').toUpperCase();
52
+ const path = String(endpoint || '').toLowerCase();
53
+ if (path.includes('capabilities'))
54
+ return 'system.capabilities';
55
+ if (path.includes('action-manifests'))
56
+ return 'action.manifest.put';
57
+ if (path.includes('/actions/validate'))
58
+ return 'action.validate';
59
+ if (path.includes('/actions/reserve'))
60
+ return 'action.reserve';
61
+ if (path.includes('/actions/commit'))
62
+ return 'action.commit';
63
+ if (path.includes('/actions/fail'))
64
+ return 'action.fail';
65
+ if (path.includes('thread-state') && (normalizedMethod === 'GET' || path.includes('load')))
66
+ return 'thread-state.load';
67
+ if (path.includes('thread-state'))
68
+ return 'thread-state.save';
69
+ if (path.includes('search') || normalizedMethod === 'GET')
70
+ return 'memory.search';
71
+ if (path.includes('delete'))
72
+ return 'memory.delete';
73
+ if (path.includes('relation'))
74
+ return 'memory.search';
75
+ return 'memory.add';
76
+ }
77
+ function unwrapGatewayResponse(response) {
78
+ if (response && typeof response === 'object' && response.memoryCore && typeof response.memoryCore === 'object' && 'response' in response.memoryCore) {
79
+ return response.memoryCore.response;
80
+ }
81
+ return response;
82
+ }
@@ -0,0 +1,14 @@
1
+ import type { ISupplyDataFunctions, IExecuteFunctions, INodeType, INodeTypeDescription, INodeExecutionData } from 'n8n-workflow';
2
+ export declare class TemboryMemory implements INodeType {
3
+ description: INodeTypeDescription;
4
+ supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<{
5
+ response: any;
6
+ }>;
7
+ saveContextForItem(this: ISupplyDataFunctions, itemIndex: number, inputValues?: Record<string, unknown>, outputValues?: Record<string, unknown>): Promise<void>;
8
+ loadMemoryVariablesForItem(this: ISupplyDataFunctions, itemIndex: number, inputValues?: Record<string, unknown>): Promise<{
9
+ response: {
10
+ [x: string]: unknown;
11
+ };
12
+ }>;
13
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
14
+ }