diff --git a/anthropic.go b/anthropic.go index 039bfc5..9e6df9f 100644 --- a/anthropic.go +++ b/anthropic.go @@ -1,9 +1,15 @@ package go_llm import ( + "bytes" "context" + "encoding/base64" "encoding/json" "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" "io" "log" "log/slog" @@ -77,6 +83,51 @@ func (a anthropic) requestToAnthropicRequest(req Request) anth.MessagesRequest { } if img.Base64 != "" { + + // Anthropic models expect images to be < 5MiB in size + raw, err := base64.StdEncoding.DecodeString(img.Base64) + + if err != nil { + continue + } + + // Check if image size exceeds 5MiB (5242880 bytes) + if len(raw) >= 5242880 { + // Decode the image + imgData, format, err := image.Decode(bytes.NewReader(raw)) + if err != nil { + log.Println("failed to decode image", err) + continue + } + + var buf bytes.Buffer + + switch format { + case "jpeg", "jpg": + err = jpeg.Encode(&buf, imgData, &jpeg.Options{Quality: 60}) + case "png": + // For PNG, use a higher compression level + enc := &png.Encoder{ + CompressionLevel: png.BestCompression, + } + err = enc.Encode(&buf, imgData) + case "gif": + err = gif.Encode(&buf, imgData, &gif.Options{ + NumColors: 128, + }) + default: + continue + } + + if err != nil { + log.Println("failed to encode image", err) + continue + } + + // Update the base64 string + img.Base64 = base64.StdEncoding.EncodeToString(buf.Bytes()) + } + m.Content = append(m.Content, anth.NewImageMessageContent( anth.NewMessageContentSource( anth.MessagesContentSourceTypeBase64,