@@ -15,7 +15,9 @@ import {
15
15
extractUniqueTitlesFromDocs ,
16
16
extractYoutubeUrl ,
17
17
formatDateTime ,
18
- imageToBase64 ,
18
+ ImageContent ,
19
+ ImageProcessor ,
20
+ MessageContent ,
19
21
} from "@/utils" ;
20
22
import { Notice } from "obsidian" ;
21
23
import ChainManager from "./chainManager" ;
@@ -251,6 +253,72 @@ class CopilotPlusChainRunner extends BaseChainRunner {
251
253
return hasYoutubeCommand && youtubeUrl !== null && words . length === 1 ;
252
254
}
253
255
256
+ private async processImageUrls ( urls : string [ ] ) : Promise < ImageContent [ ] > {
257
+ try {
258
+ const imageUrls = await Promise . all (
259
+ urls . map ( async ( url ) => {
260
+ if ( await ImageProcessor . isImageUrl ( url ) ) {
261
+ return await ImageProcessor . convertToBase64 ( url , this . chainManager . app . vault ) ;
262
+ }
263
+ return null ;
264
+ } )
265
+ ) ;
266
+
267
+ // Filter out null values and return valid image URLs
268
+ return imageUrls . filter ( ( item ) : item is ImageContent => item !== null ) ;
269
+ } catch ( error ) {
270
+ console . error ( "Error processing image URLs:" , error ) ;
271
+ return [ ] ;
272
+ }
273
+ }
274
+
275
+ private async processExistingImages ( content : MessageContent [ ] ) : Promise < ImageContent [ ] > {
276
+ try {
277
+ const imageContent = await Promise . all (
278
+ content
279
+ . filter (
280
+ ( item ) : item is ImageContent => item . type === "image_url" && ! ! item . image_url ?. url
281
+ )
282
+ . map ( async ( item ) => {
283
+ return await ImageProcessor . convertToBase64 (
284
+ item . image_url . url ,
285
+ this . chainManager . app . vault
286
+ ) ;
287
+ } )
288
+ ) ;
289
+ return imageContent ;
290
+ } catch ( error ) {
291
+ console . error ( "Error processing images:" , error ) ;
292
+ throw error ;
293
+ }
294
+ }
295
+
296
+ private async buildMessageContent (
297
+ textContent : string ,
298
+ userMessage : ChatMessage
299
+ ) : Promise < MessageContent [ ] > {
300
+ const content : MessageContent [ ] = [
301
+ {
302
+ type : "text" ,
303
+ text : textContent ,
304
+ } ,
305
+ ] ;
306
+
307
+ // Process URLs in the message to identify images
308
+ if ( userMessage . context ?. urls && userMessage . context . urls . length > 0 ) {
309
+ const imageContents = await this . processImageUrls ( userMessage . context . urls ) ;
310
+ content . push ( ...imageContents ) ;
311
+ }
312
+
313
+ // Add existing image content if present
314
+ if ( userMessage . content && userMessage . content . length > 0 ) {
315
+ const imageContents = await this . processExistingImages ( userMessage . content ) ;
316
+ content . push ( ...imageContents ) ;
317
+ }
318
+
319
+ return content ;
320
+ }
321
+
254
322
private async streamMultimodalResponse (
255
323
textContent : string ,
256
324
userMessage : ChatMessage ,
@@ -289,39 +357,8 @@ class CopilotPlusChainRunner extends BaseChainRunner {
289
357
messages . push ( { role : "assistant" , content : ai } ) ;
290
358
}
291
359
292
- // Create content array for current message
293
- const content : Array < { type : string } & ( { text : string } | { image_url : { url : string } } ) > = [
294
- {
295
- type : "text" ,
296
- text : textContent ,
297
- } ,
298
- ] ;
299
-
300
- // Add image content if present
301
- if ( userMessage . content && userMessage . content . length > 0 ) {
302
- try {
303
- const imageContent = await Promise . all (
304
- userMessage . content
305
- . filter ( ( item ) => item . type === "image_url" && item . image_url ?. url )
306
- . map ( async ( item ) => {
307
- const base64Image = await imageToBase64 (
308
- item . image_url . url ,
309
- this . chainManager . app . vault
310
- ) ;
311
- return {
312
- type : "image_url" ,
313
- image_url : {
314
- url : base64Image ,
315
- } ,
316
- } ;
317
- } )
318
- ) ;
319
- content . push ( ...imageContent ) ;
320
- } catch ( error ) {
321
- console . error ( "Error processing images:" , error ) ;
322
- throw error ;
323
- }
324
- }
360
+ // Build message content with text and images
361
+ const content = await this . buildMessageContent ( textContent , userMessage ) ;
325
362
326
363
// Add current user message
327
364
messages . push ( {
0 commit comments