From 06edee406978d172a1f87f4c7b255282f9d55e4c Mon Sep 17 00:00:00 2001 From: Ilayaperumal Gopinathan Date: Fri, 2 May 2025 12:04:48 +0100 Subject: [PATCH] Remove deprecated UserMessage constructors - Remove deprecated constructor methods - Replace them with the builder methods Signed-off-by: Ilayaperumal Gopinathan --- .../VectorStoreChatMemoryAdvisor.java | 2 +- .../Neo4jChatMemoryAutoConfigurationIT.java | 2 +- .../ai/chat/memory/neo4j/Neo4jChatMemory.java | 7 +++- .../ai/anthropic/AnthropicChatModelIT.java | 13 +++--- .../converse/BedrockProxyChatModelIT.java | 6 ++- .../ai/mistralai/MistralAiChatModelIT.java | 30 +++++++------ .../ollama/OllamaChatModelMultimodalIT.java | 12 ++++-- .../openai/chat/MessageTypeContentTests.java | 16 ++++--- .../ai/openai/chat/OpenAiChatModelIT.java | 42 ++++++++++++------- .../chat/proxy/GroqWithOpenAiChatModelIT.java | 30 +++++++------ .../proxy/MistralWithOpenAiChatModelIT.java | 31 ++++++++------ .../proxy/OllamaWithOpenAiChatModelIT.java | 31 ++++++++------ .../gemini/CreateGeminiRequestTests.java | 8 +++- .../gemini/VertexAiGeminiChatModelIT.java | 13 +++--- .../ai/zhipuai/chat/ZhiPuAiChatModelIT.java | 31 ++++++++------ .../advisor/MessageChatMemoryAdvisor.java | 2 +- .../advisor/PromptChatMemoryAdvisor.java | 2 +- .../client/advisor/api/AdvisedRequest.java | 2 +- .../ai/chat/client/ChatClientTest.java | 4 +- .../ai/chat/messages/UserMessage.java | 40 ++---------------- 20 files changed, 179 insertions(+), 145 deletions(-) diff --git a/advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisor.java b/advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisor.java index c09b9719f..76c7ad368 100644 --- a/advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisor.java +++ b/advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisor.java @@ -140,7 +140,7 @@ public class VectorStoreChatMemoryAdvisor extends AbstractChatMemoryAdvisor mediaList) { Message message; Map metadata = record.get("metadata").asMap(); - message = new UserMessage(messageMap.get(MessageAttributes.TEXT_CONTENT.getValue()).toString(), mediaList, - metadata); + message = UserMessage.builder() + .text(messageMap.get(MessageAttributes.TEXT_CONTENT.getValue()).toString()) + .media(mediaList) + .metadata(metadata) + .build(); return message; } diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatModelIT.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatModelIT.java index 8d5d7324d..cc773efb3 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatModelIT.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatModelIT.java @@ -247,8 +247,10 @@ class AnthropicChatModelIT { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel.call(new Prompt(List.of(userMessage))); @@ -262,9 +264,10 @@ class AnthropicChatModelIT { var pdfData = new ClassPathResource("/spring-ai-reference-overview.pdf"); - var userMessage = new UserMessage( - "You are a very professional document summarization specialist. Please summarize the given document.", - List.of(new Media(new MimeType("application", "pdf"), pdfData))); + var userMessage = UserMessage.builder() + .text("You are a very professional document summarization specialist. Please summarize the given document.") + .media(List.of(new Media(new MimeType("application", "pdf"), pdfData))) + .build(); var response = this.chatModel.call(new Prompt(List.of(userMessage), ToolCallingChatOptions.builder().model(AnthropicApi.ChatModel.CLAUDE_3_5_SONNET.getName()).build())); diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelIT.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelIT.java index 592c27128..65d85c1a2 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelIT.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelIT.java @@ -245,8 +245,10 @@ class BedrockProxyChatModelIT { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel.call(new Prompt(List.of(userMessage))); diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelIT.java index 4445706a8..b3e2876f7 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelIT.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelIT.java @@ -276,8 +276,10 @@ class MistralAiChatModelIT { void multiModalityEmbeddedImage(String modelName) { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel .call(new Prompt(List.of(userMessage), ChatOptions.builder().model(modelName).build())); @@ -290,11 +292,13 @@ class MistralAiChatModelIT { @ParameterizedTest(name = "{0} : {displayName} ") @ValueSource(strings = { "pixtral-large-latest" }) void multiModalityImageUrl(String modelName) throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); ChatResponse response = this.chatModel .call(new Prompt(List.of(userMessage), ChatOptions.builder().model(modelName).build())); @@ -306,11 +310,13 @@ class MistralAiChatModelIT { @Test void streamingMultiModalityImageUrl() throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); Flux response = this.streamingChatModel.stream(new Prompt(List.of(userMessage), ChatOptions.builder().model(MistralAiApi.ChatModel.PIXTRAL_LARGE.getValue()).build())); diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java index d09c67954..28064bb77 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java @@ -51,8 +51,10 @@ class OllamaChatModelMultimodalIT extends BaseOllamaIT { void unsupportedMediaType() { var imageData = new ClassPathResource("/norway.webp"); - var userMessage = new UserMessage("Explain what do you see in this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see in this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); assertThatThrownBy(() -> this.chatModel.call(new Prompt(List.of(userMessage)))) .isInstanceOf(RuntimeException.class); @@ -62,8 +64,10 @@ class OllamaChatModelMultimodalIT extends BaseOllamaIT { void multiModalityTest() { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see in this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see in this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel.call(new Prompt(List.of(userMessage))); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java index 03fa77674..5a0968a49 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java @@ -17,6 +17,7 @@ package org.springframework.ai.openai.chat; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.util.List; import java.util.Map; @@ -127,8 +128,10 @@ public class MessageTypeContentTests { .willReturn(Mockito.mock(ResponseEntity.class)); URL mediaUrl = new URL("http://test"); - this.chatModel.call(new Prompt(List.of(new UserMessage("test message", - List.of(Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(mediaUrl).build()))))); + this.chatModel.call(new Prompt(List.of(UserMessage.builder() + .text("test message") + .media(List.of(Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(mediaUrl).build())) + .build()))); validateComplexContent(this.pomptCaptor.getValue()); } @@ -139,10 +142,11 @@ public class MessageTypeContentTests { given(this.openAiApi.chatCompletionStream(this.pomptCaptor.capture(), this.headersCaptor.capture())) .willReturn(this.fluxResponse); - URL mediaUrl = new URL("http://test"); - this.chatModel.stream(new Prompt(List.of(new UserMessage("test message", - List.of(Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(mediaUrl).build()))))) - .subscribe(); + URI mediaUrl = URI.create("http://test"); + this.chatModel.stream(new Prompt(List.of(UserMessage.builder() + .text("test message") + .media(List.of(Media.builder().mimeType(MimeTypeUtils.IMAGE_JPEG).data(mediaUrl).build())) + .build()))).subscribe(); validateComplexContent(this.pomptCaptor.getValue()); } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java index 35d34163c..37de20d9f 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java @@ -470,8 +470,10 @@ public class OpenAiChatModelIT extends AbstractIT { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel .call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); @@ -485,11 +487,13 @@ public class OpenAiChatModelIT extends AbstractIT { @ValueSource(strings = { "gpt-4o" }) void multiModalityImageUrl(String modelName) throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); ChatResponse response = this.chatModel .call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); @@ -502,11 +506,13 @@ public class OpenAiChatModelIT extends AbstractIT { @Test void streamingMultiModalityImageUrl() throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); Flux response = this.streamingChatModel.stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(OpenAiApi.ChatModel.GPT_4_O.getValue()).build())); @@ -565,8 +571,10 @@ public class OpenAiChatModelIT extends AbstractIT { @ValueSource(strings = { "gpt-4o-audio-preview" }) void multiModalityInputAudio(String modelName) { var audioResource = new ClassPathResource("speech1.mp3"); - var userMessage = new UserMessage("What is this recording about?", - List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource))); + var userMessage = UserMessage.builder() + .text("What is this recording about?") + .media(List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource))) + .build(); ChatResponse response = this.chatModel .call(new Prompt(List.of(userMessage), ChatOptions.builder().model(modelName).build())); @@ -580,8 +588,10 @@ public class OpenAiChatModelIT extends AbstractIT { @ValueSource(strings = { "gpt-4o-audio-preview" }) void streamingMultiModalityInputAudio(String modelName) { var audioResource = new ClassPathResource("speech1.mp3"); - var userMessage = new UserMessage("What is this recording about?", - List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource))); + var userMessage = UserMessage.builder() + .text("What is this recording about?") + .media(List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource))) + .build(); Flux response = this.chatModel .stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java index f40776ad5..ab2a1381d 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java @@ -312,8 +312,10 @@ class GroqWithOpenAiChatModelIT { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel .call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); @@ -328,11 +330,13 @@ class GroqWithOpenAiChatModelIT { @ValueSource(strings = { "llama3-70b-8192" }) void multiModalityImageUrl(String modelName) throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); ChatResponse response = this.chatModel .call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); @@ -346,11 +350,13 @@ class GroqWithOpenAiChatModelIT { @Test void streamingMultiModalityImageUrl() throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); Flux response = this.chatModel.stream(new Prompt(List.of(userMessage))); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/MistralWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/MistralWithOpenAiChatModelIT.java index 742729461..8ae57033d 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/MistralWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/MistralWithOpenAiChatModelIT.java @@ -17,6 +17,7 @@ package org.springframework.ai.openai.chat.proxy; import java.io.IOException; +import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -318,8 +319,10 @@ class MistralWithOpenAiChatModelIT { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel .call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); @@ -334,11 +337,13 @@ class MistralWithOpenAiChatModelIT { @ValueSource(strings = { "mistral-small-latest" }) void multiModalityImageUrl(String modelName) throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); ChatResponse response = this.chatModel .call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); @@ -352,11 +357,13 @@ class MistralWithOpenAiChatModelIT { @Test void streamingMultiModalityImageUrl() throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); Flux response = this.chatModel.stream(new Prompt(List.of(userMessage))); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java index f146abb4c..7f3697dc5 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java @@ -17,6 +17,7 @@ package org.springframework.ai.openai.chat.proxy; import java.io.IOException; +import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -341,8 +342,10 @@ class OllamaWithOpenAiChatModelIT { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel .call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); @@ -357,11 +360,13 @@ class OllamaWithOpenAiChatModelIT { @ValueSource(strings = { "llava" }) void multiModalityImageUrl(String modelName) throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); ChatResponse response = this.chatModel .call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); @@ -376,11 +381,13 @@ class OllamaWithOpenAiChatModelIT { @ValueSource(strings = { "llava" }) void streamingMultiModalityImageUrl(String modelName) throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); Flux response = this.chatModel .stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/CreateGeminiRequestTests.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/CreateGeminiRequestTests.java index 802fab3b8..af061c0b0 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/CreateGeminiRequestTests.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/CreateGeminiRequestTests.java @@ -17,6 +17,7 @@ package org.springframework.ai.vertexai.gemini; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.util.List; @@ -83,8 +84,11 @@ public class CreateGeminiRequestTests { var systemMessage = new SystemMessage("System Message Text"); - var userMessage = new UserMessage("User Message Text", - List.of(Media.builder().mimeType(MimeTypeUtils.IMAGE_PNG).data(new URL("http://example.com")).build())); + var userMessage = UserMessage.builder() + .text("User Message Text") + .media(List + .of(Media.builder().mimeType(MimeTypeUtils.IMAGE_PNG).data(URI.create("http://example.com")).build())) + .build(); var client = VertexAiGeminiChatModel.builder() .vertexAI(this.vertexAI) diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModelIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModelIT.java index b48622a1f..04826f6d4 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModelIT.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModelIT.java @@ -261,8 +261,10 @@ class VertexAiGeminiChatModelIT { var data = new ClassPathResource("/vertex.test.png"); - var userMessage = new UserMessage("Explain what do you see o this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, data))); + var userMessage = UserMessage.builder() + .text("Explain what do you see o this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, data))) + .build(); var response = this.chatModel.call(new Prompt(List.of(userMessage))); @@ -299,9 +301,10 @@ class VertexAiGeminiChatModelIT { var pdfData = new ClassPathResource("/spring-ai-reference-overview.pdf"); - var userMessage = new UserMessage( - "You are a very professional document summarization specialist. Please summarize the given document.", - List.of(new Media(new MimeType("application", "pdf"), pdfData))); + var userMessage = UserMessage.builder() + .text("You are a very professional document summarization specialist. Please summarize the given document.") + .media(List.of(new Media(new MimeType("application", "pdf"), pdfData))) + .build(); var response = this.chatModel.call(new Prompt(List.of(userMessage))); diff --git a/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/chat/ZhiPuAiChatModelIT.java b/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/chat/ZhiPuAiChatModelIT.java index 9667ce88a..1792c015c 100644 --- a/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/chat/ZhiPuAiChatModelIT.java +++ b/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/chat/ZhiPuAiChatModelIT.java @@ -17,6 +17,7 @@ package org.springframework.ai.zhipuai.chat; import java.io.IOException; +import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -298,8 +299,10 @@ class ZhiPuAiChatModelIT { var imageData = new ClassPathResource("/test.png"); - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))) + .build(); var response = this.chatModel .call(new Prompt(List.of(userMessage), ZhiPuAiChatOptions.builder().model(modelName).build())); @@ -313,11 +316,13 @@ class ZhiPuAiChatModelIT { @ValueSource(strings = { "glm-4v" }) void multiModalityImageUrl(String modelName) throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); ChatResponse response = this.chatModel .call(new Prompt(List.of(userMessage), ZhiPuAiChatOptions.builder().model(modelName).build())); @@ -330,11 +335,13 @@ class ZhiPuAiChatModelIT { @Test void streamingMultiModalityImageUrl() throws IOException { - var userMessage = new UserMessage("Explain what do you see on this picture?", - List.of(Media.builder() - .mimeType(MimeTypeUtils.IMAGE_PNG) - .data(new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) - .build())); + var userMessage = UserMessage.builder() + .text("Explain what do you see on this picture?") + .media(List.of(Media.builder() + .mimeType(MimeTypeUtils.IMAGE_PNG) + .data(URI.create("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png")) + .build())) + .build(); Flux response = this.streamingChatModel.stream(new Prompt(List.of(userMessage), ZhiPuAiChatOptions.builder().model(ZhiPuAiApi.ChatModel.GLM_4V.getValue()).build())); diff --git a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/MessageChatMemoryAdvisor.java b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/MessageChatMemoryAdvisor.java index cd1c53cb3..6a563e520 100644 --- a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/MessageChatMemoryAdvisor.java +++ b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/MessageChatMemoryAdvisor.java @@ -94,7 +94,7 @@ public class MessageChatMemoryAdvisor extends AbstractChatMemoryAdvisor(), Map.of()); } - public UserMessage(Resource resource) { - this(MessageUtils.readResource(resource)); - } - - /** - * @deprecated use {@link #builder()} instead. - */ - @Deprecated - public UserMessage(String textContent, List media) { - this(MessageType.USER, textContent, media, Map.of()); - } - - /** - * @deprecated use {@link #builder()} instead. - */ - @Deprecated - public UserMessage(String textContent, Media... media) { - this(textContent, Arrays.asList(media)); - } - - /** - * @deprecated use {@link #builder()} instead. Will be made private in the next - * release. - */ - @Deprecated - public UserMessage(String textContent, Collection media, Map metadata) { + private UserMessage(String textContent, Collection media, Map metadata) { super(MessageType.USER, textContent, metadata); Assert.notNull(media, "media cannot be null"); Assert.noNullElements(media, "media cannot have null elements"); this.media = new ArrayList<>(media); } - /** - * @deprecated use {@link #builder()} instead. - */ - @Deprecated - public UserMessage(MessageType messageType, String textContent, Collection media, - Map metadata) { - super(messageType, textContent, metadata); - Assert.notNull(media, "media data must not be null"); - this.media = new ArrayList<>(media); + public UserMessage(Resource resource) { + this(MessageUtils.readResource(resource)); } @Override @@ -105,7 +73,7 @@ public class UserMessage extends AbstractMessage implements MediaContent { } public UserMessage copy() { - return new UserMessage(getText(), List.copyOf(getMedia()), Map.copyOf(getMetadata())); + return new Builder().text(getText()).media(List.copyOf(getMedia())).metadata(Map.copyOf(getMetadata())).build(); } public Builder mutate() {