bizydraft 0.2.31__py3-none-any.whl → 0.2.78.dev20251117024007__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.
- bizydraft/env.py +3 -0
- bizydraft/hijack_nodes.py +62 -23
- bizydraft/hijack_routes.py +8 -2
- bizydraft/oss_utils.py +223 -2
- bizydraft/patch_handlers.py +197 -8
- bizydraft/static/js/aiAppHandler.js +11 -12
- bizydraft/static/js/clipspaceToOss.js +316 -0
- bizydraft/static/js/disableComfyWebSocket.js +65 -0
- bizydraft/static/js/freezeModeHandler.js +23 -0
- bizydraft/static/js/handleStyle.js +73 -0
- bizydraft/static/js/hookLoad/configLoader.js +68 -0
- bizydraft/static/js/hookLoad/media.js +498 -0
- bizydraft/static/js/hookLoad/model.js +278 -0
- bizydraft/static/js/hookLoadMedia.js +159 -0
- bizydraft/static/js/hookLoadModel.js +159 -198
- bizydraft/static/js/main.js +3 -1
- bizydraft/static/js/postEvent.js +292 -168
- bizydraft/static/js/tool.js +4 -1
- bizydraft/static/js/workflow_io.js +193 -0
- {bizydraft-0.2.31.dist-info → bizydraft-0.2.78.dev20251117024007.dist-info}/METADATA +1 -1
- bizydraft-0.2.78.dev20251117024007.dist-info/RECORD +34 -0
- bizydraft/static/js/hookLoadImage.js +0 -173
- bizydraft-0.2.31.dist-info/RECORD +0 -28
- {bizydraft-0.2.31.dist-info → bizydraft-0.2.78.dev20251117024007.dist-info}/WHEEL +0 -0
- {bizydraft-0.2.31.dist-info → bizydraft-0.2.78.dev20251117024007.dist-info}/top_level.txt +0 -0
bizydraft/static/js/postEvent.js
CHANGED
|
@@ -21,47 +21,77 @@ app.registerExtension({
|
|
|
21
21
|
pingTimeoutTimer: null, // ping超时计时器
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* 为特定socket开始心跳检测(每个socket独立的心跳)
|
|
25
25
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
26
|
+
startPingForSocket(socket) {
|
|
27
|
+
if (!socket || socket.readyState !== WebSocket.OPEN) {
|
|
30
28
|
return;
|
|
31
29
|
}
|
|
32
30
|
|
|
31
|
+
// 在socket对象上存储心跳状态
|
|
32
|
+
socket.pongReceived = false;
|
|
33
33
|
// 立即发送一次ping消息
|
|
34
|
-
|
|
35
|
-
this.socket.send('ping');
|
|
34
|
+
socket.send('ping');
|
|
36
35
|
|
|
37
36
|
// 设置ping超时检测
|
|
38
|
-
|
|
39
|
-
if (!
|
|
40
|
-
|
|
41
|
-
this.
|
|
37
|
+
socket.pingTimeoutTimer = setTimeout(() => {
|
|
38
|
+
if (!socket.pongReceived && socket.readyState === WebSocket.OPEN) {
|
|
39
|
+
console.log('心跳检测超时,关闭此连接');
|
|
40
|
+
this.stopPingForSocket(socket);
|
|
41
|
+
socket.close();
|
|
42
42
|
}
|
|
43
43
|
}, this.pingTimeout);
|
|
44
44
|
|
|
45
45
|
// 设置定时发送ping
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
socket.pingTimer = setInterval(() => {
|
|
47
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
48
|
+
socket.pongReceived = false;
|
|
49
|
+
socket.send('ping');
|
|
50
50
|
// 设置ping超时检测
|
|
51
|
-
|
|
51
|
+
socket.pingTimeoutTimer = setTimeout(() => {
|
|
52
52
|
// 如果没有收到pong响应
|
|
53
|
-
if (!
|
|
54
|
-
console.log('
|
|
55
|
-
this.
|
|
56
|
-
|
|
53
|
+
if (!socket.pongReceived) {
|
|
54
|
+
console.log('心跳检测超时,关闭此连接');
|
|
55
|
+
this.stopPingForSocket(socket);
|
|
56
|
+
socket.close();
|
|
57
57
|
}
|
|
58
58
|
}, this.pingTimeout);
|
|
59
59
|
} else {
|
|
60
|
-
this.
|
|
60
|
+
this.stopPingForSocket(socket);
|
|
61
61
|
}
|
|
62
62
|
}, this.pingInterval);
|
|
63
63
|
},
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* 停止特定socket的心跳检测
|
|
67
|
+
*/
|
|
68
|
+
stopPingForSocket(socket) {
|
|
69
|
+
if (!socket) return;
|
|
70
|
+
|
|
71
|
+
if (socket.pingTimer) {
|
|
72
|
+
clearInterval(socket.pingTimer);
|
|
73
|
+
socket.pingTimer = null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (socket.pingTimeoutTimer) {
|
|
77
|
+
clearTimeout(socket.pingTimeoutTimer);
|
|
78
|
+
socket.pingTimeoutTimer = null;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 开始心跳检测(保留向后兼容)
|
|
84
|
+
*/
|
|
85
|
+
startPing() {
|
|
86
|
+
this.stopPing();
|
|
87
|
+
|
|
88
|
+
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// 使用新的socket专用心跳方法
|
|
92
|
+
this.startPingForSocket(this.socket);
|
|
93
|
+
},
|
|
94
|
+
|
|
65
95
|
/**
|
|
66
96
|
* 停止心跳检测
|
|
67
97
|
*/
|
|
@@ -102,8 +132,6 @@ app.registerExtension({
|
|
|
102
132
|
// 标记为连接中
|
|
103
133
|
this.isConnecting = true;
|
|
104
134
|
|
|
105
|
-
// 先关闭现有连接
|
|
106
|
-
this.closeSocket();
|
|
107
135
|
|
|
108
136
|
const url = customUrl || app.api.socket.url;
|
|
109
137
|
console.log('创建WebSocket连接:', url);
|
|
@@ -117,172 +145,219 @@ app.registerExtension({
|
|
|
117
145
|
console.log('WebSocket连接已打开');
|
|
118
146
|
// 清除连接中标志
|
|
119
147
|
self.isConnecting = false;
|
|
120
|
-
//
|
|
148
|
+
// 存储为单例(最新的连接)
|
|
121
149
|
self.socket = socket;
|
|
122
150
|
// 替换app.api.socket
|
|
123
151
|
app.api.socket = socket;
|
|
124
|
-
//
|
|
125
|
-
self.
|
|
152
|
+
// 为这个socket启动独立的心跳检测
|
|
153
|
+
self.startPingForSocket(socket);
|
|
126
154
|
};
|
|
127
155
|
|
|
128
156
|
socket.onmessage = function (event) {
|
|
129
157
|
try {
|
|
158
|
+
// 从 WebSocket URL 中提取 taskId
|
|
159
|
+
let taskIdFromUrl = null;
|
|
160
|
+
try {
|
|
161
|
+
const urlParams = new URLSearchParams(socket.url.split('?')[1]);
|
|
162
|
+
taskIdFromUrl = urlParams.get('taskId');
|
|
163
|
+
if (taskIdFromUrl) {
|
|
164
|
+
taskIdFromUrl = parseInt(taskIdFromUrl, 10);
|
|
165
|
+
}
|
|
166
|
+
console.log('taskIdFromUrl:', taskIdFromUrl);
|
|
167
|
+
} catch (e) {
|
|
168
|
+
console.warn('无法从 WebSocket URL 中提取 taskId:', e);
|
|
169
|
+
}
|
|
130
170
|
// 处理心跳响应
|
|
131
171
|
if (event.data === 'pong') {
|
|
132
|
-
//
|
|
133
|
-
|
|
172
|
+
// 标记此socket收到pong响应
|
|
173
|
+
socket.pongReceived = true;
|
|
134
174
|
return;
|
|
135
175
|
}
|
|
136
176
|
if (event.data instanceof ArrayBuffer) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
177
|
+
const view = new DataView(event.data)
|
|
178
|
+
const eventType = view.getUint32(0)
|
|
179
|
+
|
|
180
|
+
let imageMime
|
|
181
|
+
switch (eventType) {
|
|
182
|
+
case 3:
|
|
183
|
+
const decoder = new TextDecoder()
|
|
184
|
+
const data = event.data.slice(4)
|
|
185
|
+
const nodeIdLength = view.getUint32(4)
|
|
186
|
+
dispatchCustomEvent('progress_text', {
|
|
187
|
+
nodeId: decoder.decode(data.slice(4, 4 + nodeIdLength)),
|
|
188
|
+
text: decoder.decode(data.slice(4 + nodeIdLength))
|
|
189
|
+
})
|
|
190
|
+
break
|
|
191
|
+
case 1:
|
|
192
|
+
const imageType = view.getUint32(4)
|
|
193
|
+
const imageData = event.data.slice(8)
|
|
194
|
+
switch (imageType) {
|
|
195
|
+
case 2:
|
|
196
|
+
imageMime = 'image/png'
|
|
197
|
+
break
|
|
151
198
|
case 1:
|
|
152
|
-
const imageType = view.getUint32(4);
|
|
153
|
-
const imageData = event.data.slice(8);
|
|
154
|
-
switch (imageType) {
|
|
155
|
-
case 2:
|
|
156
|
-
imageMime = 'image/png';
|
|
157
|
-
break;
|
|
158
|
-
case 1:
|
|
159
|
-
default:
|
|
160
|
-
imageMime = 'image/jpeg';
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
const imageBlob = new Blob([imageData], {
|
|
164
|
-
type: imageMime
|
|
165
|
-
});
|
|
166
|
-
dispatchCustomEvent('b_preview', imageBlob);
|
|
167
|
-
break;
|
|
168
199
|
default:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
200
|
+
imageMime = 'image/jpeg'
|
|
201
|
+
break
|
|
202
|
+
}
|
|
203
|
+
const imageBlob = new Blob([imageData], {
|
|
204
|
+
type: imageMime
|
|
205
|
+
})
|
|
206
|
+
dispatchCustomEvent('b_preview', imageBlob)
|
|
207
|
+
break
|
|
208
|
+
case 4:
|
|
209
|
+
// PREVIEW_IMAGE_WITH_METADATA
|
|
210
|
+
const decoder4 = new TextDecoder()
|
|
211
|
+
const metadataLength = view.getUint32(4)
|
|
212
|
+
const metadataBytes = event.data.slice(8, 8 + metadataLength)
|
|
213
|
+
const metadata = JSON.parse(decoder4.decode(metadataBytes))
|
|
214
|
+
const imageData4 = event.data.slice(8 + metadataLength)
|
|
215
|
+
|
|
216
|
+
let imageMime4 = metadata.image_type
|
|
217
|
+
|
|
218
|
+
const imageBlob4 = new Blob([imageData4], {
|
|
219
|
+
type: imageMime4
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
// Dispatch enhanced preview event with metadata
|
|
223
|
+
dispatchCustomEvent('b_preview_with_metadata', {
|
|
224
|
+
blob: imageBlob4,
|
|
225
|
+
nodeId: metadata.node_id,
|
|
226
|
+
displayNodeId: metadata.display_node_id,
|
|
227
|
+
parentNodeId: metadata.parent_node_id,
|
|
228
|
+
realNodeId: metadata.real_node_id,
|
|
229
|
+
promptId: metadata.prompt_id
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
// Also dispatch legacy b_preview for backward compatibility
|
|
233
|
+
dispatchCustomEvent('b_preview', imageBlob4)
|
|
234
|
+
break
|
|
235
|
+
default:
|
|
236
|
+
throw new Error(
|
|
237
|
+
`Unknown binary websocket message of type ${eventType}`
|
|
238
|
+
)
|
|
239
|
+
}
|
|
173
240
|
} else {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
241
|
+
// 检测[DONE]消息
|
|
242
|
+
if (event.data === '[DONE]') {
|
|
243
|
+
console.log('收到[DONE]消息,任务已完成,停止心跳并关闭连接');
|
|
244
|
+
self.taskRunning = false;
|
|
245
|
+
self.stopPingForSocket(socket);
|
|
246
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
247
|
+
socket.close(1000);
|
|
248
|
+
}
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const msg = JSON.parse(event.data)
|
|
252
|
+
// 发送进度信息,添加从 URL 中提取的 taskId
|
|
253
|
+
if (msg.progress_info) {
|
|
254
|
+
const progressData = { ...msg.progress_info };
|
|
255
|
+
if (taskIdFromUrl && !progressData.task_id) {
|
|
256
|
+
progressData.task_id = taskIdFromUrl;
|
|
257
|
+
}
|
|
258
|
+
window.parent.postMessage({
|
|
259
|
+
type: 'functionResult',
|
|
260
|
+
method: 'progress_info_change',
|
|
261
|
+
result: progressData
|
|
262
|
+
}, '*');
|
|
181
263
|
}
|
|
182
264
|
|
|
183
|
-
|
|
184
|
-
|
|
265
|
+
switch (msg.type) {
|
|
266
|
+
case 'load_start':
|
|
267
|
+
case 'load_end':
|
|
268
|
+
case 'prompt_id':
|
|
269
|
+
// 发送准备状态信息,添加从 URL 中提取的 taskId
|
|
270
|
+
const preparingData = { ...msg };
|
|
271
|
+
if (taskIdFromUrl) {
|
|
272
|
+
preparingData.task_id = taskIdFromUrl;
|
|
273
|
+
console.log(`🔗 [WebSocket] 添加 task_id=${taskIdFromUrl} 到 ${msg.type} 消息`);
|
|
274
|
+
}
|
|
275
|
+
window.parent.postMessage({
|
|
185
276
|
type: 'functionResult',
|
|
186
|
-
method: '
|
|
187
|
-
result:
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
277
|
+
method: 'preparingStatus',
|
|
278
|
+
result: preparingData
|
|
279
|
+
}, '*')
|
|
280
|
+
break
|
|
281
|
+
case 'status':
|
|
282
|
+
if (msg.data.sid) {
|
|
283
|
+
const clientId = msg.data.sid
|
|
284
|
+
window.name = clientId // use window name so it isnt reused when duplicating tabs
|
|
285
|
+
sessionStorage.setItem('clientId', clientId) // store in session storage so duplicate tab can load correct workflow
|
|
286
|
+
}
|
|
287
|
+
dispatchCustomEvent('status', msg.data.status ?? null)
|
|
288
|
+
break
|
|
289
|
+
case 'executing':
|
|
290
|
+
dispatchCustomEvent(
|
|
291
|
+
'executing',
|
|
292
|
+
msg.data.display_node || msg.data.node
|
|
293
|
+
)
|
|
294
|
+
break
|
|
295
|
+
case 'execution_start':
|
|
296
|
+
case 'execution_error':
|
|
297
|
+
case 'execution_interrupted':
|
|
298
|
+
case 'execution_cached':
|
|
299
|
+
case 'execution_success':
|
|
300
|
+
case 'progress':
|
|
301
|
+
case 'progress_state':
|
|
302
|
+
case 'executed':
|
|
303
|
+
case 'graphChanged':
|
|
304
|
+
case 'promptQueued':
|
|
305
|
+
case 'logs':
|
|
306
|
+
case 'b_preview':
|
|
307
|
+
if (msg.data.balance_not_enough) {
|
|
308
|
+
window.parent.postMessage({
|
|
309
|
+
type: "functionResult",
|
|
310
|
+
method: "balanceNotEnough",
|
|
311
|
+
result: true,
|
|
312
|
+
}, "*");
|
|
313
|
+
}
|
|
314
|
+
dispatchCustomEvent(msg.type, msg.data)
|
|
315
|
+
break
|
|
316
|
+
case 'feature_flags':
|
|
317
|
+
// Store server feature flags
|
|
318
|
+
this.serverFeatureFlags = msg.data
|
|
319
|
+
console.log(
|
|
320
|
+
'Server feature flags received:',
|
|
321
|
+
this.serverFeatureFlags
|
|
322
|
+
)
|
|
323
|
+
break
|
|
324
|
+
default:
|
|
325
|
+
const registeredTypes = socket.registeredTypes || new Set();
|
|
326
|
+
const reportedUnknownMessageTypes = socket.reportedUnknownMessageTypes || new Set();
|
|
327
|
+
|
|
328
|
+
if (registeredTypes.has(msg.type)) {
|
|
329
|
+
app.dispatchEvent(
|
|
330
|
+
new CustomEvent(msg.type, { detail: msg.data })
|
|
211
331
|
);
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
self.taskRunning = false;
|
|
218
|
-
}
|
|
219
|
-
dispatchCustomEvent(msg.type, msg.data);
|
|
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;
|
|
232
|
-
case 'execution_error':
|
|
233
|
-
case 'execution_interrupted':
|
|
234
|
-
self.taskRunning = false;
|
|
235
|
-
dispatchCustomEvent(msg.type, msg.data);
|
|
236
|
-
break;
|
|
237
|
-
case 'execution_start':
|
|
238
|
-
self.taskRunning = true;
|
|
239
|
-
dispatchCustomEvent(msg.type, msg.data);
|
|
240
|
-
break;
|
|
241
|
-
case 'progress':
|
|
242
|
-
case 'executed':
|
|
243
|
-
case 'graphChanged':
|
|
244
|
-
case 'promptQueued':
|
|
245
|
-
case 'logs':
|
|
246
|
-
case 'b_preview':
|
|
247
|
-
dispatchCustomEvent(msg.type, msg.data);
|
|
248
|
-
break;
|
|
249
|
-
default:
|
|
250
|
-
const registeredTypes = socket.registeredTypes || new Set();
|
|
251
|
-
const reportedUnknownMessageTypes = socket.reportedUnknownMessageTypes || new Set();
|
|
252
|
-
|
|
253
|
-
if (registeredTypes.has(msg.type)) {
|
|
254
|
-
app.dispatchEvent(
|
|
255
|
-
new CustomEvent(msg.type, { detail: msg.data })
|
|
256
|
-
);
|
|
257
|
-
} else if (!reportedUnknownMessageTypes.has(msg.type)) {
|
|
258
|
-
reportedUnknownMessageTypes.add(msg.type);
|
|
259
|
-
console.warn(`Unknown message type ${msg.type}`);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
332
|
+
} else if (!reportedUnknownMessageTypes.has(msg.type)) {
|
|
333
|
+
reportedUnknownMessageTypes.add(msg.type);
|
|
334
|
+
console.warn(`Unknown message type ${msg.type}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
262
337
|
}
|
|
263
|
-
|
|
264
|
-
console.warn('Unhandled message:', event.data, error)
|
|
265
|
-
|
|
338
|
+
} catch (error) {
|
|
339
|
+
console.warn('Unhandled message:', event.data, error)
|
|
340
|
+
}
|
|
266
341
|
};
|
|
267
342
|
|
|
268
343
|
socket.onerror = function(error) {
|
|
269
344
|
console.log('WebSocket 错误:', error);
|
|
270
345
|
// 清除连接中标志
|
|
271
346
|
self.isConnecting = false;
|
|
272
|
-
//
|
|
273
|
-
self.
|
|
347
|
+
// 停止此socket的心跳检测
|
|
348
|
+
self.stopPingForSocket(socket);
|
|
274
349
|
};
|
|
275
350
|
|
|
276
351
|
socket.onclose = function(event) {
|
|
277
352
|
console.log('WebSocket 连接已关闭, 状态码:', event.code, event.reason);
|
|
278
353
|
// 清除连接中标志
|
|
279
354
|
self.isConnecting = false;
|
|
280
|
-
//
|
|
355
|
+
// 停止此socket的心跳检测
|
|
356
|
+
self.stopPingForSocket(socket);
|
|
357
|
+
// 清理单例引用(如果这是当前活跃的socket)
|
|
281
358
|
if (self.socket === socket) {
|
|
282
359
|
self.socket = null;
|
|
283
360
|
}
|
|
284
|
-
// 停止心跳
|
|
285
|
-
self.stopPing();
|
|
286
361
|
};
|
|
287
362
|
|
|
288
363
|
socket.registeredTypes = new Set();
|
|
@@ -435,7 +510,9 @@ app.registerExtension({
|
|
|
435
510
|
|
|
436
511
|
const customErrorStyles = new Map()
|
|
437
512
|
|
|
438
|
-
|
|
513
|
+
// 用于节流的时间戳
|
|
514
|
+
let lastRunWorkflowTime = 0;
|
|
515
|
+
const THROTTLE_TIME = 2000; // 2秒
|
|
439
516
|
|
|
440
517
|
// 方法映射
|
|
441
518
|
const methods = {
|
|
@@ -505,9 +582,31 @@ app.registerExtension({
|
|
|
505
582
|
}, '*');
|
|
506
583
|
return graph.workflow;
|
|
507
584
|
},
|
|
585
|
+
getWorkflowNotSave: async function () {
|
|
586
|
+
const graph = await app.graphToPrompt();
|
|
587
|
+
// 规范化工作流,移除不影响逻辑的视觉字段,避免颜色等样式变化影响校验
|
|
588
|
+
const normalizeWorkflow = (workflow) => {
|
|
589
|
+
const json = JSON.stringify(workflow, (key, value) => {
|
|
590
|
+
if (key === 'color' || key === 'bgcolor' || key === 'extra') return undefined;
|
|
591
|
+
return value;
|
|
592
|
+
});
|
|
593
|
+
return JSON.parse(json);
|
|
594
|
+
};
|
|
595
|
+
const normalized = normalizeWorkflow(graph.workflow);
|
|
596
|
+
window.parent.postMessage({
|
|
597
|
+
type: 'functionResult',
|
|
598
|
+
method: 'getWorkflowNotSave',
|
|
599
|
+
result: normalized
|
|
600
|
+
}, '*');
|
|
601
|
+
return normalized;
|
|
602
|
+
},
|
|
508
603
|
// 新增:获取 workflow 和 output
|
|
509
604
|
getWorkflowWithOutput: async function () {
|
|
510
605
|
const graph = await app.graphToPrompt();
|
|
606
|
+
for (const key in graph.output) {
|
|
607
|
+
graph.output[key]._meta.id = Number(key);
|
|
608
|
+
graph.output[key]._meta.class_type =graph.output[key].class_type
|
|
609
|
+
}
|
|
511
610
|
window.parent.postMessage({
|
|
512
611
|
type: 'functionResult',
|
|
513
612
|
method: 'getWorkflowWithOutput',
|
|
@@ -558,7 +657,7 @@ app.registerExtension({
|
|
|
558
657
|
})
|
|
559
658
|
});
|
|
560
659
|
const resPromptJson = await resPrompt.json();
|
|
561
|
-
if (resPromptJson.error) {
|
|
660
|
+
if (resPromptJson.error && resPromptJson.node_id) {
|
|
562
661
|
this.openCustomError({
|
|
563
662
|
nodeId: resPromptJson.node_id,
|
|
564
663
|
nodeType: resPromptJson.node_type,
|
|
@@ -587,18 +686,10 @@ app.registerExtension({
|
|
|
587
686
|
}
|
|
588
687
|
|
|
589
688
|
if (Object.keys(resPromptJson.node_errors).length) return
|
|
590
|
-
graph.
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
graph.output[key]._meta = {};
|
|
595
|
-
}
|
|
596
|
-
graph.output[key]._meta.id = node.id;
|
|
597
|
-
break; // 找到匹配的就跳出循环
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
});
|
|
601
|
-
|
|
689
|
+
for (const key in graph.output) {
|
|
690
|
+
graph.output[key]._meta.id = Number(key);
|
|
691
|
+
graph.output[key]._meta.class_type = graph.output[key].class_type;
|
|
692
|
+
}
|
|
602
693
|
for (let i in graph.output) {
|
|
603
694
|
if (graph.output[i].class_type == 'LoadImage') {
|
|
604
695
|
graph.output[i].inputs.image = graph.output[i].inputs.image.replace('pasted/http', 'http')
|
|
@@ -644,6 +735,11 @@ app.registerExtension({
|
|
|
644
735
|
|
|
645
736
|
return true;
|
|
646
737
|
},
|
|
738
|
+
removeCookie: function (params) {
|
|
739
|
+
const expires = new Date(0).toUTCString();
|
|
740
|
+
document.cookie = params.name + "=; expires=" + expires + "; path=/";
|
|
741
|
+
return true;
|
|
742
|
+
},
|
|
647
743
|
fitView: function () {
|
|
648
744
|
app.canvas.fitViewToSelectionAnimated()
|
|
649
745
|
window.parent.postMessage({
|
|
@@ -938,6 +1034,33 @@ app.registerExtension({
|
|
|
938
1034
|
window.saveOriginalNodeColors(params.workflowId);
|
|
939
1035
|
}
|
|
940
1036
|
};
|
|
1037
|
+
|
|
1038
|
+
// 监听 Ctrl+Enter 快捷键执行工作流
|
|
1039
|
+
document.addEventListener('keydown', (event) => {
|
|
1040
|
+
if (event.ctrlKey && event.key === 'Enter') {
|
|
1041
|
+
event.preventDefault();
|
|
1042
|
+
|
|
1043
|
+
// 节流:检查距离上次执行是否已经过了2秒
|
|
1044
|
+
const now = Date.now();
|
|
1045
|
+
if (now - lastRunWorkflowTime < THROTTLE_TIME) {
|
|
1046
|
+
console.log('触发频率过高,请稍后再试');
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
// 更新上次执行时间
|
|
1051
|
+
lastRunWorkflowTime = now;
|
|
1052
|
+
|
|
1053
|
+
if (methods.runWorkflow) {
|
|
1054
|
+
window.parent.postMessage({
|
|
1055
|
+
type: 'functionResult',
|
|
1056
|
+
method: 'ctrlEnter',
|
|
1057
|
+
result: true
|
|
1058
|
+
}, '*');
|
|
1059
|
+
methods.runWorkflow();
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
|
|
941
1064
|
window.addEventListener('message', function (event) {
|
|
942
1065
|
if (event.data && event.data.type === 'callMethod') {
|
|
943
1066
|
const methodName = event.data.method;
|
|
@@ -977,5 +1100,6 @@ app.registerExtension({
|
|
|
977
1100
|
detail: e.detail
|
|
978
1101
|
}));
|
|
979
1102
|
})
|
|
1103
|
+
|
|
980
1104
|
}
|
|
981
1105
|
});
|
bizydraft/static/js/tool.js
CHANGED
|
@@ -4,7 +4,8 @@ const loadNodeList = [
|
|
|
4
4
|
'LoadAudio',
|
|
5
5
|
'LoadVideo',
|
|
6
6
|
'Load3D',
|
|
7
|
-
'VHS_LoadVideo'
|
|
7
|
+
'VHS_LoadVideo',
|
|
8
|
+
'VHS_LoadAudioUpload'
|
|
8
9
|
]
|
|
9
10
|
const extMap = {
|
|
10
11
|
'LoadImage': '.png,.jpg,.jpeg,.webp,.gif,.svg,.ico,.bmp,.tiff,.tif,.heic,.heif',
|
|
@@ -12,6 +13,8 @@ const extMap = {
|
|
|
12
13
|
'LoadAudio': '.mp3,.wav,.ogg,.m4a,.aac,.flac,.wma,.m4r',
|
|
13
14
|
'LoadVideo': '.mp4,.mov,.avi,.mkv,.webm,.flv,.wmv,.m4v',
|
|
14
15
|
'Load3D': '.glb,.gltf,.fbx,.obj,.dae,.ply,.stl',
|
|
16
|
+
'VHS_LoadAudioUpload': '.mp3,.wav,.ogg,.m4a,.aac,.flac,.wma,.m4r',
|
|
17
|
+
"VHS_LoadVideo": '.mp4,.mov,.avi,.mkv,.webm,.flv,.wmv,.m4v',
|
|
15
18
|
}
|
|
16
19
|
export function getCookie(name) {
|
|
17
20
|
const value = `; ${document.cookie}`;
|