@miskokodi/n8n-nodes-kie-ai 0.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 +76 -0
- package/dist/credentials/KieAiApi.credentials.d.ts +9 -0
- package/dist/credentials/KieAiApi.credentials.js +38 -0
- package/dist/nodes/LmChatKieAi/LmChatKieAi.node.d.ts +10 -0
- package/dist/nodes/LmChatKieAi/LmChatKieAi.node.js +204 -0
- package/dist/nodes/LmChatKieAi/kieai.svg +5 -0
- package/index.js +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# @miskokodi/n8n-nodes-kie-ai
|
|
2
|
+
|
|
3
|
+
n8n community node that adds a **KIE.ai Chat Model** — use [KIE.ai](https://kie.ai)'s discounted LLM APIs (Gemini, GPT, Claude, DeepSeek, Grok) as the language model provider for **AI Agent**, chains, and any other LangChain root node, exactly like the built-in OpenRouter / OpenAI chat model nodes.
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
KIE routes each LLM through its own OpenAI-compatible endpoint path
|
|
8
|
+
(`https://api.kie.ai/{model}/v1/chat/completions`) and has no `/models`
|
|
9
|
+
listing endpoint — which breaks n8n's stock OpenAI node (credential test
|
|
10
|
+
and model dropdown both fail). This node handles the path-based routing
|
|
11
|
+
internally and ships a model dropdown, so it Just Works.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
Self-hosted n8n → **Settings → Community Nodes → Install** → enter:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
@miskokodi/n8n-nodes-kie-ai
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
(Requires `N8N_COMMUNITY_PACKAGES_ENABLED=true`, which is the default on self-hosted.)
|
|
22
|
+
|
|
23
|
+
## Use
|
|
24
|
+
|
|
25
|
+
1. Create a **KIE.ai API** credential with your API key (kie.ai → Dashboard → API Keys). The credential test validates the key against KIE's credit endpoint.
|
|
26
|
+
2. Add **KIE.ai Chat Model** as the language model of your AI Agent / chain.
|
|
27
|
+
3. Pick a model from the dropdown, or switch the field to an expression and pass any KIE model slug directly.
|
|
28
|
+
|
|
29
|
+
### Options
|
|
30
|
+
|
|
31
|
+
Temperature, top-p, penalties, max tokens, retries, timeout — same surface as the built-in OpenAI chat model node. A **Base URL Override** option (with `{model}` placeholder) is included in case KIE changes its gateway layout.
|
|
32
|
+
|
|
33
|
+
## Model list
|
|
34
|
+
|
|
35
|
+
KIE has no public models-list API, so the dropdown is a curated list in
|
|
36
|
+
`nodes/LmChatKieAi/LmChatKieAi.node.ts` (`KIE_MODELS`). PRs welcome when
|
|
37
|
+
KIE adds/renames models; the dropdown is wired through `loadOptions`, so a
|
|
38
|
+
remote fetch can be dropped in later without a schema change.
|
|
39
|
+
|
|
40
|
+
## Development
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install
|
|
44
|
+
npm run build # tsc + copy icon to dist
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Local testing without publishing:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# in this repo
|
|
51
|
+
npm run build && npm pack # produces miskokodi-n8n-nodes-kie-ai-0.1.0.tgz
|
|
52
|
+
|
|
53
|
+
# on your n8n host
|
|
54
|
+
cd ~/.n8n/nodes # create if missing
|
|
55
|
+
npm install /path/to/miskokodi-n8n-nodes-kie-ai-0.1.0.tgz
|
|
56
|
+
# restart n8n
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Publish
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm login
|
|
63
|
+
npm publish --access public
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Then optionally submit for n8n's verified community node listing:
|
|
67
|
+
https://docs.n8n.io/integrations/creating-nodes/deploy/submit-community-nodes/
|
|
68
|
+
|
|
69
|
+
## Notes
|
|
70
|
+
|
|
71
|
+
- Function calling / tools are supported (KIE's chat endpoints accept the standard `tools` param), so AI Agent tool use works. Behavior fidelity varies per underlying model, as with any aggregator.
|
|
72
|
+
- The `model` field in the request body is effectively ignored by KIE's gateway — the URL path decides the model. The node sets both consistently.
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class KieAiApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KieAiApi = void 0;
|
|
4
|
+
class KieAiApi {
|
|
5
|
+
name = 'kieAiApi';
|
|
6
|
+
displayName = 'KIE.ai API';
|
|
7
|
+
documentationUrl = 'https://docs.kie.ai/';
|
|
8
|
+
properties = [
|
|
9
|
+
{
|
|
10
|
+
displayName: 'API Key',
|
|
11
|
+
name: 'apiKey',
|
|
12
|
+
type: 'string',
|
|
13
|
+
typeOptions: { password: true },
|
|
14
|
+
required: true,
|
|
15
|
+
default: '',
|
|
16
|
+
description: 'Your KIE.ai API key. Get it at https://kie.ai → Dashboard → API Keys.',
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
authenticate = {
|
|
20
|
+
type: 'generic',
|
|
21
|
+
properties: {
|
|
22
|
+
headers: {
|
|
23
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
// KIE has no /models endpoint, so we validate the key against the
|
|
28
|
+
// account credit endpoint instead — it exists for every account and
|
|
29
|
+
// returns 401 on a bad key.
|
|
30
|
+
test = {
|
|
31
|
+
request: {
|
|
32
|
+
baseURL: 'https://api.kie.ai',
|
|
33
|
+
url: '/api/v1/chat/credit',
|
|
34
|
+
method: 'GET',
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
exports.KieAiApi = KieAiApi;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ILoadOptionsFunctions, type INodePropertyOptions, type INodeType, type INodeTypeDescription, type ISupplyDataFunctions, type SupplyData } from 'n8n-workflow';
|
|
2
|
+
export declare class LmChatKieAi implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
methods: {
|
|
5
|
+
loadOptions: {
|
|
6
|
+
getModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LmChatKieAi = void 0;
|
|
4
|
+
const openai_1 = require("@langchain/openai");
|
|
5
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
|
+
/**
|
|
7
|
+
* KIE routes LLM traffic per-model via the URL path:
|
|
8
|
+
* POST https://api.kie.ai/{model-slug}/v1/chat/completions
|
|
9
|
+
* The `model` field in the request body is ignored by the gateway —
|
|
10
|
+
* the path segment is the source of truth. Each endpoint is
|
|
11
|
+
* OpenAI-chat-completions compatible (messages, tools, streaming).
|
|
12
|
+
*
|
|
13
|
+
* There is currently no public /models listing endpoint, so the
|
|
14
|
+
* dropdown is a curated list of the LLM slugs KIE exposes. Update
|
|
15
|
+
* KIE_MODELS below when KIE adds models, or use an expression to
|
|
16
|
+
* pass any slug directly.
|
|
17
|
+
*/
|
|
18
|
+
const KIE_MODELS = [
|
|
19
|
+
// Google
|
|
20
|
+
{ name: 'Gemini 3.1 Pro', value: 'gemini-3-1-pro' },
|
|
21
|
+
{ name: 'Gemini 3 Pro', value: 'gemini-3-pro' },
|
|
22
|
+
{ name: 'Gemini 3 Flash', value: 'gemini-3-flash' },
|
|
23
|
+
{ name: 'Gemini 2.5 Pro', value: 'gemini-2-5-pro' },
|
|
24
|
+
{ name: 'Gemini 2.5 Flash', value: 'gemini-2-5-flash' },
|
|
25
|
+
// OpenAI
|
|
26
|
+
{ name: 'GPT-5.5', value: 'gpt-5-5' },
|
|
27
|
+
{ name: 'GPT-5.4 Mini', value: 'gpt-5-4-mini' },
|
|
28
|
+
{ name: 'GPT-5.2', value: 'gpt-5-2' },
|
|
29
|
+
// Anthropic
|
|
30
|
+
{ name: 'Claude Opus 4.7', value: 'claude-opus-4-7' },
|
|
31
|
+
{ name: 'Claude Sonnet 4.6', value: 'claude-sonnet-4-6' },
|
|
32
|
+
{ name: 'Claude Haiku 4.5', value: 'claude-haiku-4-5' },
|
|
33
|
+
// DeepSeek
|
|
34
|
+
{ name: 'DeepSeek Chat (V3)', value: 'deepseek-chat' },
|
|
35
|
+
{ name: 'DeepSeek Reasoner (R1)', value: 'deepseek-reasoner' },
|
|
36
|
+
// xAI
|
|
37
|
+
{ name: 'Grok 4.3', value: 'grok-4-3' },
|
|
38
|
+
{ name: 'Grok 4.2 Fast', value: 'grok-4-2-fast' },
|
|
39
|
+
];
|
|
40
|
+
class LmChatKieAi {
|
|
41
|
+
description = {
|
|
42
|
+
displayName: 'KIE.ai Chat Model',
|
|
43
|
+
name: 'lmChatKieAi',
|
|
44
|
+
icon: 'file:kieai.svg',
|
|
45
|
+
group: ['transform'],
|
|
46
|
+
version: 1,
|
|
47
|
+
description: 'Use KIE.ai discounted LLM APIs (Gemini, GPT, Claude, DeepSeek, Grok) as the language model for AI Agents and chains',
|
|
48
|
+
defaults: {
|
|
49
|
+
name: 'KIE.ai Chat Model',
|
|
50
|
+
},
|
|
51
|
+
codex: {
|
|
52
|
+
categories: ['AI'],
|
|
53
|
+
subcategories: {
|
|
54
|
+
AI: ['Language Models', 'Root Nodes'],
|
|
55
|
+
'Language Models': ['Chat Models (Recommended)'],
|
|
56
|
+
},
|
|
57
|
+
resources: {
|
|
58
|
+
primaryDocumentation: [
|
|
59
|
+
{
|
|
60
|
+
url: 'https://docs.kie.ai/',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
// Sub-node: no main input, supplies an ai_languageModel connection
|
|
66
|
+
inputs: [],
|
|
67
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.AiLanguageModel],
|
|
68
|
+
outputNames: ['Model'],
|
|
69
|
+
credentials: [
|
|
70
|
+
{
|
|
71
|
+
name: 'kieAiApi',
|
|
72
|
+
required: true,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
properties: [
|
|
76
|
+
{
|
|
77
|
+
displayName: 'KIE routes each model via its own endpoint path. Pick a model from the list, or switch the field to an expression to pass any KIE model slug (e.g. "gemini-3-flash").',
|
|
78
|
+
name: 'notice',
|
|
79
|
+
type: 'notice',
|
|
80
|
+
default: '',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
displayName: 'Model',
|
|
84
|
+
name: 'model',
|
|
85
|
+
type: 'options',
|
|
86
|
+
description: 'The KIE.ai model to use. Choose from the list, or specify a slug using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
87
|
+
typeOptions: {
|
|
88
|
+
loadOptionsMethod: 'getModels',
|
|
89
|
+
},
|
|
90
|
+
default: 'gemini-3-flash',
|
|
91
|
+
required: true,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
displayName: 'Options',
|
|
95
|
+
name: 'options',
|
|
96
|
+
type: 'collection',
|
|
97
|
+
placeholder: 'Add Option',
|
|
98
|
+
default: {},
|
|
99
|
+
options: [
|
|
100
|
+
{
|
|
101
|
+
displayName: 'Base URL Override',
|
|
102
|
+
name: 'baseURL',
|
|
103
|
+
type: 'string',
|
|
104
|
+
default: '',
|
|
105
|
+
placeholder: 'https://api.kie.ai/{model}/v1',
|
|
106
|
+
description: 'Override the endpoint base URL. Use {model} as a placeholder for the model slug. Leave empty for the default KIE gateway.',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
displayName: 'Frequency Penalty',
|
|
110
|
+
name: 'frequencyPenalty',
|
|
111
|
+
type: 'number',
|
|
112
|
+
typeOptions: { minValue: -2, maxValue: 2, numberPrecision: 1 },
|
|
113
|
+
default: 0,
|
|
114
|
+
description: 'Positive values penalize tokens based on their existing frequency, decreasing repetition',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
displayName: 'Maximum Number of Tokens',
|
|
118
|
+
name: 'maxTokens',
|
|
119
|
+
type: 'number',
|
|
120
|
+
default: -1,
|
|
121
|
+
description: 'Maximum tokens to generate in the completion. -1 lets the provider decide.',
|
|
122
|
+
typeOptions: { maxValue: 128000 },
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
displayName: 'Max Retries',
|
|
126
|
+
name: 'maxRetries',
|
|
127
|
+
type: 'number',
|
|
128
|
+
default: 2,
|
|
129
|
+
description: 'Maximum number of retries on failed requests',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
displayName: 'Presence Penalty',
|
|
133
|
+
name: 'presencePenalty',
|
|
134
|
+
type: 'number',
|
|
135
|
+
typeOptions: { minValue: -2, maxValue: 2, numberPrecision: 1 },
|
|
136
|
+
default: 0,
|
|
137
|
+
description: 'Positive values penalize tokens that already appeared, increasing topic diversity',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
displayName: 'Sampling Temperature',
|
|
141
|
+
name: 'temperature',
|
|
142
|
+
type: 'number',
|
|
143
|
+
typeOptions: { minValue: 0, maxValue: 2, numberPrecision: 1 },
|
|
144
|
+
default: 0.7,
|
|
145
|
+
description: 'Controls randomness. Lower is more deterministic, higher more creative.',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
displayName: 'Timeout (Ms)',
|
|
149
|
+
name: 'timeout',
|
|
150
|
+
type: 'number',
|
|
151
|
+
default: 300000,
|
|
152
|
+
description: 'Maximum request time in milliseconds',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
displayName: 'Top P',
|
|
156
|
+
name: 'topP',
|
|
157
|
+
type: 'number',
|
|
158
|
+
typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 1 },
|
|
159
|
+
default: 1,
|
|
160
|
+
description: 'Nucleus sampling: consider only tokens within this cumulative probability mass',
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
};
|
|
166
|
+
methods = {
|
|
167
|
+
loadOptions: {
|
|
168
|
+
async getModels() {
|
|
169
|
+
// No public models-list endpoint on KIE yet — serve the curated
|
|
170
|
+
// list. Kept as a loadOptions method so a remote fetch can be
|
|
171
|
+
// dropped in here later without changing the node schema.
|
|
172
|
+
return KIE_MODELS.map(({ name, value }) => ({ name, value }));
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
async supplyData(itemIndex) {
|
|
177
|
+
const credentials = await this.getCredentials('kieAiApi');
|
|
178
|
+
const modelSlug = this.getNodeParameter('model', itemIndex);
|
|
179
|
+
const options = this.getNodeParameter('options', itemIndex, {});
|
|
180
|
+
const baseURL = (options.baseURL && options.baseURL.trim() !== ''
|
|
181
|
+
? options.baseURL
|
|
182
|
+
: 'https://api.kie.ai/{model}/v1').replace('{model}', modelSlug);
|
|
183
|
+
const model = new openai_1.ChatOpenAI({
|
|
184
|
+
apiKey: credentials.apiKey,
|
|
185
|
+
model: modelSlug,
|
|
186
|
+
temperature: options.temperature,
|
|
187
|
+
topP: options.topP,
|
|
188
|
+
frequencyPenalty: options.frequencyPenalty,
|
|
189
|
+
presencePenalty: options.presencePenalty,
|
|
190
|
+
maxRetries: options.maxRetries ?? 2,
|
|
191
|
+
timeout: options.timeout ?? 300000,
|
|
192
|
+
...(options.maxTokens && options.maxTokens > 0
|
|
193
|
+
? { maxTokens: options.maxTokens }
|
|
194
|
+
: {}),
|
|
195
|
+
configuration: {
|
|
196
|
+
baseURL,
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
response: model,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
exports.LmChatKieAi = LmChatKieAi;
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = {};
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@miskokodi/n8n-nodes-kie-ai",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n community node: KIE.ai Chat Model — use KIE's discounted LLM APIs (Gemini, GPT, Claude, DeepSeek, Grok) as a language model provider for AI Agents and chains, just like the OpenRouter node.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"kie",
|
|
8
|
+
"kie.ai",
|
|
9
|
+
"llm",
|
|
10
|
+
"ai",
|
|
11
|
+
"langchain",
|
|
12
|
+
"chat-model"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "Martin",
|
|
17
|
+
"email": "mconqueror17@gmail.com"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/YOUR_GH_USER/n8n-nodes-kie-ai.git"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"main": "index.js",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc && npm run copy:assets",
|
|
29
|
+
"copy:assets": "node scripts/copy-assets.js",
|
|
30
|
+
"dev": "tsc --watch",
|
|
31
|
+
"lint": "eslint nodes credentials --ext .ts",
|
|
32
|
+
"prepublishOnly": "npm run build"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"n8n": {
|
|
38
|
+
"n8nNodesApiVersion": 1,
|
|
39
|
+
"credentials": [
|
|
40
|
+
"dist/credentials/KieAiApi.credentials.js"
|
|
41
|
+
],
|
|
42
|
+
"nodes": [
|
|
43
|
+
"dist/nodes/LmChatKieAi/LmChatKieAi.node.js"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^22.0.0",
|
|
48
|
+
"n8n-workflow": "^1.70.0",
|
|
49
|
+
"typescript": "^5.6.0"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@langchain/openai": "^0.3.14"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"n8n-workflow": "*"
|
|
56
|
+
}
|
|
57
|
+
}
|