comfyui-node 1.6.6 → 1.7.0

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