@fre4x/comfyui 1.0.58 → 1.0.59
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 +38 -0
- package/dist/index.js +997 -129
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3223,8 +3223,8 @@ var require_utils = __commonJS({
|
|
|
3223
3223
|
}
|
|
3224
3224
|
return ind;
|
|
3225
3225
|
}
|
|
3226
|
-
function removeDotSegments(
|
|
3227
|
-
let input =
|
|
3226
|
+
function removeDotSegments(path2) {
|
|
3227
|
+
let input = path2;
|
|
3228
3228
|
const output = [];
|
|
3229
3229
|
let nextSlash = -1;
|
|
3230
3230
|
let len = 0;
|
|
@@ -3423,8 +3423,8 @@ var require_schemes = __commonJS({
|
|
|
3423
3423
|
wsComponent.secure = void 0;
|
|
3424
3424
|
}
|
|
3425
3425
|
if (wsComponent.resourceName) {
|
|
3426
|
-
const [
|
|
3427
|
-
wsComponent.path =
|
|
3426
|
+
const [path2, query] = wsComponent.resourceName.split("?");
|
|
3427
|
+
wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
|
|
3428
3428
|
wsComponent.query = query;
|
|
3429
3429
|
wsComponent.resourceName = void 0;
|
|
3430
3430
|
}
|
|
@@ -6786,12 +6786,12 @@ var require_dist = __commonJS({
|
|
|
6786
6786
|
throw new Error(`Unknown format "${name}"`);
|
|
6787
6787
|
return f;
|
|
6788
6788
|
};
|
|
6789
|
-
function addFormats(ajv, list,
|
|
6789
|
+
function addFormats(ajv, list, fs2, exportName) {
|
|
6790
6790
|
var _a2;
|
|
6791
6791
|
var _b;
|
|
6792
6792
|
(_a2 = (_b = ajv.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
6793
6793
|
for (const f of list)
|
|
6794
|
-
ajv.addFormat(f,
|
|
6794
|
+
ajv.addFormat(f, fs2[f]);
|
|
6795
6795
|
}
|
|
6796
6796
|
module.exports = exports = formatsPlugin;
|
|
6797
6797
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -6800,7 +6800,10 @@ var require_dist = __commonJS({
|
|
|
6800
6800
|
});
|
|
6801
6801
|
|
|
6802
6802
|
// src/index.ts
|
|
6803
|
+
import * as fs from "node:fs/promises";
|
|
6803
6804
|
import { realpathSync } from "node:fs";
|
|
6805
|
+
import { homedir } from "node:os";
|
|
6806
|
+
import path from "node:path";
|
|
6804
6807
|
import { fileURLToPath } from "node:url";
|
|
6805
6808
|
|
|
6806
6809
|
// ../packages/shared/dist/errors.js
|
|
@@ -6873,16 +6876,6 @@ Suggestion: If the problem persists, check server logs.`
|
|
|
6873
6876
|
};
|
|
6874
6877
|
}
|
|
6875
6878
|
|
|
6876
|
-
// ../packages/shared/dist/format.js
|
|
6877
|
-
function formatField(label, value) {
|
|
6878
|
-
if (value === null || value === void 0 || value === "")
|
|
6879
|
-
return "";
|
|
6880
|
-
return `**${label}:** ${value}`;
|
|
6881
|
-
}
|
|
6882
|
-
function formatFields(fields) {
|
|
6883
|
-
return fields.map(([label, value]) => formatField(label, value)).filter(Boolean).join(" \n");
|
|
6884
|
-
}
|
|
6885
|
-
|
|
6886
6879
|
// ../node_modules/zod/index.js
|
|
6887
6880
|
var zod_exports = {};
|
|
6888
6881
|
__export(zod_exports, {
|
|
@@ -7893,10 +7886,10 @@ function mergeDefs(...defs) {
|
|
|
7893
7886
|
function cloneDef(schema) {
|
|
7894
7887
|
return mergeDefs(schema._zod.def);
|
|
7895
7888
|
}
|
|
7896
|
-
function getElementAtPath(obj,
|
|
7897
|
-
if (!
|
|
7889
|
+
function getElementAtPath(obj, path2) {
|
|
7890
|
+
if (!path2)
|
|
7898
7891
|
return obj;
|
|
7899
|
-
return
|
|
7892
|
+
return path2.reduce((acc, key) => acc?.[key], obj);
|
|
7900
7893
|
}
|
|
7901
7894
|
function promiseAllObject(promisesObj) {
|
|
7902
7895
|
const keys = Object.keys(promisesObj);
|
|
@@ -8279,11 +8272,11 @@ function aborted(x, startIndex = 0) {
|
|
|
8279
8272
|
}
|
|
8280
8273
|
return false;
|
|
8281
8274
|
}
|
|
8282
|
-
function prefixIssues(
|
|
8275
|
+
function prefixIssues(path2, issues) {
|
|
8283
8276
|
return issues.map((iss) => {
|
|
8284
8277
|
var _a2;
|
|
8285
8278
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
8286
|
-
iss.path.unshift(
|
|
8279
|
+
iss.path.unshift(path2);
|
|
8287
8280
|
return iss;
|
|
8288
8281
|
});
|
|
8289
8282
|
}
|
|
@@ -8466,7 +8459,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
|
|
|
8466
8459
|
}
|
|
8467
8460
|
function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
8468
8461
|
const result = { errors: [] };
|
|
8469
|
-
const processError = (error49,
|
|
8462
|
+
const processError = (error49, path2 = []) => {
|
|
8470
8463
|
var _a2, _b;
|
|
8471
8464
|
for (const issue2 of error49.issues) {
|
|
8472
8465
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -8476,7 +8469,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
8476
8469
|
} else if (issue2.code === "invalid_element") {
|
|
8477
8470
|
processError({ issues: issue2.issues }, issue2.path);
|
|
8478
8471
|
} else {
|
|
8479
|
-
const fullpath = [...
|
|
8472
|
+
const fullpath = [...path2, ...issue2.path];
|
|
8480
8473
|
if (fullpath.length === 0) {
|
|
8481
8474
|
result.errors.push(mapper(issue2));
|
|
8482
8475
|
continue;
|
|
@@ -8508,8 +8501,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
8508
8501
|
}
|
|
8509
8502
|
function toDotPath(_path) {
|
|
8510
8503
|
const segs = [];
|
|
8511
|
-
const
|
|
8512
|
-
for (const seg of
|
|
8504
|
+
const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
8505
|
+
for (const seg of path2) {
|
|
8513
8506
|
if (typeof seg === "number")
|
|
8514
8507
|
segs.push(`[${seg}]`);
|
|
8515
8508
|
else if (typeof seg === "symbol")
|
|
@@ -20486,13 +20479,13 @@ function resolveRef(ref, ctx) {
|
|
|
20486
20479
|
if (!ref.startsWith("#")) {
|
|
20487
20480
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
20488
20481
|
}
|
|
20489
|
-
const
|
|
20490
|
-
if (
|
|
20482
|
+
const path2 = ref.slice(1).split("/").filter(Boolean);
|
|
20483
|
+
if (path2.length === 0) {
|
|
20491
20484
|
return ctx.rootSchema;
|
|
20492
20485
|
}
|
|
20493
20486
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
20494
|
-
if (
|
|
20495
|
-
const key =
|
|
20487
|
+
if (path2[0] === defsKey) {
|
|
20488
|
+
const key = path2[1];
|
|
20496
20489
|
if (!key || !ctx.defs[key]) {
|
|
20497
20490
|
throw new Error(`Reference not found: ${ref}`);
|
|
20498
20491
|
}
|
|
@@ -21284,8 +21277,8 @@ function getErrorMap2() {
|
|
|
21284
21277
|
|
|
21285
21278
|
// ../node_modules/zod/v3/helpers/parseUtil.js
|
|
21286
21279
|
var makeIssue = (params) => {
|
|
21287
|
-
const { data, path, errorMaps, issueData } = params;
|
|
21288
|
-
const fullPath = [...
|
|
21280
|
+
const { data, path: path2, errorMaps, issueData } = params;
|
|
21281
|
+
const fullPath = [...path2, ...issueData.path || []];
|
|
21289
21282
|
const fullIssue = {
|
|
21290
21283
|
...issueData,
|
|
21291
21284
|
path: fullPath
|
|
@@ -21400,11 +21393,11 @@ var errorUtil;
|
|
|
21400
21393
|
|
|
21401
21394
|
// ../node_modules/zod/v3/types.js
|
|
21402
21395
|
var ParseInputLazyPath = class {
|
|
21403
|
-
constructor(parent, value,
|
|
21396
|
+
constructor(parent, value, path2, key) {
|
|
21404
21397
|
this._cachedPath = [];
|
|
21405
21398
|
this.parent = parent;
|
|
21406
21399
|
this.data = value;
|
|
21407
|
-
this._path =
|
|
21400
|
+
this._path = path2;
|
|
21408
21401
|
this._key = key;
|
|
21409
21402
|
}
|
|
21410
21403
|
get path() {
|
|
@@ -30530,7 +30523,16 @@ var MOCK_FIXTURES = {
|
|
|
30530
30523
|
ckpt_name: [
|
|
30531
30524
|
[
|
|
30532
30525
|
"v1-5-pruned-emaonly.ckpt",
|
|
30533
|
-
"sd_xl_base_1.0.safetensors"
|
|
30526
|
+
"sd_xl_base_1.0.safetensors",
|
|
30527
|
+
"cyberrealisticPony_v160.safetensors",
|
|
30528
|
+
"harukiMIX_ponyV23.safetensors",
|
|
30529
|
+
"harukiMIX_ponyV40.safetensors",
|
|
30530
|
+
"ponyRealism_V22.safetensors",
|
|
30531
|
+
"ponyRealism_V23.safetensors",
|
|
30532
|
+
"ponyDiffusion_V6XL.safetensors",
|
|
30533
|
+
"realvisxlV50.safetensors",
|
|
30534
|
+
"juggernautXL_v9.safetensors",
|
|
30535
|
+
"waiNSFWIllustrious_v120.safetensors"
|
|
30534
30536
|
],
|
|
30535
30537
|
{}
|
|
30536
30538
|
]
|
|
@@ -30584,6 +30586,7 @@ var MOCK_FIXTURES = {
|
|
|
30584
30586
|
var zNamespace = zod_exports;
|
|
30585
30587
|
var z3 = zNamespace.z ?? zNamespace.default ?? zNamespace;
|
|
30586
30588
|
var COMFYUI_SERVER_URL = process.env.COMFYUI_SERVER_URL || "http://localhost:8188";
|
|
30589
|
+
var COMFYUI_WORKFLOWS_DIR = process.env.COMFYUI_WORKFLOWS_DIR || path.join(homedir(), ".fre4x-comfyui", "workflows");
|
|
30587
30590
|
var PACKAGE_VERSION = getPackageVersion(import.meta.url);
|
|
30588
30591
|
var BYTES_PER_GIB = 1024 ** 3;
|
|
30589
30592
|
var PaginationMetadataSchema = z3.object({
|
|
@@ -30612,15 +30615,82 @@ var ObjectInfoSchema = z3.object({
|
|
|
30612
30615
|
nodes: z3.record(z3.string(), z3.unknown()),
|
|
30613
30616
|
pagination: PaginationMetadataSchema.optional()
|
|
30614
30617
|
});
|
|
30618
|
+
var HistoryImageSchema = z3.object({
|
|
30619
|
+
filename: z3.string(),
|
|
30620
|
+
subfolder: z3.string(),
|
|
30621
|
+
type: z3.string(),
|
|
30622
|
+
view_url: z3.string().url()
|
|
30623
|
+
});
|
|
30615
30624
|
var WorkflowResponseSchema = z3.object({
|
|
30616
30625
|
prompt_id: z3.string(),
|
|
30617
30626
|
number: z3.number(),
|
|
30618
|
-
node_errors: z3.record(z3.string(), z3.unknown())
|
|
30627
|
+
node_errors: z3.record(z3.string(), z3.unknown()),
|
|
30628
|
+
status: z3.string().optional(),
|
|
30629
|
+
completed: z3.boolean().optional(),
|
|
30630
|
+
timed_out: z3.boolean().optional(),
|
|
30631
|
+
elapsed_seconds: z3.number().optional(),
|
|
30632
|
+
image_count: z3.number().optional(),
|
|
30633
|
+
images: z3.array(HistoryImageSchema).optional(),
|
|
30634
|
+
history_entry: z3.record(z3.string(), z3.unknown()).nullable().optional()
|
|
30619
30635
|
});
|
|
30620
30636
|
var HistorySchema = z3.object({
|
|
30621
30637
|
history: z3.record(z3.string(), z3.unknown()),
|
|
30622
30638
|
pagination: PaginationMetadataSchema.optional()
|
|
30623
30639
|
});
|
|
30640
|
+
var WaitForWorkflowSchema = z3.object({
|
|
30641
|
+
prompt_id: z3.string(),
|
|
30642
|
+
status: z3.string(),
|
|
30643
|
+
completed: z3.boolean(),
|
|
30644
|
+
timed_out: z3.boolean(),
|
|
30645
|
+
elapsed_seconds: z3.number(),
|
|
30646
|
+
image_count: z3.number(),
|
|
30647
|
+
images: z3.array(HistoryImageSchema),
|
|
30648
|
+
history_entry: z3.record(z3.string(), z3.unknown()).nullable()
|
|
30649
|
+
});
|
|
30650
|
+
var WorkflowTagSchema = z3.string().min(1).max(50);
|
|
30651
|
+
var EditableWorkflowValueSchema = z3.union([
|
|
30652
|
+
z3.string(),
|
|
30653
|
+
z3.number(),
|
|
30654
|
+
z3.boolean()
|
|
30655
|
+
]);
|
|
30656
|
+
var WorkflowEditableInputSchema = z3.object({
|
|
30657
|
+
node_id: z3.string(),
|
|
30658
|
+
node_class: z3.string(),
|
|
30659
|
+
input_name: z3.string(),
|
|
30660
|
+
value_type: z3.enum(["string", "number", "boolean", "enum"]),
|
|
30661
|
+
current_value: EditableWorkflowValueSchema,
|
|
30662
|
+
options: z3.array(z3.string()).default([])
|
|
30663
|
+
});
|
|
30664
|
+
var StoredWorkflowMetadataSchema = z3.object({
|
|
30665
|
+
id: z3.string(),
|
|
30666
|
+
name: z3.string(),
|
|
30667
|
+
description: z3.string().optional(),
|
|
30668
|
+
tags: z3.array(WorkflowTagSchema),
|
|
30669
|
+
created_at: z3.string(),
|
|
30670
|
+
updated_at: z3.string(),
|
|
30671
|
+
node_count: z3.number(),
|
|
30672
|
+
editable_input_count: z3.number(),
|
|
30673
|
+
source: z3.enum(["local", "mock"])
|
|
30674
|
+
});
|
|
30675
|
+
var StoredWorkflowSchema = z3.object({
|
|
30676
|
+
workflow: StoredWorkflowMetadataSchema,
|
|
30677
|
+
prompt: z3.record(z3.string(), z3.unknown()),
|
|
30678
|
+
editable_inputs: z3.array(WorkflowEditableInputSchema)
|
|
30679
|
+
});
|
|
30680
|
+
var WorkflowListSchema = z3.object({
|
|
30681
|
+
workflows: z3.array(StoredWorkflowMetadataSchema),
|
|
30682
|
+
pagination: PaginationMetadataSchema.optional()
|
|
30683
|
+
});
|
|
30684
|
+
var WorkflowOverrideSchema = z3.object({
|
|
30685
|
+
node_id: z3.string().min(1).describe("Node ID to override."),
|
|
30686
|
+
input_name: z3.string().min(1).describe("Input field name to override."),
|
|
30687
|
+
value: EditableWorkflowValueSchema.describe("Replacement scalar value.")
|
|
30688
|
+
});
|
|
30689
|
+
var RunStoredWorkflowSchema = WorkflowResponseSchema.extend({
|
|
30690
|
+
workflow_id: z3.string(),
|
|
30691
|
+
workflow_name: z3.string(),
|
|
30692
|
+
applied_overrides: z3.array(WorkflowOverrideSchema)
|
|
30693
|
+
});
|
|
30624
30694
|
var QueueSchema = z3.object({
|
|
30625
30695
|
queue_running: z3.array(z3.unknown()),
|
|
30626
30696
|
queue_pending: z3.array(z3.unknown())
|
|
@@ -30638,7 +30708,9 @@ var ListObjectInfoInputSchema = z3.object({
|
|
|
30638
30708
|
}).strict();
|
|
30639
30709
|
var ExecuteWorkflowInputSchema = z3.object({
|
|
30640
30710
|
prompt: z3.record(z3.string(), z3.unknown()).describe("Workflow in ComfyUI API JSON format."),
|
|
30641
|
-
client_id: z3.string().optional().describe("Optional unique client identifier.")
|
|
30711
|
+
client_id: z3.string().optional().describe("Optional unique client identifier."),
|
|
30712
|
+
await: z3.boolean().default(false).describe("Wait for completion before returning."),
|
|
30713
|
+
timeout: z3.number().int().min(1).max(600).default(120).describe("Wait timeout in seconds.")
|
|
30642
30714
|
}).strict();
|
|
30643
30715
|
var GetHistoryInputSchema = z3.object({
|
|
30644
30716
|
prompt_id: z3.string().optional().describe("Specific prompt ID to retrieve. Omit for full history."),
|
|
@@ -30650,6 +30722,40 @@ var GetViewUrlInputSchema = z3.object({
|
|
|
30650
30722
|
subfolder: z3.string().optional().describe("Subfolder within the output directory."),
|
|
30651
30723
|
type: z3.enum(["output", "input", "temp"]).default("output").describe("Storage type.")
|
|
30652
30724
|
}).strict();
|
|
30725
|
+
var ListWorkflowsInputSchema = z3.object({
|
|
30726
|
+
limit: z3.number().int().min(1).max(100).default(50).describe("Pagination limit."),
|
|
30727
|
+
offset: z3.number().int().min(0).default(0).describe("Pagination offset.")
|
|
30728
|
+
}).strict();
|
|
30729
|
+
var SearchWorkflowsInputSchema = z3.object({
|
|
30730
|
+
query: z3.string().min(1).describe("Search text for name, tags, or description."),
|
|
30731
|
+
limit: z3.number().int().min(1).max(100).default(50).describe("Pagination limit."),
|
|
30732
|
+
offset: z3.number().int().min(0).default(0).describe("Pagination offset.")
|
|
30733
|
+
}).strict();
|
|
30734
|
+
var GetWorkflowInputSchema = z3.object({
|
|
30735
|
+
workflow_id: z3.string().min(1).describe("Stored workflow ID.")
|
|
30736
|
+
}).strict();
|
|
30737
|
+
var SaveWorkflowInputSchema = z3.object({
|
|
30738
|
+
workflow_id: z3.string().min(1).optional().describe("Optional stable workflow ID."),
|
|
30739
|
+
name: z3.string().min(1).describe("Human-readable workflow name."),
|
|
30740
|
+
description: z3.string().optional().describe("Optional workflow summary."),
|
|
30741
|
+
tags: z3.array(WorkflowTagSchema).default([]).describe("Optional workflow tags."),
|
|
30742
|
+
prompt: z3.record(z3.string(), z3.unknown()).describe("Workflow in ComfyUI API JSON format."),
|
|
30743
|
+
overwrite: z3.boolean().default(false).describe("Overwrite an existing workflow with the same ID.")
|
|
30744
|
+
}).strict();
|
|
30745
|
+
var RunWorkflowInputSchema = z3.object({
|
|
30746
|
+
workflow_id: z3.string().min(1).describe("Stored workflow ID to execute."),
|
|
30747
|
+
overrides: z3.array(WorkflowOverrideSchema).default([]).describe("Editable input overrides to apply before execution."),
|
|
30748
|
+
client_id: z3.string().optional().describe("Optional unique client identifier."),
|
|
30749
|
+
await: z3.boolean().default(false).describe("Wait for completion before returning."),
|
|
30750
|
+
timeout: z3.number().int().min(1).max(600).default(120).describe("Wait timeout in seconds."),
|
|
30751
|
+
require_images: z3.boolean().default(false).describe("When awaiting, require generated images before return.")
|
|
30752
|
+
}).strict();
|
|
30753
|
+
var WaitForWorkflowInputSchema = z3.object({
|
|
30754
|
+
prompt_id: z3.string().min(1).describe("Prompt ID to wait for."),
|
|
30755
|
+
timeout_seconds: z3.number().int().min(1).max(600).default(120).describe("Maximum wait time in seconds."),
|
|
30756
|
+
poll_interval_ms: z3.number().int().min(100).max(1e4).default(1e3).describe("Polling interval in milliseconds."),
|
|
30757
|
+
require_images: z3.boolean().default(false).describe("Wait until images are available too.")
|
|
30758
|
+
}).strict();
|
|
30653
30759
|
var ComfyApiError = class extends Error {
|
|
30654
30760
|
constructor(message, statusCode, details) {
|
|
30655
30761
|
super(message);
|
|
@@ -30667,6 +30773,63 @@ function ensureRecord(value, label) {
|
|
|
30667
30773
|
}
|
|
30668
30774
|
return value;
|
|
30669
30775
|
}
|
|
30776
|
+
function isEditableWorkflowValue(value) {
|
|
30777
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
30778
|
+
}
|
|
30779
|
+
function slugifyWorkflowId(value) {
|
|
30780
|
+
const slug = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
30781
|
+
return slug.length > 0 ? slug : "workflow";
|
|
30782
|
+
}
|
|
30783
|
+
function getWorkflowFilePath(workflowId) {
|
|
30784
|
+
return path.join(COMFYUI_WORKFLOWS_DIR, `${workflowId}.json`);
|
|
30785
|
+
}
|
|
30786
|
+
async function ensureWorkflowStoreDir() {
|
|
30787
|
+
await fs.mkdir(COMFYUI_WORKFLOWS_DIR, { recursive: true });
|
|
30788
|
+
}
|
|
30789
|
+
async function readStoredWorkflowFile(workflowId) {
|
|
30790
|
+
try {
|
|
30791
|
+
const content = await fs.readFile(
|
|
30792
|
+
getWorkflowFilePath(workflowId),
|
|
30793
|
+
"utf8"
|
|
30794
|
+
);
|
|
30795
|
+
return StoredWorkflowSchema.parse(JSON.parse(content));
|
|
30796
|
+
} catch (error48) {
|
|
30797
|
+
if (isRecord(error48) && error48.code === "ENOENT") {
|
|
30798
|
+
return void 0;
|
|
30799
|
+
}
|
|
30800
|
+
throw error48;
|
|
30801
|
+
}
|
|
30802
|
+
}
|
|
30803
|
+
async function writeStoredWorkflowFile(workflow) {
|
|
30804
|
+
await ensureWorkflowStoreDir();
|
|
30805
|
+
await fs.writeFile(
|
|
30806
|
+
getWorkflowFilePath(workflow.workflow.id),
|
|
30807
|
+
`${JSON.stringify(workflow, null, 2)}
|
|
30808
|
+
`,
|
|
30809
|
+
"utf8"
|
|
30810
|
+
);
|
|
30811
|
+
}
|
|
30812
|
+
async function listStoredWorkflowFiles() {
|
|
30813
|
+
await ensureWorkflowStoreDir();
|
|
30814
|
+
const entries = await fs.readdir(COMFYUI_WORKFLOWS_DIR, {
|
|
30815
|
+
withFileTypes: true
|
|
30816
|
+
});
|
|
30817
|
+
const workflows = [];
|
|
30818
|
+
for (const entry of entries) {
|
|
30819
|
+
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
|
30820
|
+
continue;
|
|
30821
|
+
}
|
|
30822
|
+
const content = await fs.readFile(
|
|
30823
|
+
path.join(COMFYUI_WORKFLOWS_DIR, entry.name),
|
|
30824
|
+
"utf8"
|
|
30825
|
+
);
|
|
30826
|
+
workflows.push(StoredWorkflowSchema.parse(JSON.parse(content)));
|
|
30827
|
+
}
|
|
30828
|
+
workflows.sort(
|
|
30829
|
+
(left, right) => right.workflow.updated_at.localeCompare(left.workflow.updated_at)
|
|
30830
|
+
);
|
|
30831
|
+
return workflows;
|
|
30832
|
+
}
|
|
30670
30833
|
function unwrapNamedNode(nodeClass, value) {
|
|
30671
30834
|
if (!isRecord(value)) {
|
|
30672
30835
|
return value;
|
|
@@ -30720,6 +30883,17 @@ function normalizeSystemInfo(source) {
|
|
|
30720
30883
|
function formatGiB(bytes) {
|
|
30721
30884
|
return `${(bytes / BYTES_PER_GIB).toFixed(1)} GiB`;
|
|
30722
30885
|
}
|
|
30886
|
+
function formatJsonCodeBlock(value) {
|
|
30887
|
+
return `\`\`\`json
|
|
30888
|
+
${JSON.stringify(value, null, 2)}
|
|
30889
|
+
\`\`\``;
|
|
30890
|
+
}
|
|
30891
|
+
function formatMarkdownBulletList(items) {
|
|
30892
|
+
return items.length > 0 ? items.map((item) => `- ${item}`).join("\n") : "- none";
|
|
30893
|
+
}
|
|
30894
|
+
async function sleep(ms) {
|
|
30895
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
30896
|
+
}
|
|
30723
30897
|
function getEnumLikeOptions(value) {
|
|
30724
30898
|
if (!Array.isArray(value) || value.length === 0) {
|
|
30725
30899
|
return [];
|
|
@@ -30732,6 +30906,98 @@ function getEnumLikeOptions(value) {
|
|
|
30732
30906
|
(entry) => typeof entry === "string" || typeof entry === "number" || typeof entry === "boolean"
|
|
30733
30907
|
);
|
|
30734
30908
|
}
|
|
30909
|
+
function buildViewUrl(filename, type, subfolder) {
|
|
30910
|
+
const params = new URLSearchParams({
|
|
30911
|
+
filename,
|
|
30912
|
+
type
|
|
30913
|
+
});
|
|
30914
|
+
if (subfolder) {
|
|
30915
|
+
params.set("subfolder", subfolder);
|
|
30916
|
+
}
|
|
30917
|
+
return new URL(`/view?${params.toString()}`, COMFYUI_SERVER_URL).toString();
|
|
30918
|
+
}
|
|
30919
|
+
async function fetchNodeDefinition(nodeClass) {
|
|
30920
|
+
if (IS_MOCK) {
|
|
30921
|
+
return MOCK_FIXTURES.object_info[nodeClass];
|
|
30922
|
+
}
|
|
30923
|
+
try {
|
|
30924
|
+
const rawInfo = await fetchComfyJson(
|
|
30925
|
+
`/object_info/${encodeURIComponent(nodeClass)}`
|
|
30926
|
+
);
|
|
30927
|
+
return unwrapNamedNode(nodeClass, rawInfo);
|
|
30928
|
+
} catch (error48) {
|
|
30929
|
+
if (error48 instanceof ComfyApiError && error48.statusCode === 404) {
|
|
30930
|
+
return void 0;
|
|
30931
|
+
}
|
|
30932
|
+
throw error48;
|
|
30933
|
+
}
|
|
30934
|
+
}
|
|
30935
|
+
async function deriveEditableWorkflowInputs(prompt) {
|
|
30936
|
+
const nodeDefinitions = /* @__PURE__ */ new Map();
|
|
30937
|
+
const editableInputs = [];
|
|
30938
|
+
for (const [nodeId, nodeValue] of Object.entries(prompt)) {
|
|
30939
|
+
if (!isRecord(nodeValue)) {
|
|
30940
|
+
continue;
|
|
30941
|
+
}
|
|
30942
|
+
const nodeClass = typeof nodeValue.class_type === "string" ? nodeValue.class_type : void 0;
|
|
30943
|
+
const inputs = isRecord(nodeValue.inputs) ? nodeValue.inputs : void 0;
|
|
30944
|
+
if (!nodeClass || !inputs) {
|
|
30945
|
+
continue;
|
|
30946
|
+
}
|
|
30947
|
+
if (!nodeDefinitions.has(nodeClass)) {
|
|
30948
|
+
nodeDefinitions.set(
|
|
30949
|
+
nodeClass,
|
|
30950
|
+
await fetchNodeDefinition(nodeClass)
|
|
30951
|
+
);
|
|
30952
|
+
}
|
|
30953
|
+
const nodeDefinition = nodeDefinitions.get(nodeClass);
|
|
30954
|
+
const nodeInputRecord = isRecord(nodeDefinition) && isRecord(nodeDefinition.input) ? nodeDefinition.input : void 0;
|
|
30955
|
+
const requiredInputs = isRecord(nodeInputRecord?.required) ? nodeInputRecord.required : void 0;
|
|
30956
|
+
const optionalInputs = isRecord(nodeInputRecord?.optional) ? nodeInputRecord.optional : void 0;
|
|
30957
|
+
for (const [inputName, inputValue] of Object.entries(inputs)) {
|
|
30958
|
+
if (!isEditableWorkflowValue(inputValue)) {
|
|
30959
|
+
continue;
|
|
30960
|
+
}
|
|
30961
|
+
const definition = requiredInputs?.[inputName] ?? optionalInputs?.[inputName];
|
|
30962
|
+
const options = getEnumLikeOptions(definition).map(String);
|
|
30963
|
+
const valueType = typeof inputValue === "boolean" ? "boolean" : typeof inputValue === "number" ? "number" : options.length > 0 ? "enum" : "string";
|
|
30964
|
+
editableInputs.push({
|
|
30965
|
+
node_id: nodeId,
|
|
30966
|
+
node_class: nodeClass,
|
|
30967
|
+
input_name: inputName,
|
|
30968
|
+
value_type: valueType,
|
|
30969
|
+
current_value: inputValue,
|
|
30970
|
+
options
|
|
30971
|
+
});
|
|
30972
|
+
}
|
|
30973
|
+
}
|
|
30974
|
+
return editableInputs;
|
|
30975
|
+
}
|
|
30976
|
+
function cloneWorkflowPrompt(prompt) {
|
|
30977
|
+
return JSON.parse(JSON.stringify(prompt));
|
|
30978
|
+
}
|
|
30979
|
+
function applyWorkflowOverrides(prompt, editableInputs, overrides) {
|
|
30980
|
+
const nextPrompt = cloneWorkflowPrompt(prompt);
|
|
30981
|
+
const editableKeys = new Set(
|
|
30982
|
+
editableInputs.map((input) => `${input.node_id}.${input.input_name}`)
|
|
30983
|
+
);
|
|
30984
|
+
for (const override of overrides) {
|
|
30985
|
+
const key = `${override.node_id}.${override.input_name}`;
|
|
30986
|
+
if (!editableKeys.has(key)) {
|
|
30987
|
+
throw new Error(
|
|
30988
|
+
`Override ${key} is not editable for this stored workflow.`
|
|
30989
|
+
);
|
|
30990
|
+
}
|
|
30991
|
+
const node = nextPrompt[override.node_id];
|
|
30992
|
+
if (!isRecord(node) || !isRecord(node.inputs)) {
|
|
30993
|
+
throw new Error(
|
|
30994
|
+
`Stored workflow node ${override.node_id} is invalid.`
|
|
30995
|
+
);
|
|
30996
|
+
}
|
|
30997
|
+
node.inputs[override.input_name] = override.value;
|
|
30998
|
+
}
|
|
30999
|
+
return nextPrompt;
|
|
31000
|
+
}
|
|
30735
31001
|
function summarizeOptionLines(inputSection) {
|
|
30736
31002
|
if (!inputSection) {
|
|
30737
31003
|
return [];
|
|
@@ -30741,26 +31007,33 @@ function summarizeOptionLines(inputSection) {
|
|
|
30741
31007
|
if (options.length === 0) {
|
|
30742
31008
|
return [];
|
|
30743
31009
|
}
|
|
30744
|
-
|
|
30745
|
-
const suffix = options.length > 5 ? `, ... (${options.length} total)` : "";
|
|
30746
|
-
return [`${inputName}: ${preview}${suffix}`];
|
|
31010
|
+
return [`${inputName}: ${options.map(String).join(", ")}`];
|
|
30747
31011
|
});
|
|
30748
31012
|
}
|
|
30749
31013
|
function summarizeSystemInfoText(structuredContent) {
|
|
30750
|
-
const deviceSummary =
|
|
30751
|
-
|
|
30752
|
-
|
|
31014
|
+
const deviceSummary = formatMarkdownBulletList(
|
|
31015
|
+
structuredContent.devices.map(
|
|
31016
|
+
(device) => `[${device.index}] ${device.name} (${device.type}, ${formatGiB(device.vram_free)} free / ${formatGiB(device.vram_total)} total VRAM)`
|
|
31017
|
+
)
|
|
31018
|
+
);
|
|
30753
31019
|
return [
|
|
31020
|
+
"# ComfyUI System Info",
|
|
31021
|
+
"",
|
|
30754
31022
|
`ComfyUI server is running on ${structuredContent.system.os} with ${structuredContent.devices.length} device(s).`,
|
|
30755
|
-
|
|
30756
|
-
|
|
30757
|
-
|
|
30758
|
-
|
|
30759
|
-
|
|
30760
|
-
|
|
31023
|
+
"",
|
|
31024
|
+
"## Summary",
|
|
31025
|
+
formatMarkdownBulletList([
|
|
31026
|
+
`OS: ${structuredContent.system.os}`,
|
|
31027
|
+
`Python: ${structuredContent.system.python_version}`,
|
|
31028
|
+
`Embedded Python: ${structuredContent.system.embedded_python ? "yes" : "no"}`,
|
|
31029
|
+
`Devices: ${structuredContent.devices.length}`
|
|
30761
31030
|
]),
|
|
30762
|
-
|
|
30763
|
-
|
|
31031
|
+
"",
|
|
31032
|
+
"## Devices",
|
|
31033
|
+
deviceSummary,
|
|
31034
|
+
"",
|
|
31035
|
+
"## JSON",
|
|
31036
|
+
formatJsonCodeBlock(structuredContent)
|
|
30764
31037
|
].join("\n");
|
|
30765
31038
|
}
|
|
30766
31039
|
function summarizeNodeDefinitionText(nodeClass, nodeDefinition) {
|
|
@@ -30778,28 +31051,28 @@ function summarizeNodeDefinitionText(nodeClass, nodeDefinition) {
|
|
|
30778
31051
|
...summarizeOptionLines(optionalInputs)
|
|
30779
31052
|
];
|
|
30780
31053
|
return [
|
|
31054
|
+
"# ComfyUI Node Definition",
|
|
31055
|
+
"",
|
|
30781
31056
|
`Schema retrieved for node: ${nodeClass}`,
|
|
30782
|
-
|
|
30783
|
-
|
|
30784
|
-
|
|
30785
|
-
|
|
30786
|
-
|
|
30787
|
-
|
|
30788
|
-
|
|
30789
|
-
|
|
30790
|
-
|
|
30791
|
-
[
|
|
30792
|
-
"Required Inputs",
|
|
30793
|
-
requiredInputs ? Object.keys(requiredInputs).join(", ") || "none" : "none"
|
|
30794
|
-
],
|
|
30795
|
-
[
|
|
30796
|
-
"Optional Inputs",
|
|
30797
|
-
optionalInputs ? Object.keys(optionalInputs).join(", ") || null : null
|
|
30798
|
-
],
|
|
30799
|
-
["Outputs", outputNames.join(", ") || null]
|
|
31057
|
+
"",
|
|
31058
|
+
"## Summary",
|
|
31059
|
+
formatMarkdownBulletList([
|
|
31060
|
+
`Node Class: ${nodeClass}`,
|
|
31061
|
+
`Display Name: ${typeof nodeDefinition.display_name === "string" ? nodeDefinition.display_name : typeof nodeDefinition.name === "string" ? nodeDefinition.name : nodeClass}`,
|
|
31062
|
+
`Category: ${typeof nodeDefinition.category === "string" ? nodeDefinition.category : "unknown"}`,
|
|
31063
|
+
`Required Inputs: ${requiredInputs ? Object.keys(requiredInputs).join(", ") || "none" : "none"}`,
|
|
31064
|
+
`Optional Inputs: ${optionalInputs ? Object.keys(optionalInputs).join(", ") || "none" : "none"}`,
|
|
31065
|
+
`Outputs: ${outputNames.join(", ") || "none"}`
|
|
30800
31066
|
]),
|
|
30801
|
-
|
|
30802
|
-
|
|
31067
|
+
"",
|
|
31068
|
+
optionLines.length > 0 ? `## Enumerated Options
|
|
31069
|
+
${optionLines.map((line) => `- ${line}`).join("\n")}
|
|
31070
|
+
` : "",
|
|
31071
|
+
"## JSON",
|
|
31072
|
+
formatJsonCodeBlock({
|
|
31073
|
+
nodes: { [nodeClass]: nodeDefinition }
|
|
31074
|
+
}),
|
|
31075
|
+
""
|
|
30803
31076
|
].filter(Boolean).join("\n");
|
|
30804
31077
|
}
|
|
30805
31078
|
function summarizeHistoryEntryText(promptId, entry) {
|
|
@@ -30824,35 +31097,268 @@ function summarizeHistoryEntryText(promptId, entry) {
|
|
|
30824
31097
|
}
|
|
30825
31098
|
}
|
|
30826
31099
|
return [
|
|
31100
|
+
"# ComfyUI History Entry",
|
|
31101
|
+
"",
|
|
30827
31102
|
`History retrieved for job: ${promptId}`,
|
|
30828
|
-
|
|
30829
|
-
|
|
30830
|
-
|
|
30831
|
-
|
|
30832
|
-
|
|
30833
|
-
|
|
30834
|
-
|
|
30835
|
-
|
|
30836
|
-
|
|
30837
|
-
|
|
30838
|
-
|
|
30839
|
-
|
|
30840
|
-
|
|
30841
|
-
|
|
31103
|
+
"",
|
|
31104
|
+
"## Summary",
|
|
31105
|
+
formatMarkdownBulletList([
|
|
31106
|
+
`Prompt ID: ${promptId}`,
|
|
31107
|
+
`Status: ${typeof statusRecord?.status_str === "string" ? statusRecord.status_str : "unknown"}`,
|
|
31108
|
+
`Completed: ${statusRecord?.completed === true ? "yes" : statusRecord?.completed === false ? "no" : "unknown"}`,
|
|
31109
|
+
`Images: ${imageRefs.length}`
|
|
31110
|
+
]),
|
|
31111
|
+
"",
|
|
31112
|
+
"## Images",
|
|
31113
|
+
formatMarkdownBulletList(imageRefs),
|
|
31114
|
+
"",
|
|
31115
|
+
"## JSON",
|
|
31116
|
+
formatJsonCodeBlock({
|
|
31117
|
+
history: { [promptId]: entry }
|
|
31118
|
+
})
|
|
31119
|
+
].join("\n");
|
|
31120
|
+
}
|
|
31121
|
+
function extractHistoryImages(entry) {
|
|
31122
|
+
if (!isRecord(entry) || !isRecord(entry.outputs)) {
|
|
31123
|
+
return [];
|
|
31124
|
+
}
|
|
31125
|
+
const images = [];
|
|
31126
|
+
for (const output of Object.values(entry.outputs)) {
|
|
31127
|
+
if (!isRecord(output) || !Array.isArray(output.images)) {
|
|
31128
|
+
continue;
|
|
31129
|
+
}
|
|
31130
|
+
for (const image of output.images) {
|
|
31131
|
+
if (!isRecord(image) || typeof image.filename !== "string" || typeof image.type !== "string") {
|
|
31132
|
+
continue;
|
|
31133
|
+
}
|
|
31134
|
+
const subfolder = typeof image.subfolder === "string" ? image.subfolder : "";
|
|
31135
|
+
images.push({
|
|
31136
|
+
filename: image.filename,
|
|
31137
|
+
subfolder,
|
|
31138
|
+
type: image.type,
|
|
31139
|
+
view_url: buildViewUrl(
|
|
31140
|
+
image.filename,
|
|
31141
|
+
image.type,
|
|
31142
|
+
subfolder || void 0
|
|
31143
|
+
)
|
|
31144
|
+
});
|
|
31145
|
+
}
|
|
31146
|
+
}
|
|
31147
|
+
return images;
|
|
31148
|
+
}
|
|
31149
|
+
function getHistoryStatus(entry) {
|
|
31150
|
+
if (!isRecord(entry) || !isRecord(entry.status)) {
|
|
31151
|
+
return "unknown";
|
|
31152
|
+
}
|
|
31153
|
+
return typeof entry.status.status_str === "string" ? entry.status.status_str : "unknown";
|
|
31154
|
+
}
|
|
31155
|
+
function isHistoryCompleted(entry) {
|
|
31156
|
+
if (!isRecord(entry) || !isRecord(entry.status)) {
|
|
31157
|
+
return false;
|
|
31158
|
+
}
|
|
31159
|
+
if (entry.status.completed === true) {
|
|
31160
|
+
return true;
|
|
31161
|
+
}
|
|
31162
|
+
return entry.status.status_str === "error";
|
|
31163
|
+
}
|
|
31164
|
+
function summarizeWaitForWorkflowText(structuredContent) {
|
|
31165
|
+
return [
|
|
31166
|
+
"# ComfyUI Workflow Wait Result",
|
|
31167
|
+
"",
|
|
31168
|
+
"## Summary",
|
|
31169
|
+
formatMarkdownBulletList([
|
|
31170
|
+
`Prompt ID: ${structuredContent.prompt_id}`,
|
|
31171
|
+
`Status: ${structuredContent.status}`,
|
|
31172
|
+
`Completed: ${structuredContent.completed ? "yes" : "no"}`,
|
|
31173
|
+
`Timed Out: ${structuredContent.timed_out ? "yes" : "no"}`,
|
|
31174
|
+
`Elapsed Seconds: ${structuredContent.elapsed_seconds}`,
|
|
31175
|
+
`Images: ${structuredContent.image_count}`
|
|
31176
|
+
]),
|
|
31177
|
+
"",
|
|
31178
|
+
"## Images",
|
|
31179
|
+
formatMarkdownBulletList(
|
|
31180
|
+
structuredContent.images.map(
|
|
31181
|
+
(image) => `${image.subfolder ? `${image.subfolder}/` : ""}${image.filename} (${image.type}) -> ${image.view_url}`
|
|
31182
|
+
)
|
|
31183
|
+
),
|
|
31184
|
+
"",
|
|
31185
|
+
"## JSON",
|
|
31186
|
+
formatJsonCodeBlock(structuredContent)
|
|
31187
|
+
].join("\n");
|
|
31188
|
+
}
|
|
31189
|
+
function summarizeWorkflowListText(heading, workflows, pagination) {
|
|
31190
|
+
return [
|
|
31191
|
+
heading,
|
|
31192
|
+
"",
|
|
31193
|
+
"## Pagination",
|
|
31194
|
+
formatMarkdownBulletList([
|
|
31195
|
+
`Returned: ${workflows.length}`,
|
|
31196
|
+
`Total: ${pagination.total_count}`,
|
|
31197
|
+
`Limit: ${pagination.limit}`,
|
|
31198
|
+
`Offset: ${pagination.offset}`,
|
|
31199
|
+
`Has More: ${pagination.has_more ? "yes" : "no"}`
|
|
31200
|
+
]),
|
|
31201
|
+
"",
|
|
31202
|
+
"## Workflows",
|
|
31203
|
+
formatMarkdownBulletList(
|
|
31204
|
+
workflows.map(
|
|
31205
|
+
(workflow) => `${workflow.id} \u2014 ${workflow.name} | tags: ${workflow.tags.join(", ") || "none"} | editable inputs: ${workflow.editable_input_count}`
|
|
31206
|
+
)
|
|
31207
|
+
),
|
|
31208
|
+
"",
|
|
31209
|
+
"## JSON",
|
|
31210
|
+
formatJsonCodeBlock({
|
|
31211
|
+
workflows,
|
|
31212
|
+
pagination
|
|
31213
|
+
})
|
|
30842
31214
|
].join("\n");
|
|
30843
31215
|
}
|
|
31216
|
+
function summarizeStoredWorkflowText(workflow) {
|
|
31217
|
+
return [
|
|
31218
|
+
"# ComfyUI Stored Workflow",
|
|
31219
|
+
"",
|
|
31220
|
+
"## Summary",
|
|
31221
|
+
formatMarkdownBulletList([
|
|
31222
|
+
`Workflow ID: ${workflow.workflow.id}`,
|
|
31223
|
+
`Name: ${workflow.workflow.name}`,
|
|
31224
|
+
`Description: ${workflow.workflow.description ?? "none"}`,
|
|
31225
|
+
`Tags: ${workflow.workflow.tags.join(", ") || "none"}`,
|
|
31226
|
+
`Created At: ${workflow.workflow.created_at}`,
|
|
31227
|
+
`Updated At: ${workflow.workflow.updated_at}`,
|
|
31228
|
+
`Node Count: ${workflow.workflow.node_count}`,
|
|
31229
|
+
`Editable Inputs: ${workflow.workflow.editable_input_count}`,
|
|
31230
|
+
`Source: ${workflow.workflow.source}`
|
|
31231
|
+
]),
|
|
31232
|
+
"",
|
|
31233
|
+
"## Editable Inputs",
|
|
31234
|
+
formatMarkdownBulletList(
|
|
31235
|
+
workflow.editable_inputs.map(
|
|
31236
|
+
(input) => `${input.node_id}.${input.input_name} (${input.node_class}, ${input.value_type}) = ${String(
|
|
31237
|
+
input.current_value
|
|
31238
|
+
)}${input.options.length > 0 ? ` | options: ${input.options.join(", ")}` : ""}`
|
|
31239
|
+
)
|
|
31240
|
+
),
|
|
31241
|
+
"",
|
|
31242
|
+
"## JSON",
|
|
31243
|
+
formatJsonCodeBlock(workflow)
|
|
31244
|
+
].join("\n");
|
|
31245
|
+
}
|
|
31246
|
+
function summarizeSavedWorkflowText(workflow) {
|
|
31247
|
+
return [
|
|
31248
|
+
"# ComfyUI Workflow Saved",
|
|
31249
|
+
"",
|
|
31250
|
+
"## Summary",
|
|
31251
|
+
formatMarkdownBulletList([
|
|
31252
|
+
`Workflow ID: ${workflow.workflow.id}`,
|
|
31253
|
+
`Name: ${workflow.workflow.name}`,
|
|
31254
|
+
`Tags: ${workflow.workflow.tags.join(", ") || "none"}`,
|
|
31255
|
+
`Editable Inputs: ${workflow.workflow.editable_input_count}`
|
|
31256
|
+
]),
|
|
31257
|
+
"",
|
|
31258
|
+
"## Next Step",
|
|
31259
|
+
`Call comfyui_run_workflow with workflow_id="${workflow.workflow.id}" and optional overrides to reuse it.`,
|
|
31260
|
+
"",
|
|
31261
|
+
"## JSON",
|
|
31262
|
+
formatJsonCodeBlock(workflow)
|
|
31263
|
+
].join("\n");
|
|
31264
|
+
}
|
|
31265
|
+
async function waitForWorkflowResult(params) {
|
|
31266
|
+
const startTime = Date.now();
|
|
31267
|
+
const timeoutMs = params.timeout_seconds * 1e3;
|
|
31268
|
+
let latestEntry;
|
|
31269
|
+
while (Date.now() - startTime <= timeoutMs) {
|
|
31270
|
+
latestEntry = await fetchHistoryEntry(params.prompt_id);
|
|
31271
|
+
if (latestEntry !== void 0) {
|
|
31272
|
+
const images = extractHistoryImages(latestEntry);
|
|
31273
|
+
const completed = isHistoryCompleted(latestEntry);
|
|
31274
|
+
if (completed && (!params.require_images || images.length > 0)) {
|
|
31275
|
+
return {
|
|
31276
|
+
prompt_id: params.prompt_id,
|
|
31277
|
+
status: getHistoryStatus(latestEntry),
|
|
31278
|
+
completed: true,
|
|
31279
|
+
timed_out: false,
|
|
31280
|
+
elapsed_seconds: Number(
|
|
31281
|
+
((Date.now() - startTime) / 1e3).toFixed(3)
|
|
31282
|
+
),
|
|
31283
|
+
image_count: images.length,
|
|
31284
|
+
images,
|
|
31285
|
+
history_entry: ensureRecord(latestEntry, "history entry")
|
|
31286
|
+
};
|
|
31287
|
+
}
|
|
31288
|
+
}
|
|
31289
|
+
await sleep(params.poll_interval_ms);
|
|
31290
|
+
}
|
|
31291
|
+
const timeoutImages = latestEntry !== void 0 ? extractHistoryImages(latestEntry) : [];
|
|
31292
|
+
return {
|
|
31293
|
+
prompt_id: params.prompt_id,
|
|
31294
|
+
status: latestEntry !== void 0 ? getHistoryStatus(latestEntry) : "not_found",
|
|
31295
|
+
completed: latestEntry !== void 0 ? isHistoryCompleted(latestEntry) : false,
|
|
31296
|
+
timed_out: true,
|
|
31297
|
+
elapsed_seconds: Number(((Date.now() - startTime) / 1e3).toFixed(3)),
|
|
31298
|
+
image_count: timeoutImages.length,
|
|
31299
|
+
images: timeoutImages,
|
|
31300
|
+
history_entry: latestEntry !== void 0 ? ensureRecord(latestEntry, "history entry") : null
|
|
31301
|
+
};
|
|
31302
|
+
}
|
|
31303
|
+
async function createStoredWorkflowRecord(params) {
|
|
31304
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
31305
|
+
const editableInputs = await deriveEditableWorkflowInputs(params.prompt);
|
|
31306
|
+
const workflowId = params.workflow_id ? slugifyWorkflowId(params.workflow_id) : slugifyWorkflowId(params.name);
|
|
31307
|
+
return {
|
|
31308
|
+
workflow: {
|
|
31309
|
+
id: workflowId,
|
|
31310
|
+
name: params.name,
|
|
31311
|
+
description: params.description,
|
|
31312
|
+
tags: params.tags,
|
|
31313
|
+
created_at: params.existing?.workflow.created_at ?? now,
|
|
31314
|
+
updated_at: now,
|
|
31315
|
+
node_count: Object.keys(params.prompt).length,
|
|
31316
|
+
editable_input_count: editableInputs.length,
|
|
31317
|
+
source: params.source
|
|
31318
|
+
},
|
|
31319
|
+
prompt: params.prompt,
|
|
31320
|
+
editable_inputs: editableInputs
|
|
31321
|
+
};
|
|
31322
|
+
}
|
|
31323
|
+
async function submitWorkflow(args) {
|
|
31324
|
+
const result = IS_MOCK ? MOCK_FIXTURES.prompt_response : await fetchComfyJson(
|
|
31325
|
+
"/prompt",
|
|
31326
|
+
{
|
|
31327
|
+
method: "POST",
|
|
31328
|
+
body: JSON.stringify({
|
|
31329
|
+
prompt: args.prompt,
|
|
31330
|
+
client_id: args.client_id
|
|
31331
|
+
})
|
|
31332
|
+
}
|
|
31333
|
+
);
|
|
31334
|
+
return {
|
|
31335
|
+
prompt_id: result.prompt_id,
|
|
31336
|
+
number: result.number,
|
|
31337
|
+
node_errors: result.node_errors
|
|
31338
|
+
};
|
|
31339
|
+
}
|
|
30844
31340
|
function summarizeWorkflowResponseText(result) {
|
|
30845
31341
|
const hasErrors = Object.keys(result.node_errors).length > 0;
|
|
30846
31342
|
return [
|
|
30847
|
-
|
|
30848
|
-
|
|
30849
|
-
|
|
30850
|
-
|
|
30851
|
-
|
|
30852
|
-
|
|
30853
|
-
|
|
31343
|
+
"# ComfyUI Workflow Submission",
|
|
31344
|
+
"",
|
|
31345
|
+
"## Summary",
|
|
31346
|
+
formatMarkdownBulletList([
|
|
31347
|
+
`Status: ${hasErrors ? "Submitted with node errors" : "Successfully queued"}`,
|
|
31348
|
+
`Prompt ID: ${result.prompt_id}`,
|
|
31349
|
+
`Queue Number: ${result.number}`,
|
|
31350
|
+
`Node Errors: ${Object.keys(result.node_errors).length}`
|
|
30854
31351
|
]),
|
|
30855
|
-
|
|
31352
|
+
"",
|
|
31353
|
+
"## Next Step",
|
|
31354
|
+
hasErrors ? "Fix the reported node_errors before retrying this workflow." : `Next step: call comfyui_get_history with prompt_id="${result.prompt_id}" to monitor outputs.`,
|
|
31355
|
+
"",
|
|
31356
|
+
"## JSON",
|
|
31357
|
+
formatJsonCodeBlock({
|
|
31358
|
+
prompt_id: result.prompt_id,
|
|
31359
|
+
number: result.number,
|
|
31360
|
+
node_errors: result.node_errors
|
|
31361
|
+
})
|
|
30856
31362
|
].join("\n");
|
|
30857
31363
|
}
|
|
30858
31364
|
function createAgentFacingResult(text, structuredContent) {
|
|
@@ -30905,6 +31411,21 @@ async function fetchComfyJson(apiPath, options) {
|
|
|
30905
31411
|
}
|
|
30906
31412
|
return body;
|
|
30907
31413
|
}
|
|
31414
|
+
async function fetchHistoryEntry(promptId) {
|
|
31415
|
+
if (IS_MOCK) {
|
|
31416
|
+
return MOCK_FIXTURES.history[promptId];
|
|
31417
|
+
}
|
|
31418
|
+
try {
|
|
31419
|
+
return await fetchComfyJson(
|
|
31420
|
+
`/history/${encodeURIComponent(promptId)}`
|
|
31421
|
+
);
|
|
31422
|
+
} catch (error48) {
|
|
31423
|
+
if (error48 instanceof ComfyApiError && error48.statusCode === 404) {
|
|
31424
|
+
return void 0;
|
|
31425
|
+
}
|
|
31426
|
+
throw error48;
|
|
31427
|
+
}
|
|
31428
|
+
}
|
|
30908
31429
|
function handleComfyError(error48) {
|
|
30909
31430
|
if (error48 instanceof ZodError) {
|
|
30910
31431
|
return createValidationError(
|
|
@@ -30970,13 +31491,29 @@ async function handleListObjectInfo(args) {
|
|
|
30970
31491
|
};
|
|
30971
31492
|
return createAgentFacingResult(
|
|
30972
31493
|
[
|
|
30973
|
-
|
|
30974
|
-
|
|
30975
|
-
|
|
30976
|
-
|
|
30977
|
-
|
|
30978
|
-
|
|
30979
|
-
|
|
31494
|
+
"# ComfyUI Node Definitions",
|
|
31495
|
+
"",
|
|
31496
|
+
"## Pagination",
|
|
31497
|
+
formatMarkdownBulletList([
|
|
31498
|
+
`Returned: ${paginated.items.length}`,
|
|
31499
|
+
`Total: ${paginated.total}`,
|
|
31500
|
+
`Limit: ${paginated.limit}`,
|
|
31501
|
+
`Offset: ${paginated.offset}`,
|
|
31502
|
+
`Has More: ${paginated.hasMore ? "yes" : "no"}`
|
|
31503
|
+
]),
|
|
31504
|
+
"",
|
|
31505
|
+
"## Node Classes In This Page",
|
|
31506
|
+
formatMarkdownBulletList(
|
|
31507
|
+
paginated.items.map(([nodeClass]) => nodeClass)
|
|
31508
|
+
),
|
|
31509
|
+
"",
|
|
31510
|
+
"## Next Step",
|
|
31511
|
+
paginated.hasMore ? `Use offset=${paginated.offset + paginated.limit} to retrieve the next page.` : "This page contains the final set of node classes for the current query.",
|
|
31512
|
+
"If you need a usable workflow field list, call comfyui_list_object_info again with node_class set to the exact node name.",
|
|
31513
|
+
"",
|
|
31514
|
+
"## JSON",
|
|
31515
|
+
formatJsonCodeBlock(structuredContent)
|
|
31516
|
+
].join("\n"),
|
|
30980
31517
|
structuredContent
|
|
30981
31518
|
);
|
|
30982
31519
|
} catch (error48) {
|
|
@@ -30985,21 +31522,39 @@ async function handleListObjectInfo(args) {
|
|
|
30985
31522
|
}
|
|
30986
31523
|
async function handleExecuteWorkflow(args) {
|
|
30987
31524
|
try {
|
|
30988
|
-
const result =
|
|
30989
|
-
"/prompt",
|
|
30990
|
-
{
|
|
30991
|
-
method: "POST",
|
|
30992
|
-
body: JSON.stringify({
|
|
30993
|
-
prompt: args.prompt,
|
|
30994
|
-
client_id: args.client_id
|
|
30995
|
-
})
|
|
30996
|
-
}
|
|
30997
|
-
);
|
|
31525
|
+
const result = await submitWorkflow(args);
|
|
30998
31526
|
const structuredContent = {
|
|
30999
31527
|
prompt_id: result.prompt_id,
|
|
31000
31528
|
number: result.number,
|
|
31001
31529
|
node_errors: result.node_errors
|
|
31002
31530
|
};
|
|
31531
|
+
if (args.await && Object.keys(result.node_errors).length === 0) {
|
|
31532
|
+
const waitResult = await waitForWorkflowResult({
|
|
31533
|
+
prompt_id: result.prompt_id,
|
|
31534
|
+
timeout_seconds: args.timeout,
|
|
31535
|
+
poll_interval_ms: 1e3,
|
|
31536
|
+
require_images: false
|
|
31537
|
+
});
|
|
31538
|
+
const awaitedContent = {
|
|
31539
|
+
...structuredContent,
|
|
31540
|
+
status: waitResult.status,
|
|
31541
|
+
completed: waitResult.completed,
|
|
31542
|
+
timed_out: waitResult.timed_out,
|
|
31543
|
+
elapsed_seconds: waitResult.elapsed_seconds,
|
|
31544
|
+
image_count: waitResult.image_count,
|
|
31545
|
+
images: waitResult.images,
|
|
31546
|
+
history_entry: waitResult.history_entry
|
|
31547
|
+
};
|
|
31548
|
+
return createAgentFacingResult(
|
|
31549
|
+
[
|
|
31550
|
+
summarizeWorkflowResponseText(awaitedContent),
|
|
31551
|
+
"",
|
|
31552
|
+
"## Await Result",
|
|
31553
|
+
summarizeWaitForWorkflowText(waitResult)
|
|
31554
|
+
].join("\n"),
|
|
31555
|
+
awaitedContent
|
|
31556
|
+
);
|
|
31557
|
+
}
|
|
31003
31558
|
return createAgentFacingResult(
|
|
31004
31559
|
summarizeWorkflowResponseText(result),
|
|
31005
31560
|
structuredContent
|
|
@@ -31008,6 +31563,195 @@ async function handleExecuteWorkflow(args) {
|
|
|
31008
31563
|
return handleComfyError(error48);
|
|
31009
31564
|
}
|
|
31010
31565
|
}
|
|
31566
|
+
async function handleListWorkflows(args) {
|
|
31567
|
+
try {
|
|
31568
|
+
const workflows = (await listStoredWorkflowFiles()).map(
|
|
31569
|
+
(workflow) => workflow.workflow
|
|
31570
|
+
);
|
|
31571
|
+
const paginated = applyPagination(workflows, args);
|
|
31572
|
+
const structuredContent = {
|
|
31573
|
+
workflows: paginated.items,
|
|
31574
|
+
pagination: {
|
|
31575
|
+
total_count: paginated.total,
|
|
31576
|
+
limit: paginated.limit,
|
|
31577
|
+
offset: paginated.offset,
|
|
31578
|
+
has_more: paginated.hasMore
|
|
31579
|
+
}
|
|
31580
|
+
};
|
|
31581
|
+
return createAgentFacingResult(
|
|
31582
|
+
summarizeWorkflowListText(
|
|
31583
|
+
"# ComfyUI Stored Workflows",
|
|
31584
|
+
structuredContent.workflows,
|
|
31585
|
+
structuredContent.pagination
|
|
31586
|
+
),
|
|
31587
|
+
structuredContent
|
|
31588
|
+
);
|
|
31589
|
+
} catch (error48) {
|
|
31590
|
+
return handleComfyError(error48);
|
|
31591
|
+
}
|
|
31592
|
+
}
|
|
31593
|
+
async function handleSearchWorkflows(args) {
|
|
31594
|
+
try {
|
|
31595
|
+
const normalizedQuery = args.query.trim().toLowerCase();
|
|
31596
|
+
const matching = (await listStoredWorkflowFiles()).map((workflow) => workflow.workflow).filter(
|
|
31597
|
+
(workflow) => [
|
|
31598
|
+
workflow.id,
|
|
31599
|
+
workflow.name,
|
|
31600
|
+
workflow.description ?? "",
|
|
31601
|
+
workflow.tags.join(" ")
|
|
31602
|
+
].join(" ").toLowerCase().includes(normalizedQuery)
|
|
31603
|
+
);
|
|
31604
|
+
const paginated = applyPagination(matching, args);
|
|
31605
|
+
const structuredContent = {
|
|
31606
|
+
workflows: paginated.items,
|
|
31607
|
+
pagination: {
|
|
31608
|
+
total_count: paginated.total,
|
|
31609
|
+
limit: paginated.limit,
|
|
31610
|
+
offset: paginated.offset,
|
|
31611
|
+
has_more: paginated.hasMore
|
|
31612
|
+
}
|
|
31613
|
+
};
|
|
31614
|
+
return createAgentFacingResult(
|
|
31615
|
+
summarizeWorkflowListText(
|
|
31616
|
+
`# ComfyUI Workflow Search
|
|
31617
|
+
|
|
31618
|
+
Query: ${args.query}`,
|
|
31619
|
+
structuredContent.workflows,
|
|
31620
|
+
structuredContent.pagination
|
|
31621
|
+
),
|
|
31622
|
+
structuredContent
|
|
31623
|
+
);
|
|
31624
|
+
} catch (error48) {
|
|
31625
|
+
return handleComfyError(error48);
|
|
31626
|
+
}
|
|
31627
|
+
}
|
|
31628
|
+
async function handleGetWorkflow(args) {
|
|
31629
|
+
try {
|
|
31630
|
+
const workflow = await readStoredWorkflowFile(args.workflow_id);
|
|
31631
|
+
if (!workflow) {
|
|
31632
|
+
return createNotFoundError(`Workflow ${args.workflow_id}`);
|
|
31633
|
+
}
|
|
31634
|
+
return createAgentFacingResult(
|
|
31635
|
+
summarizeStoredWorkflowText(workflow),
|
|
31636
|
+
workflow
|
|
31637
|
+
);
|
|
31638
|
+
} catch (error48) {
|
|
31639
|
+
return handleComfyError(error48);
|
|
31640
|
+
}
|
|
31641
|
+
}
|
|
31642
|
+
async function handleSaveWorkflow(args) {
|
|
31643
|
+
try {
|
|
31644
|
+
const workflowId = args.workflow_id ? slugifyWorkflowId(args.workflow_id) : slugifyWorkflowId(args.name);
|
|
31645
|
+
const existing = await readStoredWorkflowFile(workflowId);
|
|
31646
|
+
if (existing && !args.overwrite) {
|
|
31647
|
+
return createValidationError(
|
|
31648
|
+
"workflow_id",
|
|
31649
|
+
`Workflow ${workflowId} already exists. Pass overwrite=true to replace it.`
|
|
31650
|
+
);
|
|
31651
|
+
}
|
|
31652
|
+
const workflow = await createStoredWorkflowRecord({
|
|
31653
|
+
workflow_id: workflowId,
|
|
31654
|
+
name: args.name,
|
|
31655
|
+
description: args.description,
|
|
31656
|
+
tags: args.tags,
|
|
31657
|
+
prompt: args.prompt,
|
|
31658
|
+
source: IS_MOCK ? "mock" : "local",
|
|
31659
|
+
existing
|
|
31660
|
+
});
|
|
31661
|
+
await writeStoredWorkflowFile(workflow);
|
|
31662
|
+
return createAgentFacingResult(
|
|
31663
|
+
summarizeSavedWorkflowText(workflow),
|
|
31664
|
+
workflow
|
|
31665
|
+
);
|
|
31666
|
+
} catch (error48) {
|
|
31667
|
+
return handleComfyError(error48);
|
|
31668
|
+
}
|
|
31669
|
+
}
|
|
31670
|
+
async function handleRunWorkflow(args) {
|
|
31671
|
+
try {
|
|
31672
|
+
const workflow = await readStoredWorkflowFile(args.workflow_id);
|
|
31673
|
+
if (!workflow) {
|
|
31674
|
+
return createNotFoundError(`Workflow ${args.workflow_id}`);
|
|
31675
|
+
}
|
|
31676
|
+
const prompt = applyWorkflowOverrides(
|
|
31677
|
+
workflow.prompt,
|
|
31678
|
+
workflow.editable_inputs,
|
|
31679
|
+
args.overrides
|
|
31680
|
+
);
|
|
31681
|
+
const submission = await submitWorkflow({
|
|
31682
|
+
prompt,
|
|
31683
|
+
client_id: args.client_id
|
|
31684
|
+
});
|
|
31685
|
+
const structuredContent = {
|
|
31686
|
+
prompt_id: submission.prompt_id,
|
|
31687
|
+
number: submission.number,
|
|
31688
|
+
node_errors: submission.node_errors,
|
|
31689
|
+
workflow_id: workflow.workflow.id,
|
|
31690
|
+
workflow_name: workflow.workflow.name,
|
|
31691
|
+
applied_overrides: args.overrides
|
|
31692
|
+
};
|
|
31693
|
+
if (args.await && Object.keys(submission.node_errors).length === 0) {
|
|
31694
|
+
const waitResult = await waitForWorkflowResult({
|
|
31695
|
+
prompt_id: submission.prompt_id,
|
|
31696
|
+
timeout_seconds: args.timeout,
|
|
31697
|
+
poll_interval_ms: 1e3,
|
|
31698
|
+
require_images: args.require_images
|
|
31699
|
+
});
|
|
31700
|
+
Object.assign(structuredContent, {
|
|
31701
|
+
status: waitResult.status,
|
|
31702
|
+
completed: waitResult.completed,
|
|
31703
|
+
timed_out: waitResult.timed_out,
|
|
31704
|
+
elapsed_seconds: waitResult.elapsed_seconds,
|
|
31705
|
+
image_count: waitResult.image_count,
|
|
31706
|
+
images: waitResult.images,
|
|
31707
|
+
history_entry: waitResult.history_entry
|
|
31708
|
+
});
|
|
31709
|
+
return createAgentFacingResult(
|
|
31710
|
+
[
|
|
31711
|
+
"# ComfyUI Stored Workflow Run",
|
|
31712
|
+
"",
|
|
31713
|
+
"## Summary",
|
|
31714
|
+
formatMarkdownBulletList([
|
|
31715
|
+
`Workflow ID: ${workflow.workflow.id}`,
|
|
31716
|
+
`Workflow Name: ${workflow.workflow.name}`,
|
|
31717
|
+
`Prompt ID: ${submission.prompt_id}`,
|
|
31718
|
+
`Applied Overrides: ${args.overrides.length}`
|
|
31719
|
+
]),
|
|
31720
|
+
"",
|
|
31721
|
+
summarizeWorkflowResponseText(structuredContent),
|
|
31722
|
+
"",
|
|
31723
|
+
"## Await Result",
|
|
31724
|
+
summarizeWaitForWorkflowText(waitResult),
|
|
31725
|
+
"",
|
|
31726
|
+
"## JSON",
|
|
31727
|
+
formatJsonCodeBlock(structuredContent)
|
|
31728
|
+
].join("\n"),
|
|
31729
|
+
structuredContent
|
|
31730
|
+
);
|
|
31731
|
+
}
|
|
31732
|
+
return createAgentFacingResult(
|
|
31733
|
+
[
|
|
31734
|
+
"# ComfyUI Stored Workflow Run",
|
|
31735
|
+
"",
|
|
31736
|
+
"## Summary",
|
|
31737
|
+
formatMarkdownBulletList([
|
|
31738
|
+
`Workflow ID: ${workflow.workflow.id}`,
|
|
31739
|
+
`Workflow Name: ${workflow.workflow.name}`,
|
|
31740
|
+
`Prompt ID: ${submission.prompt_id}`,
|
|
31741
|
+
`Applied Overrides: ${args.overrides.length}`
|
|
31742
|
+
]),
|
|
31743
|
+
"",
|
|
31744
|
+
summarizeWorkflowResponseText(structuredContent),
|
|
31745
|
+
"",
|
|
31746
|
+
"## JSON",
|
|
31747
|
+
formatJsonCodeBlock(structuredContent)
|
|
31748
|
+
].join("\n"),
|
|
31749
|
+
structuredContent
|
|
31750
|
+
);
|
|
31751
|
+
} catch (error48) {
|
|
31752
|
+
return handleComfyError(error48);
|
|
31753
|
+
}
|
|
31754
|
+
}
|
|
31011
31755
|
async function handleGetHistory(args) {
|
|
31012
31756
|
try {
|
|
31013
31757
|
const rawHistory = IS_MOCK ? args.prompt_id ? MOCK_FIXTURES.history[args.prompt_id] : MOCK_FIXTURES.history : await fetchComfyJson(
|
|
@@ -31038,12 +31782,39 @@ async function handleGetHistory(args) {
|
|
|
31038
31782
|
};
|
|
31039
31783
|
return createAgentFacingResult(
|
|
31040
31784
|
[
|
|
31041
|
-
|
|
31042
|
-
|
|
31043
|
-
|
|
31044
|
-
|
|
31045
|
-
|
|
31046
|
-
|
|
31785
|
+
"# ComfyUI History",
|
|
31786
|
+
"",
|
|
31787
|
+
"## Pagination",
|
|
31788
|
+
formatMarkdownBulletList([
|
|
31789
|
+
`Returned: ${paginated.items.length}`,
|
|
31790
|
+
`Total: ${paginated.total}`,
|
|
31791
|
+
`Limit: ${paginated.limit}`,
|
|
31792
|
+
`Offset: ${paginated.offset}`,
|
|
31793
|
+
`Has More: ${paginated.hasMore ? "yes" : "no"}`
|
|
31794
|
+
]),
|
|
31795
|
+
"",
|
|
31796
|
+
"## Prompt IDs In This Page",
|
|
31797
|
+
formatMarkdownBulletList(
|
|
31798
|
+
paginated.items.map(([promptId]) => promptId)
|
|
31799
|
+
),
|
|
31800
|
+
"",
|
|
31801
|
+
"## Next Step",
|
|
31802
|
+
paginated.hasMore ? `Use offset=${paginated.offset + paginated.limit} to retrieve the next page.` : "This page contains the final set of history entries for the current query.",
|
|
31803
|
+
"",
|
|
31804
|
+
"## JSON",
|
|
31805
|
+
formatJsonCodeBlock(structuredContent)
|
|
31806
|
+
].join("\n"),
|
|
31807
|
+
structuredContent
|
|
31808
|
+
);
|
|
31809
|
+
} catch (error48) {
|
|
31810
|
+
return handleComfyError(error48);
|
|
31811
|
+
}
|
|
31812
|
+
}
|
|
31813
|
+
async function handleWaitForWorkflow(args) {
|
|
31814
|
+
try {
|
|
31815
|
+
const structuredContent = await waitForWorkflowResult(args);
|
|
31816
|
+
return createAgentFacingResult(
|
|
31817
|
+
summarizeWaitForWorkflowText(structuredContent),
|
|
31047
31818
|
structuredContent
|
|
31048
31819
|
);
|
|
31049
31820
|
} catch (error48) {
|
|
@@ -31059,7 +31830,18 @@ async function handleGetQueue() {
|
|
|
31059
31830
|
queue_pending: Array.isArray(queueRecord.queue_pending) ? queueRecord.queue_pending : []
|
|
31060
31831
|
};
|
|
31061
31832
|
return createAgentFacingResult(
|
|
31062
|
-
|
|
31833
|
+
[
|
|
31834
|
+
"# ComfyUI Queue",
|
|
31835
|
+
"",
|
|
31836
|
+
"## Summary",
|
|
31837
|
+
formatMarkdownBulletList([
|
|
31838
|
+
`Running Jobs: ${structuredContent.queue_running.length}`,
|
|
31839
|
+
`Pending Jobs: ${structuredContent.queue_pending.length}`
|
|
31840
|
+
]),
|
|
31841
|
+
"",
|
|
31842
|
+
"## JSON",
|
|
31843
|
+
formatJsonCodeBlock(structuredContent)
|
|
31844
|
+
].join("\n"),
|
|
31063
31845
|
structuredContent
|
|
31064
31846
|
);
|
|
31065
31847
|
} catch (error48) {
|
|
@@ -31067,20 +31849,22 @@ async function handleGetQueue() {
|
|
|
31067
31849
|
}
|
|
31068
31850
|
}
|
|
31069
31851
|
async function handleGetViewUrl(args) {
|
|
31070
|
-
const
|
|
31071
|
-
filename: args.filename,
|
|
31072
|
-
type: args.type
|
|
31073
|
-
});
|
|
31074
|
-
if (args.subfolder) {
|
|
31075
|
-
params.set("subfolder", args.subfolder);
|
|
31076
|
-
}
|
|
31077
|
-
const url2 = new URL(
|
|
31078
|
-
`/view?${params.toString()}`,
|
|
31079
|
-
COMFYUI_SERVER_URL
|
|
31080
|
-
).toString();
|
|
31852
|
+
const url2 = buildViewUrl(args.filename, args.type, args.subfolder);
|
|
31081
31853
|
return createAgentFacingResult(
|
|
31082
|
-
|
|
31083
|
-
|
|
31854
|
+
[
|
|
31855
|
+
"# ComfyUI View URL",
|
|
31856
|
+
"",
|
|
31857
|
+
"## Summary",
|
|
31858
|
+
formatMarkdownBulletList([
|
|
31859
|
+
`Filename: ${args.filename}`,
|
|
31860
|
+
`Subfolder: ${args.subfolder ?? "(root)"}`,
|
|
31861
|
+
`Type: ${args.type}`,
|
|
31862
|
+
`URL: ${url2}`
|
|
31863
|
+
]),
|
|
31864
|
+
"",
|
|
31865
|
+
"## JSON",
|
|
31866
|
+
formatJsonCodeBlock({ url: url2 })
|
|
31867
|
+
].join("\n"),
|
|
31084
31868
|
{ url: url2 }
|
|
31085
31869
|
);
|
|
31086
31870
|
}
|
|
@@ -31132,6 +31916,77 @@ function createServer() {
|
|
|
31132
31916
|
},
|
|
31133
31917
|
handleExecuteWorkflow
|
|
31134
31918
|
);
|
|
31919
|
+
server.registerTool(
|
|
31920
|
+
"comfyui_list_workflows",
|
|
31921
|
+
{
|
|
31922
|
+
title: "List Stored Workflows",
|
|
31923
|
+
description: "List stored ComfyUI workflows with pagination.",
|
|
31924
|
+
inputSchema: ListWorkflowsInputSchema,
|
|
31925
|
+
outputSchema: WorkflowListSchema,
|
|
31926
|
+
annotations: {
|
|
31927
|
+
readOnlyHint: true,
|
|
31928
|
+
idempotentHint: true,
|
|
31929
|
+
openWorldHint: true
|
|
31930
|
+
}
|
|
31931
|
+
},
|
|
31932
|
+
handleListWorkflows
|
|
31933
|
+
);
|
|
31934
|
+
server.registerTool(
|
|
31935
|
+
"comfyui_search_workflows",
|
|
31936
|
+
{
|
|
31937
|
+
title: "Search Stored Workflows",
|
|
31938
|
+
description: "Search stored ComfyUI workflows by name, tags, or description.",
|
|
31939
|
+
inputSchema: SearchWorkflowsInputSchema,
|
|
31940
|
+
outputSchema: WorkflowListSchema,
|
|
31941
|
+
annotations: {
|
|
31942
|
+
readOnlyHint: true,
|
|
31943
|
+
idempotentHint: true,
|
|
31944
|
+
openWorldHint: true
|
|
31945
|
+
}
|
|
31946
|
+
},
|
|
31947
|
+
handleSearchWorkflows
|
|
31948
|
+
);
|
|
31949
|
+
server.registerTool(
|
|
31950
|
+
"comfyui_get_workflow",
|
|
31951
|
+
{
|
|
31952
|
+
title: "Get Stored Workflow",
|
|
31953
|
+
description: "Get a stored ComfyUI workflow and its editable inputs.",
|
|
31954
|
+
inputSchema: GetWorkflowInputSchema,
|
|
31955
|
+
outputSchema: StoredWorkflowSchema,
|
|
31956
|
+
annotations: {
|
|
31957
|
+
readOnlyHint: true,
|
|
31958
|
+
idempotentHint: true,
|
|
31959
|
+
openWorldHint: true
|
|
31960
|
+
}
|
|
31961
|
+
},
|
|
31962
|
+
handleGetWorkflow
|
|
31963
|
+
);
|
|
31964
|
+
server.registerTool(
|
|
31965
|
+
"comfyui_save_workflow",
|
|
31966
|
+
{
|
|
31967
|
+
title: "Save Workflow",
|
|
31968
|
+
description: "Save a ComfyUI workflow for later reuse.",
|
|
31969
|
+
inputSchema: SaveWorkflowInputSchema,
|
|
31970
|
+
outputSchema: StoredWorkflowSchema,
|
|
31971
|
+
annotations: {
|
|
31972
|
+
openWorldHint: true
|
|
31973
|
+
}
|
|
31974
|
+
},
|
|
31975
|
+
handleSaveWorkflow
|
|
31976
|
+
);
|
|
31977
|
+
server.registerTool(
|
|
31978
|
+
"comfyui_run_workflow",
|
|
31979
|
+
{
|
|
31980
|
+
title: "Run Stored Workflow",
|
|
31981
|
+
description: "Run a stored workflow with optional overrides.",
|
|
31982
|
+
inputSchema: RunWorkflowInputSchema,
|
|
31983
|
+
outputSchema: RunStoredWorkflowSchema,
|
|
31984
|
+
annotations: {
|
|
31985
|
+
openWorldHint: true
|
|
31986
|
+
}
|
|
31987
|
+
},
|
|
31988
|
+
handleRunWorkflow
|
|
31989
|
+
);
|
|
31135
31990
|
server.registerTool(
|
|
31136
31991
|
"comfyui_get_history",
|
|
31137
31992
|
{
|
|
@@ -31147,6 +32002,19 @@ function createServer() {
|
|
|
31147
32002
|
},
|
|
31148
32003
|
handleGetHistory
|
|
31149
32004
|
);
|
|
32005
|
+
server.registerTool(
|
|
32006
|
+
"comfyui_wait_for_workflow",
|
|
32007
|
+
{
|
|
32008
|
+
title: "Wait for ComfyUI Workflow",
|
|
32009
|
+
description: "Wait for a workflow result with timeout-based polling.",
|
|
32010
|
+
inputSchema: WaitForWorkflowInputSchema,
|
|
32011
|
+
outputSchema: WaitForWorkflowSchema,
|
|
32012
|
+
annotations: {
|
|
32013
|
+
openWorldHint: true
|
|
32014
|
+
}
|
|
32015
|
+
},
|
|
32016
|
+
handleWaitForWorkflow
|
|
32017
|
+
);
|
|
31150
32018
|
server.registerTool(
|
|
31151
32019
|
"comfyui_get_queue",
|
|
31152
32020
|
{
|