From 2da1de2f6d537d3817284eceb8f74a2bd9485790 Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Fri, 10 Jul 2026 11:36:38 +0000 Subject: [PATCH] Prefer source images for MSR analysis --- js/msr_character.js | 62 ++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/js/msr_character.js b/js/msr_character.js index 581fa65..15069e7 100644 --- a/js/msr_character.js +++ b/js/msr_character.js @@ -27,12 +27,9 @@ function coercePreviewUrl(value) { return ""; } -function resolvePreviewUrlFromOrigin(originNode) { +function resolveFileWidgetUrlFromOrigin(originNode) { if (!originNode) return ""; - const preview = Array.isArray(originNode.imgs) ? coercePreviewUrl(originNode.imgs[0]) : ""; - if (preview) return preview; - const widgets = originNode.widgets || []; const fileWidget = widgets.find((widget) => ["image", "filename", "file"].includes(widget.name)); const subfolderWidget = widgets.find((widget) => widget.name === "subfolder"); @@ -45,22 +42,47 @@ function resolvePreviewUrlFromOrigin(originNode) { ); } +function resolvePreviewUrlFromOrigin(originNode) { + if (!originNode) return ""; + const preview = Array.isArray(originNode.imgs) ? coercePreviewUrl(originNode.imgs[0]) : ""; + return preview || ""; +} + +function resolveCandidateImageUrls(originNode) { + const urls = []; + const fileUrl = resolveFileWidgetUrlFromOrigin(originNode); + const previewUrl = resolvePreviewUrlFromOrigin(originNode); + if (fileUrl) urls.push(fileUrl); + if (previewUrl && previewUrl !== fileUrl) urls.push(previewUrl); + return urls; +} + async function imageInputToDataUrl(node, inputName) { const originNode = getOriginNodeForInput(node, inputName); - const previewUrl = resolvePreviewUrlFromOrigin(originNode); - if (!previewUrl) return null; - try { - const response = await fetch(previewUrl); - const blob = await response.blob(); - return await new Promise((resolve) => { - const reader = new FileReader(); - reader.onloadend = () => resolve(reader.result); - reader.readAsDataURL(blob); - }); - } catch (error) { - console.error("[MSRCharacter] Failed to load preview image", error); - return null; + const candidateUrls = resolveCandidateImageUrls(originNode); + if (!candidateUrls.length) return null; + + for (const imageUrl of candidateUrls) { + try { + const response = await fetch(imageUrl); + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + const blob = await response.blob(); + if (!blob.type.startsWith("image/")) { + throw new Error(`Unexpected blob type: ${blob.type || "unknown"}`); + } + return await new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.readAsDataURL(blob); + }); + } catch (error) { + console.warn("[MSRCharacter] Failed candidate image source", imageUrl, error); + } } + + return null; } function setWidgetValue(node, widget, value) { @@ -120,7 +142,11 @@ function refreshCharacterPreview(node) { const inputNames = ["image_1", "image_2"]; const previewUrls = inputNames - .map((inputName) => resolvePreviewUrlFromOrigin(getOriginNodeForInput(node, inputName))) + .map((inputName) => { + const originNode = getOriginNodeForInput(node, inputName); + const candidates = resolveCandidateImageUrls(originNode); + return candidates[0] || ""; + }) .filter(Boolean); const previewRow = node._msrPreviewRow;