animastor-comfyui-workflow-connector 0.1.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 +21 -0
- package/README.md +298 -0
- package/package.json +41 -0
- package/src/connector-loader.js +978 -0
- package/src/entity-schema.js +340 -0
- package/src/index.js +265 -0
- package/src/workflow-loader.js +138 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Animastor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# animastor-comfyui-workflow-connector
|
|
2
|
+
|
|
3
|
+
Declarative mapping between data entities (prompts, images, audio, parameters) and ComfyUI workflow JSON.
|
|
4
|
+
|
|
5
|
+
Loads ComfyUI workflow templates and connector definitions from directories you provide, validates their compatibility (content-sensitive SHA-256 + node-class checks), applies entity-keyed bindings, and produces runnable workflow JSON — without exposing ComfyUI node IDs through the API boundary.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install animastor-comfyui-workflow-connector
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires Node.js >= 18. Zero runtime dependencies — uses only Node builtins (`fs`, `path`, `crypto`).
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
const { createWorkflowConnector } = require('animastor-comfyui-workflow-connector');
|
|
19
|
+
|
|
20
|
+
// Point the package at your workflow and connector directories
|
|
21
|
+
const connector = createWorkflowConnector({
|
|
22
|
+
workflowsDir: '/path/to/workflows',
|
|
23
|
+
connectorsDir: '/path/to/connectors',
|
|
24
|
+
logger: console, // optional, defaults to console
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// List loaded workflows
|
|
28
|
+
const workflows = connector.listWorkflows();
|
|
29
|
+
// → [{ name, hash, hasConnector, type, label, compatible }]
|
|
30
|
+
|
|
31
|
+
// Build a runnable workflow from entity-keyed inputs
|
|
32
|
+
const { workflowJson, workflowHash } = connector.build({
|
|
33
|
+
workflow: 'my-workflow',
|
|
34
|
+
inputs: { positivePrompt: 'A castle at dawn' },
|
|
35
|
+
parameters: { steps: 30 },
|
|
36
|
+
});
|
|
37
|
+
// Send workflowJson to ComfyUI
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### `createWorkflowConnector(options)`
|
|
43
|
+
|
|
44
|
+
Factory function. Returns the connector API instance.
|
|
45
|
+
|
|
46
|
+
**Options:**
|
|
47
|
+
|
|
48
|
+
| Property | Type | Description |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `workflowsDir` | `string` | Path to directory containing ComfyUI workflow JSON files |
|
|
51
|
+
| `connectorsDir` | `string` | Path to directory containing `conn-*.json` connector files |
|
|
52
|
+
| `logger` | `object` | Logger with `log()`, `warn()`, `error()` methods (defaults to `console`) |
|
|
53
|
+
|
|
54
|
+
Directories can also be set via `WF_DIR` and `CONNECTOR_DIR` environment variables, but explicit options take precedence.
|
|
55
|
+
|
|
56
|
+
### `.listWorkflows()`
|
|
57
|
+
|
|
58
|
+
Returns an array of loaded workflows with entity-level metadata:
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
[{
|
|
62
|
+
name: 'my-workflow', // filename without .json
|
|
63
|
+
hash: 'abc123...', // SHA-256 of the workflow JSON
|
|
64
|
+
hasConnector: true, // whether a matching connector exists
|
|
65
|
+
type: 'image', // connector type: 'image' | 'audio' | 'video'
|
|
66
|
+
label: 'My Workflow', // human-readable label from connector
|
|
67
|
+
compatible: true // hash + node-class compatibility check result
|
|
68
|
+
}]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
No ComfyUI node IDs are exposed.
|
|
72
|
+
|
|
73
|
+
### `.getWorkflow(name)`
|
|
74
|
+
|
|
75
|
+
Returns a deep-cloned workflow JSON object. Mutating the returned object does not affect the internal registry.
|
|
76
|
+
|
|
77
|
+
Throws `WorkflowNotFoundError` if the workflow name is not loaded.
|
|
78
|
+
|
|
79
|
+
### `.getConnector(name)`
|
|
80
|
+
|
|
81
|
+
Returns an entity-level view of the connector:
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
{
|
|
85
|
+
name: 'my-workflow',
|
|
86
|
+
type: 'image',
|
|
87
|
+
label: 'My Workflow',
|
|
88
|
+
description: '',
|
|
89
|
+
version: '1.0.0',
|
|
90
|
+
profile: {},
|
|
91
|
+
inputs: { positivePrompt: { entityType: 'string', label: 'Positive Prompt', required: true } },
|
|
92
|
+
outputs: { generatedImage: { entityType: 'image', label: 'Generated Image', required: true } },
|
|
93
|
+
parameters: { steps: { entityType: 'int', label: 'Steps', required: false, default: 20, min: 1, max: 100 } }
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
ComfyUI-specific internals (`nodeId`, `field`, `expectedClass`) are stripped from the output.
|
|
98
|
+
|
|
99
|
+
Throws `ConnectorMissingError` if no connector is registered for the workflow.
|
|
100
|
+
|
|
101
|
+
### `.validate(name)`
|
|
102
|
+
|
|
103
|
+
Returns `{ compatible: boolean, warnings: string[] }` after checking hash and node-class compatibility between a workflow and its connector.
|
|
104
|
+
|
|
105
|
+
Throws `WorkflowNotFoundError` or `ConnectorMissingError`.
|
|
106
|
+
|
|
107
|
+
### `.build({ workflow, inputs, parameters })`
|
|
108
|
+
|
|
109
|
+
Builds a runnable workflow JSON from entity-keyed inputs and parameters.
|
|
110
|
+
|
|
111
|
+
| Property | Type | Description |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `workflow` | `string` | Workflow name (required) |
|
|
114
|
+
| `inputs` | `object` | `{ entityKey: value }` applied via connector bindings |
|
|
115
|
+
| `parameters` | `object` | `{ entityKey: value }`; connector defaults fill gaps for unspecified keys |
|
|
116
|
+
|
|
117
|
+
Returns `{ workflowJson, workflowHash }`.
|
|
118
|
+
|
|
119
|
+
Throws:
|
|
120
|
+
- `WorkflowNotFoundError` — workflow not loaded
|
|
121
|
+
- `ConnectorMissingError` — no connector registered
|
|
122
|
+
- `IncompatibleWorkflowError` — hash/node-class mismatch
|
|
123
|
+
- `BuildError` — unknown input/parameter keys or missing workflow name
|
|
124
|
+
|
|
125
|
+
### `.getWorkflowHash(name)`
|
|
126
|
+
|
|
127
|
+
Returns the SHA-256 hash string for a loaded workflow, or `null` if not found.
|
|
128
|
+
|
|
129
|
+
### `.load()`
|
|
130
|
+
|
|
131
|
+
Reloads all workflows and connectors from the configured directories.
|
|
132
|
+
|
|
133
|
+
## Typed Errors
|
|
134
|
+
|
|
135
|
+
All errors extend `ConnectorApiError` which extends `Error`. Each has a `code` property:
|
|
136
|
+
|
|
137
|
+
| Error | Code | When |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| `WorkflowNotFoundError` | `WORKFLOW_NOT_FOUND` | Requested workflow name not loaded |
|
|
140
|
+
| `ConnectorMissingError` | `CONNECTOR_MISSING` | No connector file for the workflow |
|
|
141
|
+
| `IncompatibleWorkflowError` | `INCOMPATIBLE_WORKFLOW` | Hash or node-class mismatch |
|
|
142
|
+
| `BuildError` | `BUILD_FAILED` | Invalid build input (missing name, unknown keys) |
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
const { WorkflowNotFoundError } = require('animastor-comfyui-workflow-connector');
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
connector.getWorkflow('nonexistent');
|
|
149
|
+
} catch (err) {
|
|
150
|
+
if (err instanceof WorkflowNotFoundError) {
|
|
151
|
+
console.log(err.code); // 'WORKFLOW_NOT_FOUND'
|
|
152
|
+
console.log(err.message); // 'Workflow not found: nonexistent'
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Workflow Format
|
|
158
|
+
|
|
159
|
+
The package expects ComfyUI workflow JSON in the standard format — an object keyed by node IDs:
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"1": {
|
|
164
|
+
"class_type": "CLIPTextEncode",
|
|
165
|
+
"inputs": { "text": "" }
|
|
166
|
+
},
|
|
167
|
+
"2": {
|
|
168
|
+
"class_type": "KSampler",
|
|
169
|
+
"inputs": { "seed": 42, "steps": 20 }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Workflow files are plain `.json` files placed in the `workflowsDir` directory. Files prefixed with `old_` are ignored.
|
|
175
|
+
|
|
176
|
+
## Connector Format
|
|
177
|
+
|
|
178
|
+
Connector files define the mapping between data entities and workflow nodes. They live in `connectorsDir` and must be named `conn-*.json`:
|
|
179
|
+
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"connectorVersion": "1.0.0",
|
|
183
|
+
"workflow": "my-workflow",
|
|
184
|
+
"type": "image",
|
|
185
|
+
"label": "My Image Workflow",
|
|
186
|
+
"description": "Generates images from text prompts",
|
|
187
|
+
"inputs": {
|
|
188
|
+
"positivePrompt": {
|
|
189
|
+
"nodeId": "1",
|
|
190
|
+
"field": "inputs.text",
|
|
191
|
+
"entityType": "positivePrompt",
|
|
192
|
+
"label": "Positive Prompt",
|
|
193
|
+
"required": true
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"parameters": {
|
|
197
|
+
"steps": {
|
|
198
|
+
"nodeId": "2",
|
|
199
|
+
"field": "inputs.steps",
|
|
200
|
+
"entityType": "steps",
|
|
201
|
+
"default": 20,
|
|
202
|
+
"min": 1,
|
|
203
|
+
"max": 100
|
|
204
|
+
},
|
|
205
|
+
"seed": {
|
|
206
|
+
"nodeId": "2",
|
|
207
|
+
"field": "inputs.seed",
|
|
208
|
+
"entityType": "seed",
|
|
209
|
+
"default": 42
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Key fields per binding:**
|
|
216
|
+
|
|
217
|
+
| Field | Description |
|
|
218
|
+
|---|---|
|
|
219
|
+
| `nodeId` | ComfyUI node ID in the workflow (internal, not exposed through API) |
|
|
220
|
+
| `field` | Dot-separated path within the node (e.g. `inputs.text`) |
|
|
221
|
+
| `entityType` | Canonical entity key (see Entity Types below) |
|
|
222
|
+
| `default` | Default value applied when parameter is not provided |
|
|
223
|
+
| `min` / `max` | Numeric bounds (for parameter validation) |
|
|
224
|
+
| `required` | Whether the binding must be provided |
|
|
225
|
+
|
|
226
|
+
### Multi-bindings
|
|
227
|
+
|
|
228
|
+
For workflows that accept arrays of inputs (e.g. multiple source images), use the `multi` type:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"sourceImages": {
|
|
233
|
+
"type": "multi",
|
|
234
|
+
"entityType": "sourceImages",
|
|
235
|
+
"bindings": [
|
|
236
|
+
{ "nodeId": "10", "field": "inputs.image_1" },
|
|
237
|
+
{ "nodeId": "11", "field": "inputs.image_2" }
|
|
238
|
+
]
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Entity Types
|
|
244
|
+
|
|
245
|
+
Built-in entity keys recognized by the validation system:
|
|
246
|
+
|
|
247
|
+
**Inputs:**
|
|
248
|
+
`positivePrompt`, `negativePrompt`, `narrationText`, `voiceInstruction`, `dialogueScript`, `defaultInstruct`, `character1Voice`, `character2Voice`, `character3Voice`, `roleName1`, `roleName2`, `roleName3`, `sourceImage`, `sourceImages`, `mask`, `characterImage`, `coverImage`, `audio`
|
|
249
|
+
|
|
250
|
+
**Outputs:**
|
|
251
|
+
`generatedImage`, `generatedVideo`, `generatedAudio`, `videoFrames`
|
|
252
|
+
|
|
253
|
+
**Parameters:**
|
|
254
|
+
`totalFrames`, `frameRate`, `width`, `height`, `steps`, `cfg`, `sampler`, `scheduler`, `seed`, `outputFilenamePrefix`, `fps`, `quality`, `language`, `temperature`, `guideFrameIndex`, `guideStrength`
|
|
255
|
+
|
|
256
|
+
Entity types with `image` or `image[]` type are not validated at runtime (they represent file paths or buffers). String/int/float types receive type checking in parameter updates.
|
|
257
|
+
|
|
258
|
+
## Compatibility Exports
|
|
259
|
+
|
|
260
|
+
For advanced use cases (e.g. migrating from internal APIs), the package also exports the underlying loader singletons:
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
const { workflowLoader, connectorLoader, entitySchema } = require('animastor-comfyui-workflow-connector');
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
These expose the full internal API (node ID lookups, registry manipulation, etc.) and are intended for transitional compatibility only. Prefer `createWorkflowConnector()` for new code.
|
|
267
|
+
|
|
268
|
+
## Standalone Contract
|
|
269
|
+
|
|
270
|
+
This package has **zero** external dependencies:
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
your code ──requires──▶ animastor-comfyui-workflow-connector ──▶ fs/path/crypto
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
- No database, Redis, or HTTP dependencies
|
|
277
|
+
- No GPU Hub, dispatcher, or job protocol dependencies
|
|
278
|
+
- No hardcoded filesystem paths — all directories are injected at runtime
|
|
279
|
+
- No generated artifacts or secrets in the published package
|
|
280
|
+
|
|
281
|
+
The package ships only: `src/` (4 JS files), `README.md`, `LICENSE`, `package.json`.
|
|
282
|
+
|
|
283
|
+
## Running Tests
|
|
284
|
+
|
|
285
|
+
Tests are included in the repository but **not** in the published npm package:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
git clone https://github.com/Animastor/animastor.git
|
|
289
|
+
cd animastor/packages/animastor-comfyui-workflow-connector
|
|
290
|
+
npm install
|
|
291
|
+
npm test
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The test suite (34 tests) verifies workflow loading, connector validation, hash determinism, compatibility checks, binding application, the public API surface, typed errors, and dependency purity — all using local fixture files with zero host dependencies.
|
|
295
|
+
|
|
296
|
+
## License
|
|
297
|
+
|
|
298
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "animastor-comfyui-workflow-connector",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Declarative mapping between data entities and ComfyUI workflow JSON. Loads workflows + connectors, validates compatibility (SHA-256 + node-class checks), applies entity-keyed bindings, and builds runnable workflow JSON. Zero runtime dependencies.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"comfyui",
|
|
8
|
+
"workflow",
|
|
9
|
+
"connector",
|
|
10
|
+
"mapping",
|
|
11
|
+
"ai",
|
|
12
|
+
"image-generation",
|
|
13
|
+
"node-id",
|
|
14
|
+
"declarative"
|
|
15
|
+
],
|
|
16
|
+
"files": [
|
|
17
|
+
"src/",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "mocha --exit tests/*.test.js",
|
|
23
|
+
"test:connector-core": "mocha --exit tests/connector-core.test.js"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/Animastor/animastor.git",
|
|
32
|
+
"directory": "packages/animastor-comfyui-workflow-connector"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/Animastor/animastor/issues"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"chai": "^6.2.2",
|
|
39
|
+
"mocha": "^11.7.5"
|
|
40
|
+
}
|
|
41
|
+
}
|