Skip to content

Commit 97e9a42

Browse files
committed
Inline image attachments as base64 data URLs for cross-provider compatibility
Instead of keeping image attachments as file references (which not all providers support), read the image, resize if needed, and inline it as a base64 data URL. Non-image binary files (e.g. PDFs) continue to use file references. Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
1 parent a89374a commit 97e9a42

1 file changed

Lines changed: 34 additions & 8 deletions

File tree

pkg/cli/runner.go

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cli
33
import (
44
"cmp"
55
"context"
6+
"encoding/base64"
67
"encoding/json"
78
"errors"
89
"fmt"
@@ -436,19 +437,44 @@ func CreateUserMessageWithAttachment(userContent, attachmentPath string) *sessio
436437
})
437438

438439
default:
439-
// Binary files (images, PDFs) are kept as file references.
440+
// Binary files (images, PDFs) are handled based on type.
440441
mimeType := chat.DetectMimeType(absPath)
441442
if !chat.IsSupportedMimeType(mimeType) {
442443
slog.Warn("Unsupported attachment file type", "path", absPath, "mime_type", mimeType)
443444
return session.UserMessage(userContent)
444445
}
445-
multiContent = append(multiContent, chat.MessagePart{
446-
Type: chat.MessagePartTypeFile,
447-
File: &chat.MessageFile{
448-
Path: absPath,
449-
MimeType: mimeType,
450-
},
451-
})
446+
if chat.IsImageMimeType(mimeType) {
447+
// Read, resize if needed, and inline as base64 data URL.
448+
// This ensures cross-provider compatibility (not all providers
449+
// support file references).
450+
imgData, readErr := os.ReadFile(absPath)
451+
if readErr != nil {
452+
slog.Warn("Failed to read image attachment", "path", absPath, "error", readErr)
453+
return session.UserMessage(userContent)
454+
}
455+
resized, resizeErr := chat.ResizeImage(imgData, mimeType)
456+
if resizeErr != nil {
457+
slog.Warn("Image resize failed for attachment", "path", absPath, "error", resizeErr)
458+
return session.UserMessage(userContent)
459+
}
460+
dataURL := fmt.Sprintf("data:%s;base64,%s", resized.MimeType, base64.StdEncoding.EncodeToString(resized.Data))
461+
multiContent = append(multiContent, chat.MessagePart{
462+
Type: chat.MessagePartTypeImageURL,
463+
ImageURL: &chat.MessageImageURL{
464+
URL: dataURL,
465+
Detail: chat.ImageURLDetailAuto,
466+
},
467+
})
468+
} else {
469+
// Non-image binary files (e.g. PDFs) are kept as file references.
470+
multiContent = append(multiContent, chat.MessagePart{
471+
Type: chat.MessagePartTypeFile,
472+
File: &chat.MessageFile{
473+
Path: absPath,
474+
MimeType: mimeType,
475+
},
476+
})
477+
}
452478
}
453479

454480
return session.UserMessage(textContent, multiContent...)

0 commit comments

Comments
 (0)