From fd5ed8802ad301ee3bf4b45f5cbbb9314a3c9873 Mon Sep 17 00:00:00 2001
From: jialiuyang <495120021@qq.com>
Date: Sun, 28 Jun 2026 23:42:42 +0800
Subject: [PATCH] Add WebP support for Google GenAI and Vertex AI
Gemini chat models and Vertex AI Multimodal Embedding both accept
image/webp inputs, but Spring AI rejected them before they could
reach the provider:
* MimeTypeDetector registered only png, jpeg, jpg and gif, so any
.webp resource passed to Gemini chat clients raised "Unable to
detect the MIME type" during URL, URI, file or resource detection.
* VertexAiMultimodalEmbeddingModel rejected image/webp media at the
SUPPORTED_IMAGE_MIME_SUB_TYPES check, throwing "Unsupported image
mime type" before any embedding request was issued.
This adds image/webp to both code paths, updates the MimeTypeDetector
class javadoc, and extends the parameterized MimeTypeDetectorTests so
the new mapping is exercised through every detection entry point.
Fixes #6474
Signed-off-by: jialiuyang <495120021@qq.com>
---
.../org/springframework/ai/google/genai/MimeTypeDetector.java | 2 ++
.../ai/google/genai/MimeTypeDetectorTests.java | 4 ++--
.../multimodal/VertexAiMultimodalEmbeddingModel.java | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/MimeTypeDetector.java b/models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/MimeTypeDetector.java
index c82ce4d9bc..141550fbb3 100644
--- a/models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/MimeTypeDetector.java
+++ b/models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/MimeTypeDetector.java
@@ -35,6 +35,7 @@
*
image/gif
* image/png
* image/jpeg
+ * image/webp
* video/mov
* video/mpeg
* video/mp4
@@ -109,6 +110,7 @@ public static MimeType getMimeType(String path) {
GEMINI_MIME_TYPES.put("jpeg", MimeTypeUtils.IMAGE_JPEG);
GEMINI_MIME_TYPES.put("jpg", MimeTypeUtils.IMAGE_JPEG);
GEMINI_MIME_TYPES.put("gif", MimeTypeUtils.IMAGE_GIF);
+ GEMINI_MIME_TYPES.put("webp", MimeTypeUtils.parseMimeType("image/webp"));
GEMINI_MIME_TYPES.put("mov", new MimeType("video", "mov"));
GEMINI_MIME_TYPES.put("mp4", new MimeType("video", "mp4"));
GEMINI_MIME_TYPES.put("mpg", new MimeType("video", "mpg"));
diff --git a/models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/MimeTypeDetectorTests.java b/models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/MimeTypeDetectorTests.java
index 4018b7b330..3982c79122 100644
--- a/models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/MimeTypeDetectorTests.java
+++ b/models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/MimeTypeDetectorTests.java
@@ -101,7 +101,7 @@ void getMimeTypeByStringWithInvalidInputShouldThrowException(String invalidPath)
}
@ParameterizedTest
- @ValueSource(strings = { "JPG", "PNG", "GIF" })
+ @ValueSource(strings = { "JPG", "PNG", "GIF", "WEBP" })
void getMimeTypeByStringWithUppercaseExtensionsShouldWork(String uppercaseExt) {
String upperFileName = "test." + uppercaseExt;
String lowerFileName = "test." + uppercaseExt.toLowerCase();
@@ -118,7 +118,7 @@ void getMimeTypeByStringWithUppercaseExtensionsShouldWork(String uppercaseExt) {
}
@ParameterizedTest
- @ValueSource(strings = { "test.jpg", "test.png", "test.gif" })
+ @ValueSource(strings = { "test.jpg", "test.png", "test.gif", "test.webp" })
void getMimeTypeSupportedFileAcrossDifferentMethodsShouldBeConsistent(String fileName) {
MimeType stringResult = MimeTypeDetector.getMimeType(fileName);
MimeType fileResult = MimeTypeDetector.getMimeType(new File(fileName));
diff --git a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModel.java b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModel.java
index afa116f142..0a099c1e65 100644
--- a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModel.java
+++ b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModel.java
@@ -78,7 +78,8 @@ public class VertexAiMultimodalEmbeddingModel implements DocumentEmbeddingModel
private static final MimeType VIDEO_MIME_TYPE = MimeTypeUtils.parseMimeType("video/*");
private static final List SUPPORTED_IMAGE_MIME_SUB_TYPES = List.of(MimeTypeUtils.IMAGE_JPEG,
- MimeTypeUtils.IMAGE_GIF, MimeTypeUtils.IMAGE_PNG, MimeTypeUtils.parseMimeType("image/bmp"));
+ MimeTypeUtils.IMAGE_GIF, MimeTypeUtils.IMAGE_PNG, MimeTypeUtils.parseMimeType("image/bmp"),
+ MimeTypeUtils.parseMimeType("image/webp"));
private static final Map KNOWN_EMBEDDING_DIMENSIONS = Stream
.of(VertexAiMultimodalEmbeddingModelName.values())