diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 3a83edc7e6..b571c180da 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -872,7 +872,21 @@ export class Task extends EventEmitter implements TaskLike { throw new Error("Current ask promise was ignored") } - const result = { response: this.askResponse!, text: this.askResponseText, images: this.askResponseImages } + let result: { response: ClineAskResponse; text?: string; images?: string[] } = { + response: this.askResponse!, + text: this.askResponseText, + images: this.askResponseImages, + } + // Normalize any image refs to base64 data URLs before handing back to callers + if (Array.isArray(result.images) && result.images.length > 0) { + try { + const { normalizeImageRefsToDataUrls } = await import("../../integrations/misc/imageDataUrl") + const normalized = await normalizeImageRefsToDataUrls(result.images) + result.images = normalized + } catch (e) { + console.error("[Task#ask] Failed to normalize image refs:", e) + } + } this.askResponse = undefined this.askResponseText = undefined this.askResponseImages = undefined @@ -1070,6 +1084,16 @@ export class Task extends EventEmitter implements TaskLike { throw new Error(`[RooCode#say] task ${this.taskId}.${this.instanceId} aborted`) } + // Ensure any image refs are normalized to base64 data URLs before persisting or sending to APIs + if (Array.isArray(images) && images.length > 0) { + try { + const { normalizeImageRefsToDataUrls } = await import("../../integrations/misc/imageDataUrl") + images = await normalizeImageRefsToDataUrls(images) + } catch (e) { + console.error("[Task#say] Failed to normalize image refs:", e) + } + } + if (partial !== undefined) { const lastMessage = this.clineMessages.at(-1) diff --git a/src/integrations/misc/imageDataUrl.ts b/src/integrations/misc/imageDataUrl.ts index 9aaccc461a..bd8f14c14b 100644 --- a/src/integrations/misc/imageDataUrl.ts +++ b/src/integrations/misc/imageDataUrl.ts @@ -38,6 +38,24 @@ export async function normalizeImageRefsToDataUrls(imageRefs: string[]): Promise * Converts a webview URI to a file system path */ function webviewUriToFilePath(webviewUri: string): string { + // Handle VS Code CDN-style webview URLs: + // Example: https://file+.vscode-resource.vscode-cdn.net/file/ + if (webviewUri.startsWith("https://")) { + try { + const u = new URL(webviewUri) + if (u.host === "vscode-cdn.net" || u.host.endsWith(".vscode-cdn.net")) { + // Path is like /file/ - strip the /file/ prefix + let p = u.pathname || "" + if (p.startsWith("/file/")) { + p = p.slice("/file/".length) + } + return path.normalize(decodeURIComponent(p)) + } + } catch { + // fall through if not a valid URL or not the expected host + } + } + // Handle vscode-resource URIs like: // vscode-resource://vscode-webview/path/to/file if (webviewUri.includes("vscode-resource://")) {