comfyui-node 1.6.6 → 1.6.7
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/LICENSE +20 -20
- package/README.md +342 -341
- package/dist/.tsbuildinfo +1 -1
- package/dist/multipool/client-registry.d.ts +3 -3
- package/dist/multipool/client-registry.d.ts.map +1 -1
- package/dist/multipool/client-registry.js +9 -9
- package/dist/multipool/client-registry.js.map +1 -1
- package/dist/multipool/helpers.d.ts +4 -4
- package/dist/multipool/index.d.ts +2 -2
- package/dist/multipool/interfaces.d.ts +0 -2
- package/dist/multipool/interfaces.d.ts.map +1 -1
- package/dist/multipool/job-queue-processor.d.ts +3 -3
- package/dist/multipool/job-queue-processor.d.ts.map +1 -1
- package/dist/multipool/job-queue-processor.js +28 -27
- package/dist/multipool/job-queue-processor.js.map +1 -1
- package/dist/multipool/logger.d.ts +29 -29
- package/dist/multipool/multi-workflow-pool.d.ts +0 -1
- package/dist/multipool/multi-workflow-pool.d.ts.map +1 -1
- package/dist/multipool/multi-workflow-pool.js +36 -37
- package/dist/multipool/multi-workflow-pool.js.map +1 -1
- package/dist/multipool/tests/client-registry-api-demo.js +1 -3
- package/dist/multipool/tests/client-registry-api-demo.js.map +1 -1
- package/dist/multipool/tests/client-registry.spec.js +6 -7
- package/dist/multipool/tests/client-registry.spec.js.map +1 -1
- package/dist/multipool/tests/error-classification-tests.d.ts +1 -1
- package/dist/multipool/tests/event-forwarding-demo.js +1 -3
- package/dist/multipool/tests/event-forwarding-demo.js.map +1 -1
- package/dist/multipool/tests/job-queue-processor.spec.js +7 -7
- package/dist/multipool/tests/job-queue-processor.spec.js.map +1 -1
- package/dist/multipool/tests/job-state-registry.d.ts +16 -16
- package/dist/multipool/tests/job-state-registry.js +23 -23
- package/dist/multipool/tests/job-state-registry.spec.js +5 -4
- package/dist/multipool/tests/job-state-registry.spec.js.map +1 -1
- package/dist/multipool/tests/multipool-basic.d.ts +11 -11
- package/dist/multipool/tests/profiling-demo.d.ts +6 -6
- package/dist/multipool/tests/profiling-demo.js +1 -2
- package/dist/multipool/tests/profiling-demo.js.map +1 -1
- package/dist/multipool/tests/prompt-generator.d.ts +9 -9
- package/dist/multipool/tests/test-helpers.d.ts +3 -3
- package/dist/multipool/tests/two-stage-edit-simulation.d.ts +31 -31
- package/dist/multipool/tests/two-stage-edit-simulation.d.ts.map +1 -1
- package/dist/multipool/tests/two-stage-edit-simulation.js +1 -2
- package/dist/multipool/tests/two-stage-edit-simulation.js.map +1 -1
- package/dist/pool/SmartPool.d.ts +143 -143
- package/dist/pool/SmartPool.js +676 -676
- package/dist/pool/SmartPoolV2.d.ts +119 -119
- package/dist/pool/SmartPoolV2.js +586 -586
- package/dist/pool/WorkflowPool.d.ts +202 -202
- package/dist/pool/client/ClientManager.d.ts +86 -86
- package/dist/pool/index.d.ts +9 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,341 +1,342 @@
|
|
|
1
|
-
# ComfyUI SDK
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/comfyui-node)
|
|
4
|
-
[](https://github.com/igorls/comfyui-node/blob/main/LICENSE)
|
|
5
|
-

|
|
6
|
-

|
|
7
|
-

|
|
8
|
-
|
|
9
|
-
TypeScript SDK for interacting with the [ComfyUI](https://github.com/comfyanonymous/ComfyUI) API – focused on workflow construction, prompt execution orchestration, multi-instance scheduling and extension integration.
|
|
10
|
-
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
- Fully typed TypeScript surface with progressive output typing
|
|
14
|
-
- High-level `Workflow` API – tweak existing JSON workflows with minimal boilerplate
|
|
15
|
-
- Low-level `PromptBuilder` – programmatic graph construction with validation
|
|
16
|
-
- WebSocket events – progress, preview, output, completion with reconnection
|
|
17
|
-
- Multi-instance pooling – `WorkflowPool` with smart failover & health checks (v1.4.1+)
|
|
18
|
-
- Modular features – `api.ext.*` namespaces (queue, history, system, file, etc.)
|
|
19
|
-
- Authentication – basic, bearer token, custom headers
|
|
20
|
-
- Image attachments – upload files directly with workflow submissions
|
|
21
|
-
- Preview metadata – rich preview frames with metadata support
|
|
22
|
-
- Auto seed substitution – `seed: -1` randomized automatically
|
|
23
|
-
- API node support – compatible with custom/paid API nodes (Comfy.org)
|
|
24
|
-
|
|
25
|
-
## Installation
|
|
26
|
-
|
|
27
|
-
Requires Node.js >= 22. Works with Bun.
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npm install comfyui-node
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Quick Start
|
|
34
|
-
|
|
35
|
-
```ts
|
|
36
|
-
import { ComfyApi, Workflow } from 'comfyui-node';
|
|
37
|
-
import BaseWorkflow from './example-txt2img-workflow.json';
|
|
38
|
-
|
|
39
|
-
const api = await new ComfyApi('http://127.0.0.1:8188').ready();
|
|
40
|
-
|
|
41
|
-
const wf = Workflow.from(BaseWorkflow)
|
|
42
|
-
.set('6.inputs.text', 'A dramatic cinematic landscape')
|
|
43
|
-
.output('images:9');
|
|
44
|
-
|
|
45
|
-
const job = await api.run(wf, { autoDestroy: true });
|
|
46
|
-
job.on('progress_pct', p => console.log(`${p}%`));
|
|
47
|
-
|
|
48
|
-
const result = await job.done();
|
|
49
|
-
for (const img of (result.images?.images || [])) {
|
|
50
|
-
console.log(api.ext.file.getPathImage(img));
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Documentation
|
|
55
|
-
|
|
56
|
-
### Getting Started
|
|
57
|
-
|
|
58
|
-
- **[Getting Started Guide](./docs/getting-started.md)** – Installation, quick start, core concepts, cheat sheet
|
|
59
|
-
- **[Workflow Guide](./docs/workflow-guide.md)** – Complete high-level Workflow API tutorial with progressive typing
|
|
60
|
-
- **[PromptBuilder Guide](./docs/prompt-builder.md)** – Lower-level graph construction, validation, serialization
|
|
61
|
-
|
|
62
|
-
### Multi-Instance Pooling
|
|
63
|
-
|
|
64
|
-
- **[WorkflowPool Documentation](./docs/workflow-pool.md)** – Production-ready pooling with health checks, profiling, and timeout protection
|
|
65
|
-
- **[
|
|
66
|
-
- **[
|
|
67
|
-
- **[
|
|
68
|
-
- **[
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
- **[
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- **[
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
.
|
|
90
|
-
.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
new ComfyApi("http://localhost:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
console.log(`
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
- **
|
|
147
|
-
- **
|
|
148
|
-
- **
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
import
|
|
154
|
-
import
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
- **
|
|
206
|
-
- **
|
|
207
|
-
- **
|
|
208
|
-
- **
|
|
209
|
-
- **
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
await api.ext.queue.
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
await api.ext.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
api.on('
|
|
246
|
-
api.on('
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
job.on('
|
|
250
|
-
job.on('
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
bun
|
|
260
|
-
bun run test:integration
|
|
261
|
-
bun run test:
|
|
262
|
-
bun run test:
|
|
263
|
-
bun run
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
-
|
|
287
|
-
-
|
|
288
|
-
-
|
|
289
|
-
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
- `test/integration/
|
|
294
|
-
- `test/integration/
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
await
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
await
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
-
|
|
330
|
-
-
|
|
331
|
-
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
- **
|
|
341
|
-
- **
|
|
1
|
+
# ComfyUI SDK
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/comfyui-node)
|
|
4
|
+
[](https://github.com/igorls/comfyui-node/blob/main/LICENSE)
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
TypeScript SDK for interacting with the [ComfyUI](https://github.com/comfyanonymous/ComfyUI) API – focused on workflow construction, prompt execution orchestration, multi-instance scheduling and extension integration.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Fully typed TypeScript surface with progressive output typing
|
|
14
|
+
- High-level `Workflow` API – tweak existing JSON workflows with minimal boilerplate
|
|
15
|
+
- Low-level `PromptBuilder` – programmatic graph construction with validation
|
|
16
|
+
- WebSocket events – progress, preview, output, completion with reconnection
|
|
17
|
+
- Multi-instance pooling – `WorkflowPool` with smart failover & health checks (v1.4.1+)
|
|
18
|
+
- Modular features – `api.ext.*` namespaces (queue, history, system, file, etc.)
|
|
19
|
+
- Authentication – basic, bearer token, custom headers
|
|
20
|
+
- Image attachments – upload files directly with workflow submissions
|
|
21
|
+
- Preview metadata – rich preview frames with metadata support
|
|
22
|
+
- Auto seed substitution – `seed: -1` randomized automatically
|
|
23
|
+
- API node support – compatible with custom/paid API nodes (Comfy.org)
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
Requires Node.js >= 22. Works with Bun.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install comfyui-node
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { ComfyApi, Workflow } from 'comfyui-node';
|
|
37
|
+
import BaseWorkflow from './example-txt2img-workflow.json';
|
|
38
|
+
|
|
39
|
+
const api = await new ComfyApi('http://127.0.0.1:8188').ready();
|
|
40
|
+
|
|
41
|
+
const wf = Workflow.from(BaseWorkflow)
|
|
42
|
+
.set('6.inputs.text', 'A dramatic cinematic landscape')
|
|
43
|
+
.output('images:9');
|
|
44
|
+
|
|
45
|
+
const job = await api.run(wf, { autoDestroy: true });
|
|
46
|
+
job.on('progress_pct', p => console.log(`${p}%`));
|
|
47
|
+
|
|
48
|
+
const result = await job.done();
|
|
49
|
+
for (const img of (result.images?.images || [])) {
|
|
50
|
+
console.log(api.ext.file.getPathImage(img));
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Documentation
|
|
55
|
+
|
|
56
|
+
### Getting Started
|
|
57
|
+
|
|
58
|
+
- **[Getting Started Guide](./docs/getting-started.md)** – Installation, quick start, core concepts, cheat sheet
|
|
59
|
+
- **[Workflow Guide](./docs/workflow-guide.md)** – Complete high-level Workflow API tutorial with progressive typing
|
|
60
|
+
- **[PromptBuilder Guide](./docs/prompt-builder.md)** – Lower-level graph construction, validation, serialization
|
|
61
|
+
|
|
62
|
+
### Multi-Instance Pooling
|
|
63
|
+
|
|
64
|
+
- **[WorkflowPool Documentation](./docs/workflow-pool.md)** – Production-ready pooling with health checks, profiling, and timeout protection
|
|
65
|
+
- **[Event-Based Logging](./docs/logging.md)** – Guide to the new event-based logging system (v1.6.7+)
|
|
66
|
+
- **[Connection Stability Guide](./docs/websocket-idle-issue.md)** – WebSocket health check implementation details
|
|
67
|
+
- **[Hash-Based Routing Guide](./docs/hash-routing-guide.md)** – Workflow-level failure tracking and intelligent failover
|
|
68
|
+
- **[Profiling Guide](./docs/profiling.md)** – Automatic per-node performance profiling (v1.5.0+)
|
|
69
|
+
- **[Execution Timeout Guide](./docs/execution-timeout.md)** – Timeout protection for stuck servers and nodes (v1.5.0+)
|
|
70
|
+
|
|
71
|
+
### Advanced Features
|
|
72
|
+
|
|
73
|
+
- **[Advanced Usage](./docs/advanced-usage.md)** – Authentication, events, preview metadata, API nodes, image attachments
|
|
74
|
+
- **[API Features](./docs/api-features.md)** – Modular `api.ext.*` namespaces (queue, file, system, etc.)
|
|
75
|
+
|
|
76
|
+
### Help & Migration
|
|
77
|
+
|
|
78
|
+
- **[Troubleshooting](./docs/troubleshooting.md)** – Common issues, error types, testing, diagnostics
|
|
79
|
+
- **[Migration Guide](./docs/migration-guide.md)** – Upgrading from <1.0 to 1.0+ with complete API mappings
|
|
80
|
+
|
|
81
|
+
## Key Concepts
|
|
82
|
+
|
|
83
|
+
### Workflow vs PromptBuilder
|
|
84
|
+
|
|
85
|
+
**Use `Workflow`** for tweaking existing JSON workflows:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
const wf = Workflow.from(baseJson)
|
|
89
|
+
.set('3.inputs.steps', 20)
|
|
90
|
+
.input('SAMPLER', 'cfg', 4)
|
|
91
|
+
.output('images:9');
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Use `PromptBuilder`** for programmatic graph construction:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const builder = new PromptBuilder(base, ['positive', 'seed'], ['images'])
|
|
98
|
+
.setInputNode('positive', '6.inputs.text')
|
|
99
|
+
.validateOutputMappings();
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
See [comparison guide](./docs/workflow-guide.md#choosing-workflow-vs-promptbuilder) for details.
|
|
103
|
+
|
|
104
|
+
### WorkflowPool
|
|
105
|
+
|
|
106
|
+
Production-ready multi-instance scheduling with automatic health checks and intelligent hash-based routing:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { WorkflowPool, MemoryQueueAdapter, SmartFailoverStrategy } from "comfyui-node";
|
|
110
|
+
|
|
111
|
+
const pool = new WorkflowPool([
|
|
112
|
+
new ComfyApi("http://localhost:8188"),
|
|
113
|
+
new ComfyApi("http://localhost:8189")
|
|
114
|
+
], {
|
|
115
|
+
failoverStrategy: new SmartFailoverStrategy({
|
|
116
|
+
cooldownMs: 60_000, // Block workflow for 60s after failure
|
|
117
|
+
maxFailuresBeforeBlock: 1 // Block on first failure
|
|
118
|
+
}),
|
|
119
|
+
healthCheckIntervalMs: 30000, // keeps connections alive
|
|
120
|
+
enableProfiling: true, // NEW: enable automatic performance profiling
|
|
121
|
+
executionStartTimeoutMs: 5000 // NEW: 5s timeout for execution to start
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Monitor job completion and view profiling stats
|
|
125
|
+
pool.on("job:completed", ev => {
|
|
126
|
+
if (ev.detail.job.profileStats) {
|
|
127
|
+
const { totalDuration, executionTime, summary } = ev.detail.job.profileStats;
|
|
128
|
+
console.log(`Job ${ev.detail.job.jobId} completed in ${totalDuration}ms`);
|
|
129
|
+
console.log(`Slowest nodes:`, summary.slowestNodes);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const jobId = await pool.enqueue(workflow, { priority: 10 });
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Hash-based routing intelligently handles failures at the workflow level (not client level). When a workflow fails on one client, the pool routes it to others while keeping that client available for different workflows.
|
|
137
|
+
|
|
138
|
+
See [Hash-Based Routing Guide](./docs/hash-routing-guide.md) for details and demos.
|
|
139
|
+
|
|
140
|
+
### Advanced: `MultiWorkflowPool` for Heterogeneous Clusters
|
|
141
|
+
|
|
142
|
+
For complex use cases involving a heterogeneous cluster of workers (e.g., some with SDXL models, others for video generation), `MultiWorkflowPool` provides fine-grained control over job routing based on workflow requirements.
|
|
143
|
+
|
|
144
|
+
It uses an event-driven architecture to manage clients with specific **workflow affinities**, ensuring that jobs are only sent to nodes capable of processing them.
|
|
145
|
+
|
|
146
|
+
- **Workflow Affinity:** Assign clients to specific workflows. Jobs are automatically routed to the correct client.
|
|
147
|
+
- **Dynamic Job Queues:** A separate job queue is created for each workflow type, preventing head-of-line blocking.
|
|
148
|
+
- **Event-Driven Architecture:** Zero polling for maximum efficiency and responsiveness.
|
|
149
|
+
- **Built-in Monitoring:** Optional real-time monitoring of client and queue states.
|
|
150
|
+
|
|
151
|
+
**Example:**
|
|
152
|
+
```ts
|
|
153
|
+
import { MultiWorkflowPool, Workflow } from "comfyui-node";
|
|
154
|
+
import SdxlWorkflow from './sdxl-workflow.json';
|
|
155
|
+
import VideoWorkflow from './video-workflow.json';
|
|
156
|
+
|
|
157
|
+
// 1. Define workflows and generate their hash for affinity mapping
|
|
158
|
+
const sdxlWF = Workflow.from(SdxlWorkflow).updateHash();
|
|
159
|
+
const videoWF = Workflow.from(VideoWorkflow).updateHash();
|
|
160
|
+
|
|
161
|
+
// 2. Create a new pool
|
|
162
|
+
const pool = new MultiWorkflowPool({
|
|
163
|
+
logLevel: "info",
|
|
164
|
+
enableMonitoring: true,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// 3. Add clients with workflow affinity
|
|
168
|
+
// This client is specialized for SDXL workflows
|
|
169
|
+
pool.addClient("http://localhost:8188", { workflowAffinity: [sdxlWF] });
|
|
170
|
+
|
|
171
|
+
// This client is specialized for Video workflows
|
|
172
|
+
pool.addClient("http://localhost:8189", { workflowAffinity: [videoWF] });
|
|
173
|
+
|
|
174
|
+
// This client is a general-purpose worker
|
|
175
|
+
pool.addClient("http://localhost:8190");
|
|
176
|
+
|
|
177
|
+
// 4. Initialize the pool (connects to all clients)
|
|
178
|
+
await pool.init();
|
|
179
|
+
|
|
180
|
+
// 5. Submit jobs
|
|
181
|
+
// The pool automatically routes them to the correct client
|
|
182
|
+
const sdxlJobId = await pool.submitJob(sdxlWF);
|
|
183
|
+
const videoJobId = await pool.submitJob(videoWF);
|
|
184
|
+
|
|
185
|
+
// 6. Wait for a job to complete
|
|
186
|
+
const results = await pool.waitForJobCompletion(sdxlJobId);
|
|
187
|
+
console.log("SDXL Job completed!", results.images);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## What's New in v1.6.5
|
|
191
|
+
|
|
192
|
+
- **Integration Test Infrastructure** – Comprehensive reconnection testing with real mock server processes
|
|
193
|
+
- Mock servers spawn in separate OS processes that can be killed/restarted
|
|
194
|
+
- 13 integration tests covering manual/auto-reconnection, state transitions, and multiple restart cycles
|
|
195
|
+
- Test helpers and utilities for easy test development
|
|
196
|
+
- 900+ lines of documentation with quick-start guide and examples
|
|
197
|
+
- Run with: `bun test test/integration/` or `bun run test:integration`
|
|
198
|
+
|
|
199
|
+
See [CHANGELOG.md](./CHANGELOG.md) for complete release notes.
|
|
200
|
+
|
|
201
|
+
## Examples
|
|
202
|
+
|
|
203
|
+
Check the `scripts/` directory for comprehensive examples:
|
|
204
|
+
|
|
205
|
+
- **Basic workflows:** `workflow-tutorial-basic.ts`, `test-simple-txt2img.ts`
|
|
206
|
+
- **Image editing:** `qwen-image-edit-demo.ts`, `qwen-image-edit-queue.ts`
|
|
207
|
+
- **Pooling:** `workflow-pool-demo.ts`, `workflow-pool-debug.ts`
|
|
208
|
+
- **Node bypass:** `demo-node-bypass.ts`, `demo-workflow-bypass.ts`
|
|
209
|
+
- **API nodes:** `api-node-image-edit.ts` (Comfy.org paid nodes)
|
|
210
|
+
- **Image loading:** `image-loading-demo.ts`
|
|
211
|
+
|
|
212
|
+
Live demo: `demos/recursive-edit/` – recursive image editing server + web client.
|
|
213
|
+
|
|
214
|
+
## API Reference
|
|
215
|
+
|
|
216
|
+
### ComfyApi Client
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
const api = new ComfyApi('http://127.0.0.1:8188', 'optional-id', {
|
|
220
|
+
credentials: { type: 'basic', username: 'user', password: 'pass' },
|
|
221
|
+
wsTimeout: 60000,
|
|
222
|
+
comfyOrgApiKey: process.env.COMFY_ORG_API_KEY,
|
|
223
|
+
debug: true
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
await api.ready(); // Connection + feature probing
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Modular Features (`api.ext`)
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
await api.ext.queue.queuePrompt(null, workflow);
|
|
233
|
+
await api.ext.queue.interrupt();
|
|
234
|
+
const stats = await api.ext.system.getSystemStats();
|
|
235
|
+
const checkpoints = await api.ext.node.getCheckpoints();
|
|
236
|
+
await api.ext.file.uploadImage(buffer, 'image.png');
|
|
237
|
+
const history = await api.ext.history.getHistory('prompt-id');
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
See [API Features docs](./docs/api-features.md) for complete namespace reference.
|
|
241
|
+
|
|
242
|
+
### Events
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
api.on('progress', ev => console.log(ev.detail.value, '/', ev.detail.max));
|
|
246
|
+
api.on('b_preview', ev => console.log('Preview:', ev.detail.size));
|
|
247
|
+
api.on('executed', ev => console.log('Node:', ev.detail.node));
|
|
248
|
+
|
|
249
|
+
job.on('progress_pct', pct => console.log(`${pct}%`));
|
|
250
|
+
job.on('preview', blob => console.log('Preview:', blob.size));
|
|
251
|
+
job.on('failed', err => console.error(err));
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Testing
|
|
255
|
+
|
|
256
|
+
### Unit and Integration Tests
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
bun test # Unit + integration tests
|
|
260
|
+
bun run test:integration # Run all integration tests
|
|
261
|
+
bun run test:integration:simple # Run simple reconnection examples
|
|
262
|
+
bun run test:real # Real server tests (COMFY_REAL=1)
|
|
263
|
+
bun run test:full # Comprehensive tests (COMFY_FULL=1)
|
|
264
|
+
bun run coverage # Coverage report
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Integration Tests (v1.6.5+)
|
|
268
|
+
|
|
269
|
+
The library includes a comprehensive integration test infrastructure that spawns real mock server processes to test reconnection behavior:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
# Run all integration tests
|
|
273
|
+
bun test test/integration/
|
|
274
|
+
|
|
275
|
+
# Run simple examples (recommended first)
|
|
276
|
+
bun run test:integration:simple
|
|
277
|
+
|
|
278
|
+
# Validate the mock server infrastructure
|
|
279
|
+
bun test/integration/validate-mock-server.ts
|
|
280
|
+
|
|
281
|
+
# Debug: Run mock server standalone
|
|
282
|
+
bun test/integration/mock-server.ts 8191
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**What's Tested:**
|
|
286
|
+
- Manual and automatic reconnection after server crashes
|
|
287
|
+
- Connection state transitions (connecting → connected → disconnected → reconnecting)
|
|
288
|
+
- Event emission (`reconnected`, `reconnection_failed`)
|
|
289
|
+
- Multiple server restart cycles
|
|
290
|
+
- WebSocket message handling across reconnections
|
|
291
|
+
|
|
292
|
+
**Documentation:**
|
|
293
|
+
- `test/integration/README.md` – Comprehensive guide
|
|
294
|
+
- `test/integration/QUICKSTART.md` – Developer quick-start with patterns
|
|
295
|
+
- `test/integration/SUMMARY.md` – Architecture overview
|
|
296
|
+
|
|
297
|
+
**Example:**
|
|
298
|
+
```ts
|
|
299
|
+
// Integration test pattern
|
|
300
|
+
const manager = new ServerManager({ port: 8191 });
|
|
301
|
+
await manager.startServer(8191);
|
|
302
|
+
|
|
303
|
+
const api = new ComfyApi("http://localhost:8191");
|
|
304
|
+
await initializeClient(api);
|
|
305
|
+
|
|
306
|
+
// Kill server to simulate crash
|
|
307
|
+
await manager.killServer(8191);
|
|
308
|
+
await sleep(500);
|
|
309
|
+
|
|
310
|
+
// Restart server
|
|
311
|
+
await manager.startServer(8191);
|
|
312
|
+
|
|
313
|
+
// Verify reconnection
|
|
314
|
+
await api.reconnectWs(true);
|
|
315
|
+
await waitForConnection(api);
|
|
316
|
+
expect(api.isConnected()).toBe(true);
|
|
317
|
+
|
|
318
|
+
// Cleanup
|
|
319
|
+
api.destroy();
|
|
320
|
+
await manager.killAll();
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
See [Troubleshooting docs](./docs/troubleshooting.md#testing--coverage) for details.
|
|
324
|
+
|
|
325
|
+
## Contributing
|
|
326
|
+
|
|
327
|
+
Issues and PRs welcome! Please:
|
|
328
|
+
|
|
329
|
+
- Include tests for new features
|
|
330
|
+
- Follow existing code style
|
|
331
|
+
- Keep feature surfaces minimal & cohesive
|
|
332
|
+
- Run `bun test && bun run coverage` before submitting
|
|
333
|
+
|
|
334
|
+
## License
|
|
335
|
+
|
|
336
|
+
MIT – see [LICENSE](./LICENSE)
|
|
337
|
+
|
|
338
|
+
## Links
|
|
339
|
+
|
|
340
|
+
- **npm:** [comfyui-node](https://www.npmjs.com/package/comfyui-node)
|
|
341
|
+
- **GitHub:** [igorls/comfyui-node](https://github.com/igorls/comfyui-node)
|
|
342
|
+
- **ComfyUI:** [comfyanonymous/ComfyUI](https://github.com/comfyanonymous/ComfyUI)
|