Add image handling for Gemini requests with URL download and base64 support
This commit is contained in:
		
							
								
								
									
										54
									
								
								google.go
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								google.go
									
									
									
									
									
								
							| @@ -2,8 +2,11 @@ package go_llm | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"encoding/base64" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"net/http" | ||||||
|  |  | ||||||
| 	"github.com/google/generative-ai-go/genai" | 	"github.com/google/generative-ai-go/genai" | ||||||
| 	"google.golang.org/api/option" | 	"google.golang.org/api/option" | ||||||
| @@ -54,6 +57,57 @@ func (g google) requestToChatHistory(in Request, model *genai.GenerativeModel) ( | |||||||
| 			content.Role = "user" | 			content.Role = "user" | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		for _, img := range c.Images { | ||||||
|  | 			if img.Url != "" { | ||||||
|  | 				// gemini does not support URLs, so we need to download the image and convert it to a blob | ||||||
|  |  | ||||||
|  | 				// Download the image from the URL | ||||||
|  | 				resp, err := http.Get(img.Url) | ||||||
|  | 				if err != nil { | ||||||
|  | 					panic(fmt.Sprintf("error downloading image: %v", err)) | ||||||
|  | 				} | ||||||
|  | 				defer resp.Body.Close() | ||||||
|  |  | ||||||
|  | 				// Check the Content-Length to ensure it's not over 20MB | ||||||
|  | 				if resp.ContentLength > 20*1024*1024 { | ||||||
|  | 					panic(fmt.Sprintf("image size exceeds 20MB: %d bytes", resp.ContentLength)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				// Read the content into a byte slice | ||||||
|  | 				data, err := io.ReadAll(resp.Body) | ||||||
|  | 				if err != nil { | ||||||
|  | 					panic(fmt.Sprintf("error reading image data: %v", err)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				// Ensure the MIME type is appropriate | ||||||
|  | 				mimeType := http.DetectContentType(data) | ||||||
|  | 				switch mimeType { | ||||||
|  | 				case "image/jpeg", "image/png", "image/gif": | ||||||
|  | 					// MIME type is valid | ||||||
|  | 				default: | ||||||
|  | 					panic(fmt.Sprintf("unsupported image MIME type: %s", mimeType)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				// Create a genai.Blob using the validated image data | ||||||
|  | 				content.Parts = append(content.Parts, genai.Blob{ | ||||||
|  | 					MIMEType: mimeType, | ||||||
|  | 					Data:     data, | ||||||
|  | 				}) | ||||||
|  |  | ||||||
|  | 			} else { | ||||||
|  | 				// convert base64 to blob | ||||||
|  | 				b, e := base64.StdEncoding.DecodeString(img.Base64) | ||||||
|  | 				if e != nil { | ||||||
|  | 					panic(fmt.Sprintf("error decoding base64: %v", e)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				content.Parts = append(content.Parts, genai.Blob{ | ||||||
|  | 					MIMEType: img.ContentType, | ||||||
|  | 					Data:     b, | ||||||
|  | 				}) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		// if this is the last message, we want to add to history, we want it to be the parts | 		// if this is the last message, we want to add to history, we want it to be the parts | ||||||
| 		if i == len(in.Messages)-1 { | 		if i == len(in.Messages)-1 { | ||||||
| 			return &res, cs, content.Parts | 			return &res, cs, content.Parts | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user