n8n-nodes-mindrouter 0.1.0 → 0.2.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 +12 -4
- package/dist/nodes/MindRouter/MindRouter.node.js +3 -20
- package/dist/nodes/MindRouter/mindrouter.svg +27 -3
- package/dist/nodes/MindRouterChatModel/MindRouterChatModel.node.js +137 -0
- package/dist/nodes/MindRouterChatModel/mindrouter.svg +28 -0
- package/dist/nodes/shared/api.js +21 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -22,15 +22,23 @@ npm install n8n-nodes-mindrouter
|
|
|
22
22
|
2. In n8n, add a **MindRouter API** credential and paste the key.
|
|
23
23
|
3. Leave the base URL as `https://api.mindrouter.io/v1` unless you run a self-hosted gateway.
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## Nodes
|
|
26
26
|
|
|
27
|
-
### Chat
|
|
27
|
+
### MindRouter Chat Model
|
|
28
|
+
|
|
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
|
+
|
|
31
|
+
### MindRouter
|
|
32
|
+
|
|
33
|
+
A regular node for direct calls.
|
|
34
|
+
|
|
35
|
+
#### Chat
|
|
28
36
|
|
|
29
37
|
Send a prompt (or a full OpenAI-format `messages` array) to any model your account can use. The model dropdown is loaded live from your account, so it always matches your plan and provider settings. Supports temperature, max output tokens, and a simplified output (`text`, `model`, `usage`) or the raw API response.
|
|
30
38
|
|
|
31
|
-
The node is usable as a tool by n8n **AI Agent** nodes.
|
|
39
|
+
The node is also usable as a tool by n8n **AI Agent** nodes.
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
#### List Models
|
|
34
42
|
|
|
35
43
|
Returns the models available to your account, including pricing metadata.
|
|
36
44
|
|
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MindRouter = void 0;
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
-
|
|
6
|
-
const url = String(raw !== null && raw !== void 0 ? raw : 'https://api.mindrouter.io/v1').trim();
|
|
7
|
-
return url.replace(/\/+$/, '');
|
|
8
|
-
}
|
|
5
|
+
const api_1 = require("../shared/api");
|
|
9
6
|
class MindRouter {
|
|
10
7
|
constructor() {
|
|
11
8
|
this.description = {
|
|
@@ -129,21 +126,7 @@ class MindRouter {
|
|
|
129
126
|
this.methods = {
|
|
130
127
|
loadOptions: {
|
|
131
128
|
async getModels() {
|
|
132
|
-
|
|
133
|
-
const credentials = await this.getCredentials('mindRouterApi');
|
|
134
|
-
const baseUrl = normalizeBaseUrl(credentials.baseUrl);
|
|
135
|
-
const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'mindRouterApi', {
|
|
136
|
-
method: 'GET',
|
|
137
|
-
url: `${baseUrl}/models`,
|
|
138
|
-
json: true,
|
|
139
|
-
}));
|
|
140
|
-
const models = (_a = response.data) !== null && _a !== void 0 ? _a : [];
|
|
141
|
-
return models
|
|
142
|
-
.map((m) => ({
|
|
143
|
-
name: m.display_name || m.id,
|
|
144
|
-
value: m.id,
|
|
145
|
-
}))
|
|
146
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
129
|
+
return (0, api_1.loadModelOptions)(this);
|
|
147
130
|
},
|
|
148
131
|
},
|
|
149
132
|
};
|
|
@@ -154,7 +137,7 @@ class MindRouter {
|
|
|
154
137
|
const returnData = [];
|
|
155
138
|
const operation = this.getNodeParameter('operation', 0);
|
|
156
139
|
const credentials = await this.getCredentials('mindRouterApi');
|
|
157
|
-
const baseUrl = normalizeBaseUrl(credentials.baseUrl);
|
|
140
|
+
const baseUrl = (0, api_1.normalizeBaseUrl)(credentials.baseUrl);
|
|
158
141
|
for (let i = 0; i < items.length; i++) {
|
|
159
142
|
try {
|
|
160
143
|
if (operation === 'listModels') {
|
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
|
|
2
|
-
<rect width="60" height="60" rx="12" fill="#
|
|
3
|
-
<
|
|
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>
|
|
4
28
|
</svg>
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MindRouterChatModel = 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 MindRouterChatModel {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.description = {
|
|
10
|
+
displayName: 'MindRouter Chat Model',
|
|
11
|
+
name: 'lmChatMindRouter',
|
|
12
|
+
icon: 'file:mindrouter.svg',
|
|
13
|
+
group: ['transform'],
|
|
14
|
+
version: 1,
|
|
15
|
+
description: 'Use MindRouter models with AI Agents and Chains',
|
|
16
|
+
defaults: {
|
|
17
|
+
name: 'MindRouter Chat Model',
|
|
18
|
+
},
|
|
19
|
+
codex: {
|
|
20
|
+
categories: ['AI'],
|
|
21
|
+
subcategories: {
|
|
22
|
+
AI: ['Language Models', 'Root Nodes'],
|
|
23
|
+
'Language Models': ['Chat Models (Recommended)'],
|
|
24
|
+
},
|
|
25
|
+
resources: {
|
|
26
|
+
primaryDocumentation: [
|
|
27
|
+
{
|
|
28
|
+
url: 'https://mindrouter.io/docs',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
inputs: [],
|
|
34
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.AiLanguageModel],
|
|
35
|
+
outputNames: ['Model'],
|
|
36
|
+
credentials: [
|
|
37
|
+
{
|
|
38
|
+
name: 'mindRouterApi',
|
|
39
|
+
required: true,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
properties: [
|
|
43
|
+
{
|
|
44
|
+
displayName: 'Model Name or ID',
|
|
45
|
+
name: 'model',
|
|
46
|
+
type: 'options',
|
|
47
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
48
|
+
typeOptions: {
|
|
49
|
+
loadOptionsMethod: 'getModels',
|
|
50
|
+
},
|
|
51
|
+
required: true,
|
|
52
|
+
default: '',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
displayName: 'Options',
|
|
56
|
+
name: 'options',
|
|
57
|
+
type: 'collection',
|
|
58
|
+
placeholder: 'Add option',
|
|
59
|
+
default: {},
|
|
60
|
+
options: [
|
|
61
|
+
{
|
|
62
|
+
displayName: 'Temperature',
|
|
63
|
+
name: 'temperature',
|
|
64
|
+
type: 'number',
|
|
65
|
+
typeOptions: { minValue: 0, maxValue: 2, numberPrecision: 2 },
|
|
66
|
+
default: 1,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
displayName: 'Max Output Tokens',
|
|
70
|
+
name: 'maxTokens',
|
|
71
|
+
type: 'number',
|
|
72
|
+
typeOptions: { minValue: 1 },
|
|
73
|
+
default: 1024,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
displayName: 'Top P',
|
|
77
|
+
name: 'topP',
|
|
78
|
+
type: 'number',
|
|
79
|
+
typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2 },
|
|
80
|
+
default: 1,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
displayName: 'Frequency Penalty',
|
|
84
|
+
name: 'frequencyPenalty',
|
|
85
|
+
type: 'number',
|
|
86
|
+
typeOptions: { minValue: -2, maxValue: 2, numberPrecision: 2 },
|
|
87
|
+
default: 0,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
displayName: 'Presence Penalty',
|
|
91
|
+
name: 'presencePenalty',
|
|
92
|
+
type: 'number',
|
|
93
|
+
typeOptions: { minValue: -2, maxValue: 2, numberPrecision: 2 },
|
|
94
|
+
default: 0,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
displayName: 'Timeout (Ms)',
|
|
98
|
+
name: 'timeout',
|
|
99
|
+
type: 'number',
|
|
100
|
+
typeOptions: { minValue: 1 },
|
|
101
|
+
default: 60000,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
this.methods = {
|
|
108
|
+
loadOptions: {
|
|
109
|
+
async getModels() {
|
|
110
|
+
return (0, api_1.loadModelOptions)(this);
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async supplyData(itemIndex) {
|
|
116
|
+
const credentials = await this.getCredentials('mindRouterApi');
|
|
117
|
+
const modelName = this.getNodeParameter('model', itemIndex);
|
|
118
|
+
const options = this.getNodeParameter('options', itemIndex, {});
|
|
119
|
+
const model = new openai_1.ChatOpenAI({
|
|
120
|
+
apiKey: String(credentials.apiKey),
|
|
121
|
+
model: modelName,
|
|
122
|
+
temperature: options.temperature,
|
|
123
|
+
maxTokens: options.maxTokens,
|
|
124
|
+
topP: options.topP,
|
|
125
|
+
frequencyPenalty: options.frequencyPenalty,
|
|
126
|
+
presencePenalty: options.presencePenalty,
|
|
127
|
+
timeout: options.timeout,
|
|
128
|
+
configuration: {
|
|
129
|
+
baseURL: (0, api_1.normalizeBaseUrl)(credentials.baseUrl),
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
response: model,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.MindRouterChatModel = MindRouterChatModel;
|
|
@@ -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,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeBaseUrl = normalizeBaseUrl;
|
|
4
|
+
exports.loadModelOptions = loadModelOptions;
|
|
5
|
+
function normalizeBaseUrl(raw) {
|
|
6
|
+
const url = String(raw !== null && raw !== void 0 ? raw : 'https://api.mindrouter.io/v1').trim();
|
|
7
|
+
return url.replace(/\/+$/, '');
|
|
8
|
+
}
|
|
9
|
+
async function loadModelOptions(context) {
|
|
10
|
+
var _a;
|
|
11
|
+
const credentials = await context.getCredentials('mindRouterApi');
|
|
12
|
+
const baseUrl = normalizeBaseUrl(credentials.baseUrl);
|
|
13
|
+
const response = (await context.helpers.httpRequestWithAuthentication.call(context, 'mindRouterApi', {
|
|
14
|
+
method: 'GET',
|
|
15
|
+
url: `${baseUrl}/models`,
|
|
16
|
+
json: true,
|
|
17
|
+
}));
|
|
18
|
+
return ((_a = response.data) !== null && _a !== void 0 ? _a : [])
|
|
19
|
+
.map((m) => ({ name: m.display_name || m.id, value: m.id }))
|
|
20
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
21
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-mindrouter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
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",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"dist/credentials/MindRouterApi.credentials.js"
|
|
39
39
|
],
|
|
40
40
|
"nodes": [
|
|
41
|
-
"dist/nodes/MindRouter/MindRouter.node.js"
|
|
41
|
+
"dist/nodes/MindRouter/MindRouter.node.js",
|
|
42
|
+
"dist/nodes/MindRouterChatModel/MindRouterChatModel.node.js"
|
|
42
43
|
]
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
@@ -50,5 +51,8 @@
|
|
|
50
51
|
},
|
|
51
52
|
"peerDependencies": {
|
|
52
53
|
"n8n-workflow": "*"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@langchain/openai": "^1.5.11"
|
|
53
57
|
}
|
|
54
58
|
}
|