n8n-nodes-siliconflow-ai 0.3.0 → 0.4.1

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 CHANGED
@@ -84,6 +84,29 @@ USER node
84
84
 
85
85
  ---
86
86
 
87
+ ## 🧩 模型选择:From List / By ID
88
+
89
+ 每个资源(Chat / Vision / Embeddings / Image / Rerank)以及 Chat Model 节点的模型选择都支持两种模式(顶部 **Model Selection** 切换):
90
+
91
+ | 模式 | 说明 |
92
+ |---|---|
93
+ | **From List** | 从内置的常用模型清单里选(清单见下,已按 2026-06 模型广场整理) |
94
+ | **By ID** | 手动输入任意模型 ID,**支持表达式**(如 `={{$json.model}}`)。用于清单未收录、或刚上线尚未更新的模型 |
95
+
96
+ > SiliconFlow 模型会上下架,内置清单无法保证永远最新;遇到列表里没有的模型,直接切到 **By ID** 填入即可,无需等节点更新。
97
+
98
+ 内置清单(按你提供的模型广场整理):
99
+
100
+ - **Chat(21)**:GLM-5.2、Kimi-K2.7-Code、DeepSeek-V4-Pro/Flash、DeepSeek-V3.2(+Pro)、DeepSeek-R1、Nex-N2-Pro、MiniMax-M2.5(+Pro)、Qwen3.6/3.5 系列、Step-3.5-Flash、Ling-mini-2.0、Hunyuan-MT-7B、Seed-OSS-36B 等
101
+ - **Vision(14)**:Qwen3-VL-32B、Qwen3-Omni 系列、GLM-4.5V、DeepSeek-OCR 等
102
+ - **Embedding(8)**:Qwen3-Embedding 系列、bge-m3(+Pro)、bge-large-zh/en 等
103
+ - **Image(7)**:Z-Image(+Turbo)、ERNIE-Image-Turbo、Qwen-Image(+Edit)、Kolors 等
104
+ - **Rerank(6)**:Qwen3-Reranker 系列、bge-reranker-v2-m3(+Pro) 等
105
+
106
+ 清单源码位于 `nodes/shared/models.ts`,可直接增删维护。
107
+
108
+ ---
109
+
87
110
  ## 🚀 典型用法
88
111
 
89
112
  ### 1. 简易聊天工作流
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SiliconFlow = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
+ const models_1 = require("../shared/models");
5
6
  /**
6
7
  * SiliconFlow(硅基流动)AI 节点
7
8
  *
@@ -80,34 +81,14 @@ class SiliconFlow {
80
81
  ],
81
82
  default: 'complete',
82
83
  },
83
- {
84
- displayName: 'Model',
85
- name: 'model',
86
- type: 'options',
87
- displayOptions: { show: { resource: ['chat'], operation: ['complete'] } },
88
- description: 'The model which will generate the completion. All models support tools calling.',
89
- typeOptions: {
90
- loadOptions: {
91
- routing: {
92
- request: { method: 'GET', url: '/models?sub_type=chat' },
93
- output: {
94
- postReceive: [
95
- { type: 'rootProperty', properties: { property: 'data' } },
96
- {
97
- type: 'setKeyValue',
98
- properties: {
99
- name: '={{$responseItem.id}}',
100
- value: '={{$responseItem.id}}',
101
- },
102
- },
103
- { type: 'sort', properties: { key: 'name' } },
104
- ],
105
- },
106
- },
107
- },
108
- },
109
- default: 'THUDM/glm-4-plus',
110
- },
84
+ ...(0, models_1.buildModelSelectionFields)({
85
+ modeName: 'modelMode',
86
+ listName: 'model',
87
+ idName: 'modelId',
88
+ ids: models_1.CHAT_MODEL_IDS,
89
+ show: { resource: ['chat'], operation: ['complete'] },
90
+ defaultList: 'deepseek-ai/DeepSeek-V3.2',
91
+ }),
111
92
  {
112
93
  displayName: 'Messages',
113
94
  name: 'messages',
@@ -308,24 +289,14 @@ class SiliconFlow {
308
289
  ],
309
290
  default: 'analyze',
310
291
  },
311
- {
312
- displayName: 'Model',
313
- name: 'visionModel',
314
- type: 'options',
315
- displayOptions: { show: { resource: ['vision'], operation: ['analyze'] } },
316
- options: [
317
- { name: 'Qwen2.5-VL-72B-Instruct (最强视觉理解)', value: 'Qwen/Qwen2.5-VL-72B-Instruct' },
318
- { name: 'Qwen2.5-VL-32B-Instruct (高性能)', value: 'Qwen/Qwen2.5-VL-32B-Instruct' },
319
- { name: 'QVQ-72B-Preview (视觉推理)', value: 'Qwen/QVQ-72B-Preview' },
320
- { name: 'Qwen2-VL-72B-Instruct', value: 'Qwen/Qwen2-VL-72B-Instruct' },
321
- { name: 'Qwen2-VL-7B-Instruct (Pro)', value: 'Pro/Qwen/Qwen2-VL-7B-Instruct' },
322
- { name: 'Qwen2.5-VL-7B-Instruct (Pro)', value: 'Pro/Qwen/Qwen2.5-VL-7B-Instruct' },
323
- { name: 'DeepSeek-VL2 (短上下文优化)', value: 'deepseek-ai/deepseek-vl2' },
324
- ],
325
- default: 'Qwen/Qwen2.5-VL-32B-Instruct',
326
- required: true,
327
- description: 'The vision language model to use for image analysis',
328
- },
292
+ ...(0, models_1.buildModelSelectionFields)({
293
+ modeName: 'visionModelMode',
294
+ listName: 'visionModel',
295
+ idName: 'visionModelId',
296
+ ids: models_1.VISION_MODEL_IDS,
297
+ show: { resource: ['vision'], operation: ['analyze'] },
298
+ defaultList: 'Qwen/Qwen3-VL-32B-Instruct',
299
+ }),
329
300
  {
330
301
  displayName: 'Images',
331
302
  name: 'images',
@@ -468,25 +439,14 @@ class SiliconFlow {
468
439
  ],
469
440
  default: 'create',
470
441
  },
471
- {
472
- displayName: 'Model',
473
- name: 'embeddingModel',
474
- type: 'options',
475
- displayOptions: { show: { resource: ['embeddings'], operation: ['create'] } },
476
- options: [
477
- { name: 'BAAI/bge-large-zh-v1.5 (中文, 512 tokens)', value: 'BAAI/bge-large-zh-v1.5' },
478
- { name: 'BAAI/bge-large-en-v1.5 (英文, 512 tokens)', value: 'BAAI/bge-large-en-v1.5' },
479
- { name: 'BAAI/bge-m3 (多语言, 8192 tokens)', value: 'BAAI/bge-m3' },
480
- { name: 'Pro/BAAI/bge-m3 (多语言专业版, 8192 tokens)', value: 'Pro/BAAI/bge-m3' },
481
- { name: 'Qwen3-Embedding-8B (32768 tokens)', value: 'Qwen/Qwen3-Embedding-8B' },
482
- { name: 'Qwen3-Embedding-4B (32768 tokens)', value: 'Qwen/Qwen3-Embedding-4B' },
483
- { name: 'Qwen3-Embedding-0.6B (32768 tokens)', value: 'Qwen/Qwen3-Embedding-0.6B' },
484
- { name: 'netease-youdao/bce-embedding-base_v1 (512 tokens)', value: 'netease-youdao/bce-embedding-base_v1' },
485
- { name: 'sentence-transformers/all-MiniLM-L6-v2', value: 'sentence-transformers/all-MiniLM-L6-v2' },
486
- ],
487
- default: 'BAAI/bge-large-zh-v1.5',
488
- required: true,
489
- },
442
+ ...(0, models_1.buildModelSelectionFields)({
443
+ modeName: 'embeddingModelMode',
444
+ listName: 'embeddingModel',
445
+ idName: 'embeddingModelId',
446
+ ids: models_1.EMBEDDING_MODEL_IDS,
447
+ show: { resource: ['embeddings'], operation: ['create'] },
448
+ defaultList: 'BAAI/bge-m3',
449
+ }),
490
450
  {
491
451
  displayName: 'Input',
492
452
  name: 'input',
@@ -534,21 +494,14 @@ class SiliconFlow {
534
494
  ],
535
495
  default: 'generate',
536
496
  },
537
- {
538
- displayName: 'Model',
539
- name: 'imageModel',
540
- type: 'options',
541
- displayOptions: { show: { resource: ['image'], operation: ['generate'] } },
542
- options: [
543
- { name: 'FLUX.1-schnell', value: 'black-forest-labs/FLUX.1-schnell' },
544
- { name: 'FLUX.1-dev', value: 'black-forest-labs/FLUX.1-dev' },
545
- { name: 'Stable Diffusion 2.1', value: 'stabilityai/stable-diffusion-2-1' },
546
- { name: 'Stable Diffusion 3.5 Large', value: 'stabilityai/stable-diffusion-3.5-large' },
547
- { name: 'Kolors', value: 'Kwai-Kolors/Kolors' },
548
- ],
549
- default: 'black-forest-labs/FLUX.1-schnell',
550
- required: true,
551
- },
497
+ ...(0, models_1.buildModelSelectionFields)({
498
+ modeName: 'imageModelMode',
499
+ listName: 'imageModel',
500
+ idName: 'imageModelId',
501
+ ids: models_1.IMAGE_MODEL_IDS,
502
+ show: { resource: ['image'], operation: ['generate'] },
503
+ defaultList: 'Tongyi-MAI/Z-Image-Turbo',
504
+ }),
552
505
  {
553
506
  displayName: 'Prompt',
554
507
  name: 'imagePrompt',
@@ -634,22 +587,14 @@ class SiliconFlow {
634
587
  ],
635
588
  default: 'create',
636
589
  },
637
- {
638
- displayName: 'Model',
639
- name: 'rerankModel',
640
- type: 'options',
641
- displayOptions: { show: { resource: ['rerank'], operation: ['create'] } },
642
- options: [
643
- { name: 'Qwen3-Reranker-8B', value: 'Qwen/Qwen3-Reranker-8B' },
644
- { name: 'Qwen3-Reranker-4B', value: 'Qwen/Qwen3-Reranker-4B' },
645
- { name: 'Qwen3-Reranker-0.6B', value: 'Qwen/Qwen3-Reranker-0.6B' },
646
- { name: 'BAAI/bge-reranker-v2-m3', value: 'BAAI/bge-reranker-v2-m3' },
647
- { name: 'Pro/BAAI/bge-reranker-v2-m3 (专业版)', value: 'Pro/BAAI/bge-reranker-v2-m3' },
648
- { name: 'netease-youdao/bce-reranker-base_v1', value: 'netease-youdao/bce-reranker-base_v1' },
649
- ],
650
- default: 'BAAI/bge-reranker-v2-m3',
651
- required: true,
652
- },
590
+ ...(0, models_1.buildModelSelectionFields)({
591
+ modeName: 'rerankModelMode',
592
+ listName: 'rerankModel',
593
+ idName: 'rerankModelId',
594
+ ids: models_1.RERANK_MODEL_IDS,
595
+ show: { resource: ['rerank'], operation: ['create'] },
596
+ defaultList: 'BAAI/bge-reranker-v2-m3',
597
+ }),
653
598
  {
654
599
  displayName: 'Query',
655
600
  name: 'query',
@@ -758,9 +703,14 @@ exports.SiliconFlow = SiliconFlow;
758
703
  // SiliconFlow credential (Bearer token injected automatically).
759
704
  // ----------------------------------------------------------------
760
705
  async function siliconflowRequest(path, body) {
706
+ // httpRequestWithAuthentication does NOT apply the node-level requestDefaults.baseURL,
707
+ // so we must build a fully-qualified URL from the credential's baseUrl ourselves.
708
+ // (The Authorization header IS injected automatically from the credential.)
709
+ const credentials = (await this.getCredentials('siliconFlowApi'));
710
+ const baseUrl = (credentials.baseUrl || '').replace(/\/+$/, '');
761
711
  const options = {
762
712
  method: 'POST',
763
- url: path,
713
+ url: `${baseUrl}${path}`,
764
714
  body,
765
715
  json: true,
766
716
  headers: { 'Content-Type': 'application/json' },
@@ -771,7 +721,7 @@ async function siliconflowRequest(path, body) {
771
721
  // Chat Completion
772
722
  // ----------------------------------------------------------------
773
723
  async function handleChat(itemIndex) {
774
- const model = this.getNodeParameter('model', itemIndex);
724
+ const model = (0, models_1.resolveModelId)(this, itemIndex, 'modelMode', 'model', 'modelId');
775
725
  const prompt = this.getNodeParameter('prompt', itemIndex, '');
776
726
  const messagesParam = this.getNodeParameter('messages', itemIndex, {});
777
727
  const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {});
@@ -842,7 +792,7 @@ async function handleChat(itemIndex) {
842
792
  // ----------------------------------------------------------------
843
793
  async function handleVision(itemIndex) {
844
794
  const items = this.getInputData();
845
- const model = this.getNodeParameter('visionModel', itemIndex);
795
+ const model = (0, models_1.resolveModelId)(this, itemIndex, 'visionModelMode', 'visionModel', 'visionModelId');
846
796
  const prompt = this.getNodeParameter('visionPrompt', itemIndex);
847
797
  const imagesParam = this.getNodeParameter('images', itemIndex, {});
848
798
  const additionalFields = this.getNodeParameter('visionAdditionalFields', itemIndex, {});
@@ -956,7 +906,7 @@ async function handleVision(itemIndex) {
956
906
  // Embeddings
957
907
  // ----------------------------------------------------------------
958
908
  async function handleEmbeddings(itemIndex) {
959
- const model = this.getNodeParameter('embeddingModel', itemIndex);
909
+ const model = (0, models_1.resolveModelId)(this, itemIndex, 'embeddingModelMode', 'embeddingModel', 'embeddingModelId');
960
910
  const inputRaw = this.getNodeParameter('input', itemIndex);
961
911
  const additionalFields = this.getNodeParameter('embeddingAdditionalFields', itemIndex, {});
962
912
  // input may be a plain string or a JSON array of strings
@@ -998,7 +948,7 @@ async function handleEmbeddings(itemIndex) {
998
948
  // Image Generation
999
949
  // ----------------------------------------------------------------
1000
950
  async function handleImage(itemIndex) {
1001
- const model = this.getNodeParameter('imageModel', itemIndex);
951
+ const model = (0, models_1.resolveModelId)(this, itemIndex, 'imageModelMode', 'imageModel', 'imageModelId');
1002
952
  const prompt = this.getNodeParameter('imagePrompt', itemIndex);
1003
953
  const additionalFields = this.getNodeParameter('imageAdditionalFields', itemIndex, {});
1004
954
  const requestBody = {
@@ -1030,7 +980,7 @@ async function handleImage(itemIndex) {
1030
980
  // Rerank
1031
981
  // ----------------------------------------------------------------
1032
982
  async function handleRerank(itemIndex) {
1033
- const model = this.getNodeParameter('rerankModel', itemIndex);
983
+ const model = (0, models_1.resolveModelId)(this, itemIndex, 'rerankModelMode', 'rerankModel', 'rerankModelId');
1034
984
  const query = this.getNodeParameter('query', itemIndex);
1035
985
  const documentsParam = this.getNodeParameter('documents', itemIndex);
1036
986
  const additionalFields = this.getNodeParameter('rerankAdditionalFields', itemIndex, {});
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.SiliconFlowChatModel = void 0;
5
5
  const openai_1 = require("@langchain/openai");
6
+ const models_1 = require("../shared/models");
6
7
  class SiliconFlowChatModel {
7
8
  constructor() {
8
9
  this.description = {
@@ -53,52 +54,14 @@ class SiliconFlowChatModel {
53
54
  type: 'notice',
54
55
  default: '',
55
56
  },
56
- {
57
- displayName: 'Model',
58
- name: 'model',
59
- type: 'options',
60
- description: 'The model which will generate the completion. All models support tools calling.',
61
- typeOptions: {
62
- loadOptions: {
63
- routing: {
64
- request: {
65
- method: 'GET',
66
- url: '/models?sub_type=chat',
67
- },
68
- output: {
69
- postReceive: [
70
- {
71
- type: 'rootProperty',
72
- properties: {
73
- property: 'data',
74
- },
75
- },
76
- {
77
- type: 'setKeyValue',
78
- properties: {
79
- name: '={{$responseItem.id}}',
80
- value: '={{$responseItem.id}}',
81
- },
82
- },
83
- {
84
- type: 'sort',
85
- properties: {
86
- key: 'name',
87
- },
88
- },
89
- ],
90
- },
91
- },
92
- },
93
- },
94
- routing: {
95
- send: {
96
- type: 'body',
97
- property: 'model',
98
- },
99
- },
100
- default: 'THUDM/glm-4-plus',
101
- },
57
+ ...(0, models_1.buildModelSelectionFields)({
58
+ modeName: 'modelMode',
59
+ listName: 'model',
60
+ idName: 'modelId',
61
+ ids: models_1.CHAT_MODEL_IDS,
62
+ show: {},
63
+ defaultList: 'deepseek-ai/DeepSeek-V3.2',
64
+ }),
102
65
  {
103
66
  displayName: 'Options',
104
67
  name: 'options',
@@ -241,7 +204,7 @@ class SiliconFlowChatModel {
241
204
  }
242
205
  async supplyData(itemIndex) {
243
206
  const credentials = await this.getCredentials('siliconFlowApi');
244
- const modelName = this.getNodeParameter('model', itemIndex);
207
+ const modelName = (0, models_1.resolveModelId)(this, itemIndex, 'modelMode', 'model', 'modelId');
245
208
  const options = this.getNodeParameter('options', itemIndex, {});
246
209
  const configuration = {
247
210
  baseURL: credentials.baseUrl,
@@ -0,0 +1,41 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ /**
3
+ * SiliconFlow(硅基流动)常用模型清单。
4
+ *
5
+ * 说明:SiliconFlow 的模型清单会随时间上下架,这里只收录"常用且稳定"的模型 ID。
6
+ * 任何未列入的模型(含新上线或即将下架的)都可通过节点里的 "By ID" 模式手动填写,
7
+ * 因此本清单无需保持 100% 最新。
8
+ *
9
+ * 清单来源:用户按 https://cloud.siliconflow.cn/me/models 整理(2026-06)。
10
+ */
11
+ export declare const CHAT_MODEL_IDS: string[];
12
+ export declare const VISION_MODEL_IDS: string[];
13
+ export declare const EMBEDDING_MODEL_IDS: string[];
14
+ export declare const IMAGE_MODEL_IDS: string[];
15
+ export declare const RERANK_MODEL_IDS: string[];
16
+ /**
17
+ * 生成一组"模型选择"参数:模式切换(From List / By ID) + 列表选择 + 自定义 ID 输入。
18
+ *
19
+ * 返回 3 个 INodeProperties:
20
+ * - {modeName}: options ['list' | 'id']
21
+ * - {listName}: options (仅 mode=list 时显示)
22
+ * - {idName}: string (仅 mode=id 时显示,支持表达式)
23
+ *
24
+ * @param show 资源/操作门控条件(displayOptions.show),会与 mode 条件合并
25
+ */
26
+ export declare function buildModelSelectionFields(params: {
27
+ modeName: string;
28
+ listName: string;
29
+ idName: string;
30
+ displayName?: string;
31
+ ids: string[];
32
+ show: Record<string, string[]>;
33
+ defaultList?: string;
34
+ }): INodeProperties[];
35
+ /**
36
+ * 根据模式解析出实际要使用的模型 ID。
37
+ * mode=list 时取列表选择值;mode=id 时取自定义输入值。
38
+ */
39
+ export declare function resolveModelId(ctx: {
40
+ getNodeParameter: (name: string, itemIndex: number, fallback?: unknown) => unknown;
41
+ }, itemIndex: number, modeName: string, listName: string, idName: string): string;
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RERANK_MODEL_IDS = exports.IMAGE_MODEL_IDS = exports.EMBEDDING_MODEL_IDS = exports.VISION_MODEL_IDS = exports.CHAT_MODEL_IDS = void 0;
4
+ exports.buildModelSelectionFields = buildModelSelectionFields;
5
+ exports.resolveModelId = resolveModelId;
6
+ /**
7
+ * SiliconFlow(硅基流动)常用模型清单。
8
+ *
9
+ * 说明:SiliconFlow 的模型清单会随时间上下架,这里只收录"常用且稳定"的模型 ID。
10
+ * 任何未列入的模型(含新上线或即将下架的)都可通过节点里的 "By ID" 模式手动填写,
11
+ * 因此本清单无需保持 100% 最新。
12
+ *
13
+ * 清单来源:用户按 https://cloud.siliconflow.cn/me/models 整理(2026-06)。
14
+ */
15
+ // ----------------------------------------------------------------
16
+ // Chat(对话 / 文本生成)模型 —— 用于 SiliconFlow 节点 Chat 资源 + Chat Model 节点
17
+ // ----------------------------------------------------------------
18
+ exports.CHAT_MODEL_IDS = [
19
+ 'zai-org/GLM-5.2',
20
+ 'Pro/zai-org/GLM-5.1',
21
+ 'moonshotai/Kimi-K2.7-Code',
22
+ 'Pro/moonshotai/Kimi-K2.6',
23
+ 'deepseek-ai/DeepSeek-V4-Pro',
24
+ 'deepseek-ai/DeepSeek-V4-Flash',
25
+ 'deepseek-ai/DeepSeek-V3.2',
26
+ 'Pro/deepseek-ai/DeepSeek-V3.2',
27
+ 'deepseek-ai/DeepSeek-R1',
28
+ 'nex-agi/Nex-N2-Pro',
29
+ 'MiniMaxAI/MiniMax-M2.5',
30
+ 'Pro/MiniMaxAI/MiniMax-M2.5',
31
+ 'Qwen/Qwen3.6-35B-A3B',
32
+ 'Qwen/Qwen3.6-27B',
33
+ 'Qwen/Qwen3.5-397B-A17B',
34
+ 'Qwen/Qwen3.5-122B-A10B',
35
+ 'PaddlePaddle/PaddleOCR-VL-1.5',
36
+ 'stepfun-ai/Step-3.5-Flash',
37
+ 'inclusionAI/Ling-mini-2.0',
38
+ 'tencent/Hunyuan-MT-7B',
39
+ 'ByteDance-Seed/Seed-OSS-36B-Instruct',
40
+ ];
41
+ // ----------------------------------------------------------------
42
+ // Vision(视觉 / 多模态)模型 —— SiliconFlow 节点 Vision 资源
43
+ // ----------------------------------------------------------------
44
+ exports.VISION_MODEL_IDS = [
45
+ 'Qwen/Qwen3-VL-32B-Instruct',
46
+ 'Qwen/Qwen3-VL-32B-Thinking',
47
+ 'Qwen/Qwen3-Omni-30B-A3B-Instruct',
48
+ 'Qwen/Qwen3-Omni-30B-A3B-Thinking',
49
+ 'Qwen/Qwen3-Omni-30B-A3B-Captioner',
50
+ 'zai-org/GLM-4.5V',
51
+ 'deepseek-ai/DeepSeek-OCR',
52
+ 'nex-agi/Nex-N2-Pro',
53
+ 'moonshotai/Kimi-K2.7-Code',
54
+ 'Pro/moonshotai/Kimi-K2.6',
55
+ 'Qwen/Qwen3.6-35B-A3B',
56
+ 'Qwen/Qwen3.6-27B',
57
+ 'Qwen/Qwen3.5-397B-A17B',
58
+ 'Qwen/Qwen3.5-122B-A10B',
59
+ ];
60
+ // ----------------------------------------------------------------
61
+ // Embedding(向量)模型 —— SiliconFlow 节点 Embeddings 资源
62
+ // ----------------------------------------------------------------
63
+ exports.EMBEDDING_MODEL_IDS = [
64
+ 'Qwen/Qwen3-VL-Embedding-8B',
65
+ 'Qwen/Qwen3-Embedding-8B',
66
+ 'Qwen/Qwen3-Embedding-4B',
67
+ 'Qwen/Qwen3-Embedding-0.6B',
68
+ 'BAAI/bge-m3',
69
+ 'Pro/BAAI/bge-m3',
70
+ 'BAAI/bge-large-zh-v1.5',
71
+ 'BAAI/bge-large-en-v1.5',
72
+ ];
73
+ // ----------------------------------------------------------------
74
+ // Image(文生图)模型 —— SiliconFlow 节点 Image 资源
75
+ // ----------------------------------------------------------------
76
+ exports.IMAGE_MODEL_IDS = [
77
+ 'Tongyi-MAI/Z-Image-Turbo',
78
+ 'Tongyi-MAI/Z-Image',
79
+ 'baidu/ERNIE-Image-Turbo',
80
+ 'Qwen/Qwen-Image',
81
+ 'Qwen/Qwen-Image-Edit',
82
+ 'Qwen/Qwen-Image-Edit-2509',
83
+ 'Kwai-Kolors/Kolors',
84
+ ];
85
+ // ----------------------------------------------------------------
86
+ // Rerank(重排)模型 —— SiliconFlow 节点 Rerank 资源
87
+ // ----------------------------------------------------------------
88
+ exports.RERANK_MODEL_IDS = [
89
+ 'Qwen/Qwen3-VL-Reranker-8B',
90
+ 'Qwen/Qwen3-Reranker-8B',
91
+ 'Qwen/Qwen3-Reranker-4B',
92
+ 'Qwen/Qwen3-Reranker-0.6B',
93
+ 'BAAI/bge-reranker-v2-m3',
94
+ 'Pro/BAAI/bge-reranker-v2-m3',
95
+ ];
96
+ /** 把 ID 数组转成 n8n options(显示名 = ID,值 = ID,所见即所发)。 */
97
+ function toOptions(ids) {
98
+ return ids.map((id) => ({ name: id, value: id }));
99
+ }
100
+ /**
101
+ * 生成一组"模型选择"参数:模式切换(From List / By ID) + 列表选择 + 自定义 ID 输入。
102
+ *
103
+ * 返回 3 个 INodeProperties:
104
+ * - {modeName}: options ['list' | 'id']
105
+ * - {listName}: options (仅 mode=list 时显示)
106
+ * - {idName}: string (仅 mode=id 时显示,支持表达式)
107
+ *
108
+ * @param show 资源/操作门控条件(displayOptions.show),会与 mode 条件合并
109
+ */
110
+ function buildModelSelectionFields(params) {
111
+ const { modeName, listName, idName, ids, show, defaultList } = params;
112
+ const displayName = params.displayName ?? 'Model';
113
+ return [
114
+ {
115
+ displayName: 'Model Selection',
116
+ name: modeName,
117
+ type: 'options',
118
+ noDataExpression: true,
119
+ displayOptions: { show },
120
+ options: [
121
+ { name: 'From List', value: 'list', description: '从常用模型列表中选择' },
122
+ { name: 'By ID', value: 'id', description: '手动输入任意模型 ID(用于列表中未收录的模型)' },
123
+ ],
124
+ default: 'list',
125
+ },
126
+ {
127
+ displayName: displayName,
128
+ name: listName,
129
+ type: 'options',
130
+ noDataExpression: true,
131
+ displayOptions: { show: { ...show, [modeName]: ['list'] } },
132
+ options: toOptions(ids),
133
+ default: defaultList ?? ids[0],
134
+ description: '从常用模型列表中选择。若所需模型不在列表,请将上方 "Model Selection" 切换为 By ID。',
135
+ },
136
+ {
137
+ displayName: displayName,
138
+ name: idName,
139
+ type: 'string',
140
+ displayOptions: { show: { ...show, [modeName]: ['id'] } },
141
+ default: '',
142
+ placeholder: '例如 deepseek-ai/DeepSeek-V3.2',
143
+ description: '手动输入模型 ID(支持表达式,如 {{$json.model}})。',
144
+ },
145
+ ];
146
+ }
147
+ /**
148
+ * 根据模式解析出实际要使用的模型 ID。
149
+ * mode=list 时取列表选择值;mode=id 时取自定义输入值。
150
+ */
151
+ function resolveModelId(ctx, itemIndex, modeName, listName, idName) {
152
+ const mode = ctx.getNodeParameter(modeName, itemIndex, 'list');
153
+ if (mode === 'id') {
154
+ const id = ctx.getNodeParameter(idName, itemIndex, '');
155
+ if (!id || !id.trim()) {
156
+ throw new Error('Model ID is required when using "By ID" mode');
157
+ }
158
+ return id.trim();
159
+ }
160
+ return ctx.getNodeParameter(listName, itemIndex, '');
161
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-siliconflow-ai",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "n8n community node for SiliconFlow (硅基流动). Zero runtime dependencies. Provides a SiliconFlow action node (Chat / Vision / Embeddings / Image / Rerank) and a LangChain-compatible Chat Model node for AI Agents. Installs cleanly without ERESOLVE langchain peer-dependency conflicts.",
5
5
  "keywords": [
6
6
  "n8n",