Skip to content

Commit 32b7085

Browse files
committed
optimize: implement efficient approach for PR #8225 - store base64 directly in backend messages
- Remove unnecessary memory caching logic - Store base64 data URLs directly in ClineMessage.images[] and ApiMessage content when first received - Eliminate conversion overhead at API call time (base64 already available) - Keep frontend memory efficient with webview URIs for display - Much simpler and more efficient than caching approach - One-time conversion: webview URI → base64 when storing in backend - API calls use pre-stored base64 directly (no file I/O or conversion needed) This achieves PR goals with optimal performance: frontend memory efficiency + instant API calls
1 parent e7531e5 commit 32b7085

File tree

3 files changed

+16
-26
lines changed

3 files changed

+16
-26
lines changed

src/core/prompts/responses.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import * as path from "path"
33
import * as diff from "diff"
44
import { RooIgnoreController, LOCK_TEXT_SYMBOL } from "../ignore/RooIgnoreController"
55
import { RooProtectedController } from "../protect/RooProtectedController"
6-
import { normalizeImageRefsToDataUrls } from "../../integrations/misc/imageDataUrl"
76

87
export const formatResponse = {
98
toolDenied: () => `The user denied this operation.`,
@@ -201,23 +200,6 @@ const formatImagesIntoBlocks = (images?: string[]): Anthropic.ImageBlockParam[]
201200
: []
202201
}
203202

204-
/**
205-
* Async version that converts webview URIs to base64 data URLs before creating image blocks
206-
* This is the missing piece from PR #8225 - allows frontend to use webview URIs while
207-
* backend stores base64 for API calls.
208-
*/
209-
export const formatImagesIntoBlocksAsync = async (images?: string[]): Promise<Anthropic.ImageBlockParam[]> => {
210-
if (!images || images.length === 0) {
211-
return []
212-
}
213-
214-
// Convert any webview URIs to base64 data URLs
215-
const dataUrls = await normalizeImageRefsToDataUrls(images)
216-
217-
// Now use the regular function to create image blocks
218-
return formatImagesIntoBlocks(dataUrls)
219-
}
220-
221203
const toolUseInstructionsReminder = `# Reminder: Instructions for Tool Use
222204
223205
Tool uses are formatted using XML-style tags. The tool name itself becomes the XML tag name. Each parameter is enclosed within its own set of tags. Here's the structure:

src/core/task/Task.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,15 +1212,18 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
12121212

12131213
await this.providerRef.deref()?.postStateToWebview()
12141214

1215-
await this.say("text", task, images)
1215+
// Convert webview URIs to base64 data URLs for backend storage (one-time conversion)
1216+
const { normalizeImageRefsToDataUrls } = await import("../../integrations/misc/imageDataUrl")
1217+
const base64Images = images ? await normalizeImageRefsToDataUrls(images) : undefined
1218+
1219+
await this.say("text", task, base64Images) // Store base64 in backend messages
12161220
this.isInitialized = true
12171221

1218-
// Convert webview URIs to base64 for backend storage
1219-
const { formatImagesIntoBlocksAsync } = await import("../prompts/responses")
1220-
let imageBlocks: Anthropic.ImageBlockParam[] = await formatImagesIntoBlocksAsync(images)
1222+
// Convert base64 to image blocks for API (no conversion needed, already base64)
1223+
const { formatResponse } = await import("../prompts/responses")
1224+
let imageBlocks: Anthropic.ImageBlockParam[] = formatResponse.imageBlocks(base64Images)
12211225

12221226
// Task starting
1223-
12241227
await this.initiateTaskLoop([
12251228
{
12261229
type: "text",
@@ -1482,9 +1485,13 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
14821485
}
14831486

14841487
if (responseImages && responseImages.length > 0) {
1485-
// Convert webview URIs to base64 for backend storage
1486-
const { formatImagesIntoBlocksAsync } = await import("../prompts/responses")
1487-
const responseImageBlocks = await formatImagesIntoBlocksAsync(responseImages)
1488+
// Convert webview URIs to base64 data URLs for backend storage (one-time conversion)
1489+
const { normalizeImageRefsToDataUrls } = await import("../../integrations/misc/imageDataUrl")
1490+
const base64ResponseImages = await normalizeImageRefsToDataUrls(responseImages)
1491+
1492+
// Convert base64 to image blocks for API (no conversion needed, already base64)
1493+
const { formatResponse } = await import("../prompts/responses")
1494+
const responseImageBlocks = formatResponse.imageBlocks(base64ResponseImages)
14881495
newUserContent.push(...responseImageBlocks)
14891496
}
14901497

src/integrations/misc/imageDataUrl.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as path from "path"
33

44
/**
55
* Converts webview URIs to base64 data URLs for API calls.
6+
* Simple fallback for cases where base64 isn't already stored in messages.
67
* This is the missing piece from PR #8225 that allows webview URIs
78
* to be used in frontend while converting to base64 for API calls.
89
*/

0 commit comments

Comments
 (0)