n8n-nodes-mindrouter 0.2.2 → 0.4.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 +4 -0
- package/dist/nodes/MindRouterChatModel/MindRouterChatModel.node.js +2 -0
- package/dist/nodes/MindRouterEmbeddings/MindRouterEmbeddings.node.js +126 -0
- package/dist/nodes/MindRouterEmbeddings/mindrouter.svg +28 -0
- package/dist/nodes/shared/statusCallback.js +45 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -28,6 +28,10 @@ npm install n8n-nodes-mindrouter
|
|
|
28
28
|
|
|
29
29
|
A sub-node for the **AI Agent** and **LLM Chain** nodes: click the **Chat Model** socket and pick *MindRouter Chat Model*. Choose any model from your account (loaded live) and set temperature, max tokens, top-p, penalties, and timeout. Everything the agent does then runs through the MindRouter gateway — guardrails, spend limits, and usage tracking included.
|
|
30
30
|
|
|
31
|
+
### MindRouter Embeddings
|
|
32
|
+
|
|
33
|
+
A sub-node for **Vector Store** and retriever nodes: click the **Embeddings** socket and pick *MindRouter Embeddings*. Your whole RAG pipeline — indexing and retrieval included — then runs through the MindRouter gateway on the same key and bill as the chat model. Supports batch size, dimension truncation, and newline stripping.
|
|
34
|
+
|
|
31
35
|
### MindRouter
|
|
32
36
|
|
|
33
37
|
A regular node for direct calls.
|
|
@@ -4,6 +4,7 @@ exports.MindRouterChatModel = void 0;
|
|
|
4
4
|
const openai_1 = require("@langchain/openai");
|
|
5
5
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
6
|
const api_1 = require("../shared/api");
|
|
7
|
+
const statusCallback_1 = require("../shared/statusCallback");
|
|
7
8
|
class MindRouterChatModel {
|
|
8
9
|
constructor() {
|
|
9
10
|
this.description = {
|
|
@@ -128,6 +129,7 @@ class MindRouterChatModel {
|
|
|
128
129
|
configuration: {
|
|
129
130
|
baseURL: (0, api_1.normalizeBaseUrl)(credentials.baseUrl),
|
|
130
131
|
},
|
|
132
|
+
callbacks: [new statusCallback_1.N8nExecutionStatusHandler(this)],
|
|
131
133
|
});
|
|
132
134
|
return {
|
|
133
135
|
response: model,
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MindRouterEmbeddings = void 0;
|
|
4
|
+
const openai_1 = require("@langchain/openai");
|
|
5
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
|
+
const api_1 = require("../shared/api");
|
|
7
|
+
class MindRouterEmbeddings {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.description = {
|
|
10
|
+
displayName: 'MindRouter Embeddings',
|
|
11
|
+
name: 'embeddingsMindRouter',
|
|
12
|
+
icon: 'file:mindrouter.svg',
|
|
13
|
+
group: ['transform'],
|
|
14
|
+
version: 1,
|
|
15
|
+
description: 'Use MindRouter embedding models with Vector Stores',
|
|
16
|
+
defaults: {
|
|
17
|
+
name: 'MindRouter Embeddings',
|
|
18
|
+
},
|
|
19
|
+
codex: {
|
|
20
|
+
categories: ['AI'],
|
|
21
|
+
subcategories: {
|
|
22
|
+
AI: ['Embeddings'],
|
|
23
|
+
},
|
|
24
|
+
resources: {
|
|
25
|
+
primaryDocumentation: [
|
|
26
|
+
{
|
|
27
|
+
url: 'https://mindrouter.io/docs',
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
inputs: [],
|
|
33
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.AiEmbedding],
|
|
34
|
+
outputNames: ['Embeddings'],
|
|
35
|
+
credentials: [
|
|
36
|
+
{
|
|
37
|
+
name: 'mindRouterApi',
|
|
38
|
+
required: true,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
properties: [
|
|
42
|
+
{
|
|
43
|
+
displayName: 'Model Name or ID',
|
|
44
|
+
name: 'model',
|
|
45
|
+
type: 'options',
|
|
46
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
47
|
+
typeOptions: {
|
|
48
|
+
loadOptionsMethod: 'getEmbeddingModels',
|
|
49
|
+
},
|
|
50
|
+
required: true,
|
|
51
|
+
default: '',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
displayName: 'Options',
|
|
55
|
+
name: 'options',
|
|
56
|
+
type: 'collection',
|
|
57
|
+
placeholder: 'Add option',
|
|
58
|
+
default: {},
|
|
59
|
+
options: [
|
|
60
|
+
{
|
|
61
|
+
displayName: 'Batch Size',
|
|
62
|
+
name: 'batchSize',
|
|
63
|
+
type: 'number',
|
|
64
|
+
typeOptions: { minValue: 1, maxValue: 2048 },
|
|
65
|
+
default: 512,
|
|
66
|
+
description: 'How many texts to embed per API request',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
displayName: 'Dimensions',
|
|
70
|
+
name: 'dimensions',
|
|
71
|
+
type: 'number',
|
|
72
|
+
typeOptions: { minValue: 1 },
|
|
73
|
+
default: 0,
|
|
74
|
+
description: 'Shorten vectors to this many dimensions (0 = model default). Only models that support truncation honour it.',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
displayName: 'Strip New Lines',
|
|
78
|
+
name: 'stripNewLines',
|
|
79
|
+
type: 'boolean',
|
|
80
|
+
default: true,
|
|
81
|
+
description: 'Whether to replace newlines with spaces before embedding',
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
this.methods = {
|
|
88
|
+
loadOptions: {
|
|
89
|
+
async getEmbeddingModels() {
|
|
90
|
+
var _a;
|
|
91
|
+
const credentials = await this.getCredentials('mindRouterApi');
|
|
92
|
+
const baseUrl = (0, api_1.normalizeBaseUrl)(credentials.baseUrl);
|
|
93
|
+
const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'mindRouterApi', {
|
|
94
|
+
method: 'GET',
|
|
95
|
+
url: `${baseUrl}/models`,
|
|
96
|
+
json: true,
|
|
97
|
+
}));
|
|
98
|
+
const models = (_a = response.data) !== null && _a !== void 0 ? _a : [];
|
|
99
|
+
const embedding = models.filter((m) => m.category === 'embedding');
|
|
100
|
+
return (embedding.length > 0 ? embedding : models)
|
|
101
|
+
.map((m) => ({ name: m.display_name || m.id, value: m.id }))
|
|
102
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
async supplyData(itemIndex) {
|
|
108
|
+
const credentials = await this.getCredentials('mindRouterApi');
|
|
109
|
+
const modelName = this.getNodeParameter('model', itemIndex);
|
|
110
|
+
const options = this.getNodeParameter('options', itemIndex, {});
|
|
111
|
+
const embeddings = new openai_1.OpenAIEmbeddings({
|
|
112
|
+
apiKey: String(credentials.apiKey),
|
|
113
|
+
model: modelName,
|
|
114
|
+
batchSize: options.batchSize,
|
|
115
|
+
dimensions: options.dimensions ? options.dimensions : undefined,
|
|
116
|
+
stripNewLines: options.stripNewLines,
|
|
117
|
+
configuration: {
|
|
118
|
+
baseURL: (0, api_1.normalizeBaseUrl)(credentials.baseUrl),
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
return {
|
|
122
|
+
response: embeddings,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.MindRouterEmbeddings = MindRouterEmbeddings;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" role="img" aria-label="MindRouter">
|
|
2
|
+
<rect width="60" height="60" rx="12" fill="#101826"/>
|
|
3
|
+
<g transform="translate(8 12)">
|
|
4
|
+
<defs>
|
|
5
|
+
<mask id="mh">
|
|
6
|
+
<rect width="44" height="36" fill="#fff"/>
|
|
7
|
+
<circle cx="22" cy="18.5" r="5.4" fill="#000"/>
|
|
8
|
+
</mask>
|
|
9
|
+
</defs>
|
|
10
|
+
<g mask="url(#mh)">
|
|
11
|
+
<path d="M4 32 L12 7 L22 19 Z" fill="#FFFFFF"/>
|
|
12
|
+
<path d="M22 19 L31 10 L38 32 Z" fill="#FFFFFF"/>
|
|
13
|
+
</g>
|
|
14
|
+
<circle cx="22" cy="18.5" r="5.4" fill="none" stroke="#FFFFFF" stroke-width="2"/>
|
|
15
|
+
<g transform="translate(18 14.5) scale(0.5)">
|
|
16
|
+
<g fill="none" stroke="#14B8B0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
|
17
|
+
<path d="M3.8 8 H8"/>
|
|
18
|
+
<path d="M8 8 V5 H12"/>
|
|
19
|
+
<path d="M8 8 V11 H12"/>
|
|
20
|
+
</g>
|
|
21
|
+
<g fill="#14B8B0">
|
|
22
|
+
<circle cx="3.8" cy="8" r="1.5"/>
|
|
23
|
+
<circle cx="12.2" cy="5" r="1.3"/>
|
|
24
|
+
<circle cx="12.2" cy="11" r="1.3"/>
|
|
25
|
+
</g>
|
|
26
|
+
</g>
|
|
27
|
+
</g>
|
|
28
|
+
</svg>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.N8nExecutionStatusHandler = void 0;
|
|
4
|
+
const base_1 = require("@langchain/core/callbacks/base");
|
|
5
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
|
+
class N8nExecutionStatusHandler extends base_1.BaseCallbackHandler {
|
|
7
|
+
constructor(context) {
|
|
8
|
+
super();
|
|
9
|
+
this.context = context;
|
|
10
|
+
this.name = 'mindRouterExecutionStatus';
|
|
11
|
+
this.runIndexes = new Map();
|
|
12
|
+
}
|
|
13
|
+
start(runId, payload) {
|
|
14
|
+
const { index } = this.context.addInputData(n8n_workflow_1.NodeConnectionTypes.AiLanguageModel, [
|
|
15
|
+
[{ json: { input: payload } }],
|
|
16
|
+
]);
|
|
17
|
+
this.runIndexes.set(runId, index);
|
|
18
|
+
}
|
|
19
|
+
end(runId, payload) {
|
|
20
|
+
const index = this.runIndexes.get(runId);
|
|
21
|
+
if (index === undefined)
|
|
22
|
+
return;
|
|
23
|
+
this.runIndexes.delete(runId);
|
|
24
|
+
this.context.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiLanguageModel, index, [
|
|
25
|
+
[{ json: { output: payload } }],
|
|
26
|
+
]);
|
|
27
|
+
}
|
|
28
|
+
handleChatModelStart(_llm, messages, runId) {
|
|
29
|
+
this.start(runId, messages);
|
|
30
|
+
}
|
|
31
|
+
handleLLMStart(_llm, prompts, runId) {
|
|
32
|
+
this.start(runId, prompts);
|
|
33
|
+
}
|
|
34
|
+
handleLLMEnd(output, runId) {
|
|
35
|
+
this.end(runId, output);
|
|
36
|
+
}
|
|
37
|
+
handleLLMError(error, runId) {
|
|
38
|
+
const index = this.runIndexes.get(runId);
|
|
39
|
+
if (index === undefined)
|
|
40
|
+
return;
|
|
41
|
+
this.runIndexes.delete(runId);
|
|
42
|
+
this.context.addOutputData(n8n_workflow_1.NodeConnectionTypes.AiLanguageModel, index, new n8n_workflow_1.NodeOperationError(this.context.getNode(), error.message));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.N8nExecutionStatusHandler = N8nExecutionStatusHandler;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-mindrouter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "n8n community node for MindRouter — unified gateway to AI models with Indonesian PII guardrails",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
],
|
|
40
40
|
"nodes": [
|
|
41
41
|
"dist/nodes/MindRouter/MindRouter.node.js",
|
|
42
|
-
"dist/nodes/MindRouterChatModel/MindRouterChatModel.node.js"
|
|
42
|
+
"dist/nodes/MindRouterChatModel/MindRouterChatModel.node.js",
|
|
43
|
+
"dist/nodes/MindRouterEmbeddings/MindRouterEmbeddings.node.js"
|
|
43
44
|
]
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
@@ -53,6 +54,7 @@
|
|
|
53
54
|
"n8n-workflow": "*"
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
57
|
+
"@langchain/core": "^1.2.9",
|
|
56
58
|
"@langchain/openai": "^1.5.11"
|
|
57
59
|
}
|
|
58
60
|
}
|