n8n-nodes-comfyui-all 2.2.8 → 2.2.10
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 +126 -13
- package/dist/agent-tools/ComfyUIAgentTool.d.ts +57 -0
- package/dist/agent-tools/ComfyUIAgentTool.d.ts.map +1 -0
- package/dist/agent-tools/ComfyUIAgentTool.js +405 -0
- package/dist/agent-tools/ComfyUIAgentTool.js.map +1 -0
- package/dist/nodes/ComfyUi/ComfyUi.node.d.ts +13 -35
- package/dist/nodes/ComfyUi/ComfyUi.node.d.ts.map +1 -1
- package/dist/nodes/ComfyUi/ComfyUi.node.js +67 -158
- package/dist/nodes/ComfyUi/ComfyUi.node.js.map +1 -1
- package/dist/nodes/ComfyUiClient.d.ts +81 -0
- package/dist/nodes/ComfyUiClient.d.ts.map +1 -1
- package/dist/nodes/ComfyUiClient.js +235 -26
- package/dist/nodes/ComfyUiClient.js.map +1 -1
- package/dist/nodes/constants.d.ts +5 -1
- package/dist/nodes/constants.d.ts.map +1 -1
- package/dist/nodes/constants.js +7 -12
- package/dist/nodes/constants.js.map +1 -1
- package/dist/nodes/logger.d.ts +9 -19
- package/dist/nodes/logger.d.ts.map +1 -1
- package/dist/nodes/logger.js +62 -25
- package/dist/nodes/logger.js.map +1 -1
- package/dist/nodes/types.d.ts +59 -41
- package/dist/nodes/types.d.ts.map +1 -1
- package/dist/nodes/utils.d.ts +47 -0
- package/dist/nodes/utils.d.ts.map +1 -0
- package/dist/nodes/utils.js +139 -0
- package/dist/nodes/utils.js.map +1 -0
- package/dist/nodes/validation.d.ts +2 -14
- package/dist/nodes/validation.d.ts.map +1 -1
- package/dist/nodes/validation.js +48 -90
- package/dist/nodes/validation.js.map +1 -1
- package/dist/nodes/workflowConfig.d.ts +13 -0
- package/dist/nodes/workflowConfig.d.ts.map +1 -0
- package/dist/nodes/workflowConfig.js +91 -0
- package/dist/nodes/workflowConfig.js.map +1 -0
- package/package.json +3 -1
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -59,7 +59,6 @@ Or via n8n interface: **Settings** → **Community Nodes** → **Install** → `
|
|
|
59
59
|
### Basic Example: Text to Image
|
|
60
60
|
|
|
61
61
|
**Node Configuration:**
|
|
62
|
-
- **Action**: `TextToAny`
|
|
63
62
|
- **ComfyUI URL**: `http://127.0.0.1:8188`
|
|
64
63
|
- **Workflow JSON**: Your ComfyUI workflow in API format
|
|
65
64
|
|
|
@@ -132,22 +131,74 @@ By default, the first output image/video uses `data` as the binary property name
|
|
|
132
131
|
|
|
133
132
|
## 🤖 AI Agent Integration
|
|
134
133
|
|
|
135
|
-
Use ComfyUI as a tool in AI Agent workflows
|
|
134
|
+
Use ComfyUI as a tool in AI Agent workflows.
|
|
136
135
|
|
|
137
|
-
|
|
138
|
-
2. In the **Tools** section, add **ComfyUI**
|
|
139
|
-
3. Configure the ComfyUI node parameters
|
|
140
|
-
4. Start chatting!
|
|
136
|
+
### Quick Setup
|
|
141
137
|
|
|
142
|
-
**
|
|
138
|
+
**Step 1: Create AI Agent**
|
|
139
|
+
1. Add **OpenAI Conversational Agent** node
|
|
140
|
+
2. Configure Chat Model (GPT-4/GPT-3.5)
|
|
141
|
+
3. Add Memory (optional but recommended)
|
|
142
|
+
|
|
143
|
+
**Step 2: Add ComfyUI Tool**
|
|
144
|
+
1. Click AI Agent node
|
|
145
|
+
2. In **Tools** section, click **+ Add Tool**
|
|
146
|
+
3. Search and select **ComfyUI**
|
|
147
|
+
4. Configure:
|
|
148
|
+
- **ComfyUI URL**: `http://127.0.0.1:8188`
|
|
149
|
+
- **Workflow JSON**: Your ComfyUI workflow (API format)
|
|
150
|
+
- **Node Parameters**: Configure text parameter override
|
|
151
|
+
|
|
152
|
+
**Step 3: Start Chatting**
|
|
153
|
+
Execute workflow and start conversing!
|
|
154
|
+
|
|
155
|
+
### Example Conversations
|
|
156
|
+
|
|
157
|
+
**Basic Image Generation:**
|
|
158
|
+
|
|
159
|
+
**User:**
|
|
160
|
+
```
|
|
161
|
+
Generate a picture of a cute cat sitting on a fence
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**AI:**
|
|
165
|
+
```
|
|
166
|
+
I'll generate that for you.
|
|
167
|
+
[Executes ComfyUI with prompt: "a cute cat sitting on a fence"]
|
|
168
|
+
Done! Here's the image.
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**With Parameters:**
|
|
172
|
+
|
|
173
|
+
**User:**
|
|
174
|
+
```
|
|
175
|
+
Create a cyberpunk city, size:1024x768, steps:30
|
|
143
176
|
```
|
|
144
|
-
User: Generate a cute cat picture
|
|
145
177
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
178
|
+
**Supported Parameters:**
|
|
179
|
+
- `size:WIDTHxHEIGHT` - Image dimensions
|
|
180
|
+
- `steps:N` - Sampling steps
|
|
181
|
+
- `cfg:N` - CFG strength
|
|
182
|
+
- `seed:N` - Random seed
|
|
183
|
+
- `negative:TEXT` - Negative prompt
|
|
184
|
+
|
|
185
|
+
**Negative Prompts:**
|
|
186
|
+
|
|
187
|
+
**User:**
|
|
188
|
+
```
|
|
189
|
+
Draw a beautiful sunset, negative: blurry, low quality
|
|
149
190
|
```
|
|
150
191
|
|
|
192
|
+
### Configuring Node Parameters for AI Agent
|
|
193
|
+
|
|
194
|
+
In the ComfyUI node, configure parameter overrides:
|
|
195
|
+
|
|
196
|
+
- **Node ID**: `6` (your CLIP text node)
|
|
197
|
+
- **Parameter Mode**: Single Parameter
|
|
198
|
+
- **Parameter Name**: `text`
|
|
199
|
+
- **Type**: Text
|
|
200
|
+
- **Value**: [Leave empty - AI Agent will fill this]
|
|
201
|
+
|
|
151
202
|
### Tool Mode Output Format
|
|
152
203
|
|
|
153
204
|
When used as an AI Agent tool, ComfyUI returns both binary data and URL information:
|
|
@@ -168,14 +219,76 @@ When used as an AI Agent tool, ComfyUI returns both binary data and URL informat
|
|
|
168
219
|
|
|
169
220
|
This ensures compatibility with both workflow mode (binary data) and tool mode (URLs for AI Agent).
|
|
170
221
|
|
|
171
|
-
|
|
222
|
+
### Best Practices
|
|
223
|
+
|
|
224
|
+
**1. Clear Prompts**
|
|
225
|
+
|
|
226
|
+
**Good:** "Generate a landscape painting of mountains at sunset"
|
|
227
|
+
|
|
228
|
+
**Bad:** "Make a picture"
|
|
229
|
+
|
|
230
|
+
**2. Use Specific Parameters**
|
|
231
|
+
|
|
232
|
+
**Good:** "Create a portrait, size:512x768, steps:25"
|
|
233
|
+
|
|
234
|
+
**Bad:** "Create a high-quality portrait"
|
|
235
|
+
|
|
236
|
+
**3. Negative Prompts**
|
|
237
|
+
|
|
238
|
+
Always use negative prompts for better quality:
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
A beautiful landscape, negative: blurry, distorted, low quality
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Advanced Usage
|
|
245
|
+
|
|
246
|
+
**Style Transfer:**
|
|
247
|
+
|
|
248
|
+
**User:**
|
|
249
|
+
```
|
|
250
|
+
Transform this image to oil painting style
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Setup:
|
|
254
|
+
- Upload input image as binary data
|
|
255
|
+
- Configure style parameters
|
|
256
|
+
|
|
257
|
+
**Multi-Modal Workflows:**
|
|
258
|
+
|
|
259
|
+
Combine ComfyUI with other tools:
|
|
260
|
+
|
|
261
|
+
**User:**
|
|
262
|
+
```
|
|
263
|
+
Generate an image of a futuristic city, then write a poem about it
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
AI Agent:
|
|
267
|
+
1. Calls ComfyUI to generate image
|
|
268
|
+
2. Calls Chat Model to write poem
|
|
269
|
+
3. Returns both results
|
|
270
|
+
|
|
271
|
+
### Troubleshooting
|
|
272
|
+
|
|
273
|
+
**AI Agent Doesn't Call ComfyUI**
|
|
274
|
+
|
|
275
|
+
**Check:**
|
|
276
|
+
1. ComfyUI tool added to Tools list?
|
|
277
|
+
2. Workflow JSON configured?
|
|
278
|
+
3. ComfyUI server running?
|
|
279
|
+
|
|
280
|
+
**Images Don't Match Prompts**
|
|
281
|
+
|
|
282
|
+
**Check:**
|
|
283
|
+
1. Correct node ID (e.g., `6` for CLIP text)
|
|
284
|
+
2. Parameter name matches workflow (`text`)
|
|
285
|
+
3. Workflow uses dynamic text input
|
|
172
286
|
|
|
173
287
|
## 🔧 Configuration Reference
|
|
174
288
|
|
|
175
289
|
| Field | Description |
|
|
176
290
|
|-------|-------------|
|
|
177
291
|
| **ComfyUI URL** | URL of your ComfyUI server |
|
|
178
|
-
| **Action** | TextToAny or ImagesToAny |
|
|
179
292
|
| **Workflow JSON** | ComfyUI workflow in API format |
|
|
180
293
|
| **Timeout** | Maximum wait time in seconds (default: 300) |
|
|
181
294
|
| **Output Binary Key** | Property name for first output binary data (default: `data`) |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ComfyUI Agent Tool - Custom Code Tool for n8n AI Agent
|
|
3
|
+
*
|
|
4
|
+
* This tool allows AI Agents to directly call ComfyUI API to generate images
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* 1. Create a "Custom Code Tool" node in n8n
|
|
8
|
+
* 2. Copy this code into the JavaScript code box
|
|
9
|
+
* 3. Fill in the Description: Generates images using ComfyUI. Use this tool when the user asks to create, generate, or make images.
|
|
10
|
+
* 4. Add this tool to the tools list of the AI Agent node
|
|
11
|
+
*/
|
|
12
|
+
import { Workflow, ImageInfo, ParsedParameters, ToolInputOptions, ToolResult } from '../nodes/types';
|
|
13
|
+
/**
|
|
14
|
+
* Parse user input to extract image generation parameters
|
|
15
|
+
* @param query - User query text
|
|
16
|
+
* @returns Parsed parameters object
|
|
17
|
+
*/
|
|
18
|
+
declare function parseInput(query: string): ParsedParameters;
|
|
19
|
+
/**
|
|
20
|
+
* Find node ID by node type
|
|
21
|
+
* @param workflow - Workflow object
|
|
22
|
+
* @param classType - Node type
|
|
23
|
+
* @returns Node ID or null
|
|
24
|
+
*/
|
|
25
|
+
declare function findNodeByClassType(workflow: Workflow, classType: string): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Update workflow parameters
|
|
28
|
+
* @param workflow - ComfyUI workflow object
|
|
29
|
+
* @param params - Parameters object
|
|
30
|
+
* @returns Updated workflow
|
|
31
|
+
*/
|
|
32
|
+
declare function updateWorkflow(workflow: Workflow, params: ParsedParameters): Workflow;
|
|
33
|
+
/**
|
|
34
|
+
* Extract image information from output nodes
|
|
35
|
+
* @param outputs - ComfyUI output object
|
|
36
|
+
* @param url - ComfyUI server URL
|
|
37
|
+
* @returns Array of image information
|
|
38
|
+
*/
|
|
39
|
+
declare function extractImagesFromOutputs(outputs: Record<string, unknown>, url: string): ImageInfo[];
|
|
40
|
+
/**
|
|
41
|
+
* Process single image object
|
|
42
|
+
* @param image - Image object
|
|
43
|
+
* @param nodeId - Node ID
|
|
44
|
+
* @param url - ComfyUI server URL
|
|
45
|
+
* @returns Processed image information or null
|
|
46
|
+
*/
|
|
47
|
+
declare function processImage(image: unknown, nodeId: string, url: string): ImageInfo | null;
|
|
48
|
+
/**
|
|
49
|
+
* Main function: Handle tool invocation
|
|
50
|
+
* @param query - User query text
|
|
51
|
+
* @param options - Optional configuration parameters
|
|
52
|
+
* @param options.comfyUiUrl - ComfyUI server URL
|
|
53
|
+
* @param options.workflowConfig - Workflow configuration options
|
|
54
|
+
*/
|
|
55
|
+
export declare function handleToolInput(query: string, options?: ToolInputOptions): Promise<ToolResult>;
|
|
56
|
+
export { parseInput, updateWorkflow, findNodeByClassType, extractImagesFromOutputs, processImage };
|
|
57
|
+
//# sourceMappingURL=ComfyUIAgentTool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComfyUIAgentTool.d.ts","sourceRoot":"","sources":["../../agent-tools/ComfyUIAgentTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAGL,QAAQ,EACR,SAAS,EACT,gBAAgB,EAEhB,gBAAgB,EAChB,UAAU,EAEX,MAAM,gBAAgB,CAAC;AAwHxB;;;;GAIG;AACH,iBAAS,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CA4CnD;AAED;;;;;GAKG;AACH,iBAAS,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOjF;AAED;;;;;GAKG;AACH,iBAAS,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,GAAG,QAAQ,CAyC9E;AAED;;;;;GAKG;AACH,iBAAS,wBAAwB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CA2B5F;AAED;;;;;;GAMG;AACH,iBAAS,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAsBnF;AAkGD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,CA4CxG;AAaD,OAAO,EACL,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,YAAY,EACb,CAAC"}
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ComfyUI Agent Tool - Custom Code Tool for n8n AI Agent
|
|
4
|
+
*
|
|
5
|
+
* This tool allows AI Agents to directly call ComfyUI API to generate images
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* 1. Create a "Custom Code Tool" node in n8n
|
|
9
|
+
* 2. Copy this code into the JavaScript code box
|
|
10
|
+
* 3. Fill in the Description: Generates images using ComfyUI. Use this tool when the user asks to create, generate, or make images.
|
|
11
|
+
* 4. Add this tool to the tools list of the AI Agent node
|
|
12
|
+
*/
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.handleToolInput = handleToolInput;
|
|
18
|
+
exports.parseInput = parseInput;
|
|
19
|
+
exports.updateWorkflow = updateWorkflow;
|
|
20
|
+
exports.findNodeByClassType = findNodeByClassType;
|
|
21
|
+
exports.extractImagesFromOutputs = extractImagesFromOutputs;
|
|
22
|
+
exports.processImage = processImage;
|
|
23
|
+
const axios_1 = __importDefault(require("axios"));
|
|
24
|
+
const crypto_1 = require("crypto");
|
|
25
|
+
const workflowConfig_1 = require("../nodes/workflowConfig");
|
|
26
|
+
class ConsoleLogger {
|
|
27
|
+
constructor(prefix = '[ComfyUI Tool]') {
|
|
28
|
+
this.prefix = prefix;
|
|
29
|
+
}
|
|
30
|
+
debug(message, ...args) {
|
|
31
|
+
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
|
|
32
|
+
console.log(`${this.prefix} ${message}`, ...args);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
info(message, ...args) {
|
|
36
|
+
console.log(`${this.prefix} ${message}`, ...args);
|
|
37
|
+
}
|
|
38
|
+
warn(message, ...args) {
|
|
39
|
+
console.warn(`${this.prefix} ${message}`, ...args);
|
|
40
|
+
}
|
|
41
|
+
error(message, ...args) {
|
|
42
|
+
console.error(`${this.prefix} ${message}`, ...args);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Create logger instance
|
|
46
|
+
const logger = new ConsoleLogger('[ComfyUI Tool]');
|
|
47
|
+
// Default configuration
|
|
48
|
+
const DEFAULT_COMFYUI_URL = 'http://127.0.0.1:8188';
|
|
49
|
+
// Parameter default values
|
|
50
|
+
const DEFAULT_NEGATIVE_PROMPT = 'ugly, blurry, low quality, distorted';
|
|
51
|
+
const DEFAULT_WIDTH = 512;
|
|
52
|
+
const DEFAULT_HEIGHT = 512;
|
|
53
|
+
const DEFAULT_STEPS = 20;
|
|
54
|
+
const DEFAULT_CFG = 8;
|
|
55
|
+
// Maximum random seed value (32-bit signed integer max value)
|
|
56
|
+
const MAX_SEED_VALUE = 2147483647;
|
|
57
|
+
// Polling configuration
|
|
58
|
+
const POLLING_MAX_ATTEMPTS = 120; // Maximum wait time of 2 minutes (120 seconds)
|
|
59
|
+
const POLLING_INTERVAL_MS = 1000; // Polling interval of 1 second
|
|
60
|
+
// Request timeout configuration
|
|
61
|
+
const QUEUE_REQUEST_TIMEOUT = 30000; // Queue request timeout 30 seconds
|
|
62
|
+
const HISTORY_REQUEST_TIMEOUT = 10000; // History request timeout 10 seconds
|
|
63
|
+
/**
|
|
64
|
+
* Promise-based delay function
|
|
65
|
+
* @param ms - Delay time in milliseconds
|
|
66
|
+
* @returns Promise object
|
|
67
|
+
*/
|
|
68
|
+
function delay(ms) {
|
|
69
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
70
|
+
}
|
|
71
|
+
// Parameter extraction rules configuration
|
|
72
|
+
const PARAM_PATTERNS = {
|
|
73
|
+
negative: {
|
|
74
|
+
regex: /negative:\s*([^\n]+)/i,
|
|
75
|
+
paramKey: 'negative_prompt',
|
|
76
|
+
parser: (match) => match[1].trim()
|
|
77
|
+
},
|
|
78
|
+
size: {
|
|
79
|
+
regex: /size:\s*(\d+)x(\d+)/i,
|
|
80
|
+
paramKeys: ['width', 'height'],
|
|
81
|
+
parser: (match) => ({
|
|
82
|
+
width: parseInt(match[1]),
|
|
83
|
+
height: parseInt(match[2])
|
|
84
|
+
})
|
|
85
|
+
},
|
|
86
|
+
steps: {
|
|
87
|
+
regex: /steps:\s*(\d+)/i,
|
|
88
|
+
paramKey: 'steps',
|
|
89
|
+
parser: (match) => parseInt(match[1])
|
|
90
|
+
},
|
|
91
|
+
cfg: {
|
|
92
|
+
regex: /cfg:\s*([\d.]+)/i,
|
|
93
|
+
paramKey: 'cfg',
|
|
94
|
+
parser: (match) => parseFloat(match[1])
|
|
95
|
+
},
|
|
96
|
+
seed: {
|
|
97
|
+
regex: /seed:\s*(\d+)/i,
|
|
98
|
+
paramKey: 'seed',
|
|
99
|
+
parser: (match) => parseInt(match[1])
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Extract parameter from query
|
|
104
|
+
* @param query - User query text
|
|
105
|
+
* @param pattern - Parameter pattern configuration
|
|
106
|
+
* @returns Extracted parameter and cleaned query
|
|
107
|
+
*/
|
|
108
|
+
function extractParameter(query, pattern) {
|
|
109
|
+
const match = query.match(pattern.regex);
|
|
110
|
+
if (!match) {
|
|
111
|
+
return { value: null, cleanedQuery: query };
|
|
112
|
+
}
|
|
113
|
+
const value = pattern.parser(match);
|
|
114
|
+
const cleanedQuery = query.replace(pattern.regex, '').trim();
|
|
115
|
+
return { value, cleanedQuery };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Parse user input to extract image generation parameters
|
|
119
|
+
* @param query - User query text
|
|
120
|
+
* @returns Parsed parameters object
|
|
121
|
+
*/
|
|
122
|
+
function parseInput(query) {
|
|
123
|
+
const params = {
|
|
124
|
+
prompt: '',
|
|
125
|
+
negative_prompt: DEFAULT_NEGATIVE_PROMPT,
|
|
126
|
+
width: DEFAULT_WIDTH,
|
|
127
|
+
height: DEFAULT_HEIGHT,
|
|
128
|
+
steps: DEFAULT_STEPS,
|
|
129
|
+
cfg: DEFAULT_CFG,
|
|
130
|
+
seed: (0, crypto_1.randomInt)(0, MAX_SEED_VALUE)
|
|
131
|
+
};
|
|
132
|
+
let currentQuery = query.trim();
|
|
133
|
+
for (const [, pattern] of Object.entries(PARAM_PATTERNS)) {
|
|
134
|
+
const { value, cleanedQuery } = extractParameter(currentQuery, pattern);
|
|
135
|
+
if (value !== null) {
|
|
136
|
+
if (pattern.paramKeys) {
|
|
137
|
+
// Type guard: check if value is an object with keys
|
|
138
|
+
if (typeof value === 'object' && value !== null) {
|
|
139
|
+
const valueRecord = value;
|
|
140
|
+
const valueKeys = Object.keys(valueRecord);
|
|
141
|
+
pattern.paramKeys.forEach((key, index) => {
|
|
142
|
+
params[key] = valueRecord[valueKeys[index]];
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (pattern.paramKey) {
|
|
147
|
+
params[pattern.paramKey] = value;
|
|
148
|
+
}
|
|
149
|
+
currentQuery = cleanedQuery;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Clean up remaining parameter markers and extra punctuation
|
|
153
|
+
currentQuery = currentQuery
|
|
154
|
+
.replace(/,\s*,/g, ',') // Remove consecutive Chinese commas
|
|
155
|
+
.replace(/,\s*,/g, ',') // Remove consecutive English commas
|
|
156
|
+
.replace(/[,,]\s*[,,]/g, ' ') // Remove extra spaces between commas
|
|
157
|
+
.replace(/^\s*[,,]+/g, '') // Remove all leading commas
|
|
158
|
+
.replace(/[,,]+\s*$/g, '') // Remove all trailing commas
|
|
159
|
+
.trim();
|
|
160
|
+
params.prompt = currentQuery;
|
|
161
|
+
return params;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Find node ID by node type
|
|
165
|
+
* @param workflow - Workflow object
|
|
166
|
+
* @param classType - Node type
|
|
167
|
+
* @returns Node ID or null
|
|
168
|
+
*/
|
|
169
|
+
function findNodeByClassType(workflow, classType) {
|
|
170
|
+
for (const nodeId in workflow) {
|
|
171
|
+
if (workflow[nodeId] && workflow[nodeId].class_type === classType) {
|
|
172
|
+
return nodeId;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Update workflow parameters
|
|
179
|
+
* @param workflow - ComfyUI workflow object
|
|
180
|
+
* @param params - Parameters object
|
|
181
|
+
* @returns Updated workflow
|
|
182
|
+
*/
|
|
183
|
+
function updateWorkflow(workflow, params) {
|
|
184
|
+
const updatedWorkflow = JSON.parse(JSON.stringify(workflow));
|
|
185
|
+
// Find and update positive and negative prompt nodes
|
|
186
|
+
const clipTextEncodeNodes = [];
|
|
187
|
+
for (const nodeId in updatedWorkflow) {
|
|
188
|
+
if (updatedWorkflow[nodeId] && updatedWorkflow[nodeId].class_type === 'CLIPTextEncode') {
|
|
189
|
+
clipTextEncodeNodes.push(nodeId);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (clipTextEncodeNodes.length >= 1) {
|
|
193
|
+
updatedWorkflow[clipTextEncodeNodes[0]].inputs.text = params.prompt;
|
|
194
|
+
}
|
|
195
|
+
if (clipTextEncodeNodes.length >= 2) {
|
|
196
|
+
updatedWorkflow[clipTextEncodeNodes[1]].inputs.text = params.negative_prompt;
|
|
197
|
+
}
|
|
198
|
+
// Find and update image size node
|
|
199
|
+
const latentNodeId = findNodeByClassType(updatedWorkflow, 'EmptyLatentImage') ||
|
|
200
|
+
findNodeByClassType(updatedWorkflow, 'EmptySD3LatentImage');
|
|
201
|
+
if (latentNodeId && updatedWorkflow[latentNodeId].inputs) {
|
|
202
|
+
updatedWorkflow[latentNodeId].inputs.width = params.width;
|
|
203
|
+
updatedWorkflow[latentNodeId].inputs.height = params.height;
|
|
204
|
+
}
|
|
205
|
+
// Find and update sampling parameters node
|
|
206
|
+
const samplerNodeId = findNodeByClassType(updatedWorkflow, 'KSampler');
|
|
207
|
+
if (samplerNodeId && updatedWorkflow[samplerNodeId].inputs) {
|
|
208
|
+
updatedWorkflow[samplerNodeId].inputs.steps = params.steps;
|
|
209
|
+
updatedWorkflow[samplerNodeId].inputs.cfg = params.cfg;
|
|
210
|
+
updatedWorkflow[samplerNodeId].inputs.seed = params.seed;
|
|
211
|
+
}
|
|
212
|
+
// Find and update edit instruction node (for image editing workflows)
|
|
213
|
+
const primitiveNodeId = findNodeByClassType(updatedWorkflow, 'PrimitiveStringMultiline');
|
|
214
|
+
if (primitiveNodeId && updatedWorkflow[primitiveNodeId].inputs) {
|
|
215
|
+
updatedWorkflow[primitiveNodeId].inputs.value = params.prompt;
|
|
216
|
+
}
|
|
217
|
+
return updatedWorkflow;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Extract image information from output nodes
|
|
221
|
+
* @param outputs - ComfyUI output object
|
|
222
|
+
* @param url - ComfyUI server URL
|
|
223
|
+
* @returns Array of image information
|
|
224
|
+
*/
|
|
225
|
+
function extractImagesFromOutputs(outputs, url) {
|
|
226
|
+
const images = [];
|
|
227
|
+
for (const nodeId in outputs) {
|
|
228
|
+
const nodeOutput = outputs[nodeId];
|
|
229
|
+
if (!nodeOutput || typeof nodeOutput !== 'object') {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const nodeImages = nodeOutput.images;
|
|
233
|
+
if (!nodeImages) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (!Array.isArray(nodeImages) || nodeImages.length === 0) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
for (const image of nodeImages) {
|
|
240
|
+
const imageInfo = processImage(image, nodeId, url);
|
|
241
|
+
if (imageInfo) {
|
|
242
|
+
images.push(imageInfo);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return images;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Process single image object
|
|
250
|
+
* @param image - Image object
|
|
251
|
+
* @param nodeId - Node ID
|
|
252
|
+
* @param url - ComfyUI server URL
|
|
253
|
+
* @returns Processed image information or null
|
|
254
|
+
*/
|
|
255
|
+
function processImage(image, nodeId, url) {
|
|
256
|
+
if (!image || typeof image !== 'object') {
|
|
257
|
+
logger.warn(`Invalid image object in node ${nodeId}`);
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
const imageObj = image;
|
|
261
|
+
const filename = imageObj.filename;
|
|
262
|
+
const subfolder = imageObj.subfolder || '';
|
|
263
|
+
const type = imageObj.type || 'output';
|
|
264
|
+
if (!filename) {
|
|
265
|
+
logger.warn(`Image missing filename in node ${nodeId}`);
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
filename: filename,
|
|
270
|
+
subfolder: subfolder,
|
|
271
|
+
type: type,
|
|
272
|
+
url: `${url}/view?filename=${filename}&subfolder=${subfolder}&type=${type}`
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Execute ComfyUI workflow
|
|
277
|
+
* @param workflow - ComfyUI workflow object
|
|
278
|
+
* @param comfyUiUrl - ComfyUI server URL
|
|
279
|
+
*/
|
|
280
|
+
async function executeComfyUIWorkflow(workflow, comfyUiUrl) {
|
|
281
|
+
const url = comfyUiUrl || DEFAULT_COMFYUI_URL;
|
|
282
|
+
// 1. Queue prompt
|
|
283
|
+
let promptResponse;
|
|
284
|
+
try {
|
|
285
|
+
promptResponse = await axios_1.default.post(`${url}/prompt`, {
|
|
286
|
+
prompt: workflow
|
|
287
|
+
}, {
|
|
288
|
+
timeout: QUEUE_REQUEST_TIMEOUT
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
if (error instanceof Error) {
|
|
293
|
+
const errorCode = error.code;
|
|
294
|
+
if (errorCode === 'ECONNREFUSED') {
|
|
295
|
+
throw new Error(`Failed to connect to ComfyUI server at ${url}. Please check if the server is running.`);
|
|
296
|
+
}
|
|
297
|
+
else if (errorCode === 'ETIMEDOUT' || errorCode === 'ECONNABORTED') {
|
|
298
|
+
throw new Error(`Connection timeout while connecting to ComfyUI server at ${url}.`);
|
|
299
|
+
}
|
|
300
|
+
else if (error.response) {
|
|
301
|
+
throw new Error(`ComfyUI server returned error: ${error.response.status} ${error.response.statusText}`);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
throw new Error(`Failed to queue workflow: ${error.message}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
throw new Error(`Failed to queue workflow: ${String(error)}`);
|
|
308
|
+
}
|
|
309
|
+
if (!promptResponse.data || !promptResponse.data.prompt_id) {
|
|
310
|
+
throw new Error('Invalid response from ComfyUI server: missing prompt_id');
|
|
311
|
+
}
|
|
312
|
+
const promptId = promptResponse.data.prompt_id;
|
|
313
|
+
logger.info(`Workflow queued with ID: ${promptId}`);
|
|
314
|
+
// 2. Poll for results
|
|
315
|
+
let attempts = 0;
|
|
316
|
+
while (attempts < POLLING_MAX_ATTEMPTS) {
|
|
317
|
+
await delay(POLLING_INTERVAL_MS);
|
|
318
|
+
// Check history
|
|
319
|
+
let historyResponse;
|
|
320
|
+
try {
|
|
321
|
+
historyResponse = await axios_1.default.get(`${url}/history/${promptId}`, {
|
|
322
|
+
timeout: HISTORY_REQUEST_TIMEOUT
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
const errorCode = error instanceof Error ? error.code : undefined;
|
|
327
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
328
|
+
if (errorCode === 'ECONNREFUSED') {
|
|
329
|
+
throw new Error(`Lost connection to ComfyUI server at ${url}.`);
|
|
330
|
+
}
|
|
331
|
+
else if (errorCode === 'ETIMEDOUT' || errorCode === 'ECONNABORTED') {
|
|
332
|
+
logger.warn(`Timeout checking history (attempt ${attempts + 1}/${POLLING_MAX_ATTEMPTS})`);
|
|
333
|
+
attempts++;
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
logger.warn(`Error checking history: ${errorMessage}`);
|
|
338
|
+
attempts++;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (historyResponse.data && historyResponse.data[promptId]) {
|
|
343
|
+
const outputs = historyResponse.data[promptId].outputs;
|
|
344
|
+
if (outputs) {
|
|
345
|
+
const images = extractImagesFromOutputs(outputs, url);
|
|
346
|
+
if (images.length === 0) {
|
|
347
|
+
throw new Error('Workflow completed but no images were generated');
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
success: true,
|
|
351
|
+
prompt_id: promptId,
|
|
352
|
+
images: images
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
attempts++;
|
|
357
|
+
}
|
|
358
|
+
throw new Error(`Workflow execution timeout after ${POLLING_MAX_ATTEMPTS} seconds (prompt_id: ${promptId}). The workflow may still be running on ComfyUI server.`);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Main function: Handle tool invocation
|
|
362
|
+
* @param query - User query text
|
|
363
|
+
* @param options - Optional configuration parameters
|
|
364
|
+
* @param options.comfyUiUrl - ComfyUI server URL
|
|
365
|
+
* @param options.workflowConfig - Workflow configuration options
|
|
366
|
+
*/
|
|
367
|
+
async function handleToolInput(query, options = {}) {
|
|
368
|
+
try {
|
|
369
|
+
const { comfyUiUrl, workflowConfig } = options;
|
|
370
|
+
logger.info(`Received query: ${query}`);
|
|
371
|
+
if (comfyUiUrl) {
|
|
372
|
+
logger.info(`Using ComfyUI URL: ${comfyUiUrl}`);
|
|
373
|
+
}
|
|
374
|
+
// Parse input parameters
|
|
375
|
+
const params = parseInput(query);
|
|
376
|
+
logger.debug('Parsed parameters:', JSON.stringify(params, null, 2));
|
|
377
|
+
// Get workflow template from configuration
|
|
378
|
+
const workflowTemplate = (0, workflowConfig_1.getWorkflowTemplate)(workflowConfig);
|
|
379
|
+
// Update workflow
|
|
380
|
+
const workflow = updateWorkflow(workflowTemplate, params);
|
|
381
|
+
// Execute workflow
|
|
382
|
+
const result = await executeComfyUIWorkflow(workflow, comfyUiUrl);
|
|
383
|
+
logger.info(`Generated ${result.images.length} image(s)`);
|
|
384
|
+
// Return result
|
|
385
|
+
return {
|
|
386
|
+
success: true,
|
|
387
|
+
message: `Successfully generated ${result.images.length} image(s) with prompt: "${params.prompt}"`,
|
|
388
|
+
data: {
|
|
389
|
+
prompt: params.prompt,
|
|
390
|
+
images: result.images.map(img => img.url),
|
|
391
|
+
parameters: params
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
catch (error) {
|
|
396
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
397
|
+
logger.error('Error:', errorMessage);
|
|
398
|
+
return {
|
|
399
|
+
success: false,
|
|
400
|
+
error: errorMessage,
|
|
401
|
+
message: `Failed to generate image: ${errorMessage}`
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
//# sourceMappingURL=ComfyUIAgentTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComfyUIAgentTool.js","sourceRoot":"","sources":["../../agent-tools/ComfyUIAgentTool.ts"],"names":[],"mappings":"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"}
|