n8n-nodes-openai-compatible-wwrs 0.0.2 → 0.0.3
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/credentials/DeepSeekApi.credentials.ts +50 -0
- package/credentials/OllamaApi.credentials.ts +52 -0
- package/dist/credentials/DeepSeekApi.credentials.d.ts +12 -0
- package/dist/credentials/DeepSeekApi.credentials.js +46 -0
- package/dist/credentials/DeepSeekApi.credentials.ts +50 -0
- package/dist/credentials/OllamaApi.credentials.d.ts +12 -0
- package/dist/credentials/OllamaApi.credentials.js +48 -0
- package/dist/credentials/OllamaApi.credentials.ts +52 -0
- package/dist/nodes/llms/LMChatDeepSeek/LMChatDeepSeek.node.d.ts +9 -0
- package/dist/nodes/llms/LMChatDeepSeek/LMChatDeepSeek.node.js +151 -0
- package/dist/nodes/llms/LMChatDeepSeek/LMChatDeepSeek.node.ts +166 -0
- package/dist/nodes/llms/LMChatOllama/LMChatOllama.node.d.ts +9 -0
- package/dist/nodes/llms/LMChatOllama/LMChatOllama.node.js +157 -0
- package/dist/nodes/llms/LMChatOllama/LMChatOllama.node.ts +169 -0
- package/nodes/llms/LMChatDeepSeek/LMChatDeepSeek.node.ts +166 -0
- package/nodes/llms/LMChatOllama/LMChatOllama.node.ts +169 -0
- package/package.json +8 -4
- package/credentials/OpenAICompatibleApi.credentials.ts +0 -148
- package/dist/credentials/OpenAICompatibleApi.credentials.d.ts +0 -86
- package/dist/credentials/OpenAICompatibleApi.credentials.js +0 -145
- package/dist/credentials/OpenAICompatibleApi.credentials.ts +0 -148
- package/dist/nodes/OpenAICompatible/NodeDescription.js +0 -377
- package/dist/nodes/OpenAICompatible/OpenAICompatible.node.js +0 -406
- package/dist/nodes/OpenAICompatible/openai-compatible.svg +0 -87
- package/nodes/OpenAICompatible/NodeDescription.js +0 -377
- package/nodes/OpenAICompatible/OpenAICompatible.node.js +0 -406
- package/nodes/OpenAICompatible/openai-compatible.svg +0 -87
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek API Credentials
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
IAuthenticateGeneric,
|
|
7
|
+
ICredentialTestRequest,
|
|
8
|
+
ICredentialType,
|
|
9
|
+
INodeProperties,
|
|
10
|
+
} from 'n8n-workflow';
|
|
11
|
+
|
|
12
|
+
export class DeepSeekApi implements ICredentialType {
|
|
13
|
+
name = 'deepSeekApi';
|
|
14
|
+
displayName = 'DeepSeek API';
|
|
15
|
+
documentationUrl = 'https://api.deepseek.com';
|
|
16
|
+
properties: INodeProperties[] = [
|
|
17
|
+
{
|
|
18
|
+
displayName: 'API Key',
|
|
19
|
+
name: 'apiKey',
|
|
20
|
+
type: 'string',
|
|
21
|
+
typeOptions: {
|
|
22
|
+
password: true,
|
|
23
|
+
},
|
|
24
|
+
default: '',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Base URL',
|
|
28
|
+
name: 'url',
|
|
29
|
+
type: 'hidden',
|
|
30
|
+
default: 'https://api.deepseek.com',
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
authenticate: IAuthenticateGeneric = {
|
|
36
|
+
type: 'generic',
|
|
37
|
+
properties: {
|
|
38
|
+
headers: {
|
|
39
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
test: ICredentialTestRequest = {
|
|
45
|
+
request: {
|
|
46
|
+
baseURL: '={{ $credentials.url }}',
|
|
47
|
+
url: '/models',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama API Credentials
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
IAuthenticateGeneric,
|
|
7
|
+
ICredentialTestRequest,
|
|
8
|
+
ICredentialType,
|
|
9
|
+
INodeProperties,
|
|
10
|
+
} from 'n8n-workflow';
|
|
11
|
+
|
|
12
|
+
export class OllamaApi implements ICredentialType {
|
|
13
|
+
name = 'ollamaApi';
|
|
14
|
+
displayName = 'Ollama API';
|
|
15
|
+
documentationUrl = 'https://ollama.ai';
|
|
16
|
+
properties: INodeProperties[] = [
|
|
17
|
+
{
|
|
18
|
+
displayName: 'Base URL',
|
|
19
|
+
name: 'baseUrl',
|
|
20
|
+
type: 'string',
|
|
21
|
+
default: 'http://localhost:11434',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
displayName: 'API Key',
|
|
26
|
+
hint: 'Optional: for Ollama behind a proxy with authentication',
|
|
27
|
+
name: 'apiKey',
|
|
28
|
+
type: 'string',
|
|
29
|
+
typeOptions: {
|
|
30
|
+
password: true,
|
|
31
|
+
},
|
|
32
|
+
default: '',
|
|
33
|
+
required: false,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
authenticate: IAuthenticateGeneric = {
|
|
38
|
+
type: 'generic',
|
|
39
|
+
properties: {
|
|
40
|
+
headers: {
|
|
41
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
test: ICredentialTestRequest = {
|
|
47
|
+
request: {
|
|
48
|
+
baseURL: '={{ $credentials.baseUrl }}',
|
|
49
|
+
url: '/api/tags',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek API Credentials
|
|
3
|
+
*/
|
|
4
|
+
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
5
|
+
export declare class DeepSeekApi implements ICredentialType {
|
|
6
|
+
name: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
documentationUrl: string;
|
|
9
|
+
properties: INodeProperties[];
|
|
10
|
+
authenticate: IAuthenticateGeneric;
|
|
11
|
+
test: ICredentialTestRequest;
|
|
12
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DeepSeek API Credentials
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DeepSeekApi = void 0;
|
|
7
|
+
class DeepSeekApi {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.name = 'deepSeekApi';
|
|
10
|
+
this.displayName = 'DeepSeek API';
|
|
11
|
+
this.documentationUrl = 'https://api.deepseek.com';
|
|
12
|
+
this.properties = [
|
|
13
|
+
{
|
|
14
|
+
displayName: 'API Key',
|
|
15
|
+
name: 'apiKey',
|
|
16
|
+
type: 'string',
|
|
17
|
+
typeOptions: {
|
|
18
|
+
password: true,
|
|
19
|
+
},
|
|
20
|
+
default: '',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
displayName: 'Base URL',
|
|
24
|
+
name: 'url',
|
|
25
|
+
type: 'hidden',
|
|
26
|
+
default: 'https://api.deepseek.com',
|
|
27
|
+
required: true,
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
this.authenticate = {
|
|
31
|
+
type: 'generic',
|
|
32
|
+
properties: {
|
|
33
|
+
headers: {
|
|
34
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
this.test = {
|
|
39
|
+
request: {
|
|
40
|
+
baseURL: '={{ $credentials.url }}',
|
|
41
|
+
url: '/models',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.DeepSeekApi = DeepSeekApi;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek API Credentials
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
IAuthenticateGeneric,
|
|
7
|
+
ICredentialTestRequest,
|
|
8
|
+
ICredentialType,
|
|
9
|
+
INodeProperties,
|
|
10
|
+
} from 'n8n-workflow';
|
|
11
|
+
|
|
12
|
+
export class DeepSeekApi implements ICredentialType {
|
|
13
|
+
name = 'deepSeekApi';
|
|
14
|
+
displayName = 'DeepSeek API';
|
|
15
|
+
documentationUrl = 'https://api.deepseek.com';
|
|
16
|
+
properties: INodeProperties[] = [
|
|
17
|
+
{
|
|
18
|
+
displayName: 'API Key',
|
|
19
|
+
name: 'apiKey',
|
|
20
|
+
type: 'string',
|
|
21
|
+
typeOptions: {
|
|
22
|
+
password: true,
|
|
23
|
+
},
|
|
24
|
+
default: '',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Base URL',
|
|
28
|
+
name: 'url',
|
|
29
|
+
type: 'hidden',
|
|
30
|
+
default: 'https://api.deepseek.com',
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
authenticate: IAuthenticateGeneric = {
|
|
36
|
+
type: 'generic',
|
|
37
|
+
properties: {
|
|
38
|
+
headers: {
|
|
39
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
test: ICredentialTestRequest = {
|
|
45
|
+
request: {
|
|
46
|
+
baseURL: '={{ $credentials.url }}',
|
|
47
|
+
url: '/models',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama API Credentials
|
|
3
|
+
*/
|
|
4
|
+
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
5
|
+
export declare class OllamaApi implements ICredentialType {
|
|
6
|
+
name: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
documentationUrl: string;
|
|
9
|
+
properties: INodeProperties[];
|
|
10
|
+
authenticate: IAuthenticateGeneric;
|
|
11
|
+
test: ICredentialTestRequest;
|
|
12
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ollama API Credentials
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OllamaApi = void 0;
|
|
7
|
+
class OllamaApi {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.name = 'ollamaApi';
|
|
10
|
+
this.displayName = 'Ollama API';
|
|
11
|
+
this.documentationUrl = 'https://ollama.ai';
|
|
12
|
+
this.properties = [
|
|
13
|
+
{
|
|
14
|
+
displayName: 'Base URL',
|
|
15
|
+
name: 'baseUrl',
|
|
16
|
+
type: 'string',
|
|
17
|
+
default: 'http://localhost:11434',
|
|
18
|
+
required: true,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
displayName: 'API Key',
|
|
22
|
+
hint: 'Optional: for Ollama behind a proxy with authentication',
|
|
23
|
+
name: 'apiKey',
|
|
24
|
+
type: 'string',
|
|
25
|
+
typeOptions: {
|
|
26
|
+
password: true,
|
|
27
|
+
},
|
|
28
|
+
default: '',
|
|
29
|
+
required: false,
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
this.authenticate = {
|
|
33
|
+
type: 'generic',
|
|
34
|
+
properties: {
|
|
35
|
+
headers: {
|
|
36
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
this.test = {
|
|
41
|
+
request: {
|
|
42
|
+
baseURL: '={{ $credentials.baseUrl }}',
|
|
43
|
+
url: '/api/tags',
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.OllamaApi = OllamaApi;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama API Credentials
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
IAuthenticateGeneric,
|
|
7
|
+
ICredentialTestRequest,
|
|
8
|
+
ICredentialType,
|
|
9
|
+
INodeProperties,
|
|
10
|
+
} from 'n8n-workflow';
|
|
11
|
+
|
|
12
|
+
export class OllamaApi implements ICredentialType {
|
|
13
|
+
name = 'ollamaApi';
|
|
14
|
+
displayName = 'Ollama API';
|
|
15
|
+
documentationUrl = 'https://ollama.ai';
|
|
16
|
+
properties: INodeProperties[] = [
|
|
17
|
+
{
|
|
18
|
+
displayName: 'Base URL',
|
|
19
|
+
name: 'baseUrl',
|
|
20
|
+
type: 'string',
|
|
21
|
+
default: 'http://localhost:11434',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
displayName: 'API Key',
|
|
26
|
+
hint: 'Optional: for Ollama behind a proxy with authentication',
|
|
27
|
+
name: 'apiKey',
|
|
28
|
+
type: 'string',
|
|
29
|
+
typeOptions: {
|
|
30
|
+
password: true,
|
|
31
|
+
},
|
|
32
|
+
default: '',
|
|
33
|
+
required: false,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
authenticate: IAuthenticateGeneric = {
|
|
38
|
+
type: 'generic',
|
|
39
|
+
properties: {
|
|
40
|
+
headers: {
|
|
41
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
test: ICredentialTestRequest = {
|
|
47
|
+
request: {
|
|
48
|
+
baseURL: '={{ $credentials.baseUrl }}',
|
|
49
|
+
url: '/api/tags',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek Chat Model Node for n8n
|
|
3
|
+
* Implements LangChain Chat Model interface for AI Agent integration
|
|
4
|
+
*/
|
|
5
|
+
import type { INodeType, INodeTypeDescription, ISupplyDataFunctions, SupplyData } from 'n8n-workflow';
|
|
6
|
+
export declare class LMChatDeepSeek implements INodeType {
|
|
7
|
+
description: INodeTypeDescription;
|
|
8
|
+
supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DeepSeek Chat Model Node for n8n
|
|
4
|
+
* Implements LangChain Chat Model interface for AI Agent integration
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.LMChatDeepSeek = void 0;
|
|
8
|
+
const openai_1 = require("@langchain/openai");
|
|
9
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
10
|
+
class LMChatDeepSeek {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.description = {
|
|
13
|
+
displayName: 'DeepSeek Chat Model',
|
|
14
|
+
name: 'lmChatDeepSeek',
|
|
15
|
+
icon: 'file:deepseek.svg',
|
|
16
|
+
group: ['transform'],
|
|
17
|
+
version: 1,
|
|
18
|
+
description: 'Language model for DeepSeek',
|
|
19
|
+
defaults: {
|
|
20
|
+
name: 'DeepSeek Chat Model',
|
|
21
|
+
},
|
|
22
|
+
// 关键:配置在 AI 分类中
|
|
23
|
+
codex: {
|
|
24
|
+
categories: ['AI'],
|
|
25
|
+
subcategories: {
|
|
26
|
+
AI: ['Language Models'],
|
|
27
|
+
'Language Models': ['Chat Models (Recommended)'],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
// 关键:无输入,输出 AI Language Model
|
|
31
|
+
inputs: [],
|
|
32
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.AiLanguageModel],
|
|
33
|
+
outputNames: ['Model'],
|
|
34
|
+
credentials: [
|
|
35
|
+
{
|
|
36
|
+
name: 'deepSeekApi',
|
|
37
|
+
required: true,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
properties: [
|
|
41
|
+
{
|
|
42
|
+
displayName: 'Model',
|
|
43
|
+
name: 'model',
|
|
44
|
+
type: 'options',
|
|
45
|
+
description: 'The DeepSeek model to use',
|
|
46
|
+
typeOptions: {
|
|
47
|
+
loadOptions: {
|
|
48
|
+
routing: {
|
|
49
|
+
request: {
|
|
50
|
+
method: 'GET',
|
|
51
|
+
url: '/models',
|
|
52
|
+
},
|
|
53
|
+
output: {
|
|
54
|
+
postReceive: [
|
|
55
|
+
{
|
|
56
|
+
type: 'rootProperty',
|
|
57
|
+
properties: { property: 'data' },
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: 'setKeyValue',
|
|
61
|
+
properties: {
|
|
62
|
+
name: '={{$responseItem.id}}',
|
|
63
|
+
value: '={{$responseItem.id}}',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: 'sort',
|
|
68
|
+
properties: { key: 'id' },
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
default: 'deepseek-chat',
|
|
76
|
+
options: [
|
|
77
|
+
{
|
|
78
|
+
name: 'DeepSeek Chat',
|
|
79
|
+
value: 'deepseek-chat',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'DeepSeek Coder',
|
|
83
|
+
value: 'deepseek-coder',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
displayName: 'Options',
|
|
89
|
+
name: 'options',
|
|
90
|
+
type: 'collection',
|
|
91
|
+
placeholder: 'Add Option',
|
|
92
|
+
default: {},
|
|
93
|
+
options: [
|
|
94
|
+
{
|
|
95
|
+
displayName: 'Temperature',
|
|
96
|
+
name: 'temperature',
|
|
97
|
+
type: 'number',
|
|
98
|
+
typeOptions: {
|
|
99
|
+
maxValue: 2,
|
|
100
|
+
minValue: 0,
|
|
101
|
+
numberPrecision: 1,
|
|
102
|
+
},
|
|
103
|
+
default: 0.7,
|
|
104
|
+
description: 'What sampling temperature to use',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
displayName: 'Max Tokens',
|
|
108
|
+
name: 'maxTokens',
|
|
109
|
+
type: 'number',
|
|
110
|
+
default: 2048,
|
|
111
|
+
description: 'The maximum number of tokens to generate',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
displayName: 'Top P',
|
|
115
|
+
name: 'topP',
|
|
116
|
+
type: 'number',
|
|
117
|
+
typeOptions: {
|
|
118
|
+
maxValue: 1,
|
|
119
|
+
minValue: 0,
|
|
120
|
+
numberPrecision: 2,
|
|
121
|
+
},
|
|
122
|
+
default: 1,
|
|
123
|
+
description: 'An alternative to sampling with temperature',
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// 关键:使用 supplyData 方法而非 execute
|
|
131
|
+
async supplyData(itemIndex) {
|
|
132
|
+
const credentials = await this.getCredentials('deepSeekApi');
|
|
133
|
+
const model = this.getNodeParameter('model', itemIndex);
|
|
134
|
+
const options = this.getNodeParameter('options', itemIndex, {});
|
|
135
|
+
const configuration = {
|
|
136
|
+
baseURL: 'https://api.deepseek.com',
|
|
137
|
+
};
|
|
138
|
+
const chatModel = new openai_1.ChatOpenAI({
|
|
139
|
+
apiKey: credentials.apiKey,
|
|
140
|
+
model,
|
|
141
|
+
temperature: options.temperature ?? 0.7,
|
|
142
|
+
maxTokens: options.maxTokens ?? 2048,
|
|
143
|
+
topP: options.topP ?? 1,
|
|
144
|
+
configuration,
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
response: chatModel,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.LMChatDeepSeek = LMChatDeepSeek;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek Chat Model Node for n8n
|
|
3
|
+
* Implements LangChain Chat Model interface for AI Agent integration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ClientOptions,
|
|
8
|
+
ChatOpenAI,
|
|
9
|
+
} from '@langchain/openai';
|
|
10
|
+
import type {
|
|
11
|
+
INodeType,
|
|
12
|
+
INodeTypeDescription,
|
|
13
|
+
ISupplyDataFunctions,
|
|
14
|
+
SupplyData,
|
|
15
|
+
} from 'n8n-workflow';
|
|
16
|
+
import {
|
|
17
|
+
NodeConnectionTypes,
|
|
18
|
+
} from 'n8n-workflow';
|
|
19
|
+
|
|
20
|
+
export class LMChatDeepSeek implements INodeType {
|
|
21
|
+
description: INodeTypeDescription = {
|
|
22
|
+
displayName: 'DeepSeek Chat Model',
|
|
23
|
+
name: 'lmChatDeepSeek',
|
|
24
|
+
icon: 'file:deepseek.svg',
|
|
25
|
+
group: ['transform'],
|
|
26
|
+
version: 1,
|
|
27
|
+
description: 'Language model for DeepSeek',
|
|
28
|
+
defaults: {
|
|
29
|
+
name: 'DeepSeek Chat Model',
|
|
30
|
+
},
|
|
31
|
+
// 关键:配置在 AI 分类中
|
|
32
|
+
codex: {
|
|
33
|
+
categories: ['AI'],
|
|
34
|
+
subcategories: {
|
|
35
|
+
AI: ['Language Models'],
|
|
36
|
+
'Language Models': ['Chat Models (Recommended)'],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
// 关键:无输入,输出 AI Language Model
|
|
40
|
+
inputs: [],
|
|
41
|
+
outputs: [NodeConnectionTypes.AiLanguageModel],
|
|
42
|
+
outputNames: ['Model'],
|
|
43
|
+
credentials: [
|
|
44
|
+
{
|
|
45
|
+
name: 'deepSeekApi',
|
|
46
|
+
required: true,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
properties: [
|
|
50
|
+
{
|
|
51
|
+
displayName: 'Model',
|
|
52
|
+
name: 'model',
|
|
53
|
+
type: 'options',
|
|
54
|
+
description: 'The DeepSeek model to use',
|
|
55
|
+
typeOptions: {
|
|
56
|
+
loadOptions: {
|
|
57
|
+
routing: {
|
|
58
|
+
request: {
|
|
59
|
+
method: 'GET',
|
|
60
|
+
url: '/models',
|
|
61
|
+
},
|
|
62
|
+
output: {
|
|
63
|
+
postReceive: [
|
|
64
|
+
{
|
|
65
|
+
type: 'rootProperty',
|
|
66
|
+
properties: { property: 'data' },
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'setKeyValue',
|
|
70
|
+
properties: {
|
|
71
|
+
name: '={{$responseItem.id}}',
|
|
72
|
+
value: '={{$responseItem.id}}',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'sort',
|
|
77
|
+
properties: { key: 'id' },
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
default: 'deepseek-chat',
|
|
85
|
+
options: [
|
|
86
|
+
{
|
|
87
|
+
name: 'DeepSeek Chat',
|
|
88
|
+
value: 'deepseek-chat',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'DeepSeek Coder',
|
|
92
|
+
value: 'deepseek-coder',
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
displayName: 'Options',
|
|
98
|
+
name: 'options',
|
|
99
|
+
type: 'collection',
|
|
100
|
+
placeholder: 'Add Option',
|
|
101
|
+
default: {},
|
|
102
|
+
options: [
|
|
103
|
+
{
|
|
104
|
+
displayName: 'Temperature',
|
|
105
|
+
name: 'temperature',
|
|
106
|
+
type: 'number',
|
|
107
|
+
typeOptions: {
|
|
108
|
+
maxValue: 2,
|
|
109
|
+
minValue: 0,
|
|
110
|
+
numberPrecision: 1,
|
|
111
|
+
},
|
|
112
|
+
default: 0.7,
|
|
113
|
+
description: 'What sampling temperature to use',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
displayName: 'Max Tokens',
|
|
117
|
+
name: 'maxTokens',
|
|
118
|
+
type: 'number',
|
|
119
|
+
default: 2048,
|
|
120
|
+
description: 'The maximum number of tokens to generate',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
displayName: 'Top P',
|
|
124
|
+
name: 'topP',
|
|
125
|
+
type: 'number',
|
|
126
|
+
typeOptions: {
|
|
127
|
+
maxValue: 1,
|
|
128
|
+
minValue: 0,
|
|
129
|
+
numberPrecision: 2,
|
|
130
|
+
},
|
|
131
|
+
default: 1,
|
|
132
|
+
description: 'An alternative to sampling with temperature',
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// 关键:使用 supplyData 方法而非 execute
|
|
140
|
+
async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
|
|
141
|
+
const credentials = await this.getCredentials('deepSeekApi');
|
|
142
|
+
const model = this.getNodeParameter('model', itemIndex) as string;
|
|
143
|
+
const options = this.getNodeParameter('options', itemIndex, {}) as {
|
|
144
|
+
temperature?: number;
|
|
145
|
+
maxTokens?: number;
|
|
146
|
+
topP?: number;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const configuration: ClientOptions = {
|
|
150
|
+
baseURL: 'https://api.deepseek.com',
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const chatModel = new ChatOpenAI({
|
|
154
|
+
apiKey: credentials.apiKey as string,
|
|
155
|
+
model,
|
|
156
|
+
temperature: options.temperature ?? 0.7,
|
|
157
|
+
maxTokens: options.maxTokens ?? 2048,
|
|
158
|
+
topP: options.topP ?? 1,
|
|
159
|
+
configuration,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
response: chatModel,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama Chat Model Node for n8n
|
|
3
|
+
* Implements LangChain Chat Model interface for Ollama
|
|
4
|
+
*/
|
|
5
|
+
import type { INodeType, INodeTypeDescription, ISupplyDataFunctions, SupplyData } from 'n8n-workflow';
|
|
6
|
+
export declare class LMChatOllama implements INodeType {
|
|
7
|
+
description: INodeTypeDescription;
|
|
8
|
+
supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData>;
|
|
9
|
+
}
|