comfyui-node 1.2.0 → 1.3.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.
- package/LICENSE +1 -1
- package/README.md +126 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/call-wrapper.d.ts.map +1 -1
- package/dist/call-wrapper.js +18 -1
- package/dist/call-wrapper.js.map +1 -1
- package/dist/client.d.ts +9 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +132 -2
- package/dist/client.js.map +1 -1
- package/dist/features/queue.d.ts.map +1 -1
- package/dist/features/queue.js +5 -1
- package/dist/features/queue.js.map +1 -1
- package/dist/types/api.d.ts +6 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/event.d.ts +30 -1
- package/dist/types/event.d.ts.map +1 -1
- package/dist/workflow.d.ts +14 -0
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +83 -2
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -25,6 +25,8 @@ TypeScript SDK for interacting with the [ComfyUI](https://github.com/comfyanonym
|
|
|
25
25
|
- [Modular Features (`api.ext`)](#modular-features-apiext)
|
|
26
26
|
- [Events](#events)
|
|
27
27
|
- [Preview Metadata](#preview-metadata)
|
|
28
|
+
- [API Nodes (Comfy.org paid)](#api-nodes-comfyorg-paid)
|
|
29
|
+
- [Image Inputs: Attach Files (DX)](#image-inputs-attach-files-dx)
|
|
28
30
|
- [1.0 Migration](#10-migration)
|
|
29
31
|
- [Reference Overview](#reference-overview)
|
|
30
32
|
- [Examples](#examples)
|
|
@@ -65,7 +67,7 @@ npm install comfyui-node
|
|
|
65
67
|
pnpm add comfyui-node
|
|
66
68
|
# or
|
|
67
69
|
bun add comfyui-node
|
|
68
|
-
```
|
|
70
|
+
```
|
|
69
71
|
|
|
70
72
|
TypeScript types are bundled; no extra install needed.
|
|
71
73
|
|
|
@@ -87,7 +89,7 @@ async function main() {
|
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
91
|
main();
|
|
90
|
-
```
|
|
92
|
+
```
|
|
91
93
|
|
|
92
94
|
## Cheat Sheet
|
|
93
95
|
|
|
@@ -613,8 +615,6 @@ Auto‑generated metadata keys:
|
|
|
613
615
|
|
|
614
616
|
---
|
|
615
617
|
|
|
616
|
-
```
|
|
617
|
-
|
|
618
618
|
### Job Weighting
|
|
619
619
|
|
|
620
620
|
Jobs are inserted into an internal priority queue ordered by ascending weight. Lower weight runs earlier. By default the weight is set to the queue length at insertion (FIFO). You can override:
|
|
@@ -878,6 +878,128 @@ Troubleshooting:
|
|
|
878
878
|
|
|
879
879
|
---
|
|
880
880
|
|
|
881
|
+
## API Nodes (Comfy.org paid)
|
|
882
|
+
|
|
883
|
+
Some workflows use paid API nodes (for example, Luma/Photon) that communicate progress and results via additional binary WebSocket frames. This SDK supports those nodes by:
|
|
884
|
+
|
|
885
|
+
- Allowing you to pass your Comfy.org API key to the server with each job
|
|
886
|
+
- Emitting low-level events for binary/text frames so you can surface progress and result URLs
|
|
887
|
+
|
|
888
|
+
### Enabling API-node runs
|
|
889
|
+
|
|
890
|
+
Provide your key through the `comfyOrgApiKey` client option (recommended to source it from an environment variable):
|
|
891
|
+
|
|
892
|
+
```ts
|
|
893
|
+
import { ComfyApi, Workflow } from 'comfyui-node';
|
|
894
|
+
import LumaPhoton from './your-luma-photon-workflow.json';
|
|
895
|
+
|
|
896
|
+
const api = await new ComfyApi(
|
|
897
|
+
process.env.COMFY_HOST || 'http://127.0.0.1:8188',
|
|
898
|
+
undefined,
|
|
899
|
+
{
|
|
900
|
+
comfyOrgApiKey: process.env.COMFY_ORG_API_KEY,
|
|
901
|
+
wsTimeout: 30000, // API nodes may take longer; increase if needed
|
|
902
|
+
debug: true // optional: structured socket + polling logs
|
|
903
|
+
}
|
|
904
|
+
).ready();
|
|
905
|
+
|
|
906
|
+
// Minimal example: set prompt/seed, declare output, observe events
|
|
907
|
+
const wf = Workflow.fromAugmented(LumaPhoton)
|
|
908
|
+
.input('LUMA', 'prompt', 'Old photograph of the Guanabara Bay in Rio de Janeiro, aerial view')
|
|
909
|
+
.input('LUMA', 'seed', -1) // -1 => randomized; see _autoSeeds in result
|
|
910
|
+
.output('final_images', '2'); // alias, nodeId (auto-corrects if swapped)
|
|
911
|
+
|
|
912
|
+
// Low-level API-node events (binary channel text + raw preview bytes)
|
|
913
|
+
api.on('b_text', (ev) => {
|
|
914
|
+
const text = (ev as any).detail as string;
|
|
915
|
+
if (typeof text === 'string') console.log('[api-node text]', text.slice(0, 200));
|
|
916
|
+
});
|
|
917
|
+
api.on('b_text_meta', (ev) => {
|
|
918
|
+
// { channel: number, text: string }
|
|
919
|
+
console.log('[api-node text meta]', (ev as any).detail);
|
|
920
|
+
});
|
|
921
|
+
api.on('b_preview_raw', (ev) => {
|
|
922
|
+
const bytes = (ev as any).detail as Uint8Array;
|
|
923
|
+
console.log('[api-node preview raw bytes]', bytes?.byteLength);
|
|
924
|
+
});
|
|
925
|
+
|
|
926
|
+
const job = await api.run(wf, { autoDestroy: true });
|
|
927
|
+
|
|
928
|
+
job
|
|
929
|
+
.on('start', (id) => console.log('[start]', id))
|
|
930
|
+
.on('progress_pct', (p) => process.stdout.write(`\rprogress ${p}% `))
|
|
931
|
+
.on('preview', (blob) => console.log('\npreview bytes=', blob.size))
|
|
932
|
+
.on('failed', (e) => console.error('\nfailed', e));
|
|
933
|
+
|
|
934
|
+
const result = await job.done();
|
|
935
|
+
console.log('\nPrompt ID:', result._promptId);
|
|
936
|
+
for (const img of (result.final_images?.images || [])) {
|
|
937
|
+
console.log('image path:', api.ext.file.getPathImage(img));
|
|
938
|
+
}
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
Notes:
|
|
942
|
+
|
|
943
|
+
- API-node text frames often include human-readable progress and a final “Result URL:” line. The SDK exposes the raw text via `b_text` and `{ channel, text }` via `b_text_meta` so you can parse or display them as desired.
|
|
944
|
+
- For long-running API calls, increase `wsTimeout` and consider enabling `debug` or setting `COMFY_DEBUG=1` to troubleshoot reconnection/polling.
|
|
945
|
+
- Output declaration accepts any of: `'alias:NodeId'`, `('alias','NodeId')`, or `'NodeId'`. If you accidentally swap the alias/id parameters, the SDK will auto-correct and warn.
|
|
946
|
+
|
|
947
|
+
Security tip: Never print your API key. The built-in debug logger redacts common key/authorization fields automatically.
|
|
948
|
+
|
|
949
|
+
---
|
|
950
|
+
|
|
951
|
+
## Image Inputs: Attach Files (DX)
|
|
952
|
+
|
|
953
|
+
When a workflow references images (e.g., `LoadImage.image = "IMAGE_A.png"` or folder loaders such as `LoadImageSetFromFolderNode`), you can attach local buffers directly to the `Workflow` and let the SDK handle uploads before execution.
|
|
954
|
+
|
|
955
|
+
Helpers:
|
|
956
|
+
|
|
957
|
+
- `wf.attachImage(nodeId, inputName, data, fileName, opts?)`
|
|
958
|
+
- Uploads `data` (Blob/Buffer/ArrayBuffer/Uint8Array) and sets the node input to `fileName` automatically.
|
|
959
|
+
- Options: `{ subfolder?: string; override?: boolean }`.
|
|
960
|
+
- `wf.attachFolderFiles(subfolder, files[], opts?)`
|
|
961
|
+
- Upload multiple files into a server subfolder; ideal for folder‑based loaders.
|
|
962
|
+
|
|
963
|
+
Example (see `scripts/image-loading-demo.ts`):
|
|
964
|
+
|
|
965
|
+
```ts
|
|
966
|
+
import { ComfyApi, Workflow } from 'comfyui-node';
|
|
967
|
+
import Graph from './ImageLoading.json';
|
|
968
|
+
import * as fs from 'node:fs/promises';
|
|
969
|
+
import * as path from 'node:path';
|
|
970
|
+
|
|
971
|
+
const api = await new ComfyApi(process.env.COMFY_HOST || 'http://127.0.0.1:8188').ready();
|
|
972
|
+
const wf = Workflow.from(Graph);
|
|
973
|
+
|
|
974
|
+
// Attach two individual images for LoadImage nodes 2 and 4
|
|
975
|
+
const dir = path.resolve(process.cwd(), 'scripts', 'example_images');
|
|
976
|
+
const a = await fs.readFile(path.join(dir, 'IMAGE_A.png'));
|
|
977
|
+
const b = await fs.readFile(path.join(dir, 'IMAGE_B.png'));
|
|
978
|
+
wf.attachImage('2', 'image', a, 'IMAGE_A.png', { override: true })
|
|
979
|
+
.attachImage('4', 'image', b, 'IMAGE_B.png', { override: true });
|
|
980
|
+
|
|
981
|
+
// Attach an entire folder for node 5 (LoadImageSetFromFolderNode)
|
|
982
|
+
const files = (await fs.readdir(dir))
|
|
983
|
+
.filter(f => /\.(png|jpe?g|webp)$/i.test(f))
|
|
984
|
+
.map(async f => ({ fileName: f, data: await fs.readFile(path.join(dir, f)) }));
|
|
985
|
+
wf.attachFolderFiles('EXAMPLE_IMAGES', await Promise.all(files), { override: true });
|
|
986
|
+
wf.set('5.inputs.folder', 'EXAMPLE_IMAGES');
|
|
987
|
+
|
|
988
|
+
// Collect a simple output target for demonstration
|
|
989
|
+
wf.output('1');
|
|
990
|
+
|
|
991
|
+
const job = await api.run(wf, { autoDestroy: true });
|
|
992
|
+
job.on('progress_pct', p => process.stdout.write(`\rprogress ${p}% `));
|
|
993
|
+
await job.done();
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
Notes:
|
|
997
|
+
|
|
998
|
+
- The inputs are updated to point at the uploaded filenames; subfolders are handled server‑side.
|
|
999
|
+
- Use `override: true` to replace existing files with the same name if needed.
|
|
1000
|
+
|
|
1001
|
+
---
|
|
1002
|
+
|
|
881
1003
|
## 1.0 Migration
|
|
882
1004
|
|
|
883
1005
|
All legacy `ComfyApi` instance methods listed below were **removed in 1.0.0** after a deprecation window in 0.2.x. Migrate to the `api.ext.*` namespaces. If you're upgrading from <1.0, replace calls as shown. No runtime warnings remain (they were stripped with the removals).
|