n8n-nodes-comfyui-all 2.2.23 → 2.3.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/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/nodes/ComfyUi/ComfyUi.node.d.ts +63 -30
- package/dist/nodes/ComfyUi/ComfyUi.node.d.ts.map +1 -1
- package/dist/nodes/ComfyUi/ComfyUi.node.js +142 -55
- package/dist/nodes/ComfyUi/ComfyUi.node.js.map +1 -1
- package/dist/nodes/ComfyUiTool/ComfyUiTool.node.d.ts +157 -0
- package/dist/nodes/ComfyUiTool/ComfyUiTool.node.d.ts.map +1 -0
- package/dist/nodes/ComfyUiTool/ComfyUiTool.node.js +435 -0
- package/dist/nodes/ComfyUiTool/ComfyUiTool.node.js.map +1 -0
- package/dist/nodes/ComfyUiTool.node.d.ts +125 -0
- package/dist/nodes/ComfyUiTool.node.d.ts.map +1 -0
- package/dist/nodes/ComfyUiTool.node.js +265 -0
- package/dist/nodes/ComfyUiTool.node.js.map +1 -0
- package/dist/nodes/agentToolHelpers.d.ts +93 -0
- package/dist/nodes/agentToolHelpers.d.ts.map +1 -0
- package/dist/nodes/agentToolHelpers.js +337 -0
- package/dist/nodes/agentToolHelpers.js.map +1 -0
- package/dist/nodes/parameterProcessor.d.ts.map +1 -1
- package/dist/nodes/parameterProcessor.js +19 -9
- package/dist/nodes/parameterProcessor.js.map +1 -1
- package/dist/nodes/validation.d.ts +10 -0
- package/dist/nodes/validation.d.ts.map +1 -1
- package/dist/nodes/validation.js +81 -0
- package/dist/nodes/validation.js.map +1 -1
- package/dist/nodes/workflowConfig.d.ts +8 -1
- package/dist/nodes/workflowConfig.d.ts.map +1 -1
- package/dist/nodes/workflowConfig.js +75 -1
- package/dist/nodes/workflowConfig.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ComfyUI Tool - AI Agent-friendly image generation node
|
|
3
|
+
*
|
|
4
|
+
* This node is designed to be used as an AI Agent tool with minimal configuration.
|
|
5
|
+
* It accepts a simple text query and automatically generates images using ComfyUI.
|
|
6
|
+
* Supports both Text-to-Image and Image-to-Image workflows.
|
|
7
|
+
*/
|
|
8
|
+
import { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
9
|
+
export declare class ComfyUiTool {
|
|
10
|
+
/**
|
|
11
|
+
* Node description for n8n
|
|
12
|
+
*/
|
|
13
|
+
description: {
|
|
14
|
+
displayName: string;
|
|
15
|
+
name: string;
|
|
16
|
+
icon: string;
|
|
17
|
+
iconColor: string;
|
|
18
|
+
group: string[];
|
|
19
|
+
version: number[];
|
|
20
|
+
defaultVersion: number;
|
|
21
|
+
description: string;
|
|
22
|
+
defaults: {
|
|
23
|
+
name: string;
|
|
24
|
+
};
|
|
25
|
+
usableAsTool: boolean;
|
|
26
|
+
inputs: string[];
|
|
27
|
+
outputs: string[];
|
|
28
|
+
subtitle: string;
|
|
29
|
+
notes: string[];
|
|
30
|
+
inputSample: {
|
|
31
|
+
query: string;
|
|
32
|
+
parameters: {
|
|
33
|
+
seed: number;
|
|
34
|
+
steps: number;
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
outputSample: {
|
|
40
|
+
json: {
|
|
41
|
+
success: boolean;
|
|
42
|
+
imageCount: number;
|
|
43
|
+
imageUrls: string[];
|
|
44
|
+
prompt: string;
|
|
45
|
+
mode: string;
|
|
46
|
+
parameters: {
|
|
47
|
+
width: number;
|
|
48
|
+
height: number;
|
|
49
|
+
steps: number;
|
|
50
|
+
cfg: number;
|
|
51
|
+
seed: number;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
properties: ({
|
|
56
|
+
displayName: string;
|
|
57
|
+
name: string;
|
|
58
|
+
type: string;
|
|
59
|
+
required: boolean;
|
|
60
|
+
default: string;
|
|
61
|
+
description: string;
|
|
62
|
+
minValue?: undefined;
|
|
63
|
+
maxValue?: undefined;
|
|
64
|
+
typeOptions?: undefined;
|
|
65
|
+
validate?: undefined;
|
|
66
|
+
placeholder?: undefined;
|
|
67
|
+
displayOptions?: undefined;
|
|
68
|
+
} | {
|
|
69
|
+
displayName: string;
|
|
70
|
+
name: string;
|
|
71
|
+
type: string;
|
|
72
|
+
default: number;
|
|
73
|
+
description: string;
|
|
74
|
+
minValue: number;
|
|
75
|
+
maxValue: number;
|
|
76
|
+
required?: undefined;
|
|
77
|
+
typeOptions?: undefined;
|
|
78
|
+
validate?: undefined;
|
|
79
|
+
placeholder?: undefined;
|
|
80
|
+
displayOptions?: undefined;
|
|
81
|
+
} | {
|
|
82
|
+
displayName: string;
|
|
83
|
+
name: string;
|
|
84
|
+
type: string;
|
|
85
|
+
required: boolean;
|
|
86
|
+
typeOptions: {
|
|
87
|
+
rows: number;
|
|
88
|
+
loadOptionsMethod?: undefined;
|
|
89
|
+
};
|
|
90
|
+
default: string;
|
|
91
|
+
description: string;
|
|
92
|
+
validate: (parameterValue: string) => Promise<string | undefined>;
|
|
93
|
+
minValue?: undefined;
|
|
94
|
+
maxValue?: undefined;
|
|
95
|
+
placeholder?: undefined;
|
|
96
|
+
displayOptions?: undefined;
|
|
97
|
+
} | {
|
|
98
|
+
displayName: string;
|
|
99
|
+
name: string;
|
|
100
|
+
type: string;
|
|
101
|
+
description: string;
|
|
102
|
+
typeOptions: {
|
|
103
|
+
loadOptionsMethod: string;
|
|
104
|
+
rows?: undefined;
|
|
105
|
+
};
|
|
106
|
+
placeholder: string;
|
|
107
|
+
default: string;
|
|
108
|
+
required?: undefined;
|
|
109
|
+
minValue?: undefined;
|
|
110
|
+
maxValue?: undefined;
|
|
111
|
+
validate?: undefined;
|
|
112
|
+
displayOptions?: undefined;
|
|
113
|
+
} | {
|
|
114
|
+
displayName: string;
|
|
115
|
+
name: string;
|
|
116
|
+
type: string;
|
|
117
|
+
description: string;
|
|
118
|
+
typeOptions: {
|
|
119
|
+
loadOptionsMethod: string;
|
|
120
|
+
rows?: undefined;
|
|
121
|
+
};
|
|
122
|
+
placeholder: string;
|
|
123
|
+
default: never[];
|
|
124
|
+
displayOptions: {
|
|
125
|
+
show: {
|
|
126
|
+
nodeId: (string | null | undefined)[];
|
|
127
|
+
mode: string;
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
required?: undefined;
|
|
131
|
+
minValue?: undefined;
|
|
132
|
+
maxValue?: undefined;
|
|
133
|
+
validate?: undefined;
|
|
134
|
+
})[];
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Execute function - called when the node runs
|
|
138
|
+
*/
|
|
139
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
140
|
+
/**
|
|
141
|
+
* Load all nodes from workflow JSON for Node ID dropdown
|
|
142
|
+
*/
|
|
143
|
+
getWorkflowNodes(this: IExecuteFunctions): Promise<{
|
|
144
|
+
name: string;
|
|
145
|
+
value: string;
|
|
146
|
+
description?: string;
|
|
147
|
+
}[]>;
|
|
148
|
+
/**
|
|
149
|
+
* Load parameters for a specific node for Allowed Parameters multi-select
|
|
150
|
+
*/
|
|
151
|
+
getNodeParameters(this: IExecuteFunctions): Promise<{
|
|
152
|
+
name: string;
|
|
153
|
+
value: string;
|
|
154
|
+
description?: string;
|
|
155
|
+
}[]>;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=ComfyUiTool.node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComfyUiTool.node.d.ts","sourceRoot":"","sources":["../../../nodes/ComfyUiTool/ComfyUiTool.node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAEnB,MAAM,cAAc,CAAC;AAiBtB,qBAAa,WAAW;IACtB;;OAEG;IACH,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCA+E4B,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuD3C;IAEF;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;IA+OvE;;OAEG;IACG,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAmCjH;;OAEG;IACG,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAsDnH"}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ComfyUI Tool - AI Agent-friendly image generation node
|
|
4
|
+
*
|
|
5
|
+
* This node is designed to be used as an AI Agent tool with minimal configuration.
|
|
6
|
+
* It accepts a simple text query and automatically generates images using ComfyUI.
|
|
7
|
+
* Supports both Text-to-Image and Image-to-Image workflows.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ComfyUiTool = void 0;
|
|
11
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
12
|
+
const ComfyUiClient_1 = require("../ComfyUiClient");
|
|
13
|
+
const validation_1 = require("../validation");
|
|
14
|
+
const logger_1 = require("../logger");
|
|
15
|
+
const agentToolHelpers_1 = require("../agentToolHelpers");
|
|
16
|
+
class ComfyUiTool {
|
|
17
|
+
constructor() {
|
|
18
|
+
/**
|
|
19
|
+
* Node description for n8n
|
|
20
|
+
*/
|
|
21
|
+
this.description = {
|
|
22
|
+
displayName: 'ComfyUI Tool',
|
|
23
|
+
name: 'comfyUiTool',
|
|
24
|
+
icon: 'file:comfyui.svg',
|
|
25
|
+
iconColor: '#77C157',
|
|
26
|
+
group: ['transform'],
|
|
27
|
+
version: [1],
|
|
28
|
+
defaultVersion: 1,
|
|
29
|
+
description: 'AI-friendly image generation tool. Supports text-to-image and image-to-image.',
|
|
30
|
+
defaults: {
|
|
31
|
+
name: 'ComfyUI Tool',
|
|
32
|
+
},
|
|
33
|
+
usableAsTool: true,
|
|
34
|
+
inputs: ['main'],
|
|
35
|
+
outputs: ['main'],
|
|
36
|
+
subtitle: 'AI Image Generator',
|
|
37
|
+
notes: [
|
|
38
|
+
'AI Agent-friendly ComfyUI tool',
|
|
39
|
+
'Requires ComfyUI workflow JSON in API format',
|
|
40
|
+
'Export workflow: ComfyUI Menu > Export > API Format',
|
|
41
|
+
'Supports both text-to-image and image-to-image workflows',
|
|
42
|
+
'Configure which node/parameters AI can modify using "Node ID" and "Allowed Parameters"',
|
|
43
|
+
'AI Agent provides: { query: "...", parameters: { seed: 123456, steps: 30 } }',
|
|
44
|
+
'Only parameters in "Allowed Parameters" list will be applied',
|
|
45
|
+
'Legacy format supported: "A sunset, size:1024x768, steps:30"',
|
|
46
|
+
],
|
|
47
|
+
inputSample: {
|
|
48
|
+
query: 'A beautiful landscape painting',
|
|
49
|
+
parameters: {
|
|
50
|
+
seed: 123456,
|
|
51
|
+
steps: 30,
|
|
52
|
+
width: 1024,
|
|
53
|
+
height: 768,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
outputSample: {
|
|
57
|
+
json: {
|
|
58
|
+
success: true,
|
|
59
|
+
imageCount: 1,
|
|
60
|
+
imageUrls: ['http://127.0.0.1:8188/view?filename=ComfyUI_00001.png'],
|
|
61
|
+
prompt: 'A beautiful landscape painting',
|
|
62
|
+
mode: 'text-to-image',
|
|
63
|
+
parameters: {
|
|
64
|
+
width: 1024,
|
|
65
|
+
height: 768,
|
|
66
|
+
steps: 30,
|
|
67
|
+
cfg: 8,
|
|
68
|
+
seed: 123456,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
properties: [
|
|
73
|
+
{
|
|
74
|
+
displayName: 'ComfyUI URL',
|
|
75
|
+
name: 'comfyUiUrl',
|
|
76
|
+
type: 'string',
|
|
77
|
+
required: true,
|
|
78
|
+
default: 'http://127.0.0.1:8188',
|
|
79
|
+
description: 'URL of ComfyUI server',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
displayName: 'Timeout (Seconds)',
|
|
83
|
+
name: 'timeout',
|
|
84
|
+
type: 'number',
|
|
85
|
+
default: 120,
|
|
86
|
+
description: 'Maximum time to wait for image generation (in seconds). Default: 120 (2 minutes).',
|
|
87
|
+
minValue: 10,
|
|
88
|
+
maxValue: 600,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
displayName: 'Workflow JSON',
|
|
92
|
+
name: 'workflowJson',
|
|
93
|
+
type: 'string',
|
|
94
|
+
required: true,
|
|
95
|
+
typeOptions: {
|
|
96
|
+
rows: 20,
|
|
97
|
+
},
|
|
98
|
+
default: '',
|
|
99
|
+
description: 'ComfyUI workflow JSON in API format. Export your workflow from ComfyUI (Menu > Export > API Format) and paste here.',
|
|
100
|
+
validate: async (parameterValue) => {
|
|
101
|
+
if (!parameterValue || parameterValue.trim().length === 0) {
|
|
102
|
+
// eslint-disable-next-line n8n-nodes-base/node-execute-block-wrong-error-thrown
|
|
103
|
+
throw new Error('Workflow JSON is required');
|
|
104
|
+
}
|
|
105
|
+
const validation = (0, validation_1.validateComfyUIWorkflowEnhanced)(parameterValue);
|
|
106
|
+
if (!validation.valid) {
|
|
107
|
+
// eslint-disable-next-line n8n-nodes-base/node-execute-block-wrong-error-thrown
|
|
108
|
+
throw new Error(validation.error || 'Invalid workflow format');
|
|
109
|
+
}
|
|
110
|
+
if (validation.warnings && validation.warnings.length > 0) {
|
|
111
|
+
const warningMessage = 'Workflow validation warnings:\n' +
|
|
112
|
+
validation.warnings.map((w, i) => `${i + 1}. ${w}`).join('\n') +
|
|
113
|
+
'\n\nSuggestions:\n' +
|
|
114
|
+
(validation.suggestions?.map((s, i) => `${i + 1}. ${s}`).join('\n') || '');
|
|
115
|
+
// Return warning message (doesn't block save, but shows warning)
|
|
116
|
+
return warningMessage;
|
|
117
|
+
}
|
|
118
|
+
return undefined;
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
displayName: 'Node Name or ID',
|
|
123
|
+
name: 'nodeId',
|
|
124
|
+
type: 'options',
|
|
125
|
+
description: 'Select a node from your workflow. AI will be able to modify parameters of this node. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
126
|
+
typeOptions: {
|
|
127
|
+
loadOptionsMethod: 'getWorkflowNodes',
|
|
128
|
+
},
|
|
129
|
+
placeholder: 'Select a node to configure AI-accessible parameters...',
|
|
130
|
+
default: '',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
displayName: 'Allowed Parameter Names or IDs',
|
|
134
|
+
name: 'allowedParameters',
|
|
135
|
+
type: 'multiOptions',
|
|
136
|
+
description: 'Select which parameters of this node AI can modify. Parameters will be loaded from the selected node. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
137
|
+
typeOptions: {
|
|
138
|
+
loadOptionsMethod: 'getNodeParameters',
|
|
139
|
+
},
|
|
140
|
+
placeholder: 'Select parameters...',
|
|
141
|
+
default: [],
|
|
142
|
+
displayOptions: {
|
|
143
|
+
show: {
|
|
144
|
+
nodeId: ['', null, undefined],
|
|
145
|
+
mode: 'invert',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Execute function - called when the node runs
|
|
154
|
+
*/
|
|
155
|
+
async execute() {
|
|
156
|
+
const logger = (0, logger_1.createLogger)(this.logger);
|
|
157
|
+
// Get node parameters
|
|
158
|
+
const comfyUiUrl = this.getNodeParameter('comfyUiUrl', 0);
|
|
159
|
+
const timeout = this.getNodeParameter('timeout', 0);
|
|
160
|
+
const workflowJson = this.getNodeParameter('workflowJson', 0);
|
|
161
|
+
// Validate URL
|
|
162
|
+
if (!(0, validation_1.validateUrl)(comfyUiUrl)) {
|
|
163
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid ComfyUI URL. Must be a valid HTTP/HTTPS URL.');
|
|
164
|
+
}
|
|
165
|
+
// Validate workflow JSON
|
|
166
|
+
if (!workflowJson || workflowJson.trim().length === 0) {
|
|
167
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Workflow JSON is required. Please export your ComfyUI workflow (Menu > Export > API Format) and paste it in the "Workflow JSON" field.');
|
|
168
|
+
}
|
|
169
|
+
// Get input data
|
|
170
|
+
const inputData = this.getInputData();
|
|
171
|
+
if (!inputData || inputData.length === 0) {
|
|
172
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No input data provided. Please provide a query text.');
|
|
173
|
+
}
|
|
174
|
+
// Check if input contains binary image data
|
|
175
|
+
const hasInputImage = (0, agentToolHelpers_1.hasBinaryData)(inputData);
|
|
176
|
+
let uploadedImageFilename = null;
|
|
177
|
+
// Get query from input
|
|
178
|
+
const firstItem = inputData[0];
|
|
179
|
+
const query = firstItem.json.query ||
|
|
180
|
+
firstItem.json.text ||
|
|
181
|
+
firstItem.json.prompt ||
|
|
182
|
+
'';
|
|
183
|
+
if (!query || query.trim().length === 0) {
|
|
184
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No query found in input. Please provide a "query", "text", or "prompt" field with a description of the image you want to generate.');
|
|
185
|
+
}
|
|
186
|
+
// Parse workflow JSON (already validated in parameter validation)
|
|
187
|
+
let workflowTemplate;
|
|
188
|
+
try {
|
|
189
|
+
workflowTemplate = (0, validation_1.safeJsonParse)(workflowJson, 'Workflow JSON');
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid Workflow JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
193
|
+
}
|
|
194
|
+
// Check if structured parameters are provided
|
|
195
|
+
const structuredParams = firstItem.json.parameters;
|
|
196
|
+
// Get node configuration (which node/parameters AI can modify)
|
|
197
|
+
const configuredNodeId = this.getNodeParameter('nodeId', 0);
|
|
198
|
+
const allowedParams = this.getNodeParameter('allowedParameters', 0) || [];
|
|
199
|
+
let params;
|
|
200
|
+
let workflow = workflowTemplate;
|
|
201
|
+
let usedStructuredParams = false;
|
|
202
|
+
if (structuredParams && typeof structuredParams === 'object' && Object.keys(structuredParams).length > 0) {
|
|
203
|
+
// Use structured parameters from AI Agent
|
|
204
|
+
logger.info('Using structured parameters from input', { parameters: structuredParams });
|
|
205
|
+
// Filter parameters based on allowed list
|
|
206
|
+
let filteredParams = structuredParams;
|
|
207
|
+
if (configuredNodeId && allowedParams.length > 0) {
|
|
208
|
+
filteredParams = {};
|
|
209
|
+
for (const paramName of allowedParams) {
|
|
210
|
+
if (paramName in structuredParams) {
|
|
211
|
+
filteredParams[paramName] = structuredParams[paramName];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
logger.info('Filtered parameters based on allowed list', {
|
|
215
|
+
configuredNodeId,
|
|
216
|
+
allowedParams,
|
|
217
|
+
filteredParams,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
// Convert structured parameters to ParsedParameters format
|
|
221
|
+
// Use filteredParams when available to ensure response only includes allowed parameters
|
|
222
|
+
const sourceParams = (configuredNodeId && allowedParams.length > 0) ? filteredParams : structuredParams;
|
|
223
|
+
params = {
|
|
224
|
+
prompt: query,
|
|
225
|
+
negative_prompt: sourceParams.negative_prompt ||
|
|
226
|
+
sourceParams.negative ||
|
|
227
|
+
structuredParams.negative_prompt ||
|
|
228
|
+
structuredParams.negative ||
|
|
229
|
+
'ugly, blurry, low quality, distorted',
|
|
230
|
+
width: sourceParams.width || 512,
|
|
231
|
+
height: sourceParams.height || 512,
|
|
232
|
+
steps: sourceParams.steps || 20,
|
|
233
|
+
cfg: sourceParams.cfg || 8,
|
|
234
|
+
seed: sourceParams.seed || Math.floor(Math.random() * 2147483647),
|
|
235
|
+
};
|
|
236
|
+
// Apply filtered parameters to the configured node
|
|
237
|
+
if (configuredNodeId && Object.keys(filteredParams).length > 0) {
|
|
238
|
+
workflow = (0, agentToolHelpers_1.applyParametersToNode)(workflowTemplate, configuredNodeId, filteredParams);
|
|
239
|
+
usedStructuredParams = true;
|
|
240
|
+
logger.debug('Applied filtered parameters to configured node', {
|
|
241
|
+
nodeId: configuredNodeId,
|
|
242
|
+
params: filteredParams,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
else if (Object.keys(structuredParams).length > 0) {
|
|
246
|
+
// Fallback to old behavior if no node configured
|
|
247
|
+
workflow = (0, agentToolHelpers_1.applyStructuredParameters)(workflowTemplate, structuredParams);
|
|
248
|
+
usedStructuredParams = true;
|
|
249
|
+
logger.debug('Applied structured parameters (auto-mapped)', structuredParams);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
// Parse the query to extract parameters (legacy behavior)
|
|
254
|
+
params = (0, agentToolHelpers_1.parseInput)(query);
|
|
255
|
+
logger.debug('Parsed parameters from query', {
|
|
256
|
+
prompt: params.prompt,
|
|
257
|
+
width: params.width,
|
|
258
|
+
height: params.height,
|
|
259
|
+
steps: params.steps,
|
|
260
|
+
cfg: params.cfg,
|
|
261
|
+
seed: params.seed,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
// Create ComfyUI client
|
|
265
|
+
const client = new ComfyUiClient_1.ComfyUIClient({
|
|
266
|
+
baseUrl: comfyUiUrl,
|
|
267
|
+
timeout: timeout * 1000,
|
|
268
|
+
helpers: this.helpers,
|
|
269
|
+
logger,
|
|
270
|
+
});
|
|
271
|
+
try {
|
|
272
|
+
logger.info('Starting ComfyUI workflow execution');
|
|
273
|
+
// If input contains image, upload it first
|
|
274
|
+
if (hasInputImage) {
|
|
275
|
+
const binaryKey = (0, agentToolHelpers_1.getFirstBinaryKey)(inputData);
|
|
276
|
+
if (!binaryKey) {
|
|
277
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Binary data found but no binary key detected.');
|
|
278
|
+
}
|
|
279
|
+
const binaryData = (0, agentToolHelpers_1.extractBinaryData)(inputData, binaryKey);
|
|
280
|
+
if (!binaryData) {
|
|
281
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to extract binary data from key "${binaryKey}".`);
|
|
282
|
+
}
|
|
283
|
+
logger.info('Uploading input image to ComfyUI', {
|
|
284
|
+
fileName: binaryData.fileName,
|
|
285
|
+
mimeType: binaryData.mimeType,
|
|
286
|
+
});
|
|
287
|
+
// Convert base64 to buffer
|
|
288
|
+
const buffer = Buffer.from(binaryData.data, 'base64');
|
|
289
|
+
// Upload image to ComfyUI
|
|
290
|
+
uploadedImageFilename = await client.uploadImage(buffer, binaryData.fileName || 'input_image.png');
|
|
291
|
+
logger.info('Successfully uploaded input image', { filename: uploadedImageFilename });
|
|
292
|
+
}
|
|
293
|
+
// Update workflow with parsed parameters (only in legacy mode)
|
|
294
|
+
// Skip if structured parameters were already applied
|
|
295
|
+
if (!usedStructuredParams) {
|
|
296
|
+
workflow = (0, agentToolHelpers_1.updateWorkflow)(workflow, params);
|
|
297
|
+
}
|
|
298
|
+
// If we uploaded an image, update workflow with the image filename
|
|
299
|
+
if (uploadedImageFilename) {
|
|
300
|
+
workflow = (0, agentToolHelpers_1.updateWorkflowWithImage)(workflow, uploadedImageFilename);
|
|
301
|
+
}
|
|
302
|
+
// Execute workflow
|
|
303
|
+
const result = await client.executeWorkflow(workflow);
|
|
304
|
+
if (!result.success) {
|
|
305
|
+
logger.error('Workflow execution failed', result.error);
|
|
306
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to generate image: ${result.error}`);
|
|
307
|
+
}
|
|
308
|
+
// Only return URLs without downloading (for AI Agent)
|
|
309
|
+
// Fix URL concatenation to handle trailing/leading slashes
|
|
310
|
+
const baseUrl = comfyUiUrl.endsWith('/') ? comfyUiUrl.slice(0, -1) : comfyUiUrl;
|
|
311
|
+
const imageUrls = result.images ? result.images.map(img => {
|
|
312
|
+
const imagePath = img.startsWith('/') ? img : `/${img}`;
|
|
313
|
+
return `${baseUrl}${imagePath}`;
|
|
314
|
+
}) : [];
|
|
315
|
+
const videoUrls = result.videos ? result.videos.map(vid => {
|
|
316
|
+
const videoPath = vid.startsWith('/') ? vid : `/${vid}`;
|
|
317
|
+
return `${baseUrl}${videoPath}`;
|
|
318
|
+
}) : [];
|
|
319
|
+
const enhancedJson = {
|
|
320
|
+
success: true,
|
|
321
|
+
imageUrls,
|
|
322
|
+
videoUrls,
|
|
323
|
+
imageCount: result.images?.length || 0,
|
|
324
|
+
videoCount: result.videos?.length || 0,
|
|
325
|
+
prompt: params.prompt,
|
|
326
|
+
parameters: {
|
|
327
|
+
width: params.width,
|
|
328
|
+
height: params.height,
|
|
329
|
+
steps: params.steps,
|
|
330
|
+
cfg: params.cfg,
|
|
331
|
+
seed: params.seed,
|
|
332
|
+
negative_prompt: params.negative_prompt,
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
logger.info('Image generation completed successfully', {
|
|
336
|
+
imageCount: enhancedJson.imageCount,
|
|
337
|
+
});
|
|
338
|
+
// Return result (no binary data for AI Agent)
|
|
339
|
+
return [this.helpers.constructExecutionMetaData([{ json: enhancedJson }], { itemData: { item: 0 } })];
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
logger.error('Error during workflow execution', error);
|
|
343
|
+
throw error;
|
|
344
|
+
}
|
|
345
|
+
finally {
|
|
346
|
+
client.destroy();
|
|
347
|
+
logger.debug('Client destroyed');
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Load all nodes from workflow JSON for Node ID dropdown
|
|
352
|
+
*/
|
|
353
|
+
async getWorkflowNodes() {
|
|
354
|
+
try {
|
|
355
|
+
const workflowJson = this.getNodeParameter('workflowJson', 0);
|
|
356
|
+
if (!workflowJson || workflowJson.trim().length === 0) {
|
|
357
|
+
return [];
|
|
358
|
+
}
|
|
359
|
+
const workflow = (0, validation_1.safeJsonParse)(workflowJson, 'Workflow JSON');
|
|
360
|
+
const nodes = [];
|
|
361
|
+
for (const [nodeId, nodeData] of Object.entries(workflow)) {
|
|
362
|
+
if (nodeData && nodeData.class_type) {
|
|
363
|
+
nodes.push({
|
|
364
|
+
name: `${nodeId} - ${nodeData.class_type}`,
|
|
365
|
+
value: nodeId,
|
|
366
|
+
description: nodeData.class_type,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Sort by node ID (numeric)
|
|
371
|
+
nodes.sort((a, b) => {
|
|
372
|
+
const aNum = parseInt(a.value);
|
|
373
|
+
const bNum = parseInt(b.value);
|
|
374
|
+
return aNum - bNum;
|
|
375
|
+
});
|
|
376
|
+
return nodes;
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
// Silently return empty array on error
|
|
380
|
+
return [];
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Load parameters for a specific node for Allowed Parameters multi-select
|
|
385
|
+
*/
|
|
386
|
+
async getNodeParameters() {
|
|
387
|
+
try {
|
|
388
|
+
const workflowJson = this.getNodeParameter('workflowJson', 0);
|
|
389
|
+
const nodeId = this.getNodeParameter('nodeId', 0);
|
|
390
|
+
if (!workflowJson || workflowJson.trim().length === 0 || !nodeId) {
|
|
391
|
+
return [];
|
|
392
|
+
}
|
|
393
|
+
const workflow = (0, validation_1.safeJsonParse)(workflowJson, 'Workflow JSON');
|
|
394
|
+
const nodeData = workflow[nodeId];
|
|
395
|
+
if (!nodeData || !nodeData.inputs) {
|
|
396
|
+
return [];
|
|
397
|
+
}
|
|
398
|
+
const parameters = [];
|
|
399
|
+
for (const [paramName, paramValue] of Object.entries(nodeData.inputs)) {
|
|
400
|
+
// Skip array values (these are connections to other nodes)
|
|
401
|
+
if (Array.isArray(paramValue)) {
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
// Auto-detect type for display
|
|
405
|
+
let detectedType = 'text';
|
|
406
|
+
if (paramName.toLowerCase().includes('image') || paramName.toLowerCase().includes('upload')) {
|
|
407
|
+
detectedType = 'image';
|
|
408
|
+
}
|
|
409
|
+
else if (typeof paramValue === 'boolean') {
|
|
410
|
+
detectedType = 'boolean';
|
|
411
|
+
}
|
|
412
|
+
else if (typeof paramValue === 'number') {
|
|
413
|
+
detectedType = 'number';
|
|
414
|
+
}
|
|
415
|
+
// Add parameter with value and type as description
|
|
416
|
+
const valueStr = String(paramValue);
|
|
417
|
+
const description = `Type: ${detectedType} | Current value: ${valueStr.length > 50 ? valueStr.substring(0, 50) + '...' : valueStr}`;
|
|
418
|
+
parameters.push({
|
|
419
|
+
name: paramName,
|
|
420
|
+
value: paramName,
|
|
421
|
+
description: description,
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
// Sort alphabetically
|
|
425
|
+
parameters.sort((a, b) => a.name.localeCompare(b.name));
|
|
426
|
+
return parameters;
|
|
427
|
+
}
|
|
428
|
+
catch (error) {
|
|
429
|
+
// Silently return empty array on error
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
exports.ComfyUiTool = ComfyUiTool;
|
|
435
|
+
//# sourceMappingURL=ComfyUiTool.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComfyUiTool.node.js","sourceRoot":"","sources":["../../../nodes/ComfyUiTool/ComfyUiTool.node.ts"],"names":[],"mappings":"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"}
|