bizydraft 0.1.29__py3-none-any.whl → 0.2.0__py3-none-any.whl
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.
Potentially problematic release.
This version of bizydraft might be problematic. Click here for more details.
- bizydraft/block_nodes.py +35 -0
- bizydraft/env.py +11 -0
- bizydraft/hijack_nodes.py +66 -6
- bizydraft/hijack_routes.py +87 -184
- bizydraft/oss_utils.py +227 -0
- bizydraft/patch_handlers.py +150 -0
- bizydraft/postload.py +26 -8
- bizydraft/server.py +2 -1
- bizydraft/static/js/aiAppHandler.js +540 -0
- bizydraft/static/js/freezeModeHandler.js +490 -0
- bizydraft/static/js/handleStyle.js +6 -0
- bizydraft/static/js/hookLoadImage.js +122 -82
- bizydraft/static/js/hookLoadModel.js +152 -0
- bizydraft/static/js/main.js +0 -1
- bizydraft/static/js/nodeFocusHandler.js +153 -0
- bizydraft/static/js/nodeParamsFilter.js +136 -0
- bizydraft/static/js/postEvent.js +336 -106
- bizydraft/static/js/socket.js +1 -1
- bizydraft/static/js/tool.js +61 -1
- bizydraft/static/js/uploadFile.js +22 -22
- bizydraft/workflow_io.py +30 -2
- {bizydraft-0.1.29.dist-info → bizydraft-0.2.0.dist-info}/METADATA +1 -1
- bizydraft-0.2.0.dist-info/RECORD +28 -0
- bizydraft-0.1.29.dist-info/RECORD +0 -19
- {bizydraft-0.1.29.dist-info → bizydraft-0.2.0.dist-info}/WHEEL +0 -0
- {bizydraft-0.1.29.dist-info → bizydraft-0.2.0.dist-info}/top_level.txt +0 -0
bizydraft/static/js/postEvent.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { app } from "../../scripts/app.js";
|
|
2
|
+
import { enableAIAppMode, disableAIAppMode, selectInputNode, deselectInputNode, updateInputNodeWidget, getSelectedInputNodes, clearSelectedInputNodes, toggleExportMode } from "./aiAppHandler.js";
|
|
3
|
+
import { focusNodeOnly } from "./nodeFocusHandler.js";
|
|
2
4
|
|
|
3
5
|
app.registerExtension({
|
|
4
6
|
name: "comfy.BizyAir.Socket",
|
|
@@ -10,28 +12,28 @@ app.registerExtension({
|
|
|
10
12
|
socket: null,
|
|
11
13
|
isConnecting: false,
|
|
12
14
|
taskRunning: false,
|
|
13
|
-
|
|
15
|
+
|
|
14
16
|
// 心跳检测
|
|
15
17
|
pingInterval: 5000, // 5秒发送一次心跳
|
|
16
18
|
pingTimer: null,
|
|
17
19
|
pingTimeout: 3000,
|
|
18
|
-
pongReceived: false,
|
|
20
|
+
pongReceived: false,
|
|
19
21
|
pingTimeoutTimer: null, // ping超时计时器
|
|
20
|
-
|
|
22
|
+
|
|
21
23
|
/**
|
|
22
24
|
* 开始心跳检测
|
|
23
25
|
*/
|
|
24
26
|
startPing() {
|
|
25
27
|
this.stopPing();
|
|
26
|
-
|
|
28
|
+
|
|
27
29
|
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
28
30
|
return;
|
|
29
31
|
}
|
|
30
|
-
|
|
32
|
+
|
|
31
33
|
// 立即发送一次ping消息
|
|
32
34
|
this.pongReceived = false;
|
|
33
35
|
this.socket.send('ping');
|
|
34
|
-
|
|
36
|
+
|
|
35
37
|
// 设置ping超时检测
|
|
36
38
|
this.pingTimeoutTimer = setTimeout(() => {
|
|
37
39
|
if (!this.pongReceived) {
|
|
@@ -39,12 +41,12 @@ app.registerExtension({
|
|
|
39
41
|
this.reconnect();
|
|
40
42
|
}
|
|
41
43
|
}, this.pingTimeout);
|
|
42
|
-
|
|
44
|
+
|
|
43
45
|
// 设置定时发送ping
|
|
44
46
|
this.pingTimer = setInterval(() => {
|
|
45
47
|
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
|
46
48
|
this.pongReceived = false;
|
|
47
|
-
this.socket.send('ping');
|
|
49
|
+
this.socket.send('ping');
|
|
48
50
|
// 设置ping超时检测
|
|
49
51
|
this.pingTimeoutTimer = setTimeout(() => {
|
|
50
52
|
// 如果没有收到pong响应
|
|
@@ -59,7 +61,7 @@ app.registerExtension({
|
|
|
59
61
|
}
|
|
60
62
|
}, this.pingInterval);
|
|
61
63
|
},
|
|
62
|
-
|
|
64
|
+
|
|
63
65
|
/**
|
|
64
66
|
* 停止心跳检测
|
|
65
67
|
*/
|
|
@@ -68,25 +70,25 @@ app.registerExtension({
|
|
|
68
70
|
clearInterval(this.pingTimer);
|
|
69
71
|
this.pingTimer = null;
|
|
70
72
|
}
|
|
71
|
-
|
|
73
|
+
|
|
72
74
|
if (this.pingTimeoutTimer) {
|
|
73
75
|
clearTimeout(this.pingTimeoutTimer);
|
|
74
76
|
this.pingTimeoutTimer = null;
|
|
75
77
|
}
|
|
76
78
|
},
|
|
77
|
-
|
|
79
|
+
|
|
78
80
|
/**
|
|
79
81
|
* 重新连接
|
|
80
82
|
*/
|
|
81
83
|
reconnect() {
|
|
82
84
|
if (this.isConnecting) {
|
|
83
85
|
return;
|
|
84
|
-
}
|
|
85
|
-
const url = this.socket ? this.socket.url : app.api.socket.url;
|
|
86
|
-
this.closeSocket();
|
|
86
|
+
}
|
|
87
|
+
const url = this.socket ? this.socket.url : app.api.socket.url;
|
|
88
|
+
this.closeSocket();
|
|
87
89
|
this.createSocket(url);
|
|
88
90
|
},
|
|
89
|
-
|
|
91
|
+
|
|
90
92
|
/**
|
|
91
93
|
* 创建新的WebSocket连接
|
|
92
94
|
*/
|
|
@@ -96,21 +98,21 @@ app.registerExtension({
|
|
|
96
98
|
console.log('WebSocket连接已在创建中,避免重复创建');
|
|
97
99
|
return null;
|
|
98
100
|
}
|
|
99
|
-
|
|
101
|
+
|
|
100
102
|
// 标记为连接中
|
|
101
103
|
this.isConnecting = true;
|
|
102
|
-
|
|
104
|
+
|
|
103
105
|
// 先关闭现有连接
|
|
104
106
|
this.closeSocket();
|
|
105
|
-
|
|
107
|
+
|
|
106
108
|
const url = customUrl || app.api.socket.url;
|
|
107
109
|
console.log('创建WebSocket连接:', url);
|
|
108
|
-
|
|
110
|
+
|
|
109
111
|
try {
|
|
110
112
|
const socket = new WebSocket(url);
|
|
111
113
|
const dispatchCustomEvent = this.dispatchCustomEvent;
|
|
112
114
|
const self = this;
|
|
113
|
-
|
|
115
|
+
|
|
114
116
|
socket.onopen = function() {
|
|
115
117
|
console.log('WebSocket连接已打开');
|
|
116
118
|
// 清除连接中标志
|
|
@@ -122,19 +124,19 @@ app.registerExtension({
|
|
|
122
124
|
// 开始心跳检测
|
|
123
125
|
self.startPing();
|
|
124
126
|
};
|
|
125
|
-
|
|
127
|
+
|
|
126
128
|
socket.onmessage = function (event) {
|
|
127
129
|
try {
|
|
128
130
|
// 处理心跳响应
|
|
129
131
|
if (event.data === 'pong') {
|
|
130
132
|
// 标记收到pong响应
|
|
131
133
|
self.pongReceived = true;
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
134
136
|
if (event.data instanceof ArrayBuffer) {
|
|
135
137
|
const view = new DataView(event.data);
|
|
136
138
|
const eventType = view.getUint32(0);
|
|
137
|
-
|
|
139
|
+
|
|
138
140
|
let imageMime;
|
|
139
141
|
switch (eventType) {
|
|
140
142
|
case 3:
|
|
@@ -177,20 +179,27 @@ app.registerExtension({
|
|
|
177
179
|
self.closeSocket(1000);
|
|
178
180
|
return;
|
|
179
181
|
}
|
|
180
|
-
|
|
182
|
+
|
|
181
183
|
const msg = JSON.parse(event.data);
|
|
182
184
|
window.parent.postMessage({
|
|
183
185
|
type: 'functionResult',
|
|
184
186
|
method: 'progress_info_change',
|
|
185
187
|
result: msg.progress_info
|
|
186
188
|
}, '*');
|
|
187
|
-
|
|
188
189
|
switch (msg.type) {
|
|
190
|
+
case 'load_start':
|
|
191
|
+
case 'load_end':
|
|
192
|
+
case 'prompt_id':
|
|
193
|
+
window.parent.postMessage({
|
|
194
|
+
type: 'functionResult',
|
|
195
|
+
method: 'preparingStatus',
|
|
196
|
+
result: msg
|
|
197
|
+
}, '*')
|
|
189
198
|
case 'status':
|
|
190
199
|
if (msg.data.sid) {
|
|
191
200
|
const clientId = msg.data.sid;
|
|
192
|
-
window.name = clientId;
|
|
193
|
-
sessionStorage.setItem('clientId', clientId);
|
|
201
|
+
window.name = clientId;
|
|
202
|
+
sessionStorage.setItem('clientId', clientId);
|
|
194
203
|
socket.clientId = clientId;
|
|
195
204
|
}
|
|
196
205
|
dispatchCustomEvent('status', msg.data.status ?? null);
|
|
@@ -209,6 +218,17 @@ app.registerExtension({
|
|
|
209
218
|
}
|
|
210
219
|
dispatchCustomEvent(msg.type, msg.data);
|
|
211
220
|
break;
|
|
221
|
+
case 'error':
|
|
222
|
+
self.taskRunning = false;
|
|
223
|
+
dispatchCustomEvent('execution_error', {
|
|
224
|
+
exception_message: msg.data.error_message || 'Unknown error',
|
|
225
|
+
traceback: ['Manual error triggered'],
|
|
226
|
+
executed: [],
|
|
227
|
+
prompt_id: 'manual',
|
|
228
|
+
node_id: '0',
|
|
229
|
+
node_type: 'RunError',
|
|
230
|
+
});
|
|
231
|
+
break;
|
|
212
232
|
case 'execution_error':
|
|
213
233
|
case 'execution_interrupted':
|
|
214
234
|
self.taskRunning = false;
|
|
@@ -229,7 +249,7 @@ app.registerExtension({
|
|
|
229
249
|
default:
|
|
230
250
|
const registeredTypes = socket.registeredTypes || new Set();
|
|
231
251
|
const reportedUnknownMessageTypes = socket.reportedUnknownMessageTypes || new Set();
|
|
232
|
-
|
|
252
|
+
|
|
233
253
|
if (registeredTypes.has(msg.type)) {
|
|
234
254
|
app.dispatchEvent(
|
|
235
255
|
new CustomEvent(msg.type, { detail: msg.data })
|
|
@@ -244,7 +264,7 @@ app.registerExtension({
|
|
|
244
264
|
console.warn('Unhandled message:', event.data, error);
|
|
245
265
|
}
|
|
246
266
|
};
|
|
247
|
-
|
|
267
|
+
|
|
248
268
|
socket.onerror = function(error) {
|
|
249
269
|
console.log('WebSocket 错误:', error);
|
|
250
270
|
// 清除连接中标志
|
|
@@ -252,7 +272,7 @@ app.registerExtension({
|
|
|
252
272
|
// 停止心跳
|
|
253
273
|
self.stopPing();
|
|
254
274
|
};
|
|
255
|
-
|
|
275
|
+
|
|
256
276
|
socket.onclose = function(event) {
|
|
257
277
|
console.log('WebSocket 连接已关闭, 状态码:', event.code, event.reason);
|
|
258
278
|
// 清除连接中标志
|
|
@@ -264,10 +284,10 @@ app.registerExtension({
|
|
|
264
284
|
// 停止心跳
|
|
265
285
|
self.stopPing();
|
|
266
286
|
};
|
|
267
|
-
|
|
287
|
+
|
|
268
288
|
socket.registeredTypes = new Set();
|
|
269
289
|
socket.reportedUnknownMessageTypes = new Set();
|
|
270
|
-
|
|
290
|
+
|
|
271
291
|
// 返回创建的socket,但不要立即使用,等待onopen
|
|
272
292
|
return socket;
|
|
273
293
|
} catch (error) {
|
|
@@ -288,7 +308,7 @@ app.registerExtension({
|
|
|
288
308
|
resolve(this.socket);
|
|
289
309
|
return;
|
|
290
310
|
}
|
|
291
|
-
|
|
311
|
+
|
|
292
312
|
// 如果连接正在创建中,等待一段时间后检查
|
|
293
313
|
if (this.isConnecting) {
|
|
294
314
|
console.log('WebSocket连接创建中,等待...');
|
|
@@ -303,26 +323,26 @@ app.registerExtension({
|
|
|
303
323
|
}, 100); // 每100ms检查一次
|
|
304
324
|
return;
|
|
305
325
|
}
|
|
306
|
-
|
|
326
|
+
|
|
307
327
|
// 创建新连接
|
|
308
328
|
const socket = this.createSocket(customUrl);
|
|
309
329
|
if (!socket) {
|
|
310
330
|
reject(new Error('创建WebSocket连接失败'));
|
|
311
331
|
return;
|
|
312
332
|
}
|
|
313
|
-
|
|
333
|
+
|
|
314
334
|
// 监听连接打开事件
|
|
315
335
|
socket.addEventListener('open', () => {
|
|
316
336
|
resolve(socket);
|
|
317
337
|
});
|
|
318
|
-
|
|
338
|
+
|
|
319
339
|
// 监听错误事件
|
|
320
340
|
socket.addEventListener('error', (error) => {
|
|
321
341
|
reject(error);
|
|
322
342
|
});
|
|
323
343
|
});
|
|
324
344
|
},
|
|
325
|
-
|
|
345
|
+
|
|
326
346
|
/**
|
|
327
347
|
* 获取可用的socket连接,如果不存在则创建
|
|
328
348
|
* 同步版本,可能返回尚未就绪的连接
|
|
@@ -332,7 +352,7 @@ app.registerExtension({
|
|
|
332
352
|
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
|
333
353
|
return this.socket;
|
|
334
354
|
}
|
|
335
|
-
|
|
355
|
+
|
|
336
356
|
// 创建新连接
|
|
337
357
|
return this.createSocket(customUrl);
|
|
338
358
|
},
|
|
@@ -344,7 +364,7 @@ app.registerExtension({
|
|
|
344
364
|
closeSocket(code) {
|
|
345
365
|
// 先停止心跳
|
|
346
366
|
this.stopPing();
|
|
347
|
-
|
|
367
|
+
|
|
348
368
|
if (this.socket) {
|
|
349
369
|
if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {
|
|
350
370
|
console.log('关闭WebSocket连接');
|
|
@@ -352,10 +372,10 @@ app.registerExtension({
|
|
|
352
372
|
}
|
|
353
373
|
this.socket = null;
|
|
354
374
|
}
|
|
355
|
-
|
|
375
|
+
|
|
356
376
|
// 重置任务状态
|
|
357
377
|
this.taskRunning = false;
|
|
358
|
-
|
|
378
|
+
|
|
359
379
|
return true;
|
|
360
380
|
},
|
|
361
381
|
|
|
@@ -365,7 +385,7 @@ app.registerExtension({
|
|
|
365
385
|
changeSocketUrl(newUrl) {
|
|
366
386
|
const clientId = sessionStorage.getItem("clientId");
|
|
367
387
|
const fullUrl = newUrl + "?clientId=" + clientId + "&a=1";
|
|
368
|
-
|
|
388
|
+
|
|
369
389
|
return this.createSocket(fullUrl);
|
|
370
390
|
},
|
|
371
391
|
|
|
@@ -402,7 +422,7 @@ app.registerExtension({
|
|
|
402
422
|
return false;
|
|
403
423
|
}
|
|
404
424
|
},
|
|
405
|
-
|
|
425
|
+
|
|
406
426
|
getCookie(name) {
|
|
407
427
|
const value = `; ${document.cookie}`;
|
|
408
428
|
const parts = value.split(`; ${name}=`);
|
|
@@ -411,14 +431,11 @@ app.registerExtension({
|
|
|
411
431
|
|
|
412
432
|
async setup() {
|
|
413
433
|
const createSocket = this.createSocket.bind(this);
|
|
414
|
-
const getSocket = this.getSocket.bind(this);
|
|
415
|
-
const getSocketAsync = this.getSocketAsync.bind(this);
|
|
416
434
|
const closeSocket = this.closeSocket.bind(this);
|
|
417
|
-
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const stopPing = this.stopPing.bind(this);
|
|
435
|
+
|
|
436
|
+
const customErrorStyles = new Map()
|
|
437
|
+
|
|
438
|
+
|
|
422
439
|
|
|
423
440
|
// 方法映射
|
|
424
441
|
const methods = {
|
|
@@ -432,26 +449,6 @@ app.registerExtension({
|
|
|
432
449
|
return socket;
|
|
433
450
|
},
|
|
434
451
|
|
|
435
|
-
startSocket: async function (params) {
|
|
436
|
-
try {
|
|
437
|
-
const socket = await getSocketAsync(params.url);
|
|
438
|
-
window.parent.postMessage({
|
|
439
|
-
type: 'functionResult',
|
|
440
|
-
method: 'startSocket',
|
|
441
|
-
result: 'Socket连接已启动'
|
|
442
|
-
}, '*');
|
|
443
|
-
return socket;
|
|
444
|
-
} catch (error) {
|
|
445
|
-
window.parent.postMessage({
|
|
446
|
-
type: 'functionResult',
|
|
447
|
-
method: 'startSocket',
|
|
448
|
-
result: 'Socket连接失败: ' + error.message,
|
|
449
|
-
error: true
|
|
450
|
-
}, '*');
|
|
451
|
-
return null;
|
|
452
|
-
}
|
|
453
|
-
},
|
|
454
|
-
|
|
455
452
|
closeSocket: function () {
|
|
456
453
|
const result = closeSocket();
|
|
457
454
|
window.parent.postMessage({
|
|
@@ -462,34 +459,6 @@ app.registerExtension({
|
|
|
462
459
|
return result;
|
|
463
460
|
},
|
|
464
461
|
|
|
465
|
-
changeSocketUrl: function (params) {
|
|
466
|
-
if (!params.url) {
|
|
467
|
-
console.error('缺少url参数');
|
|
468
|
-
return false;
|
|
469
|
-
}
|
|
470
|
-
const socket = changeSocketUrl(params.url);
|
|
471
|
-
window.parent.postMessage({
|
|
472
|
-
type: 'functionResult',
|
|
473
|
-
method: 'changeSocketUrl',
|
|
474
|
-
result: 'Socket URL已更改为' + params.url
|
|
475
|
-
}, '*');
|
|
476
|
-
return socket;
|
|
477
|
-
},
|
|
478
|
-
|
|
479
|
-
sendSocketMessage: async function (params) {
|
|
480
|
-
if (!params.message) {
|
|
481
|
-
console.error('缺少message参数');
|
|
482
|
-
return false;
|
|
483
|
-
}
|
|
484
|
-
const result = await sendSocketMessage(params.message);
|
|
485
|
-
window.parent.postMessage({
|
|
486
|
-
type: 'functionResult',
|
|
487
|
-
method: 'sendSocketMessage',
|
|
488
|
-
result: result ? '消息发送成功' : '消息发送失败'
|
|
489
|
-
}, '*');
|
|
490
|
-
return result;
|
|
491
|
-
},
|
|
492
|
-
|
|
493
462
|
clearCanvas: function () {
|
|
494
463
|
app.graph.clear();
|
|
495
464
|
window.parent.postMessage({
|
|
@@ -499,11 +468,10 @@ app.registerExtension({
|
|
|
499
468
|
}, '*');
|
|
500
469
|
return true;
|
|
501
470
|
},
|
|
502
|
-
|
|
503
471
|
loadWorkflow: function (params) {
|
|
504
472
|
app.graph.clear();
|
|
505
|
-
document.dispatchEvent(new CustomEvent('workflowLoaded', {
|
|
506
|
-
detail: params
|
|
473
|
+
document.dispatchEvent(new CustomEvent('workflowLoaded', {
|
|
474
|
+
detail: params.json
|
|
507
475
|
}));
|
|
508
476
|
if (params.json.version) {
|
|
509
477
|
app.loadGraphData(params.json);
|
|
@@ -537,6 +505,19 @@ app.registerExtension({
|
|
|
537
505
|
}, '*');
|
|
538
506
|
return graph.workflow;
|
|
539
507
|
},
|
|
508
|
+
// 新增:获取 workflow 和 output
|
|
509
|
+
getWorkflowWithOutput: async function () {
|
|
510
|
+
const graph = await app.graphToPrompt();
|
|
511
|
+
window.parent.postMessage({
|
|
512
|
+
type: 'functionResult',
|
|
513
|
+
method: 'getWorkflowWithOutput',
|
|
514
|
+
result: {
|
|
515
|
+
workflow: graph.workflow,
|
|
516
|
+
output: graph.output
|
|
517
|
+
}
|
|
518
|
+
}, '*');
|
|
519
|
+
return { workflow: graph.workflow, output: graph.output };
|
|
520
|
+
},
|
|
540
521
|
saveApiJson: async function (params) {
|
|
541
522
|
const graph = await app.graphToPrompt();
|
|
542
523
|
window.parent.postMessage({
|
|
@@ -559,9 +540,10 @@ app.registerExtension({
|
|
|
559
540
|
try {
|
|
560
541
|
// 确保有连接
|
|
561
542
|
// await getSocketAsync();
|
|
562
|
-
|
|
543
|
+
|
|
563
544
|
const graph = await app.graphToPrompt();
|
|
564
545
|
const clientId = sessionStorage.getItem("clientId");
|
|
546
|
+
await app.queuePrompt(graph.output);
|
|
565
547
|
const resPrompt = await fetch("api/prompt", {
|
|
566
548
|
method: "POST",
|
|
567
549
|
body: JSON.stringify({
|
|
@@ -577,8 +559,45 @@ app.registerExtension({
|
|
|
577
559
|
});
|
|
578
560
|
const resPromptJson = await resPrompt.json();
|
|
579
561
|
if (resPromptJson.error) {
|
|
580
|
-
|
|
562
|
+
this.openCustomError({
|
|
563
|
+
nodeId: resPromptJson.node_id,
|
|
564
|
+
nodeType: resPromptJson.node_type,
|
|
565
|
+
errorMessage: resPromptJson.error,
|
|
566
|
+
borderColor: '#FF0000'
|
|
567
|
+
})
|
|
568
|
+
return
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
for (const i in resPromptJson.node_errors) {
|
|
572
|
+
|
|
573
|
+
if (resPromptJson.node_errors[i].errors) {
|
|
574
|
+
const err = resPromptJson.node_errors[i].errors[0]
|
|
575
|
+
if (err) return
|
|
576
|
+
this.openCustomError({
|
|
577
|
+
nodeId: i,
|
|
578
|
+
nodeType: err.type,
|
|
579
|
+
errorMessage: err.error,
|
|
580
|
+
borderColor: '#FF0000'
|
|
581
|
+
})
|
|
582
|
+
return
|
|
583
|
+
} else {
|
|
584
|
+
console.log(resPromptJson.node_errors[i])
|
|
585
|
+
}
|
|
581
586
|
}
|
|
587
|
+
|
|
588
|
+
if (Object.keys(resPromptJson.node_errors).length) return
|
|
589
|
+
graph.workflow.nodes.forEach(node => {
|
|
590
|
+
for (const key in graph.output) {
|
|
591
|
+
if (graph.output[key].class_type === node.type) {
|
|
592
|
+
if (!graph.output[key]._meta) {
|
|
593
|
+
graph.output[key]._meta = {};
|
|
594
|
+
}
|
|
595
|
+
graph.output[key]._meta.id = node.id;
|
|
596
|
+
break; // 找到匹配的就跳出循环
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
console.log(graph.output)
|
|
582
601
|
window.parent.postMessage({
|
|
583
602
|
type: 'functionResult',
|
|
584
603
|
method: 'runWorkflow',
|
|
@@ -611,7 +630,8 @@ app.registerExtension({
|
|
|
611
630
|
}
|
|
612
631
|
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
|
613
632
|
};
|
|
614
|
-
console.log("-----------setCookie-----------", params)
|
|
633
|
+
// console.log("-----------setCookie-----------", params)
|
|
634
|
+
// console.log("-----------setCookie-----------", params)
|
|
615
635
|
setCookie(params.name, params.value, params.days);
|
|
616
636
|
|
|
617
637
|
|
|
@@ -675,11 +695,13 @@ app.registerExtension({
|
|
|
675
695
|
return graph.workflow;
|
|
676
696
|
},
|
|
677
697
|
|
|
678
|
-
graphToPrompt: async function () {
|
|
698
|
+
graphToPrompt: async function (params) {
|
|
699
|
+
console.log('postEvent.js - graphToPrompt被调用,参数:', params);
|
|
679
700
|
const graph = await app.graphToPrompt();
|
|
680
701
|
window.parent.postMessage({
|
|
681
702
|
type: 'functionResult',
|
|
682
703
|
method: 'graphToPrompt',
|
|
704
|
+
params: params, // 传递原始参数
|
|
683
705
|
result: {
|
|
684
706
|
workflow: graph.workflow,
|
|
685
707
|
output: graph.output
|
|
@@ -703,8 +725,204 @@ app.registerExtension({
|
|
|
703
725
|
}, '*');
|
|
704
726
|
return true;
|
|
705
727
|
},
|
|
728
|
+
|
|
729
|
+
// AI应用相关方法
|
|
730
|
+
toggleAIAppMode: function(params) {
|
|
731
|
+
const enable = params.enable === true;
|
|
732
|
+
const result = enable ? enableAIAppMode() : disableAIAppMode();
|
|
733
|
+
window.parent.postMessage({
|
|
734
|
+
type: 'functionResult',
|
|
735
|
+
method: 'toggleAIAppMode',
|
|
736
|
+
result: result
|
|
737
|
+
}, '*');
|
|
738
|
+
return result;
|
|
739
|
+
},
|
|
740
|
+
|
|
741
|
+
selectInputNode: function(params) {
|
|
742
|
+
if (!params.nodeId) return false;
|
|
743
|
+
const result = selectInputNode(params.nodeId);
|
|
744
|
+
window.parent.postMessage({
|
|
745
|
+
type: 'functionResult',
|
|
746
|
+
method: 'selectInputNode',
|
|
747
|
+
result: result
|
|
748
|
+
}, '*');
|
|
749
|
+
return result;
|
|
750
|
+
},
|
|
751
|
+
|
|
752
|
+
selectExportNode: function(params) {
|
|
753
|
+
if (!params.nodeId) return false;
|
|
754
|
+
const result = selectInputNode(params.nodeId);
|
|
755
|
+
window.parent.postMessage({
|
|
756
|
+
type: 'functionResult',
|
|
757
|
+
method: 'selectExportNode',
|
|
758
|
+
result: result
|
|
759
|
+
}, '*');
|
|
760
|
+
return result;
|
|
761
|
+
},
|
|
762
|
+
|
|
763
|
+
deselectInputNode: function(params) {
|
|
764
|
+
if (!params.nodeId) return false;
|
|
765
|
+
const result = deselectInputNode(params.nodeId);
|
|
766
|
+
window.parent.postMessage({
|
|
767
|
+
type: 'functionResult',
|
|
768
|
+
method: 'deselectInputNode',
|
|
769
|
+
result: result
|
|
770
|
+
}, '*');
|
|
771
|
+
return result;
|
|
772
|
+
},
|
|
773
|
+
|
|
774
|
+
updateInputNodeWidget: function(params) {
|
|
775
|
+
if (!params.nodeId || params.widgetName === undefined) return false;
|
|
776
|
+
const result = updateInputNodeWidget(params.nodeId, params.widgetName, params.value);
|
|
777
|
+
window.parent.postMessage({
|
|
778
|
+
type: 'functionResult',
|
|
779
|
+
method: 'updateInputNodeWidget',
|
|
780
|
+
result: result
|
|
781
|
+
}, '*');
|
|
782
|
+
return result;
|
|
783
|
+
},
|
|
784
|
+
|
|
785
|
+
getInputNodes: function() {
|
|
786
|
+
const result = getSelectedInputNodes();
|
|
787
|
+
window.parent.postMessage({
|
|
788
|
+
type: 'functionResult',
|
|
789
|
+
method: 'getInputNodes',
|
|
790
|
+
result: result
|
|
791
|
+
}, '*');
|
|
792
|
+
return result;
|
|
793
|
+
},
|
|
794
|
+
|
|
795
|
+
clearInputNodes: function() {
|
|
796
|
+
const result = clearSelectedInputNodes();
|
|
797
|
+
window.parent.postMessage({
|
|
798
|
+
type: 'functionResult',
|
|
799
|
+
method: 'clearInputNodes',
|
|
800
|
+
result: result
|
|
801
|
+
}, '*');
|
|
802
|
+
return result;
|
|
803
|
+
},
|
|
804
|
+
toggleExportMode: function(params) {
|
|
805
|
+
const result = toggleExportMode(params);
|
|
806
|
+
window.parent.postMessage({
|
|
807
|
+
type: 'functionResult',
|
|
808
|
+
method: 'toggleExportMode',
|
|
809
|
+
result: result
|
|
810
|
+
}, '*');
|
|
811
|
+
return result;
|
|
812
|
+
},
|
|
813
|
+
openCustomError: function (params) {
|
|
814
|
+
const { nodeId, nodeType, errorMessage, borderColor='#FF0000' } = params;
|
|
815
|
+
const nodeIds = Array.isArray(nodeId) ? nodeId : [nodeId];
|
|
816
|
+
function injectErrorDialogStyles() {
|
|
817
|
+
const styleId = 'custom-error-dialog-styles';
|
|
818
|
+
if (document.getElementById(styleId)) {
|
|
819
|
+
return; // 样式已经存在
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
const style = document.createElement('style');
|
|
823
|
+
style.id = styleId;
|
|
824
|
+
style.textContent = `
|
|
825
|
+
.comfy-error-report .no-results-placeholder p {
|
|
826
|
+
text-align: left;
|
|
827
|
+
}
|
|
828
|
+
`;
|
|
829
|
+
document.head.appendChild(style);
|
|
830
|
+
};
|
|
831
|
+
injectErrorDialogStyles()
|
|
832
|
+
function simulateExecutionError(nodeId, nodeType, errorMessage, borderColor) {
|
|
833
|
+
// const originalNodeErrorStyle = node.strokeStyles?.['nodeError']
|
|
834
|
+
const node = app.graph.getNodeById(nodeId)
|
|
835
|
+
if (!node) return
|
|
836
|
+
if (!customErrorStyles.has(nodeId)) {
|
|
837
|
+
customErrorStyles.set(nodeId, {
|
|
838
|
+
originalStyle: node.strokeStyles?.['nodeError'],
|
|
839
|
+
customColor: borderColor,
|
|
840
|
+
nodeId: nodeId
|
|
841
|
+
})
|
|
842
|
+
}
|
|
843
|
+
node.strokeStyles = node.strokeStyles || {}
|
|
844
|
+
node.strokeStyles['nodeError'] = function () {
|
|
845
|
+
// if (this.id === nodeId) {
|
|
846
|
+
return { color: borderColor, lineWidth: 2 } // 自定义颜色和线宽
|
|
847
|
+
// }
|
|
848
|
+
}
|
|
849
|
+
const mockErrorEvent = {
|
|
850
|
+
detail: {
|
|
851
|
+
node_id: nodeId,
|
|
852
|
+
node_type: nodeType,
|
|
853
|
+
exception_message: errorMessage,
|
|
854
|
+
exception_type: 'ManualError',
|
|
855
|
+
traceback: ['Manual error triggered'],
|
|
856
|
+
executed: [],
|
|
857
|
+
prompt_id: 'manual',
|
|
858
|
+
timestamp: Date.now()
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// 手动触发事件监听器
|
|
863
|
+
app.api.dispatchCustomEvent('execution_error', mockErrorEvent.detail)
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
nodeIds.forEach(id => {
|
|
867
|
+
simulateExecutionError(id, nodeType, errorMessage, borderColor)
|
|
868
|
+
})
|
|
869
|
+
|
|
870
|
+
app.canvas.draw(true, true)
|
|
871
|
+
window.parent.postMessage({
|
|
872
|
+
type: 'functionResult',
|
|
873
|
+
method: 'openCustomError',
|
|
874
|
+
result: true
|
|
875
|
+
}, '*');
|
|
876
|
+
},
|
|
877
|
+
clearAllCustomStyles: function () {
|
|
878
|
+
customErrorStyles.forEach((styleInfo, nodeId) => {
|
|
879
|
+
const node = app.graph.getNodeById(nodeId)
|
|
880
|
+
if (!node) return
|
|
881
|
+
console.log(node)
|
|
882
|
+
// 恢复原始样式
|
|
883
|
+
if (styleInfo.originalStyle) {
|
|
884
|
+
node.strokeStyles['nodeError'] = styleInfo.originalStyle
|
|
885
|
+
} else {
|
|
886
|
+
delete node.strokeStyles['nodeError']
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
// 从映射中移除
|
|
890
|
+
customErrorStyles.delete(nodeId)
|
|
891
|
+
})
|
|
892
|
+
|
|
893
|
+
// 重绘画布
|
|
894
|
+
app.canvas.draw(true, true)
|
|
895
|
+
},
|
|
896
|
+
focusNodeOnly: function(params) {
|
|
897
|
+
if (!params.nodeId) return false;
|
|
898
|
+
const result = focusNodeOnly(params.nodeId);
|
|
899
|
+
window.parent.postMessage({
|
|
900
|
+
type: 'functionResult',
|
|
901
|
+
method: 'focusNodeOnly',
|
|
902
|
+
result: result
|
|
903
|
+
}, '*');
|
|
904
|
+
return result;
|
|
905
|
+
},
|
|
706
906
|
};
|
|
707
907
|
|
|
908
|
+
methods.deselectExportNode = function(params) {
|
|
909
|
+
if (params && params.nodeId !== undefined) {
|
|
910
|
+
if (typeof window.deselectInputNode === 'function') {
|
|
911
|
+
window.deselectInputNode(params.nodeId);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
methods.clearExportNodes = function() {
|
|
916
|
+
if (typeof window.clearExportNodes === 'function') {
|
|
917
|
+
window.clearExportNodes();
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
// 保存工作流的原始节点颜色信息
|
|
921
|
+
methods.saveOriginalNodeColors = function(params) {
|
|
922
|
+
if (typeof window.saveOriginalNodeColors === 'function') {
|
|
923
|
+
window.saveOriginalNodeColors(params.workflowId);
|
|
924
|
+
}
|
|
925
|
+
};
|
|
708
926
|
window.addEventListener('message', function (event) {
|
|
709
927
|
if (event.data && event.data.type === 'callMethod') {
|
|
710
928
|
const methodName = event.data.method;
|
|
@@ -732,5 +950,17 @@ app.registerExtension({
|
|
|
732
950
|
}
|
|
733
951
|
});
|
|
734
952
|
window.parent.postMessage({ type: 'iframeReady' }, '*');
|
|
953
|
+
app.api.addEventListener('graphChanged', (e) => {
|
|
954
|
+
console.log('Graph 发生变化,当前 workflow JSON:', e.detail)
|
|
955
|
+
window.parent.postMessage({
|
|
956
|
+
type: 'functionResult',
|
|
957
|
+
method: 'workflowChanged',
|
|
958
|
+
result: e.detail
|
|
959
|
+
}, '*');
|
|
960
|
+
|
|
961
|
+
document.dispatchEvent(new CustomEvent('workflowLoaded', {
|
|
962
|
+
detail: e.detail
|
|
963
|
+
}));
|
|
964
|
+
})
|
|
735
965
|
}
|
|
736
966
|
});
|