Enhance Lora code update handling for browser and desktop modes. Implement broadcast support for Lora Loader nodes and improve node ID management in the workflow.

This commit is contained in:
Will Miao
2025-05-30 20:12:38 +08:00
parent 0eaef7e7a0
commit 37de26ce25
3 changed files with 85 additions and 31 deletions

View File

@@ -818,7 +818,7 @@ class MiscRoutes:
Expects a JSON body with: Expects a JSON body with:
{ {
"node_ids": [123, 456], # List of node IDs to update "node_ids": [123, 456], # Optional - List of node IDs to update (for browser mode)
"lora_code": "<lora:modelname:1.0>", # The Lora code to send "lora_code": "<lora:modelname:1.0>", # The Lora code to send
"mode": "append" # or "replace" - whether to append or replace existing code "mode": "append" # or "replace" - whether to append or replace existing code
} }
@@ -826,37 +826,59 @@ class MiscRoutes:
try: try:
# Parse the request body # Parse the request body
data = await request.json() data = await request.json()
node_ids = data.get('node_ids', []) node_ids = data.get('node_ids')
lora_code = data.get('lora_code', '') lora_code = data.get('lora_code', '')
mode = data.get('mode', 'append') mode = data.get('mode', 'append')
if not node_ids or not lora_code: if not lora_code:
return web.json_response({ return web.json_response({
'success': False, 'success': False,
'error': 'Missing node_ids or lora_code parameter' 'error': 'Missing lora_code parameter'
}, status=400) }, status=400)
# Send the lora code update to each node
results = [] results = []
for node_id in node_ids:
# Desktop mode: no specific node_ids provided
if node_ids is None:
try: try:
# Send the message to the frontend # Send broadcast message with id=-1 to all Lora Loader nodes
PromptServer.instance.send_sync("lora_code_update", { PromptServer.instance.send_sync("lora_code_update", {
"id": node_id, "id": -1,
"lora_code": lora_code, "lora_code": lora_code,
"mode": mode "mode": mode
}) })
results.append({ results.append({
'node_id': node_id, 'node_id': 'broadcast',
'success': True 'success': True
}) })
except Exception as e: except Exception as e:
logger.error(f"Error sending lora code to node {node_id}: {e}") logger.error(f"Error broadcasting lora code: {e}")
results.append({ results.append({
'node_id': node_id, 'node_id': 'broadcast',
'success': False, 'success': False,
'error': str(e) 'error': str(e)
}) })
else:
# Browser mode: send to specific nodes
for node_id in node_ids:
try:
# Send the message to the frontend
PromptServer.instance.send_sync("lora_code_update", {
"id": node_id,
"lora_code": lora_code,
"mode": mode
})
results.append({
'node_id': node_id,
'success': True
})
except Exception as e:
logger.error(f"Error sending lora code to node {node_id}: {e}")
results.append({
'node_id': node_id,
'success': False,
'error': str(e)
})
return web.json_response({ return web.json_response({
'success': True, 'success': True,

View File

@@ -362,29 +362,31 @@ export function getNSFWLevelName(level) {
*/ */
export async function sendLoraToWorkflow(loraSyntax, replaceMode = false, syntaxType = 'lora') { export async function sendLoraToWorkflow(loraSyntax, replaceMode = false, syntaxType = 'lora') {
try { try {
let loraNodes = [];
let isDesktopMode = false;
// Get the current workflow from localStorage // Get the current workflow from localStorage
const workflowData = localStorage.getItem('workflow'); const workflowData = localStorage.getItem('workflow');
if (!workflowData) { if (workflowData) {
showToast('No active workflow found', 'error'); // Web browser mode - extract node IDs from workflow
return false; const workflow = JSON.parse(workflowData);
}
// Find all Lora Loader (LoraManager) nodes
// Parse the workflow JSON if (workflow.nodes && Array.isArray(workflow.nodes)) {
const workflow = JSON.parse(workflowData); for (const node of workflow.nodes) {
if (node.type === "Lora Loader (LoraManager)") {
// Find all Lora Loader (LoraManager) nodes loraNodes.push(node.id);
const loraNodes = []; }
if (workflow.nodes && Array.isArray(workflow.nodes)) {
for (const node of workflow.nodes) {
if (node.type === "Lora Loader (LoraManager)") {
loraNodes.push(node.id);
} }
} }
}
if (loraNodes.length === 0) {
if (loraNodes.length === 0) { showToast('No Lora Loader nodes found in the workflow', 'warning');
showToast('No Lora Loader nodes found in the workflow', 'warning'); return false;
return false; }
} else {
// ComfyUI Desktop mode - don't specify node IDs and let backend handle it
isDesktopMode = true;
} }
// Call the backend API to update the lora code // Call the backend API to update the lora code
@@ -394,7 +396,7 @@ export async function sendLoraToWorkflow(loraSyntax, replaceMode = false, syntax
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify({ body: JSON.stringify({
node_ids: loraNodes, node_ids: isDesktopMode ? undefined : loraNodes,
lora_code: loraSyntax, lora_code: loraSyntax,
mode: replaceMode ? 'replace' : 'append' mode: replaceMode ? 'replace' : 'append'
}) })

View File

@@ -49,12 +49,42 @@ app.registerExtension({
// Handle lora code updates from Python // Handle lora code updates from Python
handleLoraCodeUpdate(id, loraCode, mode) { handleLoraCodeUpdate(id, loraCode, mode) {
// Handle broadcast mode (for Desktop/non-browser support)
if (id === -1) {
// Find all Lora Loader nodes in the current graph
const loraLoaderNodes = [];
for (const nodeId in app.graph._nodes_by_id) {
const node = app.graph._nodes_by_id[nodeId];
if (node.comfyClass === "Lora Loader (LoraManager)") {
loraLoaderNodes.push(node);
}
}
// Update each Lora Loader node found
if (loraLoaderNodes.length > 0) {
loraLoaderNodes.forEach(node => {
this.updateNodeLoraCode(node, loraCode, mode);
});
console.log(`Updated ${loraLoaderNodes.length} Lora Loader nodes in broadcast mode`);
} else {
console.warn("No Lora Loader nodes found in the workflow for broadcast update");
}
return;
}
// Standard mode - update a specific node
const node = app.graph.getNodeById(+id); const node = app.graph.getNodeById(+id);
if (!node || node.comfyClass !== "Lora Loader (LoraManager)") { if (!node || node.comfyClass !== "Lora Loader (LoraManager)") {
console.warn("Node not found or not a LoraLoader:", id); console.warn("Node not found or not a LoraLoader:", id);
return; return;
} }
this.updateNodeLoraCode(node, loraCode, mode);
},
// Helper method to update a single node's lora code
updateNodeLoraCode(node, loraCode, mode) {
// Update the input widget with new lora code // Update the input widget with new lora code
const inputWidget = node.widgets[0]; const inputWidget = node.widgets[0];
if (!inputWidget) return; if (!inputWidget) return;