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())