comfyui-node 1.6.1 → 1.6.2
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/dist/.tsbuildinfo +1 -1
- package/dist/call-wrapper.js +856 -856
- package/dist/index.d.ts +13 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/multipool/client-registry.d.ts +32 -11
- package/dist/multipool/client-registry.d.ts.map +1 -1
- package/dist/multipool/client-registry.js +152 -25
- package/dist/multipool/client-registry.js.map +1 -1
- package/dist/multipool/helpers.d.ts +5 -0
- package/dist/multipool/helpers.d.ts.map +1 -0
- package/dist/multipool/helpers.js +53 -0
- package/dist/multipool/helpers.js.map +1 -0
- package/dist/multipool/index.d.ts +2 -1
- package/dist/multipool/index.d.ts.map +1 -1
- package/dist/multipool/index.js +2 -1
- package/dist/multipool/index.js.map +1 -1
- package/dist/multipool/interfaces.d.ts +12 -4
- package/dist/multipool/interfaces.d.ts.map +1 -1
- package/dist/multipool/interfaces.js +1 -1
- package/dist/multipool/job-profiler.d.ts +128 -0
- package/dist/multipool/job-profiler.d.ts.map +1 -0
- package/dist/multipool/job-profiler.js +222 -0
- package/dist/multipool/job-profiler.js.map +1 -0
- package/dist/multipool/job-queue-processor.d.ts +27 -11
- package/dist/multipool/job-queue-processor.d.ts.map +1 -1
- package/dist/multipool/job-queue-processor.js +196 -9
- package/dist/multipool/job-queue-processor.js.map +1 -1
- package/dist/multipool/job-state-registry.d.ts +67 -0
- package/dist/multipool/job-state-registry.d.ts.map +1 -0
- package/dist/multipool/job-state-registry.js +283 -0
- package/dist/multipool/job-state-registry.js.map +1 -0
- package/dist/multipool/logger.d.ts +30 -0
- package/dist/multipool/logger.d.ts.map +1 -0
- package/dist/multipool/logger.js +75 -0
- package/dist/multipool/logger.js.map +1 -0
- package/dist/multipool/multi-workflow-pool.d.ts +42 -23
- package/dist/multipool/multi-workflow-pool.d.ts.map +1 -1
- package/dist/multipool/multi-workflow-pool.js +313 -72
- package/dist/multipool/multi-workflow-pool.js.map +1 -1
- package/dist/multipool/pool-event-manager.d.ts +10 -10
- package/dist/multipool/pool-event-manager.js +27 -27
- package/dist/multipool/tests/error-classification-tests.d.ts +2 -0
- package/dist/multipool/tests/error-classification-tests.d.ts.map +1 -0
- package/dist/multipool/tests/error-classification-tests.js +374 -0
- package/dist/multipool/tests/error-classification-tests.js.map +1 -0
- package/dist/multipool/tests/job-state-registry.d.ts +16 -16
- package/dist/multipool/tests/job-state-registry.js +23 -23
- package/dist/multipool/tests/multipool-basic.d.ts +11 -1
- package/dist/multipool/tests/multipool-basic.d.ts.map +1 -1
- package/dist/multipool/tests/multipool-basic.js +141 -3
- package/dist/multipool/tests/multipool-basic.js.map +1 -1
- package/dist/multipool/tests/profiling-demo.d.ts +7 -0
- package/dist/multipool/tests/profiling-demo.d.ts.map +1 -0
- package/dist/multipool/tests/profiling-demo.js +88 -0
- package/dist/multipool/tests/profiling-demo.js.map +1 -0
- package/dist/multipool/tests/prompt-generator.d.ts +10 -0
- package/dist/multipool/tests/prompt-generator.d.ts.map +1 -0
- package/dist/multipool/tests/prompt-generator.js +26 -0
- package/dist/multipool/tests/prompt-generator.js.map +1 -0
- package/dist/multipool/tests/test-helpers.d.ts +4 -0
- package/dist/multipool/tests/test-helpers.d.ts.map +1 -0
- package/dist/multipool/tests/test-helpers.js +10 -0
- package/dist/multipool/tests/test-helpers.js.map +1 -0
- package/dist/multipool/tests/two-stage-edit-simulation.d.ts +32 -0
- package/dist/multipool/tests/two-stage-edit-simulation.d.ts.map +1 -0
- package/dist/multipool/tests/two-stage-edit-simulation.js +299 -0
- package/dist/multipool/tests/two-stage-edit-simulation.js.map +1 -0
- package/dist/multipool/workflow.d.ts +178 -173
- package/dist/multipool/workflow.d.ts.map +1 -1
- package/dist/multipool/workflow.js +333 -271
- package/dist/multipool/workflow.js.map +1 -1
- package/dist/pool/SmartPool.d.ts +143 -143
- package/dist/pool/SmartPool.js +676 -676
- package/dist/pool/SmartPoolV2.d.ts +119 -119
- package/dist/pool/SmartPoolV2.js +586 -586
- package/dist/pool/WorkflowPool.d.ts +202 -202
- package/dist/pool/WorkflowPool.d.ts.map +1 -1
- package/dist/pool/WorkflowPool.js +845 -840
- package/dist/pool/WorkflowPool.js.map +1 -1
- package/dist/pool/client/ClientManager.d.ts +86 -86
- package/dist/pool/client/ClientManager.js +215 -215
- package/dist/pool/index.d.ts +9 -11
- package/dist/pool/index.d.ts.map +1 -1
- package/dist/pool/index.js +3 -5
- package/dist/pool/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profiling Demo for MultiWorkflowPool
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates the integrated JobProfiler functionality
|
|
5
|
+
*/
|
|
6
|
+
import { MultiWorkflowPool } from "../multi-workflow-pool.js";
|
|
7
|
+
import { Workflow } from "../workflow.js";
|
|
8
|
+
import GenerationGraph from "../../../scripts/workflows/T2I-one-obsession.json" with { type: "json" };
|
|
9
|
+
const GEN_HOST = "http://server1:8188";
|
|
10
|
+
// Create pool with profiling enabled
|
|
11
|
+
const pool = new MultiWorkflowPool({
|
|
12
|
+
enableProfiling: true,
|
|
13
|
+
logLevel: "info"
|
|
14
|
+
});
|
|
15
|
+
const genWorkflow = Workflow.fromAugmented(GenerationGraph);
|
|
16
|
+
pool.addClient(GEN_HOST, {
|
|
17
|
+
workflowAffinity: [genWorkflow],
|
|
18
|
+
priority: 1
|
|
19
|
+
});
|
|
20
|
+
console.log("\n" + "=".repeat(80));
|
|
21
|
+
console.log("PROFILING DEMO - MultiWorkflowPool");
|
|
22
|
+
console.log("=".repeat(80));
|
|
23
|
+
console.log(`Generation Host: ${GEN_HOST}`);
|
|
24
|
+
console.log(`Profiling: ENABLED`);
|
|
25
|
+
console.log("=".repeat(80) + "\n");
|
|
26
|
+
await pool.init();
|
|
27
|
+
// Run a single generation job with profiling
|
|
28
|
+
const workflow = Workflow.fromAugmented(GenerationGraph)
|
|
29
|
+
.input("1", "value", "1girl, anime style, beautiful landscape, high quality, vibrant colors")
|
|
30
|
+
.input("2", "value", "ugly, blurry, low quality")
|
|
31
|
+
.input("10", "steps", 30)
|
|
32
|
+
.input("10", "seed", -1);
|
|
33
|
+
console.log("Submitting job with profiling enabled...\n");
|
|
34
|
+
const jobId = await pool.submitJob(workflow);
|
|
35
|
+
const result = await pool.waitForJobCompletion(jobId);
|
|
36
|
+
console.log("\n" + "=".repeat(80));
|
|
37
|
+
console.log("JOB COMPLETED - PROFILING RESULTS");
|
|
38
|
+
console.log("=".repeat(80));
|
|
39
|
+
if (result.profileStats) {
|
|
40
|
+
const stats = result.profileStats;
|
|
41
|
+
console.log(`\n📊 Execution Summary:`);
|
|
42
|
+
console.log(` Total Duration: ${stats.totalDuration}ms`);
|
|
43
|
+
console.log(` Queue Time: ${stats.queueTime}ms`);
|
|
44
|
+
console.log(` Execution Time: ${stats.executionTime}ms`);
|
|
45
|
+
console.log(` Prompt ID: ${stats.promptId}`);
|
|
46
|
+
console.log(`\n📈 Node Statistics:`);
|
|
47
|
+
console.log(` Total Nodes: ${stats.summary.totalNodes}`);
|
|
48
|
+
console.log(` Executed: ${stats.summary.executedNodes}`);
|
|
49
|
+
console.log(` Cached: ${stats.summary.cachedNodes}`);
|
|
50
|
+
console.log(` Failed: ${stats.summary.failedNodes}`);
|
|
51
|
+
console.log(` Progress Tracked: ${stats.summary.progressNodes.length}`);
|
|
52
|
+
if (stats.summary.slowestNodes.length > 0) {
|
|
53
|
+
console.log(`\n🐌 Slowest Nodes (Top ${Math.min(5, stats.summary.slowestNodes.length)}):`);
|
|
54
|
+
stats.summary.slowestNodes.forEach((node, i) => {
|
|
55
|
+
const title = node.title ? ` (${node.title})` : '';
|
|
56
|
+
console.log(` ${i + 1}. Node ${node.nodeId}${title}: ${node.duration}ms`);
|
|
57
|
+
console.log(` Type: ${node.type || 'unknown'}`);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (stats.summary.progressNodes.length > 0) {
|
|
61
|
+
console.log(`\n⏱️ Nodes with Progress Tracking:`);
|
|
62
|
+
stats.summary.progressNodes.forEach(nodeId => {
|
|
63
|
+
const nodeProfile = stats.nodes.find(n => n.nodeId === nodeId);
|
|
64
|
+
if (nodeProfile?.progressEvents) {
|
|
65
|
+
console.log(` Node ${nodeId} (${nodeProfile.type || 'unknown'}): ${nodeProfile.progressEvents.length} progress events`);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// Show detailed node execution timeline
|
|
70
|
+
console.log(`\n📅 Execution Timeline (All Nodes):`);
|
|
71
|
+
const executedNodes = stats.nodes
|
|
72
|
+
.filter(n => n.duration !== undefined)
|
|
73
|
+
.sort((a, b) => (a.startedAt || 0) - (b.startedAt || 0));
|
|
74
|
+
executedNodes.forEach(node => {
|
|
75
|
+
const status = node.cached ? '⚡ CACHED' : '✓ EXECUTED';
|
|
76
|
+
const title = node.title ? ` (${node.title})` : '';
|
|
77
|
+
const duration = node.cached ? '0ms' : `${node.duration}ms`;
|
|
78
|
+
console.log(` ${status} | Node ${node.nodeId}${title} | ${node.type || 'unknown'} | ${duration}`);
|
|
79
|
+
});
|
|
80
|
+
console.log("\n" + "=".repeat(80));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.log("\n⚠️ No profiling data available (profiling may be disabled)");
|
|
84
|
+
}
|
|
85
|
+
await pool.shutdown();
|
|
86
|
+
console.log("\n✅ Profiling demo completed, exiting...");
|
|
87
|
+
process.exit(0);
|
|
88
|
+
//# sourceMappingURL=profiling-demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiling-demo.js","sourceRoot":"","sources":["../../../src/multipool/tests/profiling-demo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a random image generation prompt for testing.
|
|
3
|
+
*/
|
|
4
|
+
export declare function promptGenerator(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Generate a random prompt specifically for the Anime XL model. Using more anime-focused elements and danbooru-style tags.
|
|
7
|
+
*/
|
|
8
|
+
export declare function animeXLPromptGenerator(): string;
|
|
9
|
+
export declare const NEGATIVE_PROMPT = "modern, recent, old, oldest, cartoon, graphic, text, painting, crayon, graphite, abstract, glitch, deformed, mutated, ugly, disfigured, long body, lowres, bad anatomy, bad hands, missing fingers, extra digits, fewer digits, cropped, very displeasing, (worst quality, bad quality:1.2), bad anatomy, sketch, jpeg artifacts, signature, watermark, username, signature, simple background, conjoined,bad ai-generated";
|
|
10
|
+
//# sourceMappingURL=prompt-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-generator.d.ts","sourceRoot":"","sources":["../../../src/multipool/tests/prompt-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAYxC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAU/C;AAED,eAAO,MAAM,eAAe,+ZAA+Z,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a random image generation prompt for testing.
|
|
3
|
+
*/
|
|
4
|
+
export function promptGenerator() {
|
|
5
|
+
const subjects = ["a cat", "a dog", "a futuristic city", "a beautiful landscape", "an astronaut", "a dragon", "a robot", "a magical forest"];
|
|
6
|
+
const styles = ["in the style of Van Gogh", "as a Pixar movie", "like a watercolor painting", "as a cyberpunk scene", "in a surrealist style", "like a comic book illustration"];
|
|
7
|
+
const actions = ["flying through the sky", "exploring a new world", "sitting on a throne", "dancing in the rain", "holding a glowing orb", "standing on a mountain peak"];
|
|
8
|
+
const subject = subjects[Math.floor(Math.random() * subjects.length)];
|
|
9
|
+
const style = styles[Math.floor(Math.random() * styles.length)];
|
|
10
|
+
const action = actions[Math.floor(Math.random() * actions.length)];
|
|
11
|
+
return `A high-resolution image of ${subject} ${action}, ${style}, vibrant colors, detailed, 4k resolution`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate a random prompt specifically for the Anime XL model. Using more anime-focused elements and danbooru-style tags.
|
|
15
|
+
*/
|
|
16
|
+
export function animeXLPromptGenerator() {
|
|
17
|
+
const subjects = ["1girl", "2boys", "catgirl", "mecha", "futuristic city", "magical girl", "samurai", "ninja"];
|
|
18
|
+
const styles = ["anime style", "manga style", "chibi style", "cyberpunk anime", "fantasy anime", "mecha anime"];
|
|
19
|
+
const actions = ["holding a katana", "sitting under cherry blossoms", "flying through the sky", "exploring a futuristic city", "casting a spell", "standing on a rooftop"];
|
|
20
|
+
const subject = subjects[Math.floor(Math.random() * subjects.length)];
|
|
21
|
+
const style = styles[Math.floor(Math.random() * styles.length)];
|
|
22
|
+
const action = actions[Math.floor(Math.random() * actions.length)];
|
|
23
|
+
return `score_9, score_8_up, score_7_up, score_6_up, score_5_up, score_4_up, source_anime, BREAK, ${subject}, ${action}, ${style}`;
|
|
24
|
+
}
|
|
25
|
+
export const NEGATIVE_PROMPT = `modern, recent, old, oldest, cartoon, graphic, text, painting, crayon, graphite, abstract, glitch, deformed, mutated, ugly, disfigured, long body, lowres, bad anatomy, bad hands, missing fingers, extra digits, fewer digits, cropped, very displeasing, (worst quality, bad quality:1.2), bad anatomy, sketch, jpeg artifacts, signature, watermark, username, signature, simple background, conjoined,bad ai-generated`;
|
|
26
|
+
//# sourceMappingURL=prompt-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-generator.js","sourceRoot":"","sources":["../../../src/multipool/tests/prompt-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,eAAe;IAE7B,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC7I,MAAM,MAAM,GAAG,CAAC,0BAA0B,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,gCAAgC,CAAC,CAAC;IACjL,MAAM,OAAO,GAAG,CAAC,wBAAwB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,6BAA6B,CAAC,CAAC;IAE1K,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnE,OAAO,8BAA8B,OAAO,IAAI,MAAM,KAAK,KAAK,2CAA2C,CAAC;AAE9G,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC/G,MAAM,MAAM,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;IAChH,MAAM,OAAO,GAAG,CAAC,kBAAkB,EAAE,+BAA+B,EAAE,wBAAwB,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;IAE3K,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnE,OAAO,6FAA6F,OAAO,KAAK,MAAM,KAAK,KAAK,EAAE,CAAC;AACrI,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,4ZAA4Z,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../../src/multipool/tests/test-helpers.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAEzC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function pickRandom(arr) {
|
|
2
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
3
|
+
}
|
|
4
|
+
export function randomInt(min, max) {
|
|
5
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
6
|
+
}
|
|
7
|
+
export function randomSeed() {
|
|
8
|
+
return Math.floor(Math.random() * 2147483647);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=test-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../../src/multipool/tests/test-helpers.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAI,GAAQ;IACpC,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,GAAW;IAChD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare class TwoStageUser {
|
|
2
|
+
private userId;
|
|
3
|
+
private shouldRun;
|
|
4
|
+
private totalGenerations;
|
|
5
|
+
private generatedImages;
|
|
6
|
+
private editsPerImage;
|
|
7
|
+
private minDelayMs;
|
|
8
|
+
private maxDelayMs;
|
|
9
|
+
stats: {
|
|
10
|
+
generationsStarted: number;
|
|
11
|
+
generationsCompleted: number;
|
|
12
|
+
generationsFailed: number;
|
|
13
|
+
editsStarted: number;
|
|
14
|
+
editsCompleted: number;
|
|
15
|
+
editsFailed: number;
|
|
16
|
+
};
|
|
17
|
+
constructor(userId: string, options?: {
|
|
18
|
+
totalGenerations?: number;
|
|
19
|
+
editsPerImage?: number;
|
|
20
|
+
minDelayMs?: number;
|
|
21
|
+
maxDelayMs?: number;
|
|
22
|
+
});
|
|
23
|
+
stop(): void;
|
|
24
|
+
start(): Promise<void>;
|
|
25
|
+
private generationLoop;
|
|
26
|
+
private editLoop;
|
|
27
|
+
private generateImage;
|
|
28
|
+
private editImage;
|
|
29
|
+
private delay;
|
|
30
|
+
private printStats;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=two-stage-edit-simulation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"two-stage-edit-simulation.d.ts","sourceRoot":"","sources":["../../../src/multipool/tests/two-stage-edit-simulation.ts"],"names":[],"mappings":"AAsFA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,eAAe,CAAwB;IAC/C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAGpB,KAAK;;;;;;;MAOV;gBAGA,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QACP,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KAChB;IASR,IAAI;IAIE,KAAK;YAcG,cAAc;YAWd,QAAQ;YAiBR,aAAa;YAqDb,SAAS;IAyCvB,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,UAAU;CASnB"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { MultiWorkflowPool } from "../multi-workflow-pool.js";
|
|
2
|
+
import { Workflow } from "../workflow.js";
|
|
3
|
+
import GenerationGraph from "../../../scripts/workflows/T2I-anime-nova-xl.json" with { type: "json" };
|
|
4
|
+
import EditGraph from "../../../scripts/workflows/quick-edit-test.json" with { type: "json" };
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { animeXLPromptGenerator, NEGATIVE_PROMPT } from "src/multipool/tests/prompt-generator.js";
|
|
7
|
+
import { pickRandom, randomInt, randomSeed } from "./test-helpers.js";
|
|
8
|
+
/**
|
|
9
|
+
* Two-Stage Edit Simulation for MultiWorkflowPool
|
|
10
|
+
*
|
|
11
|
+
* This test simulates real-world usage where users:
|
|
12
|
+
* 1. Generate images using text-to-image workflows on a dedicated generation server
|
|
13
|
+
* 2. Edit those generated images using image editing workflows on dedicated edit servers
|
|
14
|
+
*
|
|
15
|
+
* The simulation demonstrates:
|
|
16
|
+
* - Proper workflow affinity routing (generation → GEN_HOST, edits → EDIT_HOSTS)
|
|
17
|
+
* - Concurrent multi-user workflows
|
|
18
|
+
* - Image blob handling through the pool's public API (no direct host access)
|
|
19
|
+
* - Event-driven queue processing and client state management
|
|
20
|
+
*
|
|
21
|
+
* Each TwoStageUser class instance simulates an independent user generating and editing images.
|
|
22
|
+
*/ // ============================================================================
|
|
23
|
+
// CONFIGURATION
|
|
24
|
+
// ============================================================================
|
|
25
|
+
const GEN_HOST = "http://server1:8188";
|
|
26
|
+
const EDIT_HOSTS = ["http://server2:8188", "http://server3:8188"];
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// PROMPT GENERATORS
|
|
29
|
+
// ============================================================================
|
|
30
|
+
const editPrompts = [
|
|
31
|
+
"Shift to a nighttime scene with glowing lanterns and gentle rain, add reflective puddles",
|
|
32
|
+
"Transform into a winter landscape with snowfall and frosted trees, keep main subject",
|
|
33
|
+
"Reimagine as a bustling cyberpunk alley filled with holographic signs and neon rain",
|
|
34
|
+
"Convert the environment to a tranquil seaside at sunrise with warm golden lighting",
|
|
35
|
+
"Reframe as an autumn festival with floating lanterns and soft embers",
|
|
36
|
+
"Turn into a bioluminescent jungle with fog and glowing flora",
|
|
37
|
+
"Adapt into a desert oasis at twilight with swirling dust and warm rim light"
|
|
38
|
+
];
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// POOL SETUP
|
|
41
|
+
// ============================================================================
|
|
42
|
+
const pool = new MultiWorkflowPool({
|
|
43
|
+
enableMonitoring: true,
|
|
44
|
+
logLevel: "info"
|
|
45
|
+
});
|
|
46
|
+
const genWorkflow = Workflow.fromAugmented(GenerationGraph);
|
|
47
|
+
const editWorkflow = Workflow.fromAugmented(EditGraph);
|
|
48
|
+
console.log(`Generation Workflow Hash: ${genWorkflow.structureHash}`);
|
|
49
|
+
console.log(`Edit Workflow Hash: ${editWorkflow.structureHash}`);
|
|
50
|
+
// Set affinity mapping: generation on GEN_HOST, editing on EDIT_HOSTS
|
|
51
|
+
pool.addClient(GEN_HOST, {
|
|
52
|
+
workflowAffinity: [genWorkflow],
|
|
53
|
+
priority: 1
|
|
54
|
+
});
|
|
55
|
+
for (const editHost of EDIT_HOSTS) {
|
|
56
|
+
pool.addClient(editHost, {
|
|
57
|
+
workflowAffinity: [editWorkflow],
|
|
58
|
+
priority: 1
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
await pool.init();
|
|
62
|
+
export class TwoStageUser {
|
|
63
|
+
userId;
|
|
64
|
+
shouldRun = true;
|
|
65
|
+
totalGenerations = 0;
|
|
66
|
+
generatedImages = [];
|
|
67
|
+
editsPerImage;
|
|
68
|
+
minDelayMs;
|
|
69
|
+
maxDelayMs;
|
|
70
|
+
// Statistics
|
|
71
|
+
stats = {
|
|
72
|
+
generationsStarted: 0,
|
|
73
|
+
generationsCompleted: 0,
|
|
74
|
+
generationsFailed: 0,
|
|
75
|
+
editsStarted: 0,
|
|
76
|
+
editsCompleted: 0,
|
|
77
|
+
editsFailed: 0
|
|
78
|
+
};
|
|
79
|
+
constructor(userId, options = {}) {
|
|
80
|
+
this.userId = userId;
|
|
81
|
+
this.totalGenerations = options.totalGenerations ?? 3;
|
|
82
|
+
this.editsPerImage = options.editsPerImage ?? 2;
|
|
83
|
+
this.minDelayMs = options.minDelayMs ?? 1000;
|
|
84
|
+
this.maxDelayMs = options.maxDelayMs ?? 5000;
|
|
85
|
+
}
|
|
86
|
+
stop() {
|
|
87
|
+
this.shouldRun = false;
|
|
88
|
+
}
|
|
89
|
+
async start() {
|
|
90
|
+
console.log(`\n[${this.userId}] Starting two-stage workflow simulation`);
|
|
91
|
+
console.log(`[${this.userId}] Will generate ${this.totalGenerations} images, each with ${this.editsPerImage} edits`);
|
|
92
|
+
// Start generation and edit loops concurrently
|
|
93
|
+
await Promise.all([
|
|
94
|
+
this.generationLoop(),
|
|
95
|
+
this.editLoop()
|
|
96
|
+
]);
|
|
97
|
+
console.log(`\n[${this.userId}] Completed workflow simulation`);
|
|
98
|
+
this.printStats();
|
|
99
|
+
}
|
|
100
|
+
async generationLoop() {
|
|
101
|
+
for (let i = 0; i < this.totalGenerations && this.shouldRun; i++) {
|
|
102
|
+
try {
|
|
103
|
+
await this.generateImage();
|
|
104
|
+
await this.delay(randomInt(this.minDelayMs, this.maxDelayMs));
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.error(`[${this.userId}] Error in generation loop:`, error);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async editLoop() {
|
|
112
|
+
while (this.shouldRun) {
|
|
113
|
+
// Wait if no images are available
|
|
114
|
+
if (this.generatedImages.length === 0) {
|
|
115
|
+
await this.delay(500);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
await this.editImage();
|
|
120
|
+
await this.delay(randomInt(this.minDelayMs, this.maxDelayMs));
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.error(`[${this.userId}] Error in edit loop:`, error);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async generateImage() {
|
|
128
|
+
const prompt = animeXLPromptGenerator();
|
|
129
|
+
const seed = randomSeed();
|
|
130
|
+
const workflow = Workflow.fromAugmented(GenerationGraph)
|
|
131
|
+
.input("1", "value", prompt)
|
|
132
|
+
.input("2", "value", NEGATIVE_PROMPT)
|
|
133
|
+
.input("10", "steps", 30)
|
|
134
|
+
.input("10", "seed", seed);
|
|
135
|
+
this.stats.generationsStarted++;
|
|
136
|
+
const jobId = await pool.submitJob(workflow);
|
|
137
|
+
console.log(`[${this.userId}] 🎨 Generation started: "${prompt.substring(0, 40)}..." (job: ${jobId.substring(0, 8)})`);
|
|
138
|
+
try {
|
|
139
|
+
const result = await pool.waitForJobCompletion(jobId);
|
|
140
|
+
if (result.status === "completed") {
|
|
141
|
+
this.stats.generationsCompleted++;
|
|
142
|
+
if (result.images.length === 0) {
|
|
143
|
+
throw new Error("No images returned from generation");
|
|
144
|
+
}
|
|
145
|
+
const imageUrl = result.images[0];
|
|
146
|
+
// Download image from URL as blob
|
|
147
|
+
const response = await fetch(imageUrl);
|
|
148
|
+
if (!response.ok) {
|
|
149
|
+
throw new Error(`Failed to fetch generated image from ${imageUrl}: ${response.statusText}`);
|
|
150
|
+
}
|
|
151
|
+
const blob = await response.blob();
|
|
152
|
+
// Queue this image for editing
|
|
153
|
+
this.generatedImages.push({
|
|
154
|
+
jobId,
|
|
155
|
+
imageRecord: { url: imageUrl, blob },
|
|
156
|
+
prompt
|
|
157
|
+
});
|
|
158
|
+
console.log(`[${this.userId}] ✅ Generation completed: ${jobId.substring(0, 8)} (${result.images.length} images, queued for ${this.editsPerImage} edits)`);
|
|
159
|
+
}
|
|
160
|
+
else if (result.status === "failed") {
|
|
161
|
+
this.stats.generationsFailed++;
|
|
162
|
+
console.error(`[${this.userId}] ❌ Generation failed: ${jobId.substring(0, 8)}`, result.error);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
this.stats.generationsFailed++;
|
|
167
|
+
console.error(`[${this.userId}] ❌ Generation error: ${jobId.substring(0, 8)}`, error);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async editImage() {
|
|
171
|
+
const genImage = this.generatedImages.shift();
|
|
172
|
+
if (!genImage)
|
|
173
|
+
return;
|
|
174
|
+
for (let i = 0; i < this.editsPerImage && this.shouldRun; i++) {
|
|
175
|
+
const editPrompt = pickRandom(editPrompts);
|
|
176
|
+
try {
|
|
177
|
+
// Create edit workflow with the generated image attached as a blob
|
|
178
|
+
// The pool will handle uploading the image to the assigned edit server
|
|
179
|
+
const editWorkflowInstance = Workflow.fromAugmented(EditGraph)
|
|
180
|
+
.attachImage("97", "image", genImage.imageRecord.blob, `${randomUUID()}.png`)
|
|
181
|
+
.input("91", "prompt", editPrompt)
|
|
182
|
+
.input("51", "seed", -1); // Auto-generate seed this.stats.editsStarted++;
|
|
183
|
+
const editJobId = await pool.submitJob(editWorkflowInstance);
|
|
184
|
+
console.log(`[${this.userId}] ✏️ Edit ${i + 1}/${this.editsPerImage} started: "${editPrompt.substring(0, 40)}..." (job: ${editJobId.substring(0, 8)})`);
|
|
185
|
+
try {
|
|
186
|
+
const editResult = await pool.waitForJobCompletion(editJobId);
|
|
187
|
+
if (editResult.status === "completed") {
|
|
188
|
+
this.stats.editsCompleted++;
|
|
189
|
+
console.log(`[${this.userId}] ✅ Edit completed: ${editJobId.substring(0, 8)} (${editResult.images.length} images)`);
|
|
190
|
+
}
|
|
191
|
+
else if (editResult.status === "failed") {
|
|
192
|
+
this.stats.editsFailed++;
|
|
193
|
+
console.error(`[${this.userId}] ❌ Edit failed: ${editJobId.substring(0, 8)}`, editResult.error);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
this.stats.editsFailed++;
|
|
198
|
+
console.error(`[${this.userId}] ❌ Edit error: ${editJobId.substring(0, 8)}`, error);
|
|
199
|
+
}
|
|
200
|
+
// Small delay between edits of the same image
|
|
201
|
+
if (i < this.editsPerImage - 1) {
|
|
202
|
+
await this.delay(randomInt(500, 1500));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.error(`[${this.userId}] ❌ Error during edit process:`, error);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
delay(ms) {
|
|
211
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
212
|
+
}
|
|
213
|
+
printStats() {
|
|
214
|
+
console.log(`\n[${this.userId}] === Final Statistics ===`);
|
|
215
|
+
console.log(` Generations: ${this.stats.generationsCompleted}/${this.stats.generationsStarted} (${this.stats.generationsFailed} failed)`);
|
|
216
|
+
console.log(` Edits: ${this.stats.editsCompleted}/${this.stats.editsStarted} (${this.stats.editsFailed} failed)`);
|
|
217
|
+
const totalSuccess = this.stats.generationsCompleted + this.stats.editsCompleted;
|
|
218
|
+
const totalStarted = this.stats.generationsStarted + this.stats.editsStarted;
|
|
219
|
+
const successRate = totalStarted > 0 ? ((totalSuccess / totalStarted) * 100).toFixed(1) : "0.0";
|
|
220
|
+
console.log(` Success Rate: ${successRate}%`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// RUN SIMULATION
|
|
225
|
+
// ============================================================================
|
|
226
|
+
async function runSimulation() {
|
|
227
|
+
console.log("\n" + "=".repeat(80));
|
|
228
|
+
console.log("TWO-STAGE EDIT SIMULATION - MultiWorkflowPool");
|
|
229
|
+
console.log("=".repeat(80));
|
|
230
|
+
console.log(`Generation Host: ${GEN_HOST}`);
|
|
231
|
+
console.log(`Edit Hosts: ${EDIT_HOSTS.join(", ")}`);
|
|
232
|
+
console.log("=".repeat(80) + "\n");
|
|
233
|
+
// Create multiple simulated users
|
|
234
|
+
const user1 = new TwoStageUser("User-1", {
|
|
235
|
+
totalGenerations: 2,
|
|
236
|
+
editsPerImage: 2,
|
|
237
|
+
minDelayMs: 1000,
|
|
238
|
+
maxDelayMs: 3000
|
|
239
|
+
});
|
|
240
|
+
const user2 = new TwoStageUser("User-2", {
|
|
241
|
+
totalGenerations: 2,
|
|
242
|
+
editsPerImage: 1,
|
|
243
|
+
minDelayMs: 1500,
|
|
244
|
+
maxDelayMs: 4000
|
|
245
|
+
});
|
|
246
|
+
const user3 = new TwoStageUser("User-3", {
|
|
247
|
+
totalGenerations: 1,
|
|
248
|
+
editsPerImage: 3,
|
|
249
|
+
minDelayMs: 2000,
|
|
250
|
+
maxDelayMs: 5000
|
|
251
|
+
});
|
|
252
|
+
// Run all users concurrently
|
|
253
|
+
try {
|
|
254
|
+
await Promise.all([
|
|
255
|
+
user1.start(),
|
|
256
|
+
user2.start(),
|
|
257
|
+
user3.start()
|
|
258
|
+
]);
|
|
259
|
+
console.log("\n" + "=".repeat(80));
|
|
260
|
+
console.log("SIMULATION COMPLETED SUCCESSFULLY");
|
|
261
|
+
console.log("=".repeat(80));
|
|
262
|
+
// Print combined statistics
|
|
263
|
+
const totalStats = {
|
|
264
|
+
generationsCompleted: user1.stats.generationsCompleted + user2.stats.generationsCompleted + user3.stats.generationsCompleted,
|
|
265
|
+
generationsStarted: user1.stats.generationsStarted + user2.stats.generationsStarted + user3.stats.generationsStarted,
|
|
266
|
+
generationsFailed: user1.stats.generationsFailed + user2.stats.generationsFailed + user3.stats.generationsFailed,
|
|
267
|
+
editsCompleted: user1.stats.editsCompleted + user2.stats.editsCompleted + user3.stats.editsCompleted,
|
|
268
|
+
editsStarted: user1.stats.editsStarted + user2.stats.editsStarted + user3.stats.editsStarted,
|
|
269
|
+
editsFailed: user1.stats.editsFailed + user2.stats.editsFailed + user3.stats.editsFailed
|
|
270
|
+
};
|
|
271
|
+
console.log("\n=== Combined Statistics ===");
|
|
272
|
+
console.log(` Generations: ${totalStats.generationsCompleted}/${totalStats.generationsStarted} (${totalStats.generationsFailed} failed)`);
|
|
273
|
+
console.log(` Edits: ${totalStats.editsCompleted}/${totalStats.editsStarted} (${totalStats.editsFailed} failed)`);
|
|
274
|
+
const totalSuccess = totalStats.generationsCompleted + totalStats.editsCompleted;
|
|
275
|
+
const totalAttempted = totalStats.generationsStarted + totalStats.editsStarted;
|
|
276
|
+
const successRate = totalAttempted > 0 ? ((totalSuccess / totalAttempted) * 100).toFixed(1) : "0.0";
|
|
277
|
+
console.log(` Overall Success Rate: ${successRate}%\n`);
|
|
278
|
+
const hasFailures = totalStats.generationsFailed > 0 || totalStats.editsFailed > 0;
|
|
279
|
+
if (hasFailures) {
|
|
280
|
+
console.log("⚠️ Some operations failed during the simulation");
|
|
281
|
+
process.exitCode = 1;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
console.error("\n❌ SIMULATION FAILED:", error);
|
|
286
|
+
process.exitCode = 1;
|
|
287
|
+
}
|
|
288
|
+
finally {
|
|
289
|
+
await pool.shutdown();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
runSimulation().then(() => {
|
|
293
|
+
console.log("\n✅ Test script completed, exiting...");
|
|
294
|
+
process.exit(0);
|
|
295
|
+
}).catch(error => {
|
|
296
|
+
console.error("\n❌ Fatal error:", error);
|
|
297
|
+
process.exit(1);
|
|
298
|
+
});
|
|
299
|
+
//# sourceMappingURL=two-stage-edit-simulation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"two-stage-edit-simulation.js","sourceRoot":"","sources":["../../../src/multipool/tests/two-stage-edit-simulation.ts"],"names":[],"mappings":"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"}
|