Expose MSR image analysis payload debug

This commit is contained in:
OpenClaw Agent
2026-07-10 11:40:10 +00:00
parent 2da1de2f6d
commit f372a2ed69
2 changed files with 63 additions and 11 deletions

View File

@@ -60,7 +60,22 @@ function resolveCandidateImageUrls(originNode) {
async function imageInputToDataUrl(node, inputName) {
const originNode = getOriginNodeForInput(node, inputName);
const candidateUrls = resolveCandidateImageUrls(originNode);
if (!candidateUrls.length) return null;
if (!candidateUrls.length) {
return {
dataUrl: null,
debug: {
inputName,
originNodeId: originNode?.id ?? null,
originNodeType: originNode?.type ?? null,
candidateUrls: [],
selectedUrl: null,
mimeType: null,
blobBytes: 0,
dataUrlLength: 0,
error: "No candidate image URLs found",
},
};
}
for (const imageUrl of candidateUrls) {
try {
@@ -72,17 +87,44 @@ async function imageInputToDataUrl(node, inputName) {
if (!blob.type.startsWith("image/")) {
throw new Error(`Unexpected blob type: ${blob.type || "unknown"}`);
}
return await new Promise((resolve) => {
const dataUrl = await new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
return {
dataUrl,
debug: {
inputName,
originNodeId: originNode?.id ?? null,
originNodeType: originNode?.type ?? null,
candidateUrls,
selectedUrl: imageUrl,
mimeType: blob.type || null,
blobBytes: blob.size || 0,
dataUrlLength: typeof dataUrl === "string" ? dataUrl.length : 0,
error: null,
},
};
} catch (error) {
console.warn("[MSRCharacter] Failed candidate image source", imageUrl, error);
}
}
return null;
return {
dataUrl: null,
debug: {
inputName,
originNodeId: originNode?.id ?? null,
originNodeType: originNode?.type ?? null,
candidateUrls,
selectedUrl: null,
mimeType: null,
blobBytes: 0,
dataUrlLength: 0,
error: "All candidate image URLs failed",
},
};
}
function setWidgetValue(node, widget, value) {
@@ -330,11 +372,13 @@ async function analyzeCharacterNode(node, buttonWidget) {
node.setDirtyCanvas?.(true, true);
try {
const imageResults = await Promise.all([
imageInputToDataUrl(node, "image_1"),
imageInputToDataUrl(node, "image_2"),
]);
const imageDebug = imageResults.map((result) => result?.debug || null).filter(Boolean);
const images = (
await Promise.all([
imageInputToDataUrl(node, "image_1"),
imageInputToDataUrl(node, "image_2"),
])
imageResults.map((result) => result?.dataUrl || null)
).filter(Boolean);
if (!images.length) {
@@ -348,10 +392,15 @@ async function analyzeCharacterNode(node, buttonWidget) {
base_url: baseUrlWidget?.value || "",
model: modelWidget?.value || "",
image_b64: images,
image_debug: imageDebug,
}),
});
const result = await response.json();
if (result.status !== "success") {
console.warn("[MSRCharacter] analyze debug", {
sentImages: imageDebug,
response: result,
});
throw new Error(result.message || "Unknown analysis error");
}

View File

@@ -551,6 +551,7 @@ async def analyze_character_endpoint(request):
import aiohttp
data = await request.json()
image_b64 = data.get("image_b64", "")
image_debug = data.get("image_debug") or []
char_index = int(data.get("char_index", 0))
provider, base_url, model_name = _resolve_provider(data)
@@ -639,6 +640,8 @@ async def analyze_character_endpoint(request):
"status": "error",
"message": "Ollama returned only a truncated analysis response.",
"debug_candidates": debug_candidates,
"image_debug": image_debug,
"image_lengths": [len(b64) for b64 in cleaned_b64_list],
"description": generated_text,
})
else: