fix: force deep model refresh by calling /refresh_models and re-fetching defs

This commit is contained in:
Thomas
2026-05-10 18:56:52 +02:00
parent 477ec76132
commit 5fa6ce0290
4 changed files with 72 additions and 48 deletions
+12 -7
View File
@@ -15,7 +15,7 @@ async def model_downloaded(request):
# 1. Dateisystem-Cache löschen (Kurze Pause für Windows-Dateisystem-Handles)
await asyncio.sleep(0.5)
# Robusteres Löschen der Caches in folder_paths
# Alle Caches in folder_paths radikal leeren
if hasattr(folder_paths, "folder_names"):
for k in list(folder_paths.folder_names.keys()):
folder_paths.folder_names[k] = []
@@ -32,21 +32,26 @@ async def model_downloaded(request):
# Dies zwingt ComfyUI, die Node-Metadaten (inkl. Modell-Listen) neu zu generieren
server.PromptServer.instance.object_info = None
# 3. Aktiven Scan triggern
# Durch den Aufruf von get_filename_list wird ComfyUI gezwungen, die Ordner neu zu indizieren
for folder in ["checkpoints", "loras", "vae", "controlnet", "diffusion_models", "upscale_models", "clip", "unet", "gligen"]:
# 3. Aktiven Scan triggern (Offizieller Weg via get_filename_list)
# Wir decken hier alle gängigen Modell-Typen ab
folders = ["checkpoints", "loras", "vae", "controlnet", "diffusion_models", "upscale_models",
"clip", "unet", "gligen", "embeddings", "configs", "hypernetworks", "style_models"]
for folder in folders:
try:
folder_paths.get_filename_list(folder)
except: pass
print("[Model-Downloader] Backend-Reset und Scan abgeschlossen.")
print(f"[Model-Downloader] Backend-Reset abgeschlossen. Gescannte Ordner: {len(folders)}")
except Exception as e:
print(f"[Model-Downloader] Fehler beim Reset: {e}")
# 4. Signale an alle Browser (jetzt mit frischen Daten)
# "refresh" ist ein Standard-Signal, "kippster-refresh-ui" ist unser spezieller Trigger für Deep-Update
# 4. Signale an alle Browser
# "refresh_models" wird von vielen Extensions abgefangen
server.PromptServer.instance.send_sync("refresh_models", {})
# "refresh" ist der Standard für ComfyUI
server.PromptServer.instance.send_sync("refresh", {})
# Unser spezieller Trigger
server.PromptServer.instance.send_sync("kippster-refresh-ui", {"message": "ready"})
return web.json_response({"status": "success", "message": "Backend reset and rescan complete"})
+12 -7
View File
@@ -15,7 +15,7 @@ async def model_downloaded(request):
# 1. Dateisystem-Cache löschen (Kurze Pause für Windows-Dateisystem-Handles)
await asyncio.sleep(0.5)
# Robusteres Löschen der Caches in folder_paths
# Alle Caches in folder_paths radikal leeren
if hasattr(folder_paths, "folder_names"):
for k in list(folder_paths.folder_names.keys()):
folder_paths.folder_names[k] = []
@@ -32,21 +32,26 @@ async def model_downloaded(request):
# Dies zwingt ComfyUI, die Node-Metadaten (inkl. Modell-Listen) neu zu generieren
server.PromptServer.instance.object_info = None
# 3. Aktiven Scan triggern
# Durch den Aufruf von get_filename_list wird ComfyUI gezwungen, die Ordner neu zu indizieren
for folder in ["checkpoints", "loras", "vae", "controlnet", "diffusion_models", "upscale_models", "clip", "unet", "gligen"]:
# 3. Aktiven Scan triggern (Offizieller Weg via get_filename_list)
# Wir decken hier alle gängigen Modell-Typen ab
folders = ["checkpoints", "loras", "vae", "controlnet", "diffusion_models", "upscale_models",
"clip", "unet", "gligen", "embeddings", "configs", "hypernetworks", "style_models"]
for folder in folders:
try:
folder_paths.get_filename_list(folder)
except: pass
print("[Model-Downloader] Backend-Reset und Scan abgeschlossen.")
print(f"[Model-Downloader] Backend-Reset abgeschlossen. Gescannte Ordner: {len(folders)}")
except Exception as e:
print(f"[Model-Downloader] Fehler beim Reset: {e}")
# 4. Signale an alle Browser (jetzt mit frischen Daten)
# "refresh" ist ein Standard-Signal, "kippster-refresh-ui" ist unser spezieller Trigger für Deep-Update
# 4. Signale an alle Browser
# "refresh_models" wird von vielen Extensions abgefangen
server.PromptServer.instance.send_sync("refresh_models", {})
# "refresh" ist der Standard für ComfyUI
server.PromptServer.instance.send_sync("refresh", {})
# Unser spezieller Trigger
server.PromptServer.instance.send_sync("kippster-refresh-ui", {"message": "ready"})
return web.json_response({"status": "success", "message": "Backend reset and rescan complete"})
@@ -3,7 +3,7 @@ let app = null;
let api = null;
const initializeExtension = async () => {
// 1. Try to find ComfyUI app and api objects
// 1. Suche nach ComfyUI App/API
const paths = ["../../scripts/app.js", "/scripts/app.js", "../../../scripts/app.js"];
const apiPaths = ["../../scripts/api.js", "/scripts/api.js", "../../../scripts/api.js"];
for (const path of paths) { try { const mod = await import(path); if (mod.app) { app = mod.app; break; } } catch (e) {} }
@@ -11,27 +11,31 @@ const initializeExtension = async () => {
if (!app || !api) { setTimeout(initializeExtension, 2000); return; }
// 2. Setup WebSocket Listener for Deep-Sync
// 2. WebSocket Listener für den "Sync"-Trigger
api.addEventListener("kippster-refresh-ui", async (event) => {
console.log("%c🔥 [Model-Downloader] SIGNAL EMPFANGEN! Starte Deep-Node-Update...", "background: #ff0000; color: #fff; font-size: 14px;");
console.log("%c🔥 [Model-Downloader] SIGNAL ERHALTEN! Erzwinge harten UI-Refresh...", "background: #ff0000; color: #fff; font-size: 14px;");
try {
// Backend Zeit zum Scannen geben (wichtig für Windows HDDs)
// A. Offiziellen ComfyUI Refresh-Endpoint triggern (wie der Button im Manager)
console.log("[Model-Downloader] Trigger /refresh_models...");
await fetch('/refresh_models', { method: 'POST' });
// B. Kurze Pause für das Backend
await new Promise(r => setTimeout(r, 1000));
// Definitionen neu laden (Zwingt den Browser die neuesten Modell-Listen vom Backend anzufragen)
// C. Node-Definitionen neu laden (Zwingt den Browser die neuen Listen anzufragen)
console.log("[Model-Downloader] Re-fetching Node Definitions...");
const nodeDefs = await api.getNodeDefs();
let updatedCount = 0;
// Bestehende Nodes auf dem Canvas aktualisieren
// D. Nodes auf dem Canvas manuell aktualisieren
if (app.graph && app.graph._nodes) {
for (const node of app.graph._nodes) {
const def = nodeDefs[node.type];
if (def && def.input && def.input.required) {
if (def?.input?.required) {
for (const widgetName in def.input.required) {
const inputDef = def.input.required[widgetName];
// Falls es ein Dropdown (Combo) ist (Array an Position 0)
if (Array.isArray(inputDef[0])) {
if (Array.isArray(inputDef[0])) { // Es ist ein Dropdown (Combo)
const newValues = inputDef[0];
const widget = node.widgets?.find(w => w.name === widgetName);
@@ -39,7 +43,7 @@ const initializeExtension = async () => {
const oldValue = widget.value;
widget.options.values = newValues;
// Validierung: Ist das aktuell gewählte Modell jetzt verfügbar?
// Check ob das ehemals rote Modell jetzt da ist
if (newValues.includes(oldValue)) {
if (node.color === "#322" || node.color === "#a22") {
node.color = "";
@@ -47,7 +51,7 @@ const initializeExtension = async () => {
updatedCount++;
}
} else if (oldValue && oldValue !== "None" && !newValues.includes(oldValue)) {
// Markiere fehlende Modelle rot
// Modell fehlt immer noch -> rot markieren
node.color = "#322";
node.bgcolor = "#a22";
}
@@ -59,24 +63,27 @@ const initializeExtension = async () => {
}
}
// E. ComfyUI Standard-Refresh (lädt Sidebars etc. neu)
if (app.refresh) await app.refresh();
// F. Canvas neu zeichnen
app.graph.setDirtyCanvas(true, true);
console.log(`[Model-Downloader] Deep-Sync fertig. ${updatedCount} Nodes geheilt.`);
console.log(`[Model-Downloader] Sync abgeschlossen. ${updatedCount} Nodes aktualisiert.`);
const msg = updatedCount > 0
? `✅ Synchronisation abgeschlossen!\n${updatedCount} Nodes wurden aktualisiert und sind jetzt bereit.`
: "✅ Synchronisation abgeschlossen! Die Modell-Listen sind auf dem neuesten Stand.";
? `✅ Deep-Sync abgeschlossen!\n${updatedCount} Nodes wurden aktualisiert.`
: "✅ Synchronisation abgeschlossen! Die Modell-Listen sind aktuell.";
if (app.ui?.dialog?.show) app.ui.dialog.show(msg);
else alert(msg);
} catch (e) {
console.error("[Model-Downloader] Fehler beim Deep-Node-Update:", e);
console.error("[Model-Downloader] Fehler beim erzwungenen Refresh:", e);
}
});
// 3. Load Token and setup UI
// 3. Token & FAB UI
let apiToken = null;
const loadConfig = async () => {
try {
@@ -109,7 +116,7 @@ const initializeExtension = async () => {
if (app.ui?.dialog?.show) app.ui.dialog.show("🚀 Workflow an Downloader gesendet!");
}
} catch (e) {
alert("❌ Downloader App nicht erreichbar! Läuft sie?");
alert("❌ Downloader App nicht erreichbar!");
}
};
document.body.appendChild(fab);
+24 -17
View File
@@ -3,7 +3,7 @@ let app = null;
let api = null;
const initializeExtension = async () => {
// 1. Try to find ComfyUI app and api objects
// 1. Suche nach ComfyUI App/API
const paths = ["../../scripts/app.js", "/scripts/app.js", "../../../scripts/app.js"];
const apiPaths = ["../../scripts/api.js", "/scripts/api.js", "../../../scripts/api.js"];
for (const path of paths) { try { const mod = await import(path); if (mod.app) { app = mod.app; break; } } catch (e) {} }
@@ -11,27 +11,31 @@ const initializeExtension = async () => {
if (!app || !api) { setTimeout(initializeExtension, 2000); return; }
// 2. Setup WebSocket Listener for Deep-Sync
// 2. WebSocket Listener für den "Sync"-Trigger
api.addEventListener("kippster-refresh-ui", async (event) => {
console.log("%c🔥 [Model-Downloader] SIGNAL EMPFANGEN! Starte Deep-Node-Update...", "background: #ff0000; color: #fff; font-size: 14px;");
console.log("%c🔥 [Model-Downloader] SIGNAL ERHALTEN! Erzwinge harten UI-Refresh...", "background: #ff0000; color: #fff; font-size: 14px;");
try {
// Backend Zeit zum Scannen geben (wichtig für Windows HDDs)
// A. Offiziellen ComfyUI Refresh-Endpoint triggern (wie der Button im Manager)
console.log("[Model-Downloader] Trigger /refresh_models...");
await fetch('/refresh_models', { method: 'POST' });
// B. Kurze Pause für das Backend
await new Promise(r => setTimeout(r, 1000));
// Definitionen neu laden (Zwingt den Browser die neuesten Modell-Listen vom Backend anzufragen)
// C. Node-Definitionen neu laden (Zwingt den Browser die neuen Listen anzufragen)
console.log("[Model-Downloader] Re-fetching Node Definitions...");
const nodeDefs = await api.getNodeDefs();
let updatedCount = 0;
// Bestehende Nodes auf dem Canvas aktualisieren
// D. Nodes auf dem Canvas manuell aktualisieren
if (app.graph && app.graph._nodes) {
for (const node of app.graph._nodes) {
const def = nodeDefs[node.type];
if (def && def.input && def.input.required) {
if (def?.input?.required) {
for (const widgetName in def.input.required) {
const inputDef = def.input.required[widgetName];
// Falls es ein Dropdown (Combo) ist (Array an Position 0)
if (Array.isArray(inputDef[0])) {
if (Array.isArray(inputDef[0])) { // Es ist ein Dropdown (Combo)
const newValues = inputDef[0];
const widget = node.widgets?.find(w => w.name === widgetName);
@@ -39,7 +43,7 @@ const initializeExtension = async () => {
const oldValue = widget.value;
widget.options.values = newValues;
// Validierung: Ist das aktuell gewählte Modell jetzt verfügbar?
// Check ob das ehemals rote Modell jetzt da ist
if (newValues.includes(oldValue)) {
if (node.color === "#322" || node.color === "#a22") {
node.color = "";
@@ -47,7 +51,7 @@ const initializeExtension = async () => {
updatedCount++;
}
} else if (oldValue && oldValue !== "None" && !newValues.includes(oldValue)) {
// Markiere fehlende Modelle rot
// Modell fehlt immer noch -> rot markieren
node.color = "#322";
node.bgcolor = "#a22";
}
@@ -59,24 +63,27 @@ const initializeExtension = async () => {
}
}
// E. ComfyUI Standard-Refresh (lädt Sidebars etc. neu)
if (app.refresh) await app.refresh();
// F. Canvas neu zeichnen
app.graph.setDirtyCanvas(true, true);
console.log(`[Model-Downloader] Deep-Sync fertig. ${updatedCount} Nodes geheilt.`);
console.log(`[Model-Downloader] Sync abgeschlossen. ${updatedCount} Nodes aktualisiert.`);
const msg = updatedCount > 0
? `✅ Synchronisation abgeschlossen!\n${updatedCount} Nodes wurden aktualisiert und sind jetzt bereit.`
: "✅ Synchronisation abgeschlossen! Die Modell-Listen sind auf dem neuesten Stand.";
? `✅ Deep-Sync abgeschlossen!\n${updatedCount} Nodes wurden aktualisiert.`
: "✅ Synchronisation abgeschlossen! Die Modell-Listen sind aktuell.";
if (app.ui?.dialog?.show) app.ui.dialog.show(msg);
else alert(msg);
} catch (e) {
console.error("[Model-Downloader] Fehler beim Deep-Node-Update:", e);
console.error("[Model-Downloader] Fehler beim erzwungenen Refresh:", e);
}
});
// 3. Load Token and setup UI
// 3. Token & FAB UI
let apiToken = null;
const loadConfig = async () => {
try {
@@ -109,7 +116,7 @@ const initializeExtension = async () => {
if (app.ui?.dialog?.show) app.ui.dialog.show("🚀 Workflow an Downloader gesendet!");
}
} catch (e) {
alert("❌ Downloader App nicht erreichbar! Läuft sie?");
alert("❌ Downloader App nicht erreichbar!");
}
};
document.body.appendChild(fab);