Skip to content

Commit e43c50b

Browse files
committed
add image handling code
1 parent f7a9cd1 commit e43c50b

File tree

3 files changed

+37
-27
lines changed

3 files changed

+37
-27
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { ApiHandler } from ".."
2+
import { ApiMessage } from "../../core/task-persistence/apiMessages"
3+
4+
/* Removes image blocks from messages if they are not supported by the Api Handler */
5+
export function maybeRemoveImageBlocks(messages: ApiMessage[], apiHandler: ApiHandler): ApiMessage[] {
6+
return messages.map((message) => {
7+
// Handle array content (could contain image blocks).
8+
let { content } = message
9+
if (Array.isArray(content)) {
10+
if (!apiHandler.getModel().info.supportsImages) {
11+
// Convert image blocks to text descriptions.
12+
content = content.map((block) => {
13+
if (block.type === "image") {
14+
// Convert image blocks to text descriptions.
15+
// Note: We can't access the actual image content/url due to API limitations,
16+
// but we can indicate that an image was present in the conversation.
17+
return {
18+
type: "text",
19+
text: "[Referenced image in conversation]",
20+
}
21+
}
22+
return block
23+
})
24+
}
25+
}
26+
return { ...message, content }
27+
})
28+
}

src/core/condense/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Anthropic from "@anthropic-ai/sdk"
22
import { ApiHandler } from "../../api"
33
import { ApiMessage } from "../task-persistence/apiMessages"
4+
import { maybeRemoveImageBlocks } from "../../api/transform/image-cleaning"
45

56
const CONTEXT_FRAC_FOR_SUMMARY = 0.5 // TODO(canyon): make this configurable
67
const N_MESSAGES_TO_KEEP = 3
@@ -82,7 +83,10 @@ async function summarizeConversation(messages: ApiMessage[], apiHandler: ApiHand
8283
role: "user",
8384
content: "Summarize the conversation so far, as described in the prompt instructions.",
8485
}
85-
const stream = apiHandler.createMessage(SUMMARY_PROMPT, [...messagesToSummarize, finalRequestMessage])
86+
const requestMessages = maybeRemoveImageBlocks([...messagesToSummarize, finalRequestMessage], apiHandler).map(
87+
({ role, content }) => ({ role, content }),
88+
)
89+
const stream = apiHandler.createMessage(SUMMARY_PROMPT, requestMessages)
8690
let summary = ""
8791
for await (const chunk of stream) {
8892
if (chunk.type === "text") {

src/core/task/Task.ts

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import {
8080
import { processUserContentMentions } from "../mentions/processUserContentMentions"
8181
import { ApiMessage } from "../task-persistence/apiMessages"
8282
import { getMessagesSinceLastSummary, summarizeConversationIfNeeded } from "../condense"
83+
import { maybeRemoveImageBlocks } from "../../api/transform/image-cleaning"
8384

8485
export type ClineEvents = {
8586
message: [{ action: "created" | "updated"; message: ClineMessage }]
@@ -1484,32 +1485,9 @@ export class Task extends EventEmitter<ClineEvents> {
14841485
}
14851486

14861487
const messagesSinceLastSummary = getMessagesSinceLastSummary(this.apiConversationHistory)
1487-
1488-
// Clean conversation history by:
1489-
// 1. Converting to Anthropic.MessageParam by spreading only the API-required properties.
1490-
// 2. Converting image blocks to text descriptions if model doesn't support images.
1491-
const cleanConversationHistory = messagesSinceLastSummary.map(({ role, content }) => {
1492-
// Handle array content (could contain image blocks).
1493-
if (Array.isArray(content)) {
1494-
if (!this.api.getModel().info.supportsImages) {
1495-
// Convert image blocks to text descriptions.
1496-
content = content.map((block) => {
1497-
if (block.type === "image") {
1498-
// Convert image blocks to text descriptions.
1499-
// Note: We can't access the actual image content/url due to API limitations,
1500-
// but we can indicate that an image was present in the conversation.
1501-
return {
1502-
type: "text",
1503-
text: "[Referenced image in conversation]",
1504-
}
1505-
}
1506-
return block
1507-
})
1508-
}
1509-
}
1510-
1511-
return { role, content }
1512-
})
1488+
const cleanConversationHistory = maybeRemoveImageBlocks(messagesSinceLastSummary, this.api).map(
1489+
({ role, content }) => ({ role, content }),
1490+
)
15131491

15141492
const stream = this.api.createMessage(systemPrompt, cleanConversationHistory)
15151493
const iterator = stream[Symbol.asyncIterator]()

0 commit comments

Comments
 (0)