From e5422fdceedd52486a386f7fa1a8b2673de59f20 Mon Sep 17 00:00:00 2001 From: Soby Chacko Date: Sun, 13 Apr 2025 21:54:46 -0400 Subject: [PATCH] Miscellaneous checkstyle fixes Signed-off-by: Soby Chacko --- .../vectorstore/QuestionAnswerAdvisor.java | 8 +- ...ryDataSourceScriptDatabaseInitializer.java | 18 ++- .../JdbcChatMemoryAutoConfigurationIT.java | 10 +- ...aSourceScriptDatabaseInitializerTests.java | 16 ++ .../Neo4jChatMemoryAutoConfiguration.java | 1 + .../Neo4jChatMemoryProperties.java | 12 +- .../Neo4jChatMemoryPropertiesTest.java | 1 + .../AnthropicChatAutoConfiguration.java | 6 +- .../AnthropicModelConfigurationTests.java | 4 +- .../AnthropicPropertiesTests.java | 4 +- .../tool/FunctionCallWithFunctionBeanIT.java | 6 +- .../FunctionCallWithPromptFunctionIT.java | 2 +- .../AzureOpenAIClientBuilderCustomizer.java | 16 ++ ...AiAudioTranscriptionAutoConfiguration.java | 1 - ...AzureOpenAiClientBuilderConfiguration.java | 1 - ...AzureOpenAiEmbeddingAutoConfiguration.java | 1 - .../AzureOpenAiImageAutoConfiguration.java | 1 - .../AzureOpenAiAutoConfigurationIT.java | 1 - ...drockCohereEmbeddingAutoConfiguration.java | 4 +- ...ockConverseProxyChatAutoConfiguration.java | 6 +- ...edrockTitanEmbeddingAutoConfiguration.java | 4 +- ...ockCohereEmbeddingAutoConfigurationIT.java | 6 +- .../BedrockCohereModelConfigurationTests.java | 5 +- ...edrockConverseModelConfigurationTests.java | 4 +- ...kConverseProxyChatAutoConfigurationIT.java | 4 +- .../tool/FunctionCallWithFunctionBeanIT.java | 6 +- .../FunctionCallWithPromptFunctionIT.java | 6 +- ...rockTitanEmbeddingAutoConfigurationIT.java | 6 +- .../BedrockTitanModelConfigurationTests.java | 5 +- .../HuggingfaceModelConfigurationTests.java | 4 +- ...nctionCallbackWithPlainFunctionBeanIT.java | 2 +- .../MiniMaxAutoConfigurationIT.java | 2 +- .../autoconfigure/MiniMaxPropertiesTests.java | 2 +- .../MistralAiModerationProperties.java | 18 ++- .../MistralAiPropertiesTests.java | 2 +- .../MistralModelConfigurationTests.java | 4 +- .../MoonshotChatAutoConfiguration.java | 4 +- .../MoonshotChatAutoConfigurationIT.java | 2 +- .../MoonshotPropertiesTests.java | 2 +- .../tool/FunctionCallbackInPromptIT.java | 4 +- ...nctionCallbackWithPlainFunctionBeanIT.java | 4 +- .../tool/MoonshotFunctionCallbackIT.java | 4 +- .../OpenAIAutoConfigurationUtil.java | 8 +- .../tool/FunctionCallbackInPrompt2IT.java | 2 +- .../tool/FunctionCallWithFunctionBeanIT.java | 2 +- .../FunctionCallWithFunctionWrapperIT.java | 2 +- .../FunctionCallWithPromptFunctionIT.java | 2 +- .../ToolCallingAutoConfigurationTests.java | 12 +- .../CouchbaseSearchVectorStoreProperties.java | 12 +- ...eSearchVectorStoreAutoConfigurationIT.java | 2 +- .../ElasticsearchVectorStoreProperties.java | 2 +- .../autoconfigure/MariaDbStoreProperties.java | 8 +- .../PgVectorStoreProperties.java | 2 +- .../ai/reader/jsoup/JsoupDocumentReader.java | 4 +- .../ai/reader/pdf/PagePdfDocumentReader.java | 4 +- .../pdf/ParagraphPdfDocumentReader.java | 4 +- .../ai/mcp/AsyncMcpToolCallbackProvider.java | 3 +- .../springframework/ai/mcp/McpToolUtils.java | 2 +- .../ai/mcp/SyncMcpToolCallbackProvider.java | 10 +- .../springframework/ai/mcp/aot/McpHints.java | 1 + .../customizer/McpAsyncClientCustomizer.java | 1 + .../customizer/McpSyncClientCustomizer.java | 1 + .../mcp/SyncMcpToolCallbackProviderTests.java | 49 +++--- .../ai/mcp/SyncMcpToolCallbackTests.java | 20 +-- .../ai/chat/memory/jdbc/JdbcChatMemory.java | 6 +- .../aot/hint/JdbcChatMemoryRuntimeHints.java | 18 ++- .../memory/jdbc/JdbcChatMemoryConfigTest.java | 16 ++ .../ai/chat/memory/jdbc/JdbcChatMemoryIT.java | 6 +- .../hint/JdbcChatMemoryRuntimeHintsTest.java | 2 +- .../ai/chat/memory/neo4j/MediaAttributes.java | 2 +- .../chat/memory/neo4j/MessageAttributes.java | 2 +- .../ai/chat/memory/neo4j/Neo4jChatMemory.java | 46 +++--- .../memory/neo4j/Neo4jChatMemoryConfig.java | 28 ++-- .../chat/memory/neo4j/ToolCallAttributes.java | 2 +- .../memory/neo4j/ToolResponseAttributes.java | 2 +- .../ai/anthropic/AnthropicChatModel.java | 13 +- .../ai/anthropic/AnthropicChatOptions.java | 9 +- .../anthropic/aot/AnthropicRuntimeHints.java | 2 - .../ai/anthropic/api/AnthropicApi.java | 1 - .../ai/anthropic/AnthropicChatModelIT.java | 11 +- .../anthropic/AnthropicChatOptionsTests.java | 4 +- ...lientMethodInvokingFunctionCallbackIT.java | 6 +- .../ai/azure/openai/AzureOpenAiChatModel.java | 14 +- .../azure/openai/AzureOpenAiChatOptions.java | 2 +- .../converse/BedrockProxyChatModel.java | 2 +- .../converse/BedrockProxyChatModelIT.java | 2 +- .../converse/api/BedrockMediaFormatTest.java | 5 +- .../client/BedrockNovaChatClientIT.java | 48 +++--- .../ai/bedrock/aot/BedrockRuntimeHints.java | 5 - .../ai/minimax/aot/MiniMaxRuntimeHints.java | 1 - .../ai/mistralai/MistralAiChatModel.java | 34 ++-- .../ai/mistralai/MistralAiChatOptions.java | 2 +- .../ai/mistralai/api/MistralAiApi.java | 9 +- .../mistralai/api/MistralAiModerationApi.java | 27 +++- .../moderation/MistralAiModerationModel.java | 33 +++- .../MistralAiModerationOptions.java | 17 ++ .../MistralAiChatCompletionRequestTest.java | 8 +- .../ai/mistralai/MistralAiChatModelIT.java | 2 +- .../mistralai/MistralAiModerationModelIT.java | 17 ++ .../aot/MistralAiRuntimeHintsTests.java | 1 - .../ai/moonshot/aot/MoonshotRuntimeHints.java | 1 - .../aot/MoonshotRuntimeHintsTests.java | 1 - .../ai/ollama/OllamaChatModel.java | 5 +- .../ai/ollama/aot/OllamaRuntimeHints.java | 2 - .../ai/ollama/api/OllamaOptions.java | 22 +-- .../ai/ollama/OllamaChatModelTests.java | 2 +- .../ai/ollama/OllamaChatRequestTests.java | 8 +- .../ollama/aot/OllamaRuntimeHintsTests.java | 1 - .../ai/openai/OpenAiChatModel.java | 17 +- .../ai/openai/OpenAiChatOptions.java | 2 +- .../ai/openai/OpenAiEmbeddingModel.java | 5 +- .../ai/openai/OpenAiImageModel.java | 16 +- .../ai/openai/aot/OpenAiRuntimeHints.java | 4 - .../ai/openai/api/OpenAiApi.java | 2 +- .../ai/openai/api/OpenAiImageApi.java | 10 +- .../ai/openai/api/OpenAiModerationApi.java | 8 +- .../ai/openai/ChatCompletionRequestTests.java | 4 +- .../ai/openai/OpenAiChatOptionsTests.java | 5 +- .../ai/openai/api/OpenAiApiBuilderTests.java | 63 ++++---- .../api/OpenAiAudioModelNoOpApiKeysIT.java | 16 +- .../ai/openai/chat/OpenAiChatModelIT.java | 10 +- ...lientMethodInvokingFunctionCallbackIT.java | 2 +- .../chat/proxy/GroqWithOpenAiChatModelIT.java | 2 +- .../proxy/MistralWithOpenAiChatModelIT.java | 2 +- .../proxy/OllamaWithOpenAiChatModelIT.java | 2 +- .../transformer/MetadataTransformerIT.java | 4 +- .../ai/qianfan/aot/QianFanRuntimeHints.java | 2 - .../ai/qianfan/api/QianFanApiIT.java | 2 +- .../VertexAiMultimodalEmbeddingModel.java | 2 +- .../VertexAiMultimodalEmbeddingModelIT.java | 2 +- .../gemini/VertexAiGeminiChatModel.java | 151 +++++++++--------- .../gemini/VertexAiGeminiChatOptions.java | 4 +- .../gemini/schema/JsonSchemaConverter.java | 29 ++-- .../schema/VertexToolCallingManager.java | 31 ++-- .../gemini/VertexAiGeminiChatModelIT.java | 2 +- .../schema/JsonSchemaConverterTests.java | 3 +- .../ai/watsonx/aot/WatsonxAiRuntimeHints.java | 2 - .../aot/WatsonxAiRuntimeHintsTest.java | 3 - .../ai/zhipuai/aot/ZhiPuAiRuntimeHints.java | 2 - .../ai/zhipuai/api/ZhiPuAiApi.java | 4 +- .../ai/zhipuai/chat/ZhiPuAiChatModelIT.java | 2 +- .../ai/chat/client/ChatClient.java | 2 +- .../ai/chat/client/DefaultChatClient.java | 9 +- .../api/AdvisedResponseStreamUtils.java | 24 ++- .../chat/client/DefaultChatClientTests.java | 4 +- .../api/AdvisedResponseStreamUtilsTest.java | 21 ++- .../ai/converter/BeanOutputConverterTest.java | 19 +-- .../tests/tool/FunctionToolCallbackTests.java | 4 +- .../tests/tool/MethodToolCallbackTests.java | 16 +- .../tests/tool/ToolCallingManagerTests.java | 18 +-- .../vectorstore/SimpleVectorStoreIT.java | 13 +- .../aot/ToolBeanRegistrationAotProcessor.java | 13 +- .../ai/chat/metadata/DefaultUsage.java | 2 +- .../ai/chat/metadata/EmptyUsage.java | 2 +- .../ai/chat/metadata/Usage.java | 2 +- .../ai/chat/model/ChatResponse.java | 8 +- .../ai/embedding/AbstractEmbeddingModel.java | 30 ++-- .../org/springframework/ai/model/ApiKey.java | 1 + .../ai/model/SimpleApiKey.java | 1 + .../ai/model/SpringAIModelProperties.java | 6 +- .../ai/model/SpringAIModels.java | 6 +- .../DefaultFunctionCallbackBuilder.java | 2 +- .../model/tool/DefaultToolCallingManager.java | 18 +-- ...aultToolExecutionEligibilityPredicate.java | 29 ++-- .../tool/DefaultToolExecutionResult.java | 4 +- .../model/tool/LegacyToolCallingManager.java | 12 +- .../ai/model/tool/ToolCallingChatOptions.java | 110 ++++++------- .../tool/ToolExecutionEligibilityChecker.java | 31 ++-- .../ToolExecutionEligibilityPredicate.java | 31 ++-- .../ai/tool/StaticToolCallbackProvider.java | 29 ++-- .../definition/DefaultToolDefinition.java | 8 +- .../DefaultToolCallResultConverter.java | 14 +- ...efaultToolExecutionExceptionProcessor.java | 4 +- .../execution/ToolExecutionException.java | 2 +- .../tool/function/FunctionToolCallback.java | 35 ++-- .../ai/tool/metadata/DefaultToolMetadata.java | 4 +- .../ai/tool/method/MethodToolCallback.java | 37 ++--- .../method/MethodToolCallbackProvider.java | 10 +- .../DelegatingToolCallbackResolver.java | 2 +- .../SpringBeanToolCallbackResolver.java | 62 +++---- .../StaticToolCallbackResolver.java | 2 +- .../tool/resolution/TypeResolverHelper.java | 4 + .../util/json/schema/JsonSchemaGenerator.java | 3 +- .../ai/util/json/schema/SchemaType.java | 2 +- .../json/schema/SpringAiSchemaModule.java | 2 +- ...ToolBeanRegistrationAotProcessorTests.java | 3 +- .../ai/aot/ToolRuntimeHintsTests.java | 1 + .../ai/chat/metadata/DefaultUsageTests.java | 8 +- ...tImageModelObservationConventionTests.java | 2 - .../ImageModelObservationContextTests.java | 1 - ...elPromptContentObservationFilterTests.java | 2 - .../ai/metadata/UsageTests.java | 2 +- .../tool/DefaultToolCallingManagerTests.java | 14 +- ...oolExecutionEligibilityPredicateTests.java | 26 +-- .../tool/LegacyToolCallingManagerTests.java | 10 +- .../tool/ToolCallingChatOptionsTests.java | 5 +- ...oolExecutionEligibilityPredicateTests.java | 1 + .../DefaultToolCallResultConverterTests.java | 50 ++++-- .../ai/util/json/JsonParserTests.java | 18 ++- .../util/json/JsonSchemaGeneratorTests.java | 14 +- .../vectorstore/BaseVectorStoreTests.java | 10 +- .../vectorstore/SimpleVectorStoreContent.java | 2 +- .../vectorstore/SpringAIVectorStoreTypes.java | 6 +- ...eVectorStoreFilterExpressionConverter.java | 10 +- .../SimpleVectorStoreWithFilterTests.java | 13 +- ...orStoreFilterExpressionConverterTests.java | 9 +- src/checkstyle/checkstyle-suppressions.xml | 4 + src/checkstyle/checkstyle.xml | 2 +- .../cassandra/CassandraVectorStore.java | 2 +- .../CouchbaseSearchVectorStore.java | 28 ++-- .../ElasticsearchVectorStoreOptions.java | 2 +- .../milvus/MilvusVectorStoreTest.java | 8 +- 212 files changed, 1203 insertions(+), 942 deletions(-) diff --git a/advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/QuestionAnswerAdvisor.java b/advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/QuestionAnswerAdvisor.java index cc0f989b81b..dfee9f25a79 100644 --- a/advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/QuestionAnswerAdvisor.java +++ b/advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/QuestionAnswerAdvisor.java @@ -21,6 +21,10 @@ import java.util.Map; import java.util.stream.Collectors; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + import org.springframework.ai.chat.client.advisor.api.AdvisedRequest; import org.springframework.ai.chat.client.advisor.api.AdvisedResponse; import org.springframework.ai.chat.client.advisor.api.AdvisedResponseStreamUtils; @@ -28,10 +32,6 @@ import org.springframework.ai.chat.client.advisor.api.CallAroundAdvisorChain; import org.springframework.ai.chat.client.advisor.api.StreamAroundAdvisor; import org.springframework.ai.chat.client.advisor.api.StreamAroundAdvisorChain; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; - import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.document.Document; diff --git a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/main/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryDataSourceScriptDatabaseInitializer.java b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/main/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryDataSourceScriptDatabaseInitializer.java index 2f1927048df..716b6fb57c0 100644 --- a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/main/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryDataSourceScriptDatabaseInitializer.java +++ b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/main/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryDataSourceScriptDatabaseInitializer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2024-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.model.chat.memory.jdbc.autoconfigure; import java.util.List; @@ -13,7 +29,7 @@ class JdbcChatMemoryDataSourceScriptDatabaseInitializer extends DataSourceScript private static final String SCHEMA_LOCATION = "classpath:org/springframework/ai/chat/memory/jdbc/schema-@@platform@@.sql"; - public JdbcChatMemoryDataSourceScriptDatabaseInitializer(DataSource dataSource) { + JdbcChatMemoryDataSourceScriptDatabaseInitializer(DataSource dataSource) { super(dataSource, getSettings(dataSource)); } diff --git a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/test/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryAutoConfigurationIT.java b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/test/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryAutoConfigurationIT.java index 6f9573d3eb0..df9a49d85b9 100644 --- a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/test/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryAutoConfigurationIT.java +++ b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/test/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryAutoConfigurationIT.java @@ -60,16 +60,14 @@ class JdbcChatMemoryAutoConfigurationIT { @Test void jdbcChatMemoryScriptDatabaseInitializer_shouldBeLoaded() { - this.contextRunner.withPropertyValues("spring.ai.chat.memory.jdbc.initialize-schema=true").run(context -> { - assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isTrue(); - }); + this.contextRunner.withPropertyValues("spring.ai.chat.memory.jdbc.initialize-schema=true") + .run(context -> assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isTrue()); } @Test void jdbcChatMemoryScriptDatabaseInitializer_shouldNotBeLoaded() { - this.contextRunner.withPropertyValues("spring.ai.chat.memory.jdbc.initialize-schema=false").run(context -> { - assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isFalse(); - }); + this.contextRunner.withPropertyValues("spring.ai.chat.memory.jdbc.initialize-schema=false") + .run(context -> assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isFalse()); } @Test diff --git a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/test/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryDataSourceScriptDatabaseInitializerTests.java b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/test/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryDataSourceScriptDatabaseInitializerTests.java index bcb1a9daacc..f563c67cdf1 100644 --- a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/test/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryDataSourceScriptDatabaseInitializerTests.java +++ b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-jdbc/src/test/java/org/springframework/ai/model/chat/memory/jdbc/autoconfigure/JdbcChatMemoryDataSourceScriptDatabaseInitializerTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2024-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.model.chat.memory.jdbc.autoconfigure; import javax.sql.DataSource; diff --git a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/main/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryAutoConfiguration.java b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/main/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryAutoConfiguration.java index ae14ac1e698..dd94209eee2 100644 --- a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/main/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryAutoConfiguration.java +++ b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/main/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryAutoConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.ai.model.chat.memory.neo4j.autoconfigure; import org.neo4j.driver.Driver; + import org.springframework.ai.chat.memory.neo4j.Neo4jChatMemory; import org.springframework.ai.chat.memory.neo4j.Neo4jChatMemoryConfig; import org.springframework.boot.autoconfigure.AutoConfiguration; diff --git a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/main/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryProperties.java b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/main/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryProperties.java index 3cfaf6be80b..1a970ef9bed 100644 --- a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/main/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryProperties.java +++ b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/main/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryProperties.java @@ -42,7 +42,7 @@ public class Neo4jChatMemoryProperties { private String mediaLabel = Neo4jChatMemoryConfig.DEFAULT_MEDIA_LABEL; public String getSessionLabel() { - return sessionLabel; + return this.sessionLabel; } public void setSessionLabel(String sessionLabel) { @@ -50,23 +50,23 @@ public void setSessionLabel(String sessionLabel) { } public String getToolCallLabel() { - return toolCallLabel; + return this.toolCallLabel; } public String getMetadataLabel() { - return metadataLabel; + return this.metadataLabel; } public String getMessageLabel() { - return messageLabel; + return this.messageLabel; } public String getToolResponseLabel() { - return toolResponseLabel; + return this.toolResponseLabel; } public String getMediaLabel() { - return mediaLabel; + return this.mediaLabel; } public void setToolCallLabel(String toolCallLabel) { diff --git a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/test/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryPropertiesTest.java b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/test/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryPropertiesTest.java index f2cbda5218c..10022c2f608 100644 --- a/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/test/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryPropertiesTest.java +++ b/auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-neo4j/src/test/java/org/springframework/ai/model/chat/memory/neo4j/autoconfigure/Neo4jChatMemoryPropertiesTest.java @@ -17,6 +17,7 @@ package org.springframework.ai.model.chat.memory.neo4j.autoconfigure; import org.junit.jupiter.api.Test; + import org.springframework.ai.chat.memory.neo4j.Neo4jChatMemoryConfig; import static org.assertj.core.api.Assertions.assertThat; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/main/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicChatAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/main/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicChatAutoConfiguration.java index 5427e35f8f3..0caaa2c0c0a 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/main/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicChatAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/main/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicChatAutoConfiguration.java @@ -20,16 +20,16 @@ import org.springframework.ai.anthropic.AnthropicChatModel; import org.springframework.ai.anthropic.api.AnthropicApi; +import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.model.SpringAIModelProperties; import org.springframework.ai.model.SpringAIModels; -import org.springframework.ai.model.tool.autoconfigure.ToolCallingAutoConfiguration; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; -import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.model.function.DefaultFunctionCallbackResolver; import org.springframework.ai.model.function.FunctionCallbackResolver; import org.springframework.ai.model.tool.DefaultToolExecutionEligibilityPredicate; import org.springframework.ai.model.tool.ToolCallingManager; import org.springframework.ai.model.tool.ToolExecutionEligibilityPredicate; +import org.springframework.ai.model.tool.autoconfigure.ToolCallingAutoConfiguration; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicModelConfigurationTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicModelConfigurationTests.java index d9e6d3b5c27..dae74691d03 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicModelConfigurationTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicModelConfigurationTests.java @@ -37,9 +37,7 @@ public class AnthropicModelConfigurationTests { @Test void chatModelActivation() { - this.contextRunner.run(context -> { - assertThat(context.getBeansOfType(AnthropicChatModel.class)).isNotEmpty(); - }); + this.contextRunner.run(context -> assertThat(context.getBeansOfType(AnthropicChatModel.class)).isNotEmpty()); this.contextRunner.withPropertyValues("spring.ai.model.chat=none").run(context -> { assertThat(context.getBeansOfType(AnthropicChatProperties.class)).isEmpty(); diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicPropertiesTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicPropertiesTests.java index 4a6c252f7c9..e70cd9bacbe 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicPropertiesTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicPropertiesTests.java @@ -121,9 +121,7 @@ public void chatCompletionDisabled() { new ApplicationContextRunner().withPropertyValues("spring.ai.model.chat=none") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, RestClientAutoConfiguration.class, AnthropicChatAutoConfiguration.class)) - .run(context -> { - assertThat(context.getBeansOfType(AnthropicChatModel.class)).isEmpty(); - }); + .run(context -> assertThat(context.getBeansOfType(AnthropicChatModel.class)).isEmpty()); } } diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java index 5a3bdc115cf..8ec56423a35 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java @@ -27,12 +27,12 @@ import org.springframework.ai.anthropic.AnthropicChatModel; import org.springframework.ai.anthropic.AnthropicChatOptions; import org.springframework.ai.anthropic.api.AnthropicApi; -import org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration; -import org.springframework.ai.model.anthropic.autoconfigure.tool.MockWeatherService.Request; -import org.springframework.ai.model.anthropic.autoconfigure.tool.MockWeatherService.Response; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration; +import org.springframework.ai.model.anthropic.autoconfigure.tool.MockWeatherService.Request; +import org.springframework.ai.model.anthropic.autoconfigure.tool.MockWeatherService.Response; import org.springframework.ai.model.tool.ToolCallingChatOptions; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java index b7e55c4d0d5..c937963cc4f 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java @@ -26,10 +26,10 @@ import org.springframework.ai.anthropic.AnthropicChatModel; import org.springframework.ai.anthropic.AnthropicChatOptions; import org.springframework.ai.anthropic.api.AnthropicApi; -import org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration; import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAIClientBuilderCustomizer.java b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAIClientBuilderCustomizer.java index 0d4e3061b0d..a017a842a13 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAIClientBuilderCustomizer.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAIClientBuilderCustomizer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.model.azure.openai.autoconfigure; import com.azure.ai.openai.OpenAIClientBuilder; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiAudioTranscriptionAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiAudioTranscriptionAutoConfiguration.java index ae34ca3263e..aeb54bed84f 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiAudioTranscriptionAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiAudioTranscriptionAutoConfiguration.java @@ -22,7 +22,6 @@ import org.springframework.ai.model.SpringAIModelProperties; import org.springframework.ai.model.SpringAIModels; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiClientBuilderConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiClientBuilderConfiguration.java index 3838a3224ac..739b0a8e7da 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiClientBuilderConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiClientBuilderConfiguration.java @@ -28,7 +28,6 @@ import com.azure.core.util.Header; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiEmbeddingAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiEmbeddingAutoConfiguration.java index 11ee2a3f814..2d09451b987 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiEmbeddingAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiEmbeddingAutoConfiguration.java @@ -25,7 +25,6 @@ import org.springframework.ai.model.SpringAIModels; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiImageAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiImageAutoConfiguration.java index 2d34db4123e..ae5ce75b7f8 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiImageAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/main/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiImageAutoConfiguration.java @@ -22,7 +22,6 @@ import org.springframework.ai.model.SpringAIModelProperties; import org.springframework.ai.model.SpringAIModels; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/test/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/test/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiAutoConfigurationIT.java index 6dd72c57a93..19f2d78c9a7 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/test/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/src/test/java/org/springframework/ai/model/azure/openai/autoconfigure/AzureOpenAiAutoConfigurationIT.java @@ -34,7 +34,6 @@ import com.azure.core.http.HttpResponse; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; - import reactor.core.publisher.Flux; import org.springframework.ai.azure.openai.AzureOpenAiAudioTranscriptionModel; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereEmbeddingAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereEmbeddingAutoConfiguration.java index 2b07482d46c..1001b7d5b7f 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereEmbeddingAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereEmbeddingAutoConfiguration.java @@ -20,12 +20,12 @@ import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.regions.providers.AwsRegionProvider; +import org.springframework.ai.bedrock.cohere.BedrockCohereEmbeddingModel; +import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi; import org.springframework.ai.model.SpringAIModelProperties; import org.springframework.ai.model.SpringAIModels; import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionConfiguration; import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionProperties; -import org.springframework.ai.bedrock.cohere.BedrockCohereEmbeddingModel; -import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseProxyChatAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseProxyChatAutoConfiguration.java index f5aaff363cc..d91a099a9d8 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseProxyChatAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseProxyChatAutoConfiguration.java @@ -22,18 +22,18 @@ import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeAsyncClient; import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient; +import org.springframework.ai.bedrock.converse.BedrockProxyChatModel; +import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.model.SpringAIModelProperties; import org.springframework.ai.model.SpringAIModels; import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionConfiguration; import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionProperties; -import org.springframework.ai.model.tool.autoconfigure.ToolCallingAutoConfiguration; -import org.springframework.ai.bedrock.converse.BedrockProxyChatModel; -import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.model.function.DefaultFunctionCallbackResolver; import org.springframework.ai.model.function.FunctionCallbackResolver; import org.springframework.ai.model.tool.DefaultToolExecutionEligibilityPredicate; import org.springframework.ai.model.tool.ToolCallingManager; import org.springframework.ai.model.tool.ToolExecutionEligibilityPredicate; +import org.springframework.ai.model.tool.autoconfigure.ToolCallingAutoConfiguration; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanEmbeddingAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanEmbeddingAutoConfiguration.java index efb5c2637b1..73795fc494f 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanEmbeddingAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/main/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanEmbeddingAutoConfiguration.java @@ -20,12 +20,12 @@ import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.regions.providers.AwsRegionProvider; +import org.springframework.ai.bedrock.titan.BedrockTitanEmbeddingModel; +import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi; import org.springframework.ai.model.SpringAIModelProperties; import org.springframework.ai.model.SpringAIModels; import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionConfiguration; import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionProperties; -import org.springframework.ai.bedrock.titan.BedrockTitanEmbeddingModel; -import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereEmbeddingAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereEmbeddingAutoConfigurationIT.java index e77ca587300..faf880ba6ab 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereEmbeddingAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereEmbeddingAutoConfigurationIT.java @@ -21,14 +21,14 @@ import org.junit.jupiter.api.Test; import software.amazon.awssdk.regions.Region; -import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionProperties; -import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; -import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; import org.springframework.ai.bedrock.cohere.BedrockCohereEmbeddingModel; import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi.CohereEmbeddingModel; import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi.CohereEmbeddingRequest; import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi.CohereEmbeddingRequest.InputType; import org.springframework.ai.embedding.EmbeddingResponse; +import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionProperties; +import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; +import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereModelConfigurationTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereModelConfigurationTests.java index 7690cb9f7a0..3bbd14dbbee 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereModelConfigurationTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/cohere/autoconfigure/BedrockCohereModelConfigurationTests.java @@ -39,9 +39,8 @@ public class BedrockCohereModelConfigurationTests { @Test void embeddingModelActivation() { - this.contextRunner.run(context -> { - assertThat(context.getBeansOfType(BedrockCohereEmbeddingModel.class)).isNotEmpty(); - }); + this.contextRunner + .run(context -> assertThat(context.getBeansOfType(BedrockCohereEmbeddingModel.class)).isNotEmpty()); this.contextRunner.withPropertyValues("spring.ai.model.embedding=none").run(context -> { assertThat(context.getBeansOfType(BedrockCohereEmbeddingProperties.class)).isEmpty(); diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseModelConfigurationTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseModelConfigurationTests.java index 9abd3712d51..f453aab1036 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseModelConfigurationTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseModelConfigurationTests.java @@ -37,9 +37,7 @@ public class BedrockConverseModelConfigurationTests { @Test void chatModelActivation() { - this.contextRunner.run(context -> { - assertThat(context.getBeansOfType(BedrockProxyChatModel.class)).isNotEmpty(); - }); + this.contextRunner.run(context -> assertThat(context.getBeansOfType(BedrockProxyChatModel.class)).isNotEmpty()); this.contextRunner.withPropertyValues("spring.ai.model.chat=none").run(context -> { assertThat(context.getBeansOfType(BedrockConverseProxyChatProperties.class)).isEmpty(); diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseProxyChatAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseProxyChatAutoConfigurationIT.java index 8f101a35763..128e3203bb8 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseProxyChatAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/BedrockConverseProxyChatAutoConfigurationIT.java @@ -24,14 +24,14 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; -import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; -import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; import org.springframework.ai.bedrock.converse.BedrockProxyChatModel; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; +import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java index ee837f2713d..e78cc1e30f2 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java @@ -25,13 +25,13 @@ import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; -import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; -import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; -import org.springframework.ai.model.bedrock.converse.autoconfigure.BedrockConverseProxyChatAutoConfiguration; import org.springframework.ai.bedrock.converse.BedrockProxyChatModel; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; +import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; +import org.springframework.ai.model.bedrock.converse.autoconfigure.BedrockConverseProxyChatAutoConfiguration; import org.springframework.ai.model.tool.ToolCallingChatOptions; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java index efff6f3318c..ecc6033f6d7 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/converse/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java @@ -22,13 +22,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; -import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; -import org.springframework.ai.model.bedrock.converse.autoconfigure.BedrockConverseProxyChatAutoConfiguration; import org.springframework.ai.bedrock.converse.BedrockProxyChatModel; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; +import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; +import org.springframework.ai.model.bedrock.converse.autoconfigure.BedrockConverseProxyChatAutoConfiguration; import org.springframework.ai.model.tool.ToolCallingChatOptions; import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.boot.autoconfigure.AutoConfigurations; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanEmbeddingAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanEmbeddingAutoConfigurationIT.java index c5739a3a8b7..73d2751c412 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanEmbeddingAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanEmbeddingAutoConfigurationIT.java @@ -22,13 +22,13 @@ import org.junit.jupiter.api.Test; import software.amazon.awssdk.regions.Region; -import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionProperties; -import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; -import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; import org.springframework.ai.bedrock.titan.BedrockTitanEmbeddingModel; import org.springframework.ai.bedrock.titan.BedrockTitanEmbeddingModel.InputType; import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi.TitanEmbeddingModel; import org.springframework.ai.embedding.EmbeddingResponse; +import org.springframework.ai.model.bedrock.autoconfigure.BedrockAwsConnectionProperties; +import org.springframework.ai.model.bedrock.autoconfigure.BedrockTestUtils; +import org.springframework.ai.model.bedrock.autoconfigure.RequiresAwsCredentials; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.core.io.DefaultResourceLoader; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanModelConfigurationTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanModelConfigurationTests.java index 443ae6d1dc6..b66b4c4f919 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanModelConfigurationTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai/src/test/java/org/springframework/ai/model/bedrock/titan/autoconfigure/BedrockTitanModelConfigurationTests.java @@ -39,9 +39,8 @@ public class BedrockTitanModelConfigurationTests { @Test void embeddingModelActivation() { - this.contextRunner.run(context -> { - assertThat(context.getBeansOfType(BedrockTitanEmbeddingModel.class)).isNotEmpty(); - }); + this.contextRunner + .run(context -> assertThat(context.getBeansOfType(BedrockTitanEmbeddingModel.class)).isNotEmpty()); this.contextRunner.withPropertyValues("spring.ai.model.embedding=none").run(context -> { assertThat(context.getBeansOfType(BedrockTitanEmbeddingProperties.class)).isEmpty(); diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-huggingface/src/test/java/org/springframework/ai/model/huggingface/autoconfigure/HuggingfaceModelConfigurationTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-huggingface/src/test/java/org/springframework/ai/model/huggingface/autoconfigure/HuggingfaceModelConfigurationTests.java index 7d9a4a8c383..2786ef96b3d 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-huggingface/src/test/java/org/springframework/ai/model/huggingface/autoconfigure/HuggingfaceModelConfigurationTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-huggingface/src/test/java/org/springframework/ai/model/huggingface/autoconfigure/HuggingfaceModelConfigurationTests.java @@ -37,9 +37,7 @@ public class HuggingfaceModelConfigurationTests { @Test void chatModelActivation() { - this.contextRunner.run(context -> { - assertThat(context.getBeansOfType(HuggingfaceChatModel.class)).isNotEmpty(); - }); + this.contextRunner.run(context -> assertThat(context.getBeansOfType(HuggingfaceChatModel.class)).isNotEmpty()); this.contextRunner.withPropertyValues("spring.ai.model.chat=none").run(context -> { assertThat(context.getBeansOfType(HuggingfaceChatProperties.class)).isEmpty(); diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/FunctionCallbackWithPlainFunctionBeanIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/FunctionCallbackWithPlainFunctionBeanIT.java index b4e3d6a9b47..a082daf0be5 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/FunctionCallbackWithPlainFunctionBeanIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/FunctionCallbackWithPlainFunctionBeanIT.java @@ -26,7 +26,6 @@ import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; @@ -35,6 +34,7 @@ import org.springframework.ai.minimax.MiniMaxChatModel; import org.springframework.ai.minimax.MiniMaxChatOptions; import org.springframework.ai.model.function.FunctionCallingOptions; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/MiniMaxAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/MiniMaxAutoConfigurationIT.java index 86f52f0a2a9..92f36adb7b2 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/MiniMaxAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/MiniMaxAutoConfigurationIT.java @@ -25,13 +25,13 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import reactor.core.publisher.Flux; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.embedding.EmbeddingResponse; import org.springframework.ai.minimax.MiniMaxChatModel; import org.springframework.ai.minimax.MiniMaxEmbeddingModel; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/MiniMaxPropertiesTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/MiniMaxPropertiesTests.java index d9530f581de..2de55bd95af 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/MiniMaxPropertiesTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-minimax/src/test/java/org/springframework/ai/model/minimax/autoconfigure/MiniMaxPropertiesTests.java @@ -20,11 +20,11 @@ import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONCompareMode; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.minimax.MiniMaxChatModel; import org.springframework.ai.minimax.MiniMaxEmbeddingModel; import org.springframework.ai.minimax.api.MiniMaxApi; import org.springframework.ai.model.ModelOptionsUtils; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/main/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiModerationProperties.java b/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/main/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiModerationProperties.java index 47f720e1a84..5645a189551 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/main/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiModerationProperties.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/main/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiModerationProperties.java @@ -1,7 +1,23 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.model.mistralai.autoconfigure; -import org.springframework.ai.mistralai.moderation.MistralAiModerationOptions; import org.springframework.ai.mistralai.api.MistralAiModerationApi; +import org.springframework.ai.mistralai.moderation.MistralAiModerationOptions; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiPropertiesTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiPropertiesTests.java index afa001e5246..916781ca71c 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiPropertiesTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiPropertiesTests.java @@ -18,8 +18,8 @@ import org.junit.jupiter.api.Test; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.mistralai.api.MistralAiApi; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralModelConfigurationTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralModelConfigurationTests.java index 0f01a27d1fa..002aef833ca 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralModelConfigurationTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralModelConfigurationTests.java @@ -67,9 +67,7 @@ void chatModelActivation() { @Test void embeddingModelActivation() { this.contextRunner.withConfiguration(AutoConfigurations.of(MistralAiEmbeddingAutoConfiguration.class)) - .run(context -> { - assertThat(context.getBeansOfType(MistralAiEmbeddingModel.class)).isNotEmpty(); - }); + .run(context -> assertThat(context.getBeansOfType(MistralAiEmbeddingModel.class)).isNotEmpty()); this.contextRunner.withConfiguration(AutoConfigurations.of(MistralAiEmbeddingAutoConfiguration.class)) .withPropertyValues("spring.ai.model.embedding=none") diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/main/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotChatAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/main/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotChatAutoConfiguration.java index ec7b6631760..15e60c0c53f 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/main/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotChatAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/main/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotChatAutoConfiguration.java @@ -20,15 +20,15 @@ import io.micrometer.observation.ObservationRegistry; +import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.model.SpringAIModelProperties; import org.springframework.ai.model.SpringAIModels; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; -import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.model.function.DefaultFunctionCallbackResolver; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.model.function.FunctionCallbackResolver; import org.springframework.ai.moonshot.MoonshotChatModel; import org.springframework.ai.moonshot.api.MoonshotApi; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotChatAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotChatAutoConfigurationIT.java index 33f29afba92..c5e13650def 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotChatAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotChatAutoConfigurationIT.java @@ -25,11 +25,11 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import reactor.core.publisher.Flux; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.moonshot.MoonshotChatModel; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotPropertiesTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotPropertiesTests.java index bec989217d5..86274d65f1b 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotPropertiesTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/MoonshotPropertiesTests.java @@ -18,8 +18,8 @@ import org.junit.jupiter.api.Test; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.moonshot.MoonshotChatModel; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/FunctionCallbackInPromptIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/FunctionCallbackInPromptIT.java index 44960f9c506..83ab3986417 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/FunctionCallbackInPromptIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/FunctionCallbackInPromptIT.java @@ -25,16 +25,16 @@ import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; -import org.springframework.ai.model.moonshot.autoconfigure.MoonshotChatAutoConfiguration; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.model.function.FunctionCallback; +import org.springframework.ai.model.moonshot.autoconfigure.MoonshotChatAutoConfiguration; import org.springframework.ai.moonshot.MoonshotChatModel; import org.springframework.ai.moonshot.MoonshotChatOptions; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/FunctionCallbackWithPlainFunctionBeanIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/FunctionCallbackWithPlainFunctionBeanIT.java index a5f0e1e3002..025c46ab9e1 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/FunctionCallbackWithPlainFunctionBeanIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/FunctionCallbackWithPlainFunctionBeanIT.java @@ -26,16 +26,16 @@ import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; -import org.springframework.ai.model.moonshot.autoconfigure.MoonshotChatAutoConfiguration; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.model.function.FunctionCallingOptions; +import org.springframework.ai.model.moonshot.autoconfigure.MoonshotChatAutoConfiguration; import org.springframework.ai.moonshot.MoonshotChatModel; import org.springframework.ai.moonshot.MoonshotChatOptions; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/MoonshotFunctionCallbackIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/MoonshotFunctionCallbackIT.java index c769d515558..254ec524b52 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/MoonshotFunctionCallbackIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-moonshot/src/test/java/org/springframework/ai/model/moonshot/autoconfigure/tool/MoonshotFunctionCallbackIT.java @@ -26,16 +26,16 @@ import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; -import org.springframework.ai.model.moonshot.autoconfigure.MoonshotChatAutoConfiguration; -import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.model.function.FunctionCallback; +import org.springframework.ai.model.moonshot.autoconfigure.MoonshotChatAutoConfiguration; import org.springframework.ai.moonshot.MoonshotChatModel; import org.springframework.ai.moonshot.MoonshotChatOptions; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAIAutoConfigurationUtil.java b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAIAutoConfigurationUtil.java index 344e2f7e38f..60fbb75cbcc 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAIAutoConfigurationUtil.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAIAutoConfigurationUtil.java @@ -27,9 +27,13 @@ import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; -public class OpenAIAutoConfigurationUtil { +public final class OpenAIAutoConfigurationUtil { - protected static @NotNull ResolvedConnectionProperties resolveConnectionProperties( + private OpenAIAutoConfigurationUtil() { + // Avoids instantiation + } + + public static @NotNull ResolvedConnectionProperties resolveConnectionProperties( OpenAiParentProperties commonProperties, OpenAiParentProperties modelProperties, String modelType) { String baseUrl = StringUtils.hasText(modelProperties.getBaseUrl()) ? modelProperties.getBaseUrl() diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/tool/FunctionCallbackInPrompt2IT.java b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/tool/FunctionCallbackInPrompt2IT.java index 23acefa0ca6..7b334589520 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/tool/FunctionCallbackInPrompt2IT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/tool/FunctionCallbackInPrompt2IT.java @@ -59,7 +59,7 @@ void functionCallTest() { .call().content(); String content = ChatClient.builder(chatModel).build().prompt() - .user("What's the weather like in San Francisco, Tokyo, and Paris?") + .user("What's the weather like in San Francisco, Tokyo, and Paris?") .functions(FunctionToolCallback .builder("CurrentWeatherService", new MockWeatherService()) .description("Get the weather in location") diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithFunctionBeanIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithFunctionBeanIT.java index 99e6df1bac7..89c827ee571 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithFunctionBeanIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithFunctionBeanIT.java @@ -24,11 +24,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ai.model.vertexai.autoconfigure.gemini.VertexAiGeminiChatAutoConfiguration; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.model.function.FunctionCallingOptions; +import org.springframework.ai.model.vertexai.autoconfigure.gemini.VertexAiGeminiChatAutoConfiguration; import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel; import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatOptions; import org.springframework.boot.autoconfigure.AutoConfigurations; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithFunctionWrapperIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithFunctionWrapperIT.java index a0c38b4172d..bf8c4efbfa1 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithFunctionWrapperIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithFunctionWrapperIT.java @@ -23,10 +23,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ai.model.vertexai.autoconfigure.gemini.VertexAiGeminiChatAutoConfiguration; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.vertexai.autoconfigure.gemini.VertexAiGeminiChatAutoConfiguration; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel; diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithPromptFunctionIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithPromptFunctionIT.java index 1c3ed81d73e..a446ac7e194 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithPromptFunctionIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/tool/FunctionCallWithPromptFunctionIT.java @@ -23,10 +23,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ai.model.vertexai.autoconfigure.gemini.VertexAiGeminiChatAutoConfiguration; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.vertexai.autoconfigure.gemini.VertexAiGeminiChatAutoConfiguration; import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel; import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatOptions; diff --git a/auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/test/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfigurationTests.java b/auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/test/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfigurationTests.java index c320ca5fbfe..bb03817dfb8 100644 --- a/auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/test/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfigurationTests.java +++ b/auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/test/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfigurationTests.java @@ -128,12 +128,6 @@ public ToolCallbackProvider toolCallbacks() { return MethodToolCallbackProvider.builder().toolObjects(new WeatherService()).build(); } - public record Request(String location) { - } - - public record Response(String temperature) { - } - @Bean @Description("Get the weather in location. Return temperature in 36°F or 36°C format.") public Function weatherFunction1() { @@ -188,6 +182,12 @@ public ToolCallback toolCallbacks6() { .build(); } + public record Request(String location) { + } + + public record Response(String temperature) { + } + } } diff --git a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase/src/main/java/org/springframework/ai/vectorstore/couchbase/autoconfigure/CouchbaseSearchVectorStoreProperties.java b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase/src/main/java/org/springframework/ai/vectorstore/couchbase/autoconfigure/CouchbaseSearchVectorStoreProperties.java index 0aeb86a417f..0af6d225e62 100644 --- a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase/src/main/java/org/springframework/ai/vectorstore/couchbase/autoconfigure/CouchbaseSearchVectorStoreProperties.java +++ b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase/src/main/java/org/springframework/ai/vectorstore/couchbase/autoconfigure/CouchbaseSearchVectorStoreProperties.java @@ -77,7 +77,7 @@ public void setIndexName(String indexName) { } public String getCollectionName() { - return collectionName; + return this.collectionName; } public void setCollectionName(String collectionName) { @@ -85,7 +85,7 @@ public void setCollectionName(String collectionName) { } public String getScopeName() { - return scopeName; + return this.scopeName; } public void setScopeName(String scopeName) { @@ -93,7 +93,7 @@ public void setScopeName(String scopeName) { } public String getBucketName() { - return bucketName; + return this.bucketName; } public void setBucketName(String bucketName) { @@ -101,7 +101,7 @@ public void setBucketName(String bucketName) { } public Integer getDimensions() { - return dimensions; + return this.dimensions; } public void setDimensions(Integer dimensions) { @@ -109,7 +109,7 @@ public void setDimensions(Integer dimensions) { } public CouchbaseSimilarityFunction getSimilarity() { - return similarity; + return this.similarity; } public void setSimilarity(CouchbaseSimilarityFunction similarity) { @@ -117,7 +117,7 @@ public void setSimilarity(CouchbaseSimilarityFunction similarity) { } public CouchbaseIndexOptimization getOptimization() { - return optimization; + return this.optimization; } public void setOptimization(CouchbaseIndexOptimization optimization) { diff --git a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase/src/test/java/org/springframework/ai/vectorstore/couchbase/autoconfigure/CouchbaseSearchVectorStoreAutoConfigurationIT.java b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase/src/test/java/org/springframework/ai/vectorstore/couchbase/autoconfigure/CouchbaseSearchVectorStoreAutoConfigurationIT.java index 936a68d47aa..0b7531484aa 100644 --- a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase/src/test/java/org/springframework/ai/vectorstore/couchbase/autoconfigure/CouchbaseSearchVectorStoreAutoConfigurationIT.java +++ b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase/src/test/java/org/springframework/ai/vectorstore/couchbase/autoconfigure/CouchbaseSearchVectorStoreAutoConfigurationIT.java @@ -79,7 +79,7 @@ class CouchbaseSearchVectorStoreAutoConfigurationIT { @Test public void addAndSearchWithFilters() { - contextRunner.run(context -> { + this.contextRunner.run(context -> { VectorStore vectorStore = context.getBean(VectorStore.class); diff --git a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-elasticsearch/src/main/java/org/springframework/ai/vectorstore/elasticsearch/autoconfigure/ElasticsearchVectorStoreProperties.java b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-elasticsearch/src/main/java/org/springframework/ai/vectorstore/elasticsearch/autoconfigure/ElasticsearchVectorStoreProperties.java index 944250e11f4..c1f869c8d56 100644 --- a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-elasticsearch/src/main/java/org/springframework/ai/vectorstore/elasticsearch/autoconfigure/ElasticsearchVectorStoreProperties.java +++ b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-elasticsearch/src/main/java/org/springframework/ai/vectorstore/elasticsearch/autoconfigure/ElasticsearchVectorStoreProperties.java @@ -77,7 +77,7 @@ public void setSimilarity(SimilarityFunction similarity) { } public String getEmbeddingFieldName() { - return embeddingFieldName; + return this.embeddingFieldName; } public void setEmbeddingFieldName(String embeddingFieldName) { diff --git a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mariadb/src/main/java/org/springframework/ai/vectorstore/mariadb/autoconfigure/MariaDbStoreProperties.java b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mariadb/src/main/java/org/springframework/ai/vectorstore/mariadb/autoconfigure/MariaDbStoreProperties.java index 2df6e836545..59b32748528 100644 --- a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mariadb/src/main/java/org/springframework/ai/vectorstore/mariadb/autoconfigure/MariaDbStoreProperties.java +++ b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mariadb/src/main/java/org/springframework/ai/vectorstore/mariadb/autoconfigure/MariaDbStoreProperties.java @@ -108,7 +108,7 @@ public void setMaxDocumentBatchSize(int maxDocumentBatchSize) { } public String getEmbeddingFieldName() { - return embeddingFieldName; + return this.embeddingFieldName; } public void setEmbeddingFieldName(String embeddingFieldName) { @@ -116,7 +116,7 @@ public void setEmbeddingFieldName(String embeddingFieldName) { } public String getIdFieldName() { - return idFieldName; + return this.idFieldName; } public void setIdFieldName(String idFieldName) { @@ -124,7 +124,7 @@ public void setIdFieldName(String idFieldName) { } public String getMetadataFieldName() { - return metadataFieldName; + return this.metadataFieldName; } public void setMetadataFieldName(String metadataFieldName) { @@ -132,7 +132,7 @@ public void setMetadataFieldName(String metadataFieldName) { } public String getContentFieldName() { - return contentFieldName; + return this.contentFieldName; } public void setContentFieldName(String contentFieldName) { diff --git a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pgvector/src/main/java/org/springframework/ai/vectorstore/pgvector/autoconfigure/PgVectorStoreProperties.java b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pgvector/src/main/java/org/springframework/ai/vectorstore/pgvector/autoconfigure/PgVectorStoreProperties.java index da81913ed07..e4535edb5b7 100644 --- a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pgvector/src/main/java/org/springframework/ai/vectorstore/pgvector/autoconfigure/PgVectorStoreProperties.java +++ b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pgvector/src/main/java/org/springframework/ai/vectorstore/pgvector/autoconfigure/PgVectorStoreProperties.java @@ -102,7 +102,7 @@ public void setSchemaName(String schemaName) { } public PgVectorStore.PgIdType getIdType() { - return idType; + return this.idType; } public void setIdType(PgVectorStore.PgIdType idType) { diff --git a/document-readers/jsoup-reader/src/main/java/org/springframework/ai/reader/jsoup/JsoupDocumentReader.java b/document-readers/jsoup-reader/src/main/java/org/springframework/ai/reader/jsoup/JsoupDocumentReader.java index e3fd7989d90..55b1f84ea48 100644 --- a/document-readers/jsoup-reader/src/main/java/org/springframework/ai/reader/jsoup/JsoupDocumentReader.java +++ b/document-readers/jsoup-reader/src/main/java/org/springframework/ai/reader/jsoup/JsoupDocumentReader.java @@ -68,7 +68,7 @@ public JsoupDocumentReader(Resource htmlResource, JsoupDocumentReaderConfig conf @Override public List get() { - try (InputStream inputStream = htmlResource.getInputStream()) { + try (InputStream inputStream = this.htmlResource.getInputStream()) { org.jsoup.nodes.Document doc = Jsoup.parse(inputStream, this.config.charset, ""); List documents = new ArrayList<>(); @@ -104,7 +104,7 @@ else if (this.config.groupByElement) { } catch (IOException e) { - throw new RuntimeException("Failed to read HTML resource: " + htmlResource, e); + throw new RuntimeException("Failed to read HTML resource: " + this.htmlResource, e); } } diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/PagePdfDocumentReader.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/PagePdfDocumentReader.java index 724f7ee5c0a..4919929a57b 100644 --- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/PagePdfDocumentReader.java +++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/PagePdfDocumentReader.java @@ -112,7 +112,7 @@ public List get() { for (PDPage page : this.document.getDocumentCatalog().getPages()) { lastPage = page; if (counter % logFrequency == 0 && counter / logFrequency < 10) { - logger.info("Processing PDF page: {}", (counter + 1)); + this.logger.info("Processing PDF page: {}", (counter + 1)); } counter++; @@ -154,7 +154,7 @@ public List get() { readDocuments.add(toDocument(lastPage, pageTextGroupList.stream().collect(Collectors.joining()), startPageNumber, pageNumber)); } - logger.info("Processing {} pages", totalPages); + this.logger.info("Processing {} pages", totalPages); return readDocuments; } diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReader.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReader.java index 95863fff649..fa9bac7d8c0 100644 --- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReader.java +++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReader.java @@ -133,7 +133,7 @@ public List get() { List documents = new ArrayList<>(paragraphs.size()); if (!CollectionUtils.isEmpty(paragraphs)) { - logger.info("Start processing paragraphs from PDF"); + this.logger.info("Start processing paragraphs from PDF"); Iterator itr = paragraphs.iterator(); var current = itr.next(); @@ -152,7 +152,7 @@ public List get() { } } } - logger.info("End processing paragraphs from PDF"); + this.logger.info("End processing paragraphs from PDF"); return documents; } diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallbackProvider.java b/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallbackProvider.java index 73c4c20b155..1b6a191156c 100644 --- a/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallbackProvider.java +++ b/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallbackProvider.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.mcp; import java.util.ArrayList; @@ -146,7 +147,7 @@ public ToolCallback[] getToolCallbacks() { ToolCallback[] toolCallbacks = mcpClient.listTools() .map(response -> response.tools() .stream() - .filter(tool -> toolFilter.test(mcpClient, tool)) + .filter(tool -> this.toolFilter.test(mcpClient, tool)) .map(tool -> new AsyncMcpToolCallback(mcpClient, tool)) .toArray(ToolCallback[]::new)) .block(); diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/McpToolUtils.java b/mcp/common/src/main/java/org/springframework/ai/mcp/McpToolUtils.java index 93d007fa8eb..f1e30311b01 100644 --- a/mcp/common/src/main/java/org/springframework/ai/mcp/McpToolUtils.java +++ b/mcp/common/src/main/java/org/springframework/ai/mcp/McpToolUtils.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.mcp; import java.util.List; @@ -35,7 +36,6 @@ import org.springframework.ai.chat.model.ToolContext; import org.springframework.ai.model.ModelOptionsUtils; import org.springframework.ai.tool.ToolCallback; -import org.springframework.ai.util.json.JsonParser; import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; import org.springframework.util.MimeType; diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallbackProvider.java b/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallbackProvider.java index 9e11b9dfc4f..6d33b200154 100644 --- a/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallbackProvider.java +++ b/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallbackProvider.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.mcp; import java.util.ArrayList; @@ -132,14 +133,13 @@ public ToolCallback[] getToolCallbacks() { var toolCallbacks = new ArrayList<>(); - this.mcpClients.stream().forEach(mcpClient -> { - toolCallbacks.addAll(mcpClient.listTools() + this.mcpClients.stream() + .forEach(mcpClient -> toolCallbacks.addAll(mcpClient.listTools() .tools() .stream() - .filter(tool -> toolFilter.test(mcpClient, tool)) + .filter(tool -> this.toolFilter.test(mcpClient, tool)) .map(tool -> new SyncMcpToolCallback(mcpClient, tool)) - .toList()); - }); + .toList())); var array = toolCallbacks.toArray(new ToolCallback[0]); validateToolCallbacks(array); return array; diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/aot/McpHints.java b/mcp/common/src/main/java/org/springframework/ai/mcp/aot/McpHints.java index fcf8c81d2e5..52f34fa2a7d 100644 --- a/mcp/common/src/main/java/org/springframework/ai/mcp/aot/McpHints.java +++ b/mcp/common/src/main/java/org/springframework/ai/mcp/aot/McpHints.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.mcp.aot; import java.util.ArrayList; diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/customizer/McpAsyncClientCustomizer.java b/mcp/common/src/main/java/org/springframework/ai/mcp/customizer/McpAsyncClientCustomizer.java index b059bcbe3c5..6d5e01a3dfe 100644 --- a/mcp/common/src/main/java/org/springframework/ai/mcp/customizer/McpAsyncClientCustomizer.java +++ b/mcp/common/src/main/java/org/springframework/ai/mcp/customizer/McpAsyncClientCustomizer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.mcp.customizer; import io.modelcontextprotocol.client.McpClient; diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/customizer/McpSyncClientCustomizer.java b/mcp/common/src/main/java/org/springframework/ai/mcp/customizer/McpSyncClientCustomizer.java index 98c0a1cdca8..7c86efbbaf1 100644 --- a/mcp/common/src/main/java/org/springframework/ai/mcp/customizer/McpSyncClientCustomizer.java +++ b/mcp/common/src/main/java/org/springframework/ai/mcp/customizer/McpSyncClientCustomizer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.mcp.customizer; import io.modelcontextprotocol.client.McpClient; diff --git a/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackProviderTests.java b/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackProviderTests.java index be5cc98590c..af37670de73 100644 --- a/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackProviderTests.java +++ b/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackProviderTests.java @@ -16,23 +16,22 @@ package org.springframework.ai.mcp; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import java.util.List; import java.util.function.BiPredicate; +import io.modelcontextprotocol.client.McpSyncClient; +import io.modelcontextprotocol.spec.McpSchema.Implementation; +import io.modelcontextprotocol.spec.McpSchema.ListToolsResult; +import io.modelcontextprotocol.spec.McpSchema.Tool; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import io.modelcontextprotocol.client.McpSyncClient; -import io.modelcontextprotocol.spec.McpSchema.Implementation; -import io.modelcontextprotocol.spec.McpSchema.ListToolsResult; -import io.modelcontextprotocol.spec.McpSchema.Tool; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class SyncMcpToolCallbackProviderTests { @@ -45,9 +44,9 @@ void getToolCallbacksShouldReturnEmptyArrayWhenNoTools() { ListToolsResult listToolsResult = mock(ListToolsResult.class); when(listToolsResult.tools()).thenReturn(List.of()); - when(mcpClient.listTools()).thenReturn(listToolsResult); + when(this.mcpClient.listTools()).thenReturn(listToolsResult); - SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(mcpClient); + SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(this.mcpClient); var callbacks = provider.getToolCallbacks(); @@ -58,7 +57,7 @@ void getToolCallbacksShouldReturnEmptyArrayWhenNoTools() { void getToolCallbacksShouldReturnCallbacksForEachTool() { var clientInfo = new Implementation("testClient", "1.0.0"); - when(mcpClient.getClientInfo()).thenReturn(clientInfo); + when(this.mcpClient.getClientInfo()).thenReturn(clientInfo); Tool tool1 = mock(Tool.class); when(tool1.name()).thenReturn("tool1"); @@ -68,9 +67,9 @@ void getToolCallbacksShouldReturnCallbacksForEachTool() { ListToolsResult listToolsResult = mock(ListToolsResult.class); when(listToolsResult.tools()).thenReturn(List.of(tool1, tool2)); - when(mcpClient.listTools()).thenReturn(listToolsResult); + when(this.mcpClient.listTools()).thenReturn(listToolsResult); - SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(mcpClient); + SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(this.mcpClient); var callbacks = provider.getToolCallbacks(); @@ -80,7 +79,7 @@ void getToolCallbacksShouldReturnCallbacksForEachTool() { @Test void getToolCallbacksShouldThrowExceptionForDuplicateToolNames() { var clientInfo = new Implementation("testClient", "1.0.0"); - when(mcpClient.getClientInfo()).thenReturn(clientInfo); + when(this.mcpClient.getClientInfo()).thenReturn(clientInfo); Tool tool1 = mock(Tool.class); when(tool1.name()).thenReturn("sameName"); @@ -90,9 +89,9 @@ void getToolCallbacksShouldThrowExceptionForDuplicateToolNames() { ListToolsResult listToolsResult = mock(ListToolsResult.class); when(listToolsResult.tools()).thenReturn(List.of(tool1, tool2)); - when(mcpClient.listTools()).thenReturn(listToolsResult); + when(this.mcpClient.listTools()).thenReturn(listToolsResult); - SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(mcpClient); + SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(this.mcpClient); assertThatThrownBy(() -> provider.getToolCallbacks()).isInstanceOf(IllegalStateException.class) .hasMessageContaining("Multiple tools with the same name"); @@ -133,7 +132,7 @@ void getSameNameToolsButDifferntClientInfoNamesShouldProduceDifferentToolCallbac @Test void toolFilterShouldAcceptAllToolsByDefault() { var clientInfo = new Implementation("testClient", "1.0.0"); - when(mcpClient.getClientInfo()).thenReturn(clientInfo); + when(this.mcpClient.getClientInfo()).thenReturn(clientInfo); Tool tool1 = mock(Tool.class); when(tool1.name()).thenReturn("tool1"); @@ -143,11 +142,11 @@ void toolFilterShouldAcceptAllToolsByDefault() { ListToolsResult listToolsResult = mock(ListToolsResult.class); when(listToolsResult.tools()).thenReturn(List.of(tool1, tool2)); - when(mcpClient.listTools()).thenReturn(listToolsResult); + when(this.mcpClient.listTools()).thenReturn(listToolsResult); // Using the constructor without explicit filter (should use default filter that // accepts all) - SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(mcpClient); + SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(this.mcpClient); var callbacks = provider.getToolCallbacks(); @@ -162,12 +161,12 @@ void toolFilterShouldRejectAllToolsWhenConfigured() { ListToolsResult listToolsResult = mock(ListToolsResult.class); when(listToolsResult.tools()).thenReturn(List.of(tool1, tool2)); - when(mcpClient.listTools()).thenReturn(listToolsResult); + when(this.mcpClient.listTools()).thenReturn(listToolsResult); // Create a filter that rejects all tools BiPredicate rejectAllFilter = (client, tool) -> false; - SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(rejectAllFilter, mcpClient); + SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(rejectAllFilter, this.mcpClient); var callbacks = provider.getToolCallbacks(); @@ -177,7 +176,7 @@ void toolFilterShouldRejectAllToolsWhenConfigured() { @Test void toolFilterShouldFilterToolsByNameWhenConfigured() { var clientInfo = new Implementation("testClient", "1.0.0"); - when(mcpClient.getClientInfo()).thenReturn(clientInfo); + when(this.mcpClient.getClientInfo()).thenReturn(clientInfo); Tool tool1 = mock(Tool.class); when(tool1.name()).thenReturn("tool1"); @@ -190,13 +189,13 @@ void toolFilterShouldFilterToolsByNameWhenConfigured() { ListToolsResult listToolsResult = mock(ListToolsResult.class); when(listToolsResult.tools()).thenReturn(List.of(tool1, tool2, tool3)); - when(mcpClient.listTools()).thenReturn(listToolsResult); + when(this.mcpClient.listTools()).thenReturn(listToolsResult); // Create a filter that only accepts tools with names containing "2" or "3" BiPredicate nameFilter = (client, tool) -> tool.name().contains("2") || tool.name().contains("3"); - SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(nameFilter, mcpClient); + SyncMcpToolCallbackProvider provider = new SyncMcpToolCallbackProvider(nameFilter, this.mcpClient); var callbacks = provider.getToolCallbacks(); diff --git a/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackTests.java b/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackTests.java index 47fb55ef1de..1c8d2b5618f 100644 --- a/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackTests.java +++ b/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackTests.java @@ -48,11 +48,11 @@ class SyncMcpToolCallbackTests { void getToolDefinitionShouldReturnCorrectDefinition() { var clientInfo = new Implementation("testClient", "1.0.0"); - when(mcpClient.getClientInfo()).thenReturn(clientInfo); - when(tool.name()).thenReturn("testTool"); - when(tool.description()).thenReturn("Test tool description"); + when(this.mcpClient.getClientInfo()).thenReturn(clientInfo); + when(this.tool.name()).thenReturn("testTool"); + when(this.tool.description()).thenReturn("Test tool description"); - SyncMcpToolCallback callback = new SyncMcpToolCallback(mcpClient, tool); + SyncMcpToolCallback callback = new SyncMcpToolCallback(this.mcpClient, this.tool); var toolDefinition = callback.getToolDefinition(); @@ -66,11 +66,11 @@ void callShouldHandleJsonInputAndOutput() { // when(mcpClient.getClientInfo()).thenReturn(new Implementation("testClient", // "1.0.0")); - when(tool.name()).thenReturn("testTool"); + when(this.tool.name()).thenReturn("testTool"); CallToolResult callResult = mock(CallToolResult.class); - when(mcpClient.callTool(any(CallToolRequest.class))).thenReturn(callResult); + when(this.mcpClient.callTool(any(CallToolRequest.class))).thenReturn(callResult); - SyncMcpToolCallback callback = new SyncMcpToolCallback(mcpClient, tool); + SyncMcpToolCallback callback = new SyncMcpToolCallback(this.mcpClient, this.tool); String response = callback.call("{\"param\":\"value\"}"); @@ -83,11 +83,11 @@ void callShoulIngroeToolContext() { // when(mcpClient.getClientInfo()).thenReturn(new Implementation("testClient", // "1.0.0")); - when(tool.name()).thenReturn("testTool"); + when(this.tool.name()).thenReturn("testTool"); CallToolResult callResult = mock(CallToolResult.class); - when(mcpClient.callTool(any(CallToolRequest.class))).thenReturn(callResult); + when(this.mcpClient.callTool(any(CallToolRequest.class))).thenReturn(callResult); - SyncMcpToolCallback callback = new SyncMcpToolCallback(mcpClient, tool); + SyncMcpToolCallback callback = new SyncMcpToolCallback(this.mcpClient, this.tool); String response = callback.call("{\"param\":\"value\"}", new ToolContext(Map.of("foo", "bar"))); diff --git a/memory/spring-ai-model-chat-memory-jdbc/src/main/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemory.java b/memory/spring-ai-model-chat-memory-jdbc/src/main/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemory.java index 477f7509a19..6c9825bac1b 100644 --- a/memory/spring-ai-model-chat-memory-jdbc/src/main/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemory.java +++ b/memory/spring-ai-model-chat-memory-jdbc/src/main/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemory.java @@ -22,7 +22,11 @@ import java.util.List; import org.springframework.ai.chat.memory.ChatMemory; -import org.springframework.ai.chat.messages.*; +import org.springframework.ai.chat.messages.AssistantMessage; +import org.springframework.ai.chat.messages.Message; +import org.springframework.ai.chat.messages.MessageType; +import org.springframework.ai.chat.messages.SystemMessage; +import org.springframework.ai.chat.messages.UserMessage; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; diff --git a/memory/spring-ai-model-chat-memory-jdbc/src/main/java/org/springframework/ai/chat/memory/jdbc/aot/hint/JdbcChatMemoryRuntimeHints.java b/memory/spring-ai-model-chat-memory-jdbc/src/main/java/org/springframework/ai/chat/memory/jdbc/aot/hint/JdbcChatMemoryRuntimeHints.java index eae3206f9a9..6740602e3f8 100644 --- a/memory/spring-ai-model-chat-memory-jdbc/src/main/java/org/springframework/ai/chat/memory/jdbc/aot/hint/JdbcChatMemoryRuntimeHints.java +++ b/memory/spring-ai-model-chat-memory-jdbc/src/main/java/org/springframework/ai/chat/memory/jdbc/aot/hint/JdbcChatMemoryRuntimeHints.java @@ -1,3 +1,19 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.chat.memory.jdbc.aot.hint; import javax.sql.DataSource; @@ -16,7 +32,7 @@ class JdbcChatMemoryRuntimeHints implements RuntimeHintsRegistrar { @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { hints.reflection() - .registerType(DataSource.class, (hint) -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS)); + .registerType(DataSource.class, hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS)); hints.resources() .registerPattern("org/springframework/ai/chat/memory/jdbc/schema-mariadb.sql") diff --git a/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemoryConfigTest.java b/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemoryConfigTest.java index 7ae2c4477a1..c553abb7509 100644 --- a/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemoryConfigTest.java +++ b/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemoryConfigTest.java @@ -1,3 +1,19 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.chat.memory.jdbc; import org.junit.jupiter.api.Test; diff --git a/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemoryIT.java b/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemoryIT.java index 1651bd49e87..96b0e7ca5f8 100644 --- a/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemoryIT.java +++ b/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/JdbcChatMemoryIT.java @@ -32,7 +32,11 @@ import org.testcontainers.utility.MountableFile; import org.springframework.ai.chat.memory.ChatMemory; -import org.springframework.ai.chat.messages.*; +import org.springframework.ai.chat.messages.AssistantMessage; +import org.springframework.ai.chat.messages.Message; +import org.springframework.ai.chat.messages.MessageType; +import org.springframework.ai.chat.messages.SystemMessage; +import org.springframework.ai.chat.messages.UserMessage; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; diff --git a/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/aot/hint/JdbcChatMemoryRuntimeHintsTest.java b/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/aot/hint/JdbcChatMemoryRuntimeHintsTest.java index 1a6c7ff2d83..90c65272d72 100644 --- a/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/aot/hint/JdbcChatMemoryRuntimeHintsTest.java +++ b/memory/spring-ai-model-chat-memory-jdbc/src/test/java/org/springframework/ai/chat/memory/jdbc/aot/hint/JdbcChatMemoryRuntimeHintsTest.java @@ -49,7 +49,7 @@ void aotFactoriesContainsRegistrar() { var match = SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories") .load(RuntimeHintsRegistrar.class) .stream() - .anyMatch((registrar) -> registrar instanceof JdbcChatMemoryRuntimeHints); + .anyMatch(registrar -> registrar instanceof JdbcChatMemoryRuntimeHints); assertThat(match).isTrue(); } diff --git a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/MediaAttributes.java b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/MediaAttributes.java index 4169f4faa6a..126e8247cab 100644 --- a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/MediaAttributes.java +++ b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/MediaAttributes.java @@ -30,7 +30,7 @@ public enum MediaAttributes { } public String getValue() { - return value; + return this.value; } } diff --git a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/MessageAttributes.java b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/MessageAttributes.java index 77f10ec3a18..a20b6c19964 100644 --- a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/MessageAttributes.java +++ b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/MessageAttributes.java @@ -26,7 +26,7 @@ public enum MessageAttributes { private final String value; public String getValue() { - return value; + return this.value; } MessageAttributes(String value) { diff --git a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemory.java b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemory.java index 7fdcb9b1a34..0acae6f0734 100644 --- a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemory.java +++ b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemory.java @@ -16,9 +16,19 @@ package org.springframework.ai.chat.memory.neo4j; +import java.net.MalformedURLException; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + import org.neo4j.driver.Driver; import org.neo4j.driver.Result; import org.neo4j.driver.Transaction; + import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.Message; @@ -30,15 +40,6 @@ import org.springframework.ai.content.MediaContent; import org.springframework.util.MimeType; -import java.net.MalformedURLException; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - /** * Chat memory implementation using Neo4j. * @@ -66,7 +67,7 @@ public void add(String conversationId, Message message) { @Override public void add(String conversationId, List messages) { - try (Transaction t = driver.session().beginTransaction()) { + try (Transaction t = this.driver.session().beginTransaction()) { for (Message m : messages) { addMessageToTransaction(t, conversationId, m); } @@ -85,8 +86,9 @@ OPTIONAL MATCH (m)-[:HAS_TOOL_RESPONSE]-(tr:%s) WITH m, metadata, media, tr ORDE OPTIONAL MATCH (m)-[:HAS_TOOL_CALL]->(tc:%s) WITH m, metadata, media, tr, tc ORDER BY tc.idx ASC RETURN m, metadata, collect(tr) as toolResponses, collect(tc) as toolCalls, collect(media) as medias - """.formatted(config.getSessionLabel(), config.getMessageLabel(), config.getMetadataLabel(), - config.getMediaLabel(), config.getToolResponseLabel(), config.getToolCallLabel()); + """.formatted(this.config.getSessionLabel(), this.config.getMessageLabel(), + this.config.getMetadataLabel(), this.config.getMediaLabel(), this.config.getToolResponseLabel(), + this.config.getToolCallLabel()); Result res = this.driver.session() .run(statementBuilder, Map.of("conversationId", conversationId, "lastN", lastN)); return res.list(record -> { @@ -120,7 +122,7 @@ RETURN m, metadata, collect(tr) as toolResponses, collect(tc) as toolCalls, coll } public Neo4jChatMemoryConfig getConfig() { - return config; + return this.config; } @Override @@ -132,9 +134,10 @@ OPTIONAL MATCH (m)-[:HAS_MEDIA]->(media:%s) OPTIONAL MATCH (m)-[:HAS_TOOL_RESPONSE]-(tr:%s) OPTIONAL MATCH (m)-[:HAS_TOOL_CALL]->(tc:%s) DETACH DELETE m, metadata, media, tr, tc - """.formatted(config.getSessionLabel(), config.getMessageLabel(), config.getMetadataLabel(), - config.getMediaLabel(), config.getToolResponseLabel(), config.getToolCallLabel()); - try (Transaction t = driver.session().beginTransaction()) { + """.formatted(this.config.getSessionLabel(), this.config.getMessageLabel(), + this.config.getMetadataLabel(), this.config.getMediaLabel(), this.config.getToolResponseLabel(), + this.config.getToolCallLabel()); + try (Transaction t = this.driver.session().beginTransaction()) { t.run(statementBuilder, Map.of("conversationId", conversationId)); t.commit(); } @@ -149,7 +152,8 @@ private void addMessageToTransaction(Transaction t, String conversationId, Messa OPTIONAL MATCH (s)-[:HAS_MESSAGE]->(countMsg:%s) WITH coalesce(count(countMsg), 0) as totalMsg, s CREATE (s)-[:HAS_MESSAGE]->(msg:%s) SET msg = $messageProperties SET msg.idx = totalMsg + 1 - """.formatted(config.getSessionLabel(), config.getMessageLabel(), config.getMessageLabel())); + """.formatted(this.config.getSessionLabel(), this.config.getMessageLabel(), + this.config.getMessageLabel())); Map attributes = new HashMap<>(); attributes.put(MessageAttributes.MESSAGE_TYPE.getValue(), message.getMessageType().getValue()); @@ -163,7 +167,7 @@ OPTIONAL MATCH (s)-[:HAS_MESSAGE]->(countMsg:%s) WITH coalesce(count(countMsg), CREATE (metadataNode:%s) CREATE (msg)-[:HAS_METADATA]->(metadataNode) SET metadataNode = $metadata - """.formatted(config.getMetadataLabel())); + """.formatted(this.config.getMetadataLabel())); Map metadataCopy = new HashMap<>(message.getMetadata()); metadataCopy.remove("messageType"); queryParameters.put("metadata", metadataCopy); @@ -174,7 +178,7 @@ OPTIONAL MATCH (s)-[:HAS_MESSAGE]->(countMsg:%s) WITH coalesce(count(countMsg), WITH msg FOREACH(tc in $toolCalls | CREATE (toolCall:%s) SET toolCall = tc CREATE (msg)-[:HAS_TOOL_CALL]->(toolCall)) - """.formatted(config.getToolCallLabel())); + """.formatted(this.config.getToolCallLabel())); List> toolCallMaps = new ArrayList<>(); for (int i = 0; i < assistantMessage.getToolCalls().size(); i++) { AssistantMessage.ToolCall tc = assistantMessage.getToolCalls().get(i); @@ -202,7 +206,7 @@ OPTIONAL MATCH (s)-[:HAS_MESSAGE]->(countMsg:%s) WITH coalesce(count(countMsg), FOREACH(tr IN $toolResponses | CREATE (tm:%s) SET tm = tr MERGE (msg)-[:HAS_TOOL_RESPONSE]->(tm)) - """.formatted(config.getToolResponseLabel())); + """.formatted(this.config.getToolResponseLabel())); queryParameters.put("toolResponses", toolResponseMaps); } if (message instanceof MediaContent messageWithMedia && !messageWithMedia.getMedia().isEmpty()) { @@ -212,7 +216,7 @@ OPTIONAL MATCH (s)-[:HAS_MESSAGE]->(countMsg:%s) WITH coalesce(count(countMsg), UNWIND $media AS m CREATE (media:%s) SET media = m WITH msg, media CREATE (msg)-[:HAS_MEDIA]->(media) - """.formatted(config.getMediaLabel())); + """.formatted(this.config.getMediaLabel())); queryParameters.put("media", mediaNodes); } t.run(statementBuilder.toString(), queryParameters); diff --git a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemoryConfig.java b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemoryConfig.java index baa58d6638b..9d4b23877fe 100644 --- a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemoryConfig.java +++ b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/Neo4jChatMemoryConfig.java @@ -58,31 +58,31 @@ public final class Neo4jChatMemoryConfig { private final String mediaLabel; public String getSessionLabel() { - return sessionLabel; + return this.sessionLabel; } public String getToolCallLabel() { - return toolCallLabel; + return this.toolCallLabel; } public String getMetadataLabel() { - return metadataLabel; + return this.metadataLabel; } public String getMessageLabel() { - return messageLabel; + return this.messageLabel; } public String getToolResponseLabel() { - return toolResponseLabel; + return this.toolResponseLabel; } public String getMediaLabel() { - return mediaLabel; + return this.mediaLabel; } public Driver getDriver() { - return driver; + return this.driver; } private Neo4jChatMemoryConfig(Builder builder) { @@ -119,27 +119,27 @@ private Builder() { } public String getSessionLabel() { - return sessionLabel; + return this.sessionLabel; } public String getToolCallLabel() { - return toolCallLabel; + return this.toolCallLabel; } public String getMetadataLabel() { - return metadataLabel; + return this.metadataLabel; } public String getMessageLabel() { - return messageLabel; + return this.messageLabel; } public String getToolResponseLabel() { - return toolResponseLabel; + return this.toolResponseLabel; } public String getMediaLabel() { - return mediaLabel; + return this.mediaLabel; } public Builder withSessionLabel(String sessionLabel) { @@ -173,7 +173,7 @@ public Builder withMediaLabel(String mediaLabel) { } public Driver getDriver() { - return driver; + return this.driver; } public Builder withDriver(Driver driver) { diff --git a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/ToolCallAttributes.java b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/ToolCallAttributes.java index e883f63579a..f71cf8f76e5 100644 --- a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/ToolCallAttributes.java +++ b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/ToolCallAttributes.java @@ -30,7 +30,7 @@ public enum ToolCallAttributes { } public String getValue() { - return value; + return this.value; } } diff --git a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/ToolResponseAttributes.java b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/ToolResponseAttributes.java index cd1c82a5847..b725aa795df 100644 --- a/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/ToolResponseAttributes.java +++ b/memory/spring-ai-model-chat-memory-neo4j/src/main/java/org/springframework/ai/chat/memory/neo4j/ToolResponseAttributes.java @@ -30,7 +30,7 @@ public enum ToolResponseAttributes { } public String getValue() { - return value; + return this.value; } } diff --git a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java index 61d7b8010c6..d895d4070b4 100644 --- a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java +++ b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java @@ -269,7 +269,8 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha return Flux.just(ChatResponse.builder().from(chatResponse) .generations(ToolExecutionResult.buildGenerations(toolExecutionResult)) .build()); - } else { + } + else { // Send the tool execution result back to the model. return this.internalStream(new Prompt(toolExecutionResult.conversationHistory(), prompt.getOptions()), chatResponse); @@ -596,12 +597,12 @@ public Builder observationRegistry(ObservationRegistry observationRegistry) { } public AnthropicChatModel build() { - if (toolCallingManager != null) { - return new AnthropicChatModel(anthropicApi, defaultOptions, toolCallingManager, retryTemplate, - observationRegistry); + if (this.toolCallingManager != null) { + return new AnthropicChatModel(this.anthropicApi, this.defaultOptions, this.toolCallingManager, + this.retryTemplate, this.observationRegistry); } - return new AnthropicChatModel(anthropicApi, defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, retryTemplate, - observationRegistry, toolExecutionEligibilityPredicate); + return new AnthropicChatModel(this.anthropicApi, this.defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, + this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate); } } diff --git a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatOptions.java b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatOptions.java index de01e2f974d..5dde0cd3527 100644 --- a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatOptions.java +++ b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatOptions.java @@ -217,7 +217,7 @@ public void setToolNames(Set toolNames) { @Nullable @JsonIgnore public Boolean isInternalToolExecutionEnabled() { - return internalToolExecutionEnabled; + return this.internalToolExecutionEnabled; } @Override @@ -293,7 +293,7 @@ public void setToolContext(Map toolContext) { @JsonIgnore public Map getHttpHeaders() { - return httpHeaders; + return this.httpHeaders; } public void setHttpHeaders(Map httpHeaders) { @@ -328,8 +328,9 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(model, maxTokens, metadata, stopSequences, temperature, topP, topK, thinking, toolCallbacks, - toolNames, internalToolExecutionEnabled, toolContext, httpHeaders); + return Objects.hash(this.model, this.maxTokens, this.metadata, this.stopSequences, this.temperature, this.topP, + this.topK, this.thinking, this.toolCallbacks, this.toolNames, this.internalToolExecutionEnabled, + this.toolContext, this.httpHeaders); } public static class Builder { diff --git a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/aot/AnthropicRuntimeHints.java b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/aot/AnthropicRuntimeHints.java index 3a455404a5b..d007188cd13 100644 --- a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/aot/AnthropicRuntimeHints.java +++ b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/aot/AnthropicRuntimeHints.java @@ -16,8 +16,6 @@ package org.springframework.ai.anthropic.aot; -import org.springframework.ai.anthropic.AnthropicChatOptions; -import org.springframework.ai.anthropic.api.AnthropicApi; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java index 9d1bbea53da..87098c6d938 100644 --- a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java +++ b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java @@ -32,7 +32,6 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import org.springframework.ai.anthropic.api.AnthropicApi.ChatCompletionResponse; import org.springframework.ai.anthropic.api.StreamHelper.ChatCompletionResponseBuilder; import org.springframework.ai.model.ChatModelDescription; import org.springframework.ai.model.ModelOptionsUtils; 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 f308d289b54..a13c6cca869 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 @@ -23,7 +23,6 @@ import java.util.Map; import java.util.stream.Collectors; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import org.junit.jupiter.params.ParameterizedTest; @@ -46,10 +45,10 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.tool.ToolCallingChatOptions; import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.beans.factory.annotation.Autowired; @@ -384,10 +383,6 @@ void validateStreamCallResponseMetadata() { validateChatResponseMetadata(response, "claude-3-5-sonnet-latest"); } - record ActorsFilmsRecord(String actor, List movies) { - - } - @Test void thinkingTest() { UserMessage userMessage = new UserMessage( @@ -451,6 +446,10 @@ void testToolUseContentBlock() { } } + record ActorsFilmsRecord(String actor, List movies) { + + } + @SpringBootConfiguration public static class Config { diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatOptionsTests.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatOptionsTests.java index fbb8409dffc..62d97b459e4 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatOptionsTests.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatOptionsTests.java @@ -19,12 +19,12 @@ import java.util.List; import java.util.Map; -import static org.assertj.core.api.Assertions.assertThat; - import org.junit.jupiter.api.Test; import org.springframework.ai.anthropic.api.AnthropicApi.ChatCompletionRequest.Metadata; +import static org.assertj.core.api.Assertions.assertThat; + /** * Tests for {@link AnthropicChatOptions}. * diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java index b30d84017be..97331aa936b 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java @@ -221,7 +221,7 @@ void methodNoParameters() { TestFunctionClass targetObject = new TestFunctionClass(); - // @formatter:off + // @formatter:off var toolMethod = ReflectionUtils.findMethod( TestFunctionClass.class, "turnLivingRoomLightOn"); @@ -231,7 +231,7 @@ void methodNoParameters() { .toolMethod(toolMethod) .toolDefinition(ToolDefinition.builder(toolMethod) .description("Can turn lights on in the Living Room") - .build()) + .build()) .toolObject(targetObject) .build()) .call() @@ -248,7 +248,7 @@ void toolAnnotation() { TestFunctionClass targetObject = new TestFunctionClass(); - // @formatter:off + // @formatter:off String response = ChatClient.create(this.chatModel).prompt() .user("Turn light red in the living room.") .tools(targetObject) diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatModel.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatModel.java index 3c3a6cf505a..a70780436a1 100644 --- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatModel.java +++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatModel.java @@ -368,7 +368,7 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha }); return chatResponseFlux.flatMap(chatResponse -> { - if (toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), chatResponse)) { + if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), chatResponse)) { // FIXME: bounded elastic needs to be used since tool calling // is currently only synchronous return Flux.defer(() -> { @@ -923,7 +923,7 @@ public static Builder builder() { /** * Builder to construct {@link AzureOpenAiChatModel}. */ - public static class Builder { + public static final class Builder { private OpenAIClientBuilder openAIClientBuilder; @@ -968,12 +968,12 @@ public Builder observationRegistry(ObservationRegistry observationRegistry) { } public AzureOpenAiChatModel build() { - if (toolCallingManager != null) { - return new AzureOpenAiChatModel(openAIClientBuilder, defaultOptions, toolCallingManager, - observationRegistry, toolExecutionEligibilityPredicate); + if (this.toolCallingManager != null) { + return new AzureOpenAiChatModel(this.openAIClientBuilder, this.defaultOptions, this.toolCallingManager, + this.observationRegistry, this.toolExecutionEligibilityPredicate); } - return new AzureOpenAiChatModel(openAIClientBuilder, defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, - observationRegistry, toolExecutionEligibilityPredicate); + return new AzureOpenAiChatModel(this.openAIClientBuilder, this.defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, + this.observationRegistry, this.toolExecutionEligibilityPredicate); } } diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java index f90f99f64d6..0cc1177c6d0 100644 --- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java +++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java @@ -232,7 +232,7 @@ public void setToolNames(Set toolNames) { @Nullable @JsonIgnore public Boolean isInternalToolExecutionEnabled() { - return internalToolExecutionEnabled; + return this.internalToolExecutionEnabled; } @Override diff --git a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java index ff7222ff9df..cac64dbb954 100644 --- a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java +++ b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java @@ -671,7 +671,7 @@ private Flux internalStream(Prompt prompt, ChatResponse perviousCh Flux chatResponseFlux = chatResponses.switchMap(chatResponse -> { - if (toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), chatResponse) + if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), chatResponse) && chatResponse.hasFinishReasons(Set.of(StopReason.TOOL_USE.toString()))) { // FIXME: bounded elastic needs to be used since tool calling 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 b2a0cecacb7..731eec5498d 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 @@ -42,10 +42,10 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.tool.ToolCallingChatOptions; import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.beans.factory.annotation.Autowired; diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/api/BedrockMediaFormatTest.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/api/BedrockMediaFormatTest.java index 8931a39aac4..ca6cdb55b9a 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/api/BedrockMediaFormatTest.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/api/BedrockMediaFormatTest.java @@ -17,12 +17,13 @@ package org.springframework.ai.bedrock.converse.api; import org.junit.jupiter.api.Test; -import org.springframework.ai.content.Media; -import org.springframework.util.MimeType; import software.amazon.awssdk.services.bedrockruntime.model.DocumentFormat; import software.amazon.awssdk.services.bedrockruntime.model.ImageFormat; import software.amazon.awssdk.services.bedrockruntime.model.VideoFormat; +import org.springframework.ai.content.Media; +import org.springframework.util.MimeType; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/client/BedrockNovaChatClientIT.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/client/BedrockNovaChatClientIT.java index 5d73ae14c60..9efd3c2e87e 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/client/BedrockNovaChatClientIT.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/client/BedrockNovaChatClientIT.java @@ -1,18 +1,18 @@ /* -* Copyright 2024 - 2024 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.ai.bedrock.converse.client; @@ -20,7 +20,6 @@ import java.time.Duration; import java.util.Set; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,7 +59,7 @@ public class BedrockNovaChatClientIT { @Test void pdfMultiModalityTest() throws IOException { - String response = ChatClient.create(chatModel) + String response = ChatClient.create(this.chatModel) .prompt() .user(u -> u.text( "You are a very professional document summarization specialist. Please summarize the given document.") @@ -75,7 +74,7 @@ void pdfMultiModalityTest() throws IOException { @Test void imageMultiModalityTest() throws IOException { - String response = ChatClient.create(chatModel) + String response = ChatClient.create(this.chatModel) .prompt() .user(u -> u.text("Explain what do you see on this picture?") .media(Media.Format.IMAGE_PNG, new ClassPathResource("/test.png"))) @@ -95,7 +94,7 @@ void videoMultiModalityTest() throws IOException { Set birdDescriptors = Set.of("chick", "chicks", "chicken", "chickens", "bird", "birds", "poultry", "hatchling", "hatchlings"); - String response = ChatClient.create(chatModel) + String response = ChatClient.create(this.chatModel) .prompt() .user(u -> u.text("Explain what do you see in this video?") .media(Media.Format.VIDEO_MP4, new ClassPathResource("/test.video.mp4"))) @@ -136,12 +135,6 @@ void videoMultiModalityTest() throws IOException { () -> assertTrue(response.length() > 50, "Response should be sufficiently detailed (>50 characters)")); } - public static record WeatherRequest(String location, String unit) { - } - - public static record WeatherResponse(int temp, String unit) { - } - @Test void functionCallTest() { @@ -158,7 +151,6 @@ else if (request.location().contains("Tokyo")) { else if (request.location().contains("San Francisco")) { return new WeatherResponse(30, request.unit()); } - throw new IllegalArgumentException("Unknown location: " + request.location()); }) .description("Get the weather for a city in Celsius") @@ -173,6 +165,12 @@ else if (request.location().contains("San Francisco")) { assertThat(response).contains("30", "10", "15"); } + public record WeatherRequest(String location, String unit) { + } + + public record WeatherResponse(int temp, String unit) { + } + @SpringBootConfiguration public static class Config { diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java index 79939c62651..8f5ffb24839 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java @@ -16,11 +16,6 @@ package org.springframework.ai.bedrock.aot; -import org.springframework.ai.bedrock.api.AbstractBedrockApi; -import org.springframework.ai.bedrock.cohere.BedrockCohereEmbeddingOptions; -import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi; -import org.springframework.ai.bedrock.titan.BedrockTitanEmbeddingOptions; -import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/aot/MiniMaxRuntimeHints.java b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/aot/MiniMaxRuntimeHints.java index 263edcdf0a4..7eddbaf9764 100644 --- a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/aot/MiniMaxRuntimeHints.java +++ b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/aot/MiniMaxRuntimeHints.java @@ -16,7 +16,6 @@ package org.springframework.ai.minimax.aot; -import org.springframework.ai.minimax.api.MiniMaxApi; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java index 7736e2a8101..930f0de079c 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java @@ -27,13 +27,6 @@ import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import org.springframework.ai.model.tool.DefaultToolExecutionEligibilityPredicate; -import org.springframework.ai.model.tool.ToolCallingChatOptions; -import org.springframework.ai.model.tool.ToolCallingManager; -import org.springframework.ai.model.tool.ToolExecutionEligibilityPredicate; -import org.springframework.ai.model.tool.ToolExecutionResult; -import org.springframework.ai.tool.definition.ToolDefinition; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; @@ -57,6 +50,7 @@ import org.springframework.ai.chat.observation.DefaultChatModelObservationConvention; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.content.Media; import org.springframework.ai.mistralai.api.MistralAiApi; import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletion; import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletion.Choice; @@ -65,10 +59,15 @@ import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage.ChatCompletionFunction; import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage.ToolCall; import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionRequest; -import org.springframework.ai.content.Media; import org.springframework.ai.model.ModelOptionsUtils; import org.springframework.ai.model.function.FunctionCallingOptions; +import org.springframework.ai.model.tool.DefaultToolExecutionEligibilityPredicate; +import org.springframework.ai.model.tool.ToolCallingChatOptions; +import org.springframework.ai.model.tool.ToolCallingManager; +import org.springframework.ai.model.tool.ToolExecutionEligibilityPredicate; +import org.springframework.ai.model.tool.ToolExecutionResult; import org.springframework.ai.retry.RetryUtils; +import org.springframework.ai.tool.definition.ToolDefinition; import org.springframework.http.ResponseEntity; import org.springframework.retry.support.RetryTemplate; import org.springframework.util.Assert; @@ -228,7 +227,7 @@ public ChatResponse internalCall(Prompt prompt, ChatResponse previousChatRespons return chatResponse; }); - if (toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { + if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { var toolExecutionResult = this.toolCallingManager.executeToolCalls(prompt, response); if (toolExecutionResult.returnDirect()) { // Return tool execution result directly to the client. @@ -317,7 +316,7 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha // @formatter:off Flux chatResponseFlux = chatResponse.flatMap(response -> { - if (toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { + if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { // FIXME: bounded elastic needs to be used since tool calling // is currently only synchronous return Flux.defer(() -> { @@ -327,7 +326,8 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha return Flux.just(ChatResponse.builder().from(response) .generations(ToolExecutionResult.buildGenerations(toolExecutionResult)) .build()); - } else { + } + else { // Send the tool execution result back to the model. return this.internalStream(new Prompt(toolExecutionResult.conversationHistory(), prompt.getOptions()), response); @@ -534,7 +534,7 @@ public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private MistralAiApi mistralAiApi; @@ -588,12 +588,12 @@ public Builder observationRegistry(ObservationRegistry observationRegistry) { } public MistralAiChatModel build() { - if (toolCallingManager != null) { - return new MistralAiChatModel(mistralAiApi, defaultOptions, toolCallingManager, retryTemplate, - observationRegistry, toolExecutionEligibilityPredicate); + if (this.toolCallingManager != null) { + return new MistralAiChatModel(this.mistralAiApi, this.defaultOptions, this.toolCallingManager, + this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate); } - return new MistralAiChatModel(mistralAiApi, defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, retryTemplate, - observationRegistry, toolExecutionEligibilityPredicate); + return new MistralAiChatModel(this.mistralAiApi, this.defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, + this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate); } } diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java index a59e8a71e58..44ab76b6347 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java @@ -288,7 +288,7 @@ public void setToolNames(Set toolNames) { @Nullable @JsonIgnore public Boolean isInternalToolExecutionEnabled() { - return internalToolExecutionEnabled; + return this.internalToolExecutionEnabled; } @Override diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java index e57e06707bb..7b32a5911bd 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java @@ -720,9 +720,12 @@ public ChatCompletionRequest(List messages, Boolean strea public enum ToolChoice { // @formatter:off - @JsonProperty("auto") AUTO, - @JsonProperty("any") ANY, - @JsonProperty("none") NONE + @JsonProperty("auto") + AUTO, + @JsonProperty("any") + ANY, + @JsonProperty("none") + NONE // @formatter:on } diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiModerationApi.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiModerationApi.java index 02fcef6f564..da147de5052 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiModerationApi.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiModerationApi.java @@ -1,7 +1,26 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.mistralai.api; +import java.util.function.Consumer; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; + import org.springframework.ai.retry.RetryUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -10,8 +29,6 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; -import java.util.function.Consumer; - /** * MistralAI Moderation API. * @@ -98,9 +115,9 @@ public record MistralAiModerationResult( @JsonProperty("category_scores") CategoryScores categoryScores) { public boolean flagged() { - return categories != null && (categories.sexual() || categories.hateAndDiscrimination() || categories.violenceAndThreats() - || categories.selfHarm() || categories.dangerousAndCriminalContent() || categories.health() - || categories.financial() || categories.law() || categories.pii()); + return this.categories != null && (this.categories.sexual() || this.categories.hateAndDiscrimination() || this.categories.violenceAndThreats() + || this.categories.selfHarm() || this.categories.dangerousAndCriminalContent() || this.categories.health() + || this.categories.financial() || this.categories.law() || this.categories.pii()); } } diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationModel.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationModel.java index 1df7b0c259f..076d9a3433e 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationModel.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationModel.java @@ -1,10 +1,38 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.mistralai.moderation; +import java.util.ArrayList; +import java.util.List; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.ai.mistralai.api.MistralAiModerationApi; import org.springframework.ai.model.ModelOptionsUtils; -import org.springframework.ai.moderation.*; +import org.springframework.ai.moderation.Categories; +import org.springframework.ai.moderation.CategoryScores; +import org.springframework.ai.moderation.Generation; +import org.springframework.ai.moderation.Moderation; +import org.springframework.ai.moderation.ModerationModel; +import org.springframework.ai.moderation.ModerationOptions; +import org.springframework.ai.moderation.ModerationPrompt; +import org.springframework.ai.moderation.ModerationResponse; +import org.springframework.ai.moderation.ModerationResult; import org.springframework.ai.retry.RetryUtils; import org.springframework.http.ResponseEntity; import org.springframework.retry.support.RetryTemplate; @@ -14,9 +42,6 @@ import static org.springframework.ai.mistralai.api.MistralAiModerationApi.MistralAiModerationResponse; import static org.springframework.ai.mistralai.api.MistralAiModerationApi.MistralAiModerationResult; -import java.util.ArrayList; -import java.util.List; - /** * @author Ricken Bazolo */ diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptions.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptions.java index 435651409ad..b977e12bf84 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptions.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptions.java @@ -1,7 +1,24 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.mistralai.moderation; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; + import org.springframework.ai.mistralai.api.MistralAiModerationApi; import org.springframework.ai.moderation.ModerationOptions; diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatCompletionRequestTest.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatCompletionRequestTest.java index a842fddf0d6..6ef0bf541a6 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatCompletionRequestTest.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatCompletionRequestTest.java @@ -16,6 +16,8 @@ package org.springframework.ai.mistralai; +import java.util.Map; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; @@ -27,8 +29,6 @@ import org.springframework.ai.tool.definition.ToolDefinition; import org.springframework.boot.test.context.SpringBootTest; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; /** @@ -106,13 +106,13 @@ static class TestToolCallback implements ToolCallback { private final ToolDefinition toolDefinition; - public TestToolCallback(String name) { + TestToolCallback(String name) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); } @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override 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 19718020fba..0a0c6f3c6ac 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 @@ -43,11 +43,11 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; import org.springframework.ai.mistralai.api.MistralAiApi; -import org.springframework.ai.content.Media; import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiModerationModelIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiModerationModelIT.java index 9eb0f86ed3c..d7d1a0d852b 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiModerationModelIT.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiModerationModelIT.java @@ -1,9 +1,26 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.mistralai; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.ai.mistralai.moderation.MistralAiModerationModel; import org.springframework.ai.moderation.Moderation; import org.springframework.ai.moderation.ModerationPrompt; diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHintsTests.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHintsTests.java index 2ce0bcc56f1..c18f050f427 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHintsTests.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHintsTests.java @@ -29,7 +29,6 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClassesInPackage; -import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection; class MistralAiRuntimeHintsTests { diff --git a/models/spring-ai-moonshot/src/main/java/org/springframework/ai/moonshot/aot/MoonshotRuntimeHints.java b/models/spring-ai-moonshot/src/main/java/org/springframework/ai/moonshot/aot/MoonshotRuntimeHints.java index c87478e464a..7778d9809a8 100644 --- a/models/spring-ai-moonshot/src/main/java/org/springframework/ai/moonshot/aot/MoonshotRuntimeHints.java +++ b/models/spring-ai-moonshot/src/main/java/org/springframework/ai/moonshot/aot/MoonshotRuntimeHints.java @@ -16,7 +16,6 @@ package org.springframework.ai.moonshot.aot; -import org.springframework.ai.moonshot.api.MoonshotApi; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-moonshot/src/test/java/org/springframework/ai/moonshot/aot/MoonshotRuntimeHintsTests.java b/models/spring-ai-moonshot/src/test/java/org/springframework/ai/moonshot/aot/MoonshotRuntimeHintsTests.java index 9411c397ae9..2bd4a966d51 100644 --- a/models/spring-ai-moonshot/src/test/java/org/springframework/ai/moonshot/aot/MoonshotRuntimeHintsTests.java +++ b/models/spring-ai-moonshot/src/test/java/org/springframework/ai/moonshot/aot/MoonshotRuntimeHintsTests.java @@ -28,7 +28,6 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClassesInPackage; -import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection; /** * @author Geng Rong diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java index 5ffae904ca7..398b7457647 100644 --- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java +++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java @@ -345,7 +345,8 @@ private Flux internalStream(Prompt prompt, ChatResponse previousCh return Flux.just(ChatResponse.builder().from(response) .generations(ToolExecutionResult.buildGenerations(toolExecutionResult)) .build()); - } else { + } + else { // Send the tool execution result back to the model. return this.internalStream(new Prompt(toolExecutionResult.conversationHistory(), prompt.getOptions()), response); @@ -571,7 +572,7 @@ public Builder modelManagementOptions(ModelManagementOptions modelManagementOpti } public OllamaChatModel build() { - if (toolCallingManager != null) { + if (this.toolCallingManager != null) { return new OllamaChatModel(this.ollamaApi, this.defaultOptions, this.toolCallingManager, this.observationRegistry, this.modelManagementOptions, this.toolExecutionEligibilityPredicate); } diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/aot/OllamaRuntimeHints.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/aot/OllamaRuntimeHints.java index e33cffc3be5..e4198f9dae9 100644 --- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/aot/OllamaRuntimeHints.java +++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/aot/OllamaRuntimeHints.java @@ -16,8 +16,6 @@ package org.springframework.ai.ollama.aot; -import org.springframework.ai.ollama.api.OllamaApi; -import org.springframework.ai.ollama.api.OllamaOptions; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java index df2e9524f0c..f78caad5e3a 100644 --- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java +++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java @@ -707,8 +707,8 @@ public void setTruncate(Boolean truncate) { @Override @JsonIgnore public List getToolCallbacks() { - return this.toolCallbacks; - } + return this.toolCallbacks; + } @Override @JsonIgnore @@ -716,13 +716,13 @@ public void setToolCallbacks(List toolCallbacks) { Assert.notNull(toolCallbacks, "toolCallbacks cannot be null"); Assert.noNullElements(toolCallbacks, "toolCallbacks cannot contain null elements"); this.toolCallbacks = toolCallbacks; - } + } @Override @JsonIgnore public Set getToolNames() { - return this.toolNames; - } + return this.toolNames; + } @Override @JsonIgnore @@ -730,21 +730,21 @@ public void setToolNames(Set toolNames) { Assert.notNull(toolNames, "toolNames cannot be null"); Assert.noNullElements(toolNames, "toolNames cannot contain null elements"); toolNames.forEach(tool -> Assert.hasText(tool, "toolNames cannot contain empty elements")); - this.toolNames = toolNames; - } + this.toolNames = toolNames; + } @Override @Nullable @JsonIgnore public Boolean isInternalToolExecutionEnabled() { - return internalToolExecutionEnabled; - } + return this.internalToolExecutionEnabled; + } @Override @JsonIgnore public void setInternalToolExecutionEnabled(@Nullable Boolean internalToolExecutionEnabled) { - this.internalToolExecutionEnabled = internalToolExecutionEnabled; - } + this.internalToolExecutionEnabled = internalToolExecutionEnabled; + } @Override @Deprecated diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java index a2cafcee6c7..bbeb101fc9a 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java @@ -73,7 +73,7 @@ void buildOllamaChatModelWithConstructor() { @Test void buildOllamaChatModelWithBuilder() { - ChatModel chatModel = OllamaChatModel.builder().ollamaApi(ollamaApi).build(); + ChatModel chatModel = OllamaChatModel.builder().ollamaApi(this.ollamaApi).build(); assertThat(chatModel).isNotNull(); } diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java index e3221f02640..76a07de9223 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java @@ -16,6 +16,8 @@ package org.springframework.ai.ollama; +import java.util.Map; + import org.junit.jupiter.api.Test; import org.springframework.ai.chat.prompt.ChatOptions; @@ -27,8 +29,6 @@ import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.definition.ToolDefinition; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; /** @@ -167,13 +167,13 @@ static class TestToolCallback implements ToolCallback { private final ToolDefinition toolDefinition; - public TestToolCallback(String name) { + TestToolCallback(String name) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); } @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/aot/OllamaRuntimeHintsTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/aot/OllamaRuntimeHintsTests.java index 8e8a03c1fae..ae56cd033d3 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/aot/OllamaRuntimeHintsTests.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/aot/OllamaRuntimeHintsTests.java @@ -28,7 +28,6 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClassesInPackage; -import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection; class OllamaRuntimeHintsTests { diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java index 8c1ca4f2a80..7c036c67d3d 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java @@ -238,7 +238,7 @@ public ChatResponse internalCall(Prompt prompt, ChatResponse previousChatRespons }); - if (toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { + if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { var toolExecutionResult = this.toolCallingManager.executeToolCalls(prompt, response); if (toolExecutionResult.returnDirect()) { // Return tool execution result directly to the client. @@ -361,7 +361,7 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha // @formatter:off Flux flux = chatResponse.flatMap(response -> { - if (toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { + if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { return Flux.defer(() -> { // FIXME: bounded elastic needs to be used since tool calling // is currently only synchronous @@ -371,7 +371,8 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha return Flux.just(ChatResponse.builder().from(response) .generations(ToolExecutionResult.buildGenerations(toolExecutionResult)) .build()); - } else { + } + else { // Send the tool execution result back to the model. return this.internalStream(new Prompt(toolExecutionResult.conversationHistory(), prompt.getOptions()), response); @@ -741,12 +742,12 @@ public Builder observationRegistry(ObservationRegistry observationRegistry) { } public OpenAiChatModel build() { - if (toolCallingManager != null) { - return new OpenAiChatModel(openAiApi, defaultOptions, toolCallingManager, retryTemplate, - observationRegistry, toolExecutionEligibilityPredicate); + if (this.toolCallingManager != null) { + return new OpenAiChatModel(this.openAiApi, this.defaultOptions, this.toolCallingManager, + this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate); } - return new OpenAiChatModel(openAiApi, defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, retryTemplate, - observationRegistry, toolExecutionEligibilityPredicate); + return new OpenAiChatModel(this.openAiApi, this.defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, + this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate); } } diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java index cdeb64e73f2..36460af4d98 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java @@ -502,7 +502,7 @@ public void setToolNames(Set toolNames) { @Nullable @JsonIgnore public Boolean isInternalToolExecutionEnabled() { - return internalToolExecutionEnabled; + return this.internalToolExecutionEnabled; } @Override diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingModel.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingModel.java index 5a0403524ca..2ac56916fc4 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingModel.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingModel.java @@ -212,10 +212,11 @@ private EmbeddingRequest buildEmbeddingRequest(EmbeddingRequest embeddingRequest .builder() // Handle portable embedding options .model(ModelOptionsUtils.mergeOption(runtimeOptions.getModel(), this.defaultOptions.getModel())) - .dimensions(ModelOptionsUtils.mergeOption(runtimeOptions.getDimensions(), defaultOptions.getDimensions())) + .dimensions( + ModelOptionsUtils.mergeOption(runtimeOptions.getDimensions(), this.defaultOptions.getDimensions())) // Handle OpenAI specific embedding options .encodingFormat(ModelOptionsUtils.mergeOption(runtimeOptions.getEncodingFormat(), - defaultOptions.getEncodingFormat())) + this.defaultOptions.getEncodingFormat())) .user(ModelOptionsUtils.mergeOption(runtimeOptions.getUser(), this.defaultOptions.getUser())) .build(); diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageModel.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageModel.java index 88096f15399..5a8ebdf2368 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageModel.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageModel.java @@ -191,16 +191,16 @@ private ImagePrompt buildRequestImagePrompt(ImagePrompt imagePrompt) { OpenAiImageOptions requestOptions = runtimeOptions == null ? this.defaultOptions : OpenAiImageOptions.builder() // Handle portable image options - .model(ModelOptionsUtils.mergeOption(runtimeOptions.getModel(), defaultOptions.getModel())) - .N(ModelOptionsUtils.mergeOption(runtimeOptions.getN(), defaultOptions.getN())) + .model(ModelOptionsUtils.mergeOption(runtimeOptions.getModel(), this.defaultOptions.getModel())) + .N(ModelOptionsUtils.mergeOption(runtimeOptions.getN(), this.defaultOptions.getN())) .responseFormat(ModelOptionsUtils.mergeOption(runtimeOptions.getResponseFormat(), - defaultOptions.getResponseFormat())) - .width(ModelOptionsUtils.mergeOption(runtimeOptions.getWidth(), defaultOptions.getWidth())) - .height(ModelOptionsUtils.mergeOption(runtimeOptions.getHeight(), defaultOptions.getHeight())) - .style(ModelOptionsUtils.mergeOption(runtimeOptions.getStyle(), defaultOptions.getStyle())) + this.defaultOptions.getResponseFormat())) + .width(ModelOptionsUtils.mergeOption(runtimeOptions.getWidth(), this.defaultOptions.getWidth())) + .height(ModelOptionsUtils.mergeOption(runtimeOptions.getHeight(), this.defaultOptions.getHeight())) + .style(ModelOptionsUtils.mergeOption(runtimeOptions.getStyle(), this.defaultOptions.getStyle())) // Handle OpenAI specific image options - .quality(ModelOptionsUtils.mergeOption(runtimeOptions.getQuality(), defaultOptions.getQuality())) - .user(ModelOptionsUtils.mergeOption(runtimeOptions.getUser(), defaultOptions.getUser())) + .quality(ModelOptionsUtils.mergeOption(runtimeOptions.getQuality(), this.defaultOptions.getQuality())) + .user(ModelOptionsUtils.mergeOption(runtimeOptions.getUser(), this.defaultOptions.getUser())) .build(); return new ImagePrompt(imagePrompt.getInstructions(), requestOptions); diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/aot/OpenAiRuntimeHints.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/aot/OpenAiRuntimeHints.java index 5e7cbd54921..c16838de0de 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/aot/OpenAiRuntimeHints.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/aot/OpenAiRuntimeHints.java @@ -16,10 +16,6 @@ package org.springframework.ai.openai.aot; -import org.springframework.ai.openai.OpenAiChatOptions; -import org.springframework.ai.openai.api.OpenAiApi; -import org.springframework.ai.openai.api.OpenAiAudioApi; -import org.springframework.ai.openai.api.OpenAiImageApi; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java index b320c1acc65..433f59d9697 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java @@ -108,7 +108,7 @@ public OpenAiApi(String baseUrl, ApiKey apiKey, MultiValueMap he this.embeddingsPath = embeddingsPath; // @formatter:off Consumer finalHeaders = h -> { - if(!(apiKey instanceof NoopApiKey)) { + if (!(apiKey instanceof NoopApiKey)) { h.setBearerAuth(apiKey.getValue()); } diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java index fdb3423d23e..b09507528f8 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java @@ -59,7 +59,7 @@ public OpenAiImageApi(String baseUrl, ApiKey apiKey, MultiValueMap { - if(!(apiKey instanceof NoopApiKey)) { + if (!(apiKey instanceof NoopApiKey)) { h.setBearerAuth(apiKey.getValue()); } h.setContentType(MediaType.APPLICATION_JSON); @@ -81,6 +81,10 @@ public ResponseEntity createImage(OpenAiImageRequest openAi .toEntity(OpenAiImageResponse.class); } + public static Builder builder() { + return new Builder(); + } + /** * OpenAI Image API model. * DALL·E @@ -141,10 +145,6 @@ public record Data(@JsonProperty("url") String url, @JsonProperty("b64_json") St } - public static Builder builder() { - return new Builder(); - } - /** * Builder to construct {@link OpenAiImageApi} instance. */ diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java index ad0a3e9620f..aaffd56ef92 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java @@ -83,6 +83,10 @@ public ResponseEntity createModeration(OpenAiModeratio .toEntity(OpenAiModerationResponse.class); } + public static Builder builder() { + return new Builder(); + } + // @formatter:off @JsonInclude(JsonInclude.Include.NON_NULL) public record OpenAiModerationRequest( @@ -149,10 +153,6 @@ public record Data(@JsonProperty("url") String url, @JsonProperty("b64_json") St } - public static Builder builder() { - return new Builder(); - } - /** * Builder to construct {@link OpenAiModerationApi} instance. */ diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java index 84dc1c56773..928691dbaf1 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java @@ -167,13 +167,13 @@ static class TestToolCallback implements ToolCallback { private final ToolDefinition toolDefinition; - public TestToolCallback(String name) { + TestToolCallback(String name) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); } @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java index 5fc63a547ca..3ae8e204624 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java @@ -21,15 +21,16 @@ import java.util.List; import java.util.Map; -import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; -import static org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.AudioParameters.Voice.ALLOY; import org.springframework.ai.openai.api.OpenAiApi; import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.AudioParameters; import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.StreamOptions; import org.springframework.ai.openai.api.ResponseFormat; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.AudioParameters.Voice.ALLOY; + /** * Tests for {@link OpenAiChatOptions}. * diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiBuilderTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiBuilderTests.java index a2d6fe32e92..30f28f610c9 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiBuilderTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiBuilderTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.openai.api; import org.junit.jupiter.api.Test; @@ -79,70 +80,66 @@ void testDefaultValues() { @Test void testMissingApiKey() { - assertThatThrownBy(() -> { - OpenAiApi.builder().build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("apiKey must be set"); + assertThatThrownBy(() -> OpenAiApi.builder().build()).isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("apiKey must be set"); } @Test void testInvalidBaseUrl() { - assertThatThrownBy(() -> { - OpenAiApi.builder().baseUrl("").build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("baseUrl cannot be null or empty"); + assertThatThrownBy(() -> OpenAiApi.builder().baseUrl("").build()).isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("baseUrl cannot be null or empty"); - assertThatThrownBy(() -> { - OpenAiApi.builder().baseUrl(null).build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("baseUrl cannot be null or empty"); + assertThatThrownBy(() -> OpenAiApi.builder().baseUrl(null).build()).isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("baseUrl cannot be null or empty"); } @Test void testInvalidHeaders() { - assertThatThrownBy(() -> { - OpenAiApi.builder().headers(null).build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("headers cannot be null"); + assertThatThrownBy(() -> OpenAiApi.builder().headers(null).build()).isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("headers cannot be null"); } @Test void testInvalidCompletionsPath() { - assertThatThrownBy(() -> { - OpenAiApi.builder().completionsPath("").build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("completionsPath cannot be null or empty"); + assertThatThrownBy(() -> OpenAiApi.builder().completionsPath("").build()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("completionsPath cannot be null or empty"); - assertThatThrownBy(() -> { - OpenAiApi.builder().completionsPath(null).build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("completionsPath cannot be null or empty"); + assertThatThrownBy(() -> OpenAiApi.builder().completionsPath(null).build()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("completionsPath cannot be null or empty"); } @Test void testInvalidEmbeddingsPath() { - assertThatThrownBy(() -> { - OpenAiApi.builder().embeddingsPath("").build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("embeddingsPath cannot be null or empty"); + assertThatThrownBy(() -> OpenAiApi.builder().embeddingsPath("").build()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("embeddingsPath cannot be null or empty"); - assertThatThrownBy(() -> { - OpenAiApi.builder().embeddingsPath(null).build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("embeddingsPath cannot be null or empty"); + assertThatThrownBy(() -> OpenAiApi.builder().embeddingsPath(null).build()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("embeddingsPath cannot be null or empty"); } @Test void testInvalidRestClientBuilder() { - assertThatThrownBy(() -> { - OpenAiApi.builder().restClientBuilder(null).build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("restClientBuilder cannot be null"); + assertThatThrownBy(() -> OpenAiApi.builder().restClientBuilder(null).build()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("restClientBuilder cannot be null"); } @Test void testInvalidWebClientBuilder() { - assertThatThrownBy(() -> { - OpenAiApi.builder().webClientBuilder(null).build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("webClientBuilder cannot be null"); + assertThatThrownBy(() -> OpenAiApi.builder().webClientBuilder(null).build()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("webClientBuilder cannot be null"); } @Test void testInvalidResponseErrorHandler() { - assertThatThrownBy(() -> { - OpenAiApi.builder().responseErrorHandler(null).build(); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("responseErrorHandler cannot be null"); + assertThatThrownBy(() -> OpenAiApi.builder().responseErrorHandler(null).build()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("responseErrorHandler cannot be null"); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioModelNoOpApiKeysIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioModelNoOpApiKeysIT.java index 247dd76d45c..996035d09b7 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioModelNoOpApiKeysIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioModelNoOpApiKeysIT.java @@ -42,15 +42,13 @@ public class OpenAiAudioModelNoOpApiKeysIT { @Test void checkNoOpKey() { - assertThatThrownBy(() -> { - this.audioApi - .createSpeech(OpenAiAudioApi.SpeechRequest.builder() - .model(OpenAiAudioApi.TtsModel.TTS_1_HD.getValue()) - .input("Hello, my name is Chris and I love Spring A.I.") - .voice(OpenAiAudioApi.SpeechRequest.Voice.ONYX.getValue()) - .build()) - .getBody(); - }).isInstanceOf(NonTransientAiException.class); + assertThatThrownBy(() -> this.audioApi + .createSpeech(OpenAiAudioApi.SpeechRequest.builder() + .model(OpenAiAudioApi.TtsModel.TTS_1_HD.getValue()) + .input("Hello, my name is Chris and I love Spring A.I.") + .voice(OpenAiAudioApi.SpeechRequest.Voice.ONYX.getValue()) + .build()) + .getBody()).isInstanceOf(NonTransientAiException.class); } @SpringBootConfiguration 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 edb3b49f241..b8d970d8eb0 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 @@ -49,10 +49,10 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.ai.openai.OpenAiTestConfiguration; @@ -535,7 +535,7 @@ void streamingMultiModalityImageUrl() throws IOException { void multiModalityOutputAudio(String modelName) throws IOException { var userMessage = new UserMessage("Tell me joke about Spring Framework"); - ChatResponse response = chatModel.call(new Prompt(List.of(userMessage), + ChatResponse response = this.chatModel.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder() .model(modelName) .outputModalities(List.of("text", "audio")) @@ -556,7 +556,7 @@ void streamingMultiModalityOutputAudio(String modelName) throws IOException { // var audioResource = new ClassPathResource("speech1.mp3"); var userMessage = new UserMessage("Tell me joke about Spring Framework"); - assertThatThrownBy(() -> chatModel + assertThatThrownBy(() -> this.chatModel .stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder() .model(modelName) @@ -575,7 +575,7 @@ void multiModalityInputAudio(String modelName) { var userMessage = new UserMessage("What is this recording about?", List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource))); - ChatResponse response = chatModel + ChatResponse response = this.chatModel .call(new Prompt(List.of(userMessage), ChatOptions.builder().model(modelName).build())); logger.info(response.getResult().getOutput().getText()); @@ -590,7 +590,7 @@ void streamingMultiModalityInputAudio(String modelName) { var userMessage = new UserMessage("What is this recording about?", List.of(new Media(MimeTypeUtils.parseMimeType("audio/mp3"), audioResource))); - Flux response = chatModel + Flux response = this.chatModel .stream(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().model(modelName).build())); String content = response.collectList() diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/client/OpenAiChatClientMethodInvokingFunctionCallbackIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/client/OpenAiChatClientMethodInvokingFunctionCallbackIT.java index 5ead8676a8f..df93556fe26 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/client/OpenAiChatClientMethodInvokingFunctionCallbackIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/client/OpenAiChatClientMethodInvokingFunctionCallbackIT.java @@ -181,7 +181,7 @@ void methodGetWeatherToolContextButMissingContextArgument() { .build()) .toolMethod(toolMethod) .toolObject(targetObject) - .build()) + .build()) .call() .content()) .isInstanceOf(IllegalArgumentException.class) 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 f5d329e5a92..d670cc9c446 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 @@ -42,10 +42,10 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.openai.OpenAiChatModel; import org.springframework.ai.openai.OpenAiChatOptions; 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 c7f632a6970..af6e5f232e0 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 @@ -42,10 +42,10 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.SimpleApiKey; import org.springframework.ai.model.tool.LegacyToolCallingManager; import org.springframework.ai.openai.OpenAiChatModel; 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 519d5498661..d2d6b35e57d 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 @@ -45,10 +45,10 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.NoopApiKey; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.model.tool.LegacyToolCallingManager; diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java index 7823dabaade..5fa3e0a1dbb 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java @@ -24,13 +24,13 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +import org.springframework.ai.chat.transformer.KeywordMetadataEnricher; +import org.springframework.ai.chat.transformer.SummaryMetadataEnricher; import org.springframework.ai.document.DefaultContentFormatter; import org.springframework.ai.document.Document; import org.springframework.ai.openai.OpenAiChatModel; import org.springframework.ai.openai.api.OpenAiApi; import org.springframework.ai.transformer.ContentFormatTransformer; -import org.springframework.ai.chat.transformer.KeywordMetadataEnricher; -import org.springframework.ai.chat.transformer.SummaryMetadataEnricher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.test.context.SpringBootTest; diff --git a/models/spring-ai-qianfan/src/main/java/org/springframework/ai/qianfan/aot/QianFanRuntimeHints.java b/models/spring-ai-qianfan/src/main/java/org/springframework/ai/qianfan/aot/QianFanRuntimeHints.java index 0a9ed025df9..8d668f01f44 100644 --- a/models/spring-ai-qianfan/src/main/java/org/springframework/ai/qianfan/aot/QianFanRuntimeHints.java +++ b/models/spring-ai-qianfan/src/main/java/org/springframework/ai/qianfan/aot/QianFanRuntimeHints.java @@ -16,8 +16,6 @@ package org.springframework.ai.qianfan.aot; -import org.springframework.ai.qianfan.api.QianFanApi; -import org.springframework.ai.qianfan.api.QianFanImageApi; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-qianfan/src/test/java/org/springframework/ai/qianfan/api/QianFanApiIT.java b/models/spring-ai-qianfan/src/test/java/org/springframework/ai/qianfan/api/QianFanApiIT.java index d6677104935..d88c56f276a 100644 --- a/models/spring-ai-qianfan/src/test/java/org/springframework/ai/qianfan/api/QianFanApiIT.java +++ b/models/spring-ai-qianfan/src/test/java/org/springframework/ai/qianfan/api/QianFanApiIT.java @@ -25,13 +25,13 @@ import org.stringtemplate.v4.ST; import reactor.core.publisher.Flux; -import org.springframework.ai.util.ResourceUtils; import org.springframework.ai.qianfan.api.QianFanApi.ChatCompletion; import org.springframework.ai.qianfan.api.QianFanApi.ChatCompletionChunk; import org.springframework.ai.qianfan.api.QianFanApi.ChatCompletionMessage; import org.springframework.ai.qianfan.api.QianFanApi.ChatCompletionMessage.Role; import org.springframework.ai.qianfan.api.QianFanApi.ChatCompletionRequest; import org.springframework.ai.qianfan.api.QianFanApi.EmbeddingList; +import org.springframework.ai.util.ResourceUtils; import org.springframework.http.ResponseEntity; import static org.assertj.core.api.Assertions.assertThat; 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 82e802e6e4d..8d25c4e4d36 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 @@ -34,6 +34,7 @@ import org.springframework.ai.chat.metadata.DefaultUsage; import org.springframework.ai.chat.metadata.Usage; +import org.springframework.ai.content.Media; import org.springframework.ai.document.Document; import org.springframework.ai.embedding.DocumentEmbeddingModel; import org.springframework.ai.embedding.DocumentEmbeddingRequest; @@ -42,7 +43,6 @@ import org.springframework.ai.embedding.EmbeddingResponseMetadata; import org.springframework.ai.embedding.EmbeddingResultMetadata; import org.springframework.ai.embedding.EmbeddingResultMetadata.ModalityType; -import org.springframework.ai.content.Media; import org.springframework.ai.model.ModelOptionsUtils; import org.springframework.ai.vertexai.embedding.VertexAiEmbeddingConnectionDetails; import org.springframework.ai.vertexai.embedding.VertexAiEmbeddingUtils; diff --git a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java index 5aba4f2631e..09fa4767691 100644 --- a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java +++ b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java @@ -23,11 +23,11 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +import org.springframework.ai.content.Media; import org.springframework.ai.document.Document; import org.springframework.ai.embedding.DocumentEmbeddingRequest; import org.springframework.ai.embedding.EmbeddingResponse; import org.springframework.ai.embedding.EmbeddingResultMetadata; -import org.springframework.ai.content.Media; import org.springframework.ai.vertexai.embedding.VertexAiEmbeddingConnectionDetails; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java index a356f88128c..268cbf3ae94 100644 --- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java +++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java @@ -575,7 +575,7 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha // @formatter:off Flux flux = chatResponseFlux.flatMap(response -> { - if (toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { + if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { // FIXME: bounded elastic needs to be used since tool calling // is currently only synchronous return Flux.defer(() -> { @@ -585,7 +585,8 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha return Flux.just(ChatResponse.builder().from(response) .generations(ToolExecutionResult.buildGenerations(toolExecutionResult)) .build()); - } else { + } + else { // Send the tool execution result back to the model. return this.internalStream(new Prompt(toolExecutionResult.conversationHistory(), prompt.getOptions()), response); } @@ -832,72 +833,11 @@ public void setObservationConvention(ChatModelObservationConvention observationC this.observationConvention = observationConvention; } - public enum GeminiMessageType { - - USER("user"), - - MODEL("model"); - - public final String value; - - GeminiMessageType(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - } - - public enum ChatModel implements ChatModelDescription { - - /** - * Deprecated by Goolgle in favor of 1.5 pro and flash models. - */ - GEMINI_PRO_VISION("gemini-pro-vision"), - - GEMINI_PRO("gemini-pro"), - - GEMINI_1_5_PRO("gemini-1.5-pro-002"), - - GEMINI_1_5_FLASH("gemini-1.5-flash-002"), - - GEMINI_1_5_FLASH_8B("gemini-1.5-flash-8b-001"), - - GEMINI_2_0_FLASH("gemini-2.0-flash"), - - GEMINI_2_0_FLASH_LIGHT("gemini-2.0-flash-lite"), - - GEMINI_2_5_PRO("gemini-2.5-pro-exp-03-28"); - - public final String value; - - ChatModel(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - @Override - public String getName() { - return this.value; - } - - } - - @JsonInclude(Include.NON_NULL) - public record GeminiRequest(List contents, GenerativeModel model) { - - } - public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private VertexAI vertexAI; @@ -966,30 +906,91 @@ public Builder observationRegistry(ObservationRegistry observationRegistry) { } public VertexAiGeminiChatModel build() { - if (toolCallingManager != null) { - Assert.isNull(functionCallbackResolver, + if (this.toolCallingManager != null) { + Assert.isNull(this.functionCallbackResolver, "functionCallbackResolver cannot be set when toolCallingManager is set"); - Assert.isNull(toolFunctionCallbacks, + Assert.isNull(this.toolFunctionCallbacks, "toolFunctionCallbacks cannot be set when toolCallingManager is set"); - return new VertexAiGeminiChatModel(vertexAI, defaultOptions, toolCallingManager, retryTemplate, - observationRegistry, toolExecutionEligibilityPredicate); + return new VertexAiGeminiChatModel(this.vertexAI, this.defaultOptions, this.toolCallingManager, + this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate); } - if (functionCallbackResolver != null) { - Assert.isNull(toolCallingManager, + if (this.functionCallbackResolver != null) { + Assert.isNull(this.toolCallingManager, "toolCallingManager cannot be set when functionCallbackResolver is set"); List toolCallbacks = this.toolFunctionCallbacks != null ? this.toolFunctionCallbacks : List.of(); - return new VertexAiGeminiChatModel(vertexAI, defaultOptions, functionCallbackResolver, toolCallbacks, - retryTemplate, observationRegistry); + return new VertexAiGeminiChatModel(this.vertexAI, this.defaultOptions, this.functionCallbackResolver, + toolCallbacks, this.retryTemplate, this.observationRegistry); } - return new VertexAiGeminiChatModel(vertexAI, defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, retryTemplate, - observationRegistry, toolExecutionEligibilityPredicate); + return new VertexAiGeminiChatModel(this.vertexAI, this.defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, + this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate); } } + public enum GeminiMessageType { + + USER("user"), + + MODEL("model"); + + public final String value; + + GeminiMessageType(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + } + + public enum ChatModel implements ChatModelDescription { + + /** + * Deprecated by Goolgle in favor of 1.5 pro and flash models. + */ + GEMINI_PRO_VISION("gemini-pro-vision"), + + GEMINI_PRO("gemini-pro"), + + GEMINI_1_5_PRO("gemini-1.5-pro-002"), + + GEMINI_1_5_FLASH("gemini-1.5-flash-002"), + + GEMINI_1_5_FLASH_8B("gemini-1.5-flash-8b-001"), + + GEMINI_2_0_FLASH("gemini-2.0-flash"), + + GEMINI_2_0_FLASH_LIGHT("gemini-2.0-flash-lite"), + + GEMINI_2_5_PRO("gemini-2.5-pro-exp-03-28"); + + public final String value; + + ChatModel(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + @Override + public String getName() { + return this.value; + } + + } + + @JsonInclude(Include.NON_NULL) + public record GeminiRequest(List contents, GenerativeModel model) { + + } + } diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java index ae8ca2aeadc..c262d31410b 100644 --- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java +++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java @@ -16,8 +16,8 @@ package org.springframework.ai.vertexai.gemini; -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -288,7 +288,7 @@ public void setToolNames(Set toolNames) { @Override @Nullable public Boolean isInternalToolExecutionEnabled() { - return internalToolExecutionEnabled; + return this.internalToolExecutionEnabled; } @Override diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/schema/JsonSchemaConverter.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/schema/JsonSchemaConverter.java index fbdbc9904df..0317922cbc7 100644 --- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/schema/JsonSchemaConverter.java +++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/schema/JsonSchemaConverter.java @@ -1,18 +1,19 @@ /* -* Copyright 2025 - 2025 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.vertexai.gemini.schema; /** diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/schema/VertexToolCallingManager.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/schema/VertexToolCallingManager.java index 0f7e7185e0d..3261bdb13c0 100644 --- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/schema/VertexToolCallingManager.java +++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/schema/VertexToolCallingManager.java @@ -1,18 +1,19 @@ /* -* Copyright 2025 - 2025 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.vertexai.gemini.schema; import java.util.List; @@ -67,7 +68,7 @@ public VertexToolCallingManager(ToolCallingManager delegateToolCallingManager) { @Override public List resolveToolDefinitions(ToolCallingChatOptions chatOptions) { - List toolDefinitions = delegateToolCallingManager.resolveToolDefinitions(chatOptions); + List toolDefinitions = this.delegateToolCallingManager.resolveToolDefinitions(chatOptions); return toolDefinitions.stream().map(td -> { ObjectNode jsonSchema = JsonSchemaConverter.fromJson(td.inputSchema()); 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 1b6e3e8a00e..176cf111f22 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 @@ -38,10 +38,10 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel.ChatModel; import org.springframework.ai.vertexai.gemini.common.VertexAiGeminiSafetySetting; import org.springframework.beans.factory.annotation.Autowired; diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/schema/JsonSchemaConverterTests.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/schema/JsonSchemaConverterTests.java index e60e1a683c6..3e49663f56d 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/schema/JsonSchemaConverterTests.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/schema/JsonSchemaConverterTests.java @@ -17,8 +17,9 @@ package org.springframework.ai.vertexai.gemini.schema; import com.fasterxml.jackson.databind.node.ObjectNode; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/models/spring-ai-watsonx-ai/src/main/java/org/springframework/ai/watsonx/aot/WatsonxAiRuntimeHints.java b/models/spring-ai-watsonx-ai/src/main/java/org/springframework/ai/watsonx/aot/WatsonxAiRuntimeHints.java index c97f66246d0..ccdd8712676 100644 --- a/models/spring-ai-watsonx-ai/src/main/java/org/springframework/ai/watsonx/aot/WatsonxAiRuntimeHints.java +++ b/models/spring-ai-watsonx-ai/src/main/java/org/springframework/ai/watsonx/aot/WatsonxAiRuntimeHints.java @@ -16,8 +16,6 @@ package org.springframework.ai.watsonx.aot; -import org.springframework.ai.watsonx.WatsonxAiChatOptions; -import org.springframework.ai.watsonx.api.WatsonxAiApi; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-watsonx-ai/src/test/java/org/springframework/ai/watsonx/aot/WatsonxAiRuntimeHintsTest.java b/models/spring-ai-watsonx-ai/src/test/java/org/springframework/ai/watsonx/aot/WatsonxAiRuntimeHintsTest.java index 5252ba3c65c..2cf9f94b387 100644 --- a/models/spring-ai-watsonx-ai/src/test/java/org/springframework/ai/watsonx/aot/WatsonxAiRuntimeHintsTest.java +++ b/models/spring-ai-watsonx-ai/src/test/java/org/springframework/ai/watsonx/aot/WatsonxAiRuntimeHintsTest.java @@ -21,8 +21,6 @@ import org.junit.jupiter.api.Test; -import org.springframework.ai.watsonx.WatsonxAiChatOptions; -import org.springframework.ai.watsonx.api.WatsonxAiApi; import org.springframework.ai.watsonx.api.WatsonxAiChatRequest; import org.springframework.ai.watsonx.api.WatsonxAiChatResponse; import org.springframework.ai.watsonx.api.WatsonxAiChatResults; @@ -34,7 +32,6 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClassesInPackage; -import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection; /** * @author Pablo Sanchidrian Herrera diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/aot/ZhiPuAiRuntimeHints.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/aot/ZhiPuAiRuntimeHints.java index 84f989d0452..6773bec4eeb 100644 --- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/aot/ZhiPuAiRuntimeHints.java +++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/aot/ZhiPuAiRuntimeHints.java @@ -16,8 +16,6 @@ package org.springframework.ai.zhipuai.aot; -import org.springframework.ai.zhipuai.api.ZhiPuAiApi; -import org.springframework.ai.zhipuai.api.ZhiPuAiImageApi; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java index f0f1d430054..eee86766158 100644 --- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java +++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java @@ -971,7 +971,7 @@ public record EmbeddingRequest( * @param input Input text to embed. */ public EmbeddingRequest(T input) { - this(input, DEFAULT_EMBEDDING_MODEL,null); + this(input, DEFAULT_EMBEDDING_MODEL, null); } /** @@ -981,7 +981,7 @@ public EmbeddingRequest(T input) { * @param model */ public EmbeddingRequest(T input, String model) { - this(input, model,null); + this(input, model, null); } } 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 5ef81d0847b..ebbc69cd38a 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 @@ -43,10 +43,10 @@ import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.MapOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.zhipuai.ZhiPuAiChatOptions; import org.springframework.ai.zhipuai.ZhiPuAiTestConfiguration; diff --git a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/ChatClient.java b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/ChatClient.java index dddeb9cd34e..038d8da1382 100644 --- a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/ChatClient.java +++ b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/ChatClient.java @@ -32,8 +32,8 @@ import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.prompt.Prompt; -import org.springframework.ai.converter.StructuredOutputConverter; import org.springframework.ai.content.Media; +import org.springframework.ai.converter.StructuredOutputConverter; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.ToolCallbackProvider; diff --git a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java index c170091ce71..fb4d3eb35dc 100644 --- a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java +++ b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java @@ -33,10 +33,6 @@ import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor; - -import org.springframework.ai.tool.ToolCallback; -import org.springframework.ai.tool.ToolCallbackProvider; -import org.springframework.ai.tool.ToolCallbacks; import reactor.core.publisher.Flux; import reactor.core.scheduler.Schedulers; @@ -62,10 +58,13 @@ import org.springframework.ai.chat.model.StreamingChatModel; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.BeanOutputConverter; import org.springframework.ai.converter.StructuredOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.function.FunctionCallback; +import org.springframework.ai.tool.ToolCallback; +import org.springframework.ai.tool.ToolCallbackProvider; +import org.springframework.ai.tool.ToolCallbacks; import org.springframework.core.Ordered; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.Resource; diff --git a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseStreamUtils.java b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseStreamUtils.java index 91bca7581a7..a8883756135 100644 --- a/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseStreamUtils.java +++ b/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseStreamUtils.java @@ -1,15 +1,35 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.chat.client.advisor.api; +import java.util.function.Predicate; + import org.springframework.ai.chat.model.ChatResponse; import org.springframework.util.StringUtils; -import java.util.function.Predicate; - /** * A stream utility class to provide support methods handling {@link AdvisedResponse}. */ public final class AdvisedResponseStreamUtils { + private AdvisedResponseStreamUtils() { + // Avoids instantiation + } + /** * Returns a predicate that checks whether the provided {@link AdvisedResponse} * contains a {@link ChatResponse} with at least one result having a non-empty finish diff --git a/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java b/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java index 859114ee359..048272359a0 100644 --- a/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java +++ b/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java @@ -29,7 +29,6 @@ import io.micrometer.observation.ObservationRegistry; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; -import org.springframework.ai.tool.ToolCallback; import reactor.core.publisher.Flux; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; @@ -43,10 +42,11 @@ import org.springframework.ai.chat.model.Generation; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.content.Media; import org.springframework.ai.converter.ListOutputConverter; import org.springframework.ai.converter.StructuredOutputConverter; -import org.springframework.ai.content.Media; import org.springframework.ai.model.function.FunctionCallback; +import org.springframework.ai.tool.ToolCallback; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.io.ClassPathResource; diff --git a/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseStreamUtilsTest.java b/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseStreamUtilsTest.java index d70c9ff02ea..0d96cb89ccb 100644 --- a/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseStreamUtilsTest.java +++ b/spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseStreamUtilsTest.java @@ -1,14 +1,31 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.chat.client.advisor.api; +import java.util.List; + import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; + import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.metadata.ChatGenerationMetadata; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; -import java.util.List; - import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; diff --git a/spring-ai-client-chat/src/test/java/org/springframework/ai/converter/BeanOutputConverterTest.java b/spring-ai-client-chat/src/test/java/org/springframework/ai/converter/BeanOutputConverterTest.java index 07c79d6cb62..b136ded49f8 100644 --- a/spring-ai-client-chat/src/test/java/org/springframework/ai/converter/BeanOutputConverterTest.java +++ b/spring-ai-client-chat/src/test/java/org/springframework/ai/converter/BeanOutputConverterTest.java @@ -16,6 +16,10 @@ package org.springframework.ai.converter; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; @@ -33,11 +37,8 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.slf4j.LoggerFactory; -import org.springframework.core.ParameterizedTypeReference; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; +import org.springframework.core.ParameterizedTypeReference; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -63,9 +64,9 @@ void beforeEach() { var logger = (Logger) LoggerFactory.getLogger(BeanOutputConverter.class); - logAppender = new ListAppender<>(); - logAppender.start(); - logger.addAppender(logAppender); + this.logAppender = new ListAppender<>(); + this.logAppender.start(); + logger.addAppender(this.logAppender); } @Test @@ -159,8 +160,8 @@ void convertClassType() { void failToConvertInvalidJson() { var converter = new BeanOutputConverter<>(TestClass.class); assertThatThrownBy(() -> converter.convert("{invalid json")).hasCauseInstanceOf(JsonParseException.class); - assertThat(logAppender.list).hasSize(1); - final var loggingEvent = logAppender.list.get(0); + assertThat(BeanOutputConverterTest.this.logAppender.list).hasSize(1); + final var loggingEvent = BeanOutputConverterTest.this.logAppender.list.get(0); assertThat(loggingEvent.getFormattedMessage()) .isEqualTo("Could not parse the given text to the desired target type: \"{invalid json\" into " + TestClass.class); diff --git a/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/FunctionToolCallbackTests.java b/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/FunctionToolCallbackTests.java index 4f30de7c6f5..659d0e35040 100644 --- a/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/FunctionToolCallbackTests.java +++ b/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/FunctionToolCallbackTests.java @@ -216,7 +216,7 @@ Consumer welcomeUser() { Function> booksByAuthor() { return author -> { logger.info("Getting books by author: "+ author.name()); - return bookService.getBooksByAuthor(author); + return this.bookService.getBooksByAuthor(author); }; } @@ -224,7 +224,7 @@ Function> booksByAuthor() { @Description("Get the list of authors who wrote the given books available in the library") Function> authorsByBooks() { return books -> { - List authors = bookService.getAuthorsByBook(books.books()); + List authors = this.bookService.getAuthorsByBook(books.books()); logger.info("Getting authors: {} by books: {}", authors, books.books().stream().map(Book::title).toList()); return authors; }; diff --git a/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/MethodToolCallbackTests.java b/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/MethodToolCallbackTests.java index f15961e3b1a..544afcb9866 100644 --- a/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/MethodToolCallbackTests.java +++ b/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/MethodToolCallbackTests.java @@ -57,7 +57,7 @@ void chatMethodNoArgs() { .build() .prompt() .user("Welcome the user to the library") - .tools(tools) + .tools(this.tools) .call() .content(); assertThat(content).isNotEmpty(); @@ -69,7 +69,7 @@ void chatMethodVoid() { .build() .prompt() .user("Welcome %s to the library".formatted("James Bond")) - .tools(tools) + .tools(this.tools) .call() .content(); assertThat(content).isNotEmpty(); @@ -81,7 +81,7 @@ void chatMethodSingle() { .build() .prompt() .user("What books written by %s are available in the library?".formatted("J.R.R. Tolkien")) - .tools(tools) + .tools(this.tools) .call() .content(); assertThat(content).isNotEmpty() @@ -97,7 +97,7 @@ void chatMethodList() { .prompt() .user("What authors wrote the books %s and %s available in the library?".formatted("The Hobbit", "The Lion, the Witch and the Wardrobe")) - .tools(tools) + .tools(this.tools) .call() .content(); assertThat(content).isNotEmpty().contains("J.R.R. Tolkien").contains("C.S. Lewis"); @@ -110,7 +110,7 @@ void chatMethodCallback() { .prompt() .user("What authors wrote the books %s and %s available in the library?".formatted("The Hobbit", "The Lion, the Witch and the Wardrobe")) - .tools(ToolCallbacks.from(tools)) + .tools(ToolCallbacks.from(this.tools)) .call() .content(); assertThat(content).isNotEmpty().contains("J.R.R. Tolkien").contains("C.S. Lewis"); @@ -119,7 +119,7 @@ void chatMethodCallback() { @Test void chatMethodCallbackDefault() { var content = ChatClient.builder(this.openAiChatModel) - .defaultTools(tools) + .defaultTools(this.tools) .build() .prompt() .user("How many books written by %s are available in the library?".formatted("J.R.R. Tolkien")) @@ -151,13 +151,13 @@ void welcomeUser(String user) { @Tool(description = "Get the list of books written by the given author available in the library") List booksByAuthor(String author) { logger.info("Getting books by author: {}", author); - return bookService.getBooksByAuthor(new Author(author)); + return this.bookService.getBooksByAuthor(new Author(author)); } @Tool(description = "Get the list of authors who wrote the given books available in the library") List authorsByBooks(List books) { logger.info("Getting authors by books: {}", String.join(", ", books)); - return bookService.getAuthorsByBook(books.stream().map(b -> new Book(b, "")).toList()); + return this.bookService.getAuthorsByBook(books.stream().map(b -> new Book(b, "")).toList()); } } diff --git a/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/ToolCallingManagerTests.java b/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/ToolCallingManagerTests.java index 86c83546f15..63dca3849bc 100644 --- a/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/ToolCallingManagerTests.java +++ b/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/tool/ToolCallingManagerTests.java @@ -63,7 +63,7 @@ public class ToolCallingManagerTests { @Test void explicitToolCallingExecutionWithNewOptions() { ChatOptions chatOptions = ToolCallingChatOptions.builder() - .toolCallbacks(ToolCallbacks.from(tools)) + .toolCallbacks(ToolCallbacks.from(this.tools)) .internalToolExecutionEnabled(false) .build(); Prompt prompt = new Prompt( @@ -75,7 +75,7 @@ void explicitToolCallingExecutionWithNewOptions() { @Test void explicitToolCallingExecutionWithNewOptionsStream() { ChatOptions chatOptions = ToolCallingChatOptions.builder() - .toolCallbacks(ToolCallbacks.from(tools)) + .toolCallbacks(ToolCallbacks.from(this.tools)) .internalToolExecutionEnabled(false) .build(); Prompt prompt = new Prompt(new UserMessage("What books written by %s, %s, and %s are available in the library?" @@ -84,12 +84,12 @@ void explicitToolCallingExecutionWithNewOptionsStream() { } private void runExplicitToolCallingExecutionWithOptions(ChatOptions chatOptions, Prompt prompt) { - ChatResponse chatResponse = openAiChatModel.call(prompt); + ChatResponse chatResponse = this.openAiChatModel.call(prompt); assertThat(chatResponse).isNotNull(); assertThat(chatResponse.hasToolCalls()).isTrue(); - ToolExecutionResult toolExecutionResult = toolCallingManager.executeToolCalls(prompt, chatResponse); + ToolExecutionResult toolExecutionResult = this.toolCallingManager.executeToolCalls(prompt, chatResponse); assertThat(toolExecutionResult.conversationHistory()).isNotEmpty(); assertThat(toolExecutionResult.conversationHistory().stream().anyMatch(m -> m instanceof ToolResponseMessage)) @@ -97,7 +97,7 @@ private void runExplicitToolCallingExecutionWithOptions(ChatOptions chatOptions, Prompt secondPrompt = new Prompt(toolExecutionResult.conversationHistory(), chatOptions); - ChatResponse secondChatResponse = openAiChatModel.call(secondPrompt); + ChatResponse secondChatResponse = this.openAiChatModel.call(secondPrompt); assertThat(secondChatResponse).isNotNull(); assertThat(secondChatResponse.getResult().getOutput().getText()).isNotEmpty() @@ -107,9 +107,9 @@ private void runExplicitToolCallingExecutionWithOptions(ChatOptions chatOptions, } private void runExplicitToolCallingExecutionWithOptionsStream(ChatOptions chatOptions, Prompt prompt) { - ChatResponse chatResponse = openAiChatModel.stream(prompt).flatMap(response -> { + ChatResponse chatResponse = this.openAiChatModel.stream(prompt).flatMap(response -> { if (response.hasToolCalls()) { - ToolExecutionResult toolExecutionResult = toolCallingManager.executeToolCalls(prompt, response); + ToolExecutionResult toolExecutionResult = this.toolCallingManager.executeToolCalls(prompt, response); assertThat(toolExecutionResult.conversationHistory()).isNotEmpty(); assertThat(toolExecutionResult.conversationHistory() @@ -118,7 +118,7 @@ private void runExplicitToolCallingExecutionWithOptionsStream(ChatOptions chatOp Prompt secondPrompt = new Prompt(toolExecutionResult.conversationHistory(), chatOptions); // return openAiChatModel.stream(secondPrompt); - return Flux.just(openAiChatModel.call(secondPrompt)); + return Flux.just(this.openAiChatModel.call(secondPrompt)); } return Flux.just(response); }).blockLast(); @@ -141,7 +141,7 @@ static class Tools { @Tool(description = "Get the list of books written by the given author available in the library") List booksByAuthor(String author) { logger.info("Getting books by author: {}", author); - return bookService.getBooksByAuthor(new Author(author)); + return this.bookService.getBooksByAuthor(new Author(author)); } } diff --git a/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/vectorstore/SimpleVectorStoreIT.java b/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/vectorstore/SimpleVectorStoreIT.java index 98086f898e8..40bfe3f499f 100644 --- a/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/vectorstore/SimpleVectorStoreIT.java +++ b/spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/vectorstore/SimpleVectorStoreIT.java @@ -77,7 +77,7 @@ public static String getText(String uri) { @AfterEach void setUp() { - vectorStore.delete(this.documents.stream().map(Document::getId).toList()); + this.vectorStore.delete(this.documents.stream().map(Document::getId).toList()); } @Test @@ -88,9 +88,10 @@ public void searchWithThreshold() { .metadata("meta1", "meta1") .build(); - vectorStore.add(List.of(document)); + this.vectorStore.add(List.of(document)); - List results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); + List results = this.vectorStore + .similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); assertThat(results).hasSize(1); Document resultDoc = results.get(0); @@ -105,9 +106,9 @@ public void searchWithThreshold() { .metadata("meta2", "meta2") .build(); - vectorStore.add(List.of(sameIdDocument)); + this.vectorStore.add(List.of(sameIdDocument)); - results = vectorStore.similaritySearch(SearchRequest.builder().query("FooBar").topK(5).build()); + results = this.vectorStore.similaritySearch(SearchRequest.builder().query("FooBar").topK(5).build()); assertThat(results).hasSize(1); resultDoc = results.get(0); @@ -116,7 +117,7 @@ public void searchWithThreshold() { assertThat(resultDoc.getMetadata()).containsKey("meta2"); assertThat(resultDoc.getMetadata()).containsKey(DocumentMetadata.DISTANCE.value()); - vectorStore.delete(List.of(document.getId())); + this.vectorStore.delete(List.of(document.getId())); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessor.java b/spring-ai-model/src/main/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessor.java index f13aa0a6aef..069aa471517 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessor.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessor.java @@ -16,6 +16,8 @@ package org.springframework.ai.aot; +import java.util.stream.Stream; + import org.springframework.ai.tool.annotation.Tool; import org.springframework.aot.generate.GenerationContext; import org.springframework.aot.hint.MemberCategory; @@ -28,10 +30,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; -import java.util.stream.Stream; - -import static org.springframework.core.annotation.MergedAnnotations.SearchStrategy.TYPE_HIERARCHY; - /** * AOT {@code BeanRegistrationAotProcessor} that detects the presence of the {@link Tool} * annotation on methods and creates the required reflection hints. @@ -45,7 +43,8 @@ class ToolBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor { @Nullable public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { Class beanClass = registeredBean.getBeanClass(); - MergedAnnotations.Search search = MergedAnnotations.search(TYPE_HIERARCHY); + MergedAnnotations.Search search = MergedAnnotations + .search(org.springframework.core.annotation.MergedAnnotations.SearchStrategy.TYPE_HIERARCHY); boolean hasAnyToolAnnotatedMethods = Stream.of(ReflectionUtils.getDeclaredMethods(beanClass)) .anyMatch(method -> search.from(method).isPresent(Tool.class)); @@ -64,14 +63,14 @@ private static class AotContribution implements BeanRegistrationAotContribution private final Class toolClass; - public AotContribution(Class toolClass) { + AotContribution(Class toolClass) { this.toolClass = toolClass; } @Override public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) { ReflectionHints reflectionHints = generationContext.getRuntimeHints().reflection(); - reflectionHints.registerType(toolClass, memberCategories); + reflectionHints.registerType(this.toolClass, this.memberCategories); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/DefaultUsage.java b/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/DefaultUsage.java index 5e6f3190be2..e9a812f44fe 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/DefaultUsage.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/DefaultUsage.java @@ -162,4 +162,4 @@ public String toString() { + ", totalTokens=" + this.totalTokens + '}'; } -} \ No newline at end of file +} diff --git a/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java b/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java index 173ccc26764..5aeefe809d5 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java @@ -42,4 +42,4 @@ public Object getNativeUsage() { return Map.of(); } -} \ No newline at end of file +} diff --git a/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/Usage.java b/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/Usage.java index 4663b275b7e..2afe495d7c8 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/Usage.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/chat/metadata/Usage.java @@ -65,4 +65,4 @@ default Integer getTotalTokens() { */ Object getNativeUsage(); -} \ No newline at end of file +} diff --git a/spring-ai-model/src/main/java/org/springframework/ai/chat/model/ChatResponse.java b/spring-ai-model/src/main/java/org/springframework/ai/chat/model/ChatResponse.java index 4ed1963d593..66a844bab25 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/chat/model/ChatResponse.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/chat/model/ChatResponse.java @@ -106,10 +106,10 @@ public ChatResponseMetadata getMetadata() { * Whether the model has requested the execution of a tool. */ public boolean hasToolCalls() { - if (CollectionUtils.isEmpty(generations)) { + if (CollectionUtils.isEmpty(this.generations)) { return false; } - return generations.stream().anyMatch(generation -> generation.getOutput().hasToolCalls()); + return this.generations.stream().anyMatch(generation -> generation.getOutput().hasToolCalls()); } /** @@ -117,10 +117,10 @@ public boolean hasToolCalls() { */ public boolean hasFinishReasons(Set finishReasons) { Assert.notNull(finishReasons, "finishReasons cannot be null"); - if (CollectionUtils.isEmpty(generations)) { + if (CollectionUtils.isEmpty(this.generations)) { return false; } - return generations.stream().anyMatch(generation -> { + return this.generations.stream().anyMatch(generation -> { var finishReason = (generation.getMetadata().getFinishReason() != null) ? generation.getMetadata().getFinishReason() : ""; return finishReasons.stream().map(String::toLowerCase).toList().contains(finishReason.toLowerCase()); diff --git a/spring-ai-model/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingModel.java b/spring-ai-model/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingModel.java index 3706e4ecf32..7cfcf32d382 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingModel.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingModel.java @@ -16,6 +16,12 @@ package org.springframework.ai.embedding; +import java.io.IOException; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.context.annotation.ImportRuntimeHints; @@ -23,12 +29,6 @@ import org.springframework.core.io.Resource; import org.springframework.util.Assert; -import java.io.IOException; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - /** * Abstract implementation of the {@link EmbeddingModel} interface that provides * dimensions calculation caching. @@ -44,15 +44,6 @@ public abstract class AbstractEmbeddingModel implements EmbeddingModel { private static final Map KNOWN_EMBEDDING_DIMENSIONS = loadKnownModelDimensions(); - static class Hints implements RuntimeHintsRegistrar { - - @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.resources().registerResource(EMBEDDING_MODEL_DIMENSIONS_PROPERTIES); - } - - } - /** * Cached embedding dimensions. */ @@ -106,4 +97,13 @@ public int dimensions() { return this.embeddingDimensions.get(); } + static class Hints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.resources().registerResource(EMBEDDING_MODEL_DIMENSIONS_PROPERTIES); + } + + } + } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/ApiKey.java b/spring-ai-model/src/main/java/org/springframework/ai/model/ApiKey.java index 3d052202ab6..5bd354c4a04 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/ApiKey.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/ApiKey.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.model; /** diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/SimpleApiKey.java b/spring-ai-model/src/main/java/org/springframework/ai/model/SimpleApiKey.java index ce655cf3abf..12eec7ce1dc 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/SimpleApiKey.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/SimpleApiKey.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.model; import org.springframework.util.Assert; diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/SpringAIModelProperties.java b/spring-ai-model/src/main/java/org/springframework/ai/model/SpringAIModelProperties.java index 472a22e0f40..77aa39ca263 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/SpringAIModelProperties.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/SpringAIModelProperties.java @@ -16,7 +16,11 @@ package org.springframework.ai.model; -public class SpringAIModelProperties { +public final class SpringAIModelProperties { + + private SpringAIModelProperties() { + // Avoids instantiation + } public static final String MODEL_PREFIX = "spring.ai.model"; diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/SpringAIModels.java b/spring-ai-model/src/main/java/org/springframework/ai/model/SpringAIModels.java index b85d41e5663..63e7039dff5 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/SpringAIModels.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/SpringAIModels.java @@ -16,7 +16,11 @@ package org.springframework.ai.model; -public class SpringAIModels { +public final class SpringAIModels { + + private SpringAIModels() { + // Avoids instantiation + } public static final String ANTHROPIC = "anthropic"; diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/function/DefaultFunctionCallbackBuilder.java b/spring-ai-model/src/main/java/org/springframework/ai/model/function/DefaultFunctionCallbackBuilder.java index ab23de10ab1..b0d53b204a8 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/function/DefaultFunctionCallbackBuilder.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/function/DefaultFunctionCallbackBuilder.java @@ -142,7 +142,7 @@ public FunctionCallback build() { Assert.notNull(this.inputType, "InputType must not be null"); if (this.getInputTypeSchema() == null) { - boolean upperCaseTypeValues = schemaType == SchemaType.OPEN_API_SCHEMA; + boolean upperCaseTypeValues = this.schemaType == SchemaType.OPEN_API_SCHEMA; this.inputTypeSchema = ModelOptionsUtils.getJsonSchema(this.inputType, upperCaseTypeValues); } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolCallingManager.java b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolCallingManager.java index 9dcca588f85..bf885f8da29 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolCallingManager.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolCallingManager.java @@ -97,7 +97,7 @@ public List resolveToolDefinitions(ToolCallingChatOptions chatOp if (chatOptions.getToolCallbacks().stream().anyMatch(tool -> tool.getName().equals(toolName))) { continue; } - FunctionCallback toolCallback = toolCallbackResolver.resolve(toolName); + FunctionCallback toolCallback = this.toolCallbackResolver.resolve(toolName); if (toolCallback == null) { throw new IllegalStateException("No ToolCallback found for tool name: " + toolName); } @@ -203,7 +203,7 @@ else if (prompt.getOptions() instanceof FunctionCallingOptions functionOptions) FunctionCallback toolCallback = toolCallbacks.stream() .filter(tool -> toolName.equals(tool.getName())) .findFirst() - .orElseGet(() -> toolCallbackResolver.resolve(toolName)); + .orElseGet(() -> this.toolCallbackResolver.resolve(toolName)); if (toolCallback == null) { throw new IllegalStateException("No ToolCallback found for tool name: " + toolName); @@ -227,7 +227,7 @@ else if (returnDirect == null) { toolResult = toolCallback.call(toolInputArguments, toolContext); } catch (ToolExecutionException ex) { - toolResult = toolExecutionExceptionProcessor.process(ex); + toolResult = this.toolExecutionExceptionProcessor.process(ex); } toolResponses.add(new ToolResponseMessage.ToolResponse(toolCall.id(), toolName, toolResult)); @@ -244,14 +244,14 @@ private List buildConversationHistoryAfterToolExecution(List p return messages; } - private record InternalToolExecutionResult(ToolResponseMessage toolResponseMessage, boolean returnDirect) { - } - public static Builder builder() { return new Builder(); } - public static class Builder { + private record InternalToolExecutionResult(ToolResponseMessage toolResponseMessage, boolean returnDirect) { + } + + public final static class Builder { private ObservationRegistry observationRegistry = DEFAULT_OBSERVATION_REGISTRY; @@ -279,8 +279,8 @@ public Builder toolExecutionExceptionProcessor( } public DefaultToolCallingManager build() { - return new DefaultToolCallingManager(observationRegistry, toolCallbackResolver, - toolExecutionExceptionProcessor); + return new DefaultToolCallingManager(this.observationRegistry, this.toolCallbackResolver, + this.toolExecutionExceptionProcessor); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolExecutionEligibilityPredicate.java b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolExecutionEligibilityPredicate.java index 4cdc3ad8bbb..cd890796929 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolExecutionEligibilityPredicate.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolExecutionEligibilityPredicate.java @@ -1,18 +1,19 @@ /* -* Copyright 2025 - 2025 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.model.tool; import org.springframework.ai.chat.model.ChatResponse; diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolExecutionResult.java b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolExecutionResult.java index 81be2caed72..6a9d751f85a 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolExecutionResult.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolExecutionResult.java @@ -39,7 +39,7 @@ public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private List conversationHistory = List.of(); @@ -59,7 +59,7 @@ public Builder returnDirect(boolean returnDirect) { } public DefaultToolExecutionResult build() { - return new DefaultToolExecutionResult(conversationHistory, returnDirect); + return new DefaultToolExecutionResult(this.conversationHistory, this.returnDirect); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/LegacyToolCallingManager.java b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/LegacyToolCallingManager.java index 71019a803a0..760c8537e71 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/LegacyToolCallingManager.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/LegacyToolCallingManager.java @@ -108,10 +108,10 @@ public List resolveToolDefinitions(ToolCallingChatOptions chatOp @Nullable private FunctionCallback resolveFunctionCallback(String toolName) { Assert.hasText(toolName, "toolName cannot be null or empty"); - if (functionCallbacks.get(toolName) != null) { - return functionCallbacks.get(toolName); + if (this.functionCallbacks.get(toolName) != null) { + return this.functionCallbacks.get(toolName); } - return functionCallbackResolver != null ? functionCallbackResolver.resolve(toolName) : null; + return this.functionCallbackResolver != null ? this.functionCallbackResolver.resolve(toolName) : null; } @Override @@ -202,7 +202,7 @@ else if (prompt.getOptions() instanceof FunctionCallingOptions functionOptions) toolResult = toolCallback.call(toolInputArguments, toolContext); } catch (ToolExecutionException ex) { - toolResult = toolExecutionExceptionProcessor.process(ex); + toolResult = this.toolExecutionExceptionProcessor.process(ex); } toolResponses.add(new ToolResponseMessage.ToolResponse(toolCall.id(), toolName, toolResult)); @@ -223,7 +223,7 @@ public static Builder builder() { return new Builder(); } - public static class Builder { + public final static class Builder { private FunctionCallbackResolver functionCallbackResolver; @@ -243,7 +243,7 @@ public Builder functionCallbacks(List functionCallbacks) { } public LegacyToolCallingManager build() { - return new LegacyToolCallingManager(functionCallbackResolver, functionCallbacks); + return new LegacyToolCallingManager(this.functionCallbackResolver, this.functionCallbacks); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolCallingChatOptions.java b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolCallingChatOptions.java index 81bfb7fcd0d..7651861c649 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolCallingChatOptions.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolCallingChatOptions.java @@ -83,6 +83,61 @@ static Builder builder() { return new DefaultToolCallingChatOptions.Builder(); } + static boolean isInternalToolExecutionEnabled(ChatOptions chatOptions) { + Assert.notNull(chatOptions, "chatOptions cannot be null"); + boolean internalToolExecutionEnabled; + if (chatOptions instanceof ToolCallingChatOptions toolCallingChatOptions + && toolCallingChatOptions.isInternalToolExecutionEnabled() != null) { + internalToolExecutionEnabled = Boolean.TRUE.equals(toolCallingChatOptions.isInternalToolExecutionEnabled()); + } + else if (chatOptions instanceof FunctionCallingOptions functionCallingOptions + && functionCallingOptions.getProxyToolCalls() != null) { + internalToolExecutionEnabled = Boolean.TRUE.equals(!functionCallingOptions.getProxyToolCalls()); + } + else { + internalToolExecutionEnabled = DEFAULT_TOOL_EXECUTION_ENABLED; + } + return internalToolExecutionEnabled; + } + + static Set mergeToolNames(Set runtimeToolNames, Set defaultToolNames) { + Assert.notNull(runtimeToolNames, "runtimeToolNames cannot be null"); + Assert.notNull(defaultToolNames, "defaultToolNames cannot be null"); + if (CollectionUtils.isEmpty(runtimeToolNames)) { + return new HashSet<>(defaultToolNames); + } + return new HashSet<>(runtimeToolNames); + } + + static List mergeToolCallbacks(List runtimeToolCallbacks, + List defaultToolCallbacks) { + Assert.notNull(runtimeToolCallbacks, "runtimeToolCallbacks cannot be null"); + Assert.notNull(defaultToolCallbacks, "defaultToolCallbacks cannot be null"); + if (CollectionUtils.isEmpty(runtimeToolCallbacks)) { + return new ArrayList<>(defaultToolCallbacks); + } + return new ArrayList<>(runtimeToolCallbacks); + } + + static Map mergeToolContext(Map runtimeToolContext, + Map defaultToolContext) { + Assert.notNull(runtimeToolContext, "runtimeToolContext cannot be null"); + Assert.noNullElements(runtimeToolContext.keySet(), "runtimeToolContext keys cannot be null"); + Assert.notNull(defaultToolContext, "defaultToolContext cannot be null"); + Assert.noNullElements(defaultToolContext.keySet(), "defaultToolContext keys cannot be null"); + var mergedToolContext = new HashMap<>(defaultToolContext); + mergedToolContext.putAll(runtimeToolContext); + return mergedToolContext; + } + + static void validateToolCallbacks(List toolCallbacks) { + List duplicateToolNames = ToolUtils.getDuplicateToolNames(toolCallbacks); + if (!duplicateToolNames.isEmpty()) { + throw new IllegalStateException("Multiple tools with the same name (%s) found in ToolCallingChatOptions" + .formatted(String.join(", ", duplicateToolNames))); + } + } + /** * A builder to create a {@link ToolCallingChatOptions} instance. */ @@ -173,59 +228,4 @@ interface Builder extends FunctionCallingOptions.Builder { } - static boolean isInternalToolExecutionEnabled(ChatOptions chatOptions) { - Assert.notNull(chatOptions, "chatOptions cannot be null"); - boolean internalToolExecutionEnabled; - if (chatOptions instanceof ToolCallingChatOptions toolCallingChatOptions - && toolCallingChatOptions.isInternalToolExecutionEnabled() != null) { - internalToolExecutionEnabled = Boolean.TRUE.equals(toolCallingChatOptions.isInternalToolExecutionEnabled()); - } - else if (chatOptions instanceof FunctionCallingOptions functionCallingOptions - && functionCallingOptions.getProxyToolCalls() != null) { - internalToolExecutionEnabled = Boolean.TRUE.equals(!functionCallingOptions.getProxyToolCalls()); - } - else { - internalToolExecutionEnabled = DEFAULT_TOOL_EXECUTION_ENABLED; - } - return internalToolExecutionEnabled; - } - - static Set mergeToolNames(Set runtimeToolNames, Set defaultToolNames) { - Assert.notNull(runtimeToolNames, "runtimeToolNames cannot be null"); - Assert.notNull(defaultToolNames, "defaultToolNames cannot be null"); - if (CollectionUtils.isEmpty(runtimeToolNames)) { - return new HashSet<>(defaultToolNames); - } - return new HashSet<>(runtimeToolNames); - } - - static List mergeToolCallbacks(List runtimeToolCallbacks, - List defaultToolCallbacks) { - Assert.notNull(runtimeToolCallbacks, "runtimeToolCallbacks cannot be null"); - Assert.notNull(defaultToolCallbacks, "defaultToolCallbacks cannot be null"); - if (CollectionUtils.isEmpty(runtimeToolCallbacks)) { - return new ArrayList<>(defaultToolCallbacks); - } - return new ArrayList<>(runtimeToolCallbacks); - } - - static Map mergeToolContext(Map runtimeToolContext, - Map defaultToolContext) { - Assert.notNull(runtimeToolContext, "runtimeToolContext cannot be null"); - Assert.noNullElements(runtimeToolContext.keySet(), "runtimeToolContext keys cannot be null"); - Assert.notNull(defaultToolContext, "defaultToolContext cannot be null"); - Assert.noNullElements(defaultToolContext.keySet(), "defaultToolContext keys cannot be null"); - var mergedToolContext = new HashMap<>(defaultToolContext); - mergedToolContext.putAll(runtimeToolContext); - return mergedToolContext; - } - - static void validateToolCallbacks(List toolCallbacks) { - List duplicateToolNames = ToolUtils.getDuplicateToolNames(toolCallbacks); - if (!duplicateToolNames.isEmpty()) { - throw new IllegalStateException("Multiple tools with the same name (%s) found in ToolCallingChatOptions" - .formatted(String.join(", ", duplicateToolNames))); - } - } - } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolExecutionEligibilityChecker.java b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolExecutionEligibilityChecker.java index 171f94aa039..2376bc2e1b2 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolExecutionEligibilityChecker.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolExecutionEligibilityChecker.java @@ -1,18 +1,19 @@ /* -* Copyright 2025 - 2025 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.model.tool; import java.util.function.Function; @@ -77,4 +78,4 @@ else if (chatOptions instanceof FunctionCallingOptions functionCallingOptions return internalToolExecutionEnabled; } -} \ No newline at end of file +} diff --git a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicate.java b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicate.java index cb8244afd86..e3f048ebd41 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicate.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicate.java @@ -1,18 +1,19 @@ /* -* Copyright 2025 - 2025 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.model.tool; import java.util.function.BiPredicate; @@ -42,4 +43,4 @@ default boolean isToolExecutionRequired(ChatOptions promptOptions, ChatResponse return test(promptOptions, chatResponse); } -} \ No newline at end of file +} diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/StaticToolCallbackProvider.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/StaticToolCallbackProvider.java index 4ab2fc87069..71116d80034 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/StaticToolCallbackProvider.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/StaticToolCallbackProvider.java @@ -1,18 +1,19 @@ /* -* Copyright 2025 - 2025 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.tool; import java.util.List; diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/definition/DefaultToolDefinition.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/definition/DefaultToolDefinition.java index 7623a4bc05f..69632a45e0f 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/definition/DefaultToolDefinition.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/definition/DefaultToolDefinition.java @@ -38,7 +38,7 @@ public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private String name; @@ -65,10 +65,10 @@ public Builder inputSchema(String inputSchema) { } public ToolDefinition build() { - if (!StringUtils.hasText(description)) { - description = ToolUtils.getToolDescriptionFromName(name); + if (!StringUtils.hasText(this.description)) { + this.description = ToolUtils.getToolDescriptionFromName(this.name); } - return new DefaultToolDefinition(name, description, inputSchema); + return new DefaultToolDefinition(this.name, this.description, this.inputSchema); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolCallResultConverter.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolCallResultConverter.java index a70316d9eb4..d2331a3c14f 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolCallResultConverter.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolCallResultConverter.java @@ -16,12 +16,6 @@ package org.springframework.ai.tool.execution; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.ai.util.json.JsonParser; -import org.springframework.lang.Nullable; - -import javax.imageio.ImageIO; import java.awt.image.RenderedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -29,6 +23,14 @@ import java.util.Base64; import java.util.Map; +import javax.imageio.ImageIO; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.ai.util.json.JsonParser; +import org.springframework.lang.Nullable; + /** * A default implementation of {@link ToolCallResultConverter}. * diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java index 8dad5c03183..cd6ee28ccd0 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java @@ -42,7 +42,7 @@ public DefaultToolExecutionExceptionProcessor(boolean alwaysThrow) { @Override public String process(ToolExecutionException exception) { Assert.notNull(exception, "exception cannot be null"); - if (alwaysThrow) { + if (this.alwaysThrow) { throw exception; } logger.debug("Exception thrown by tool: {}. Message: {}", exception.getToolDefinition().name(), @@ -64,7 +64,7 @@ public Builder alwaysThrow(boolean alwaysThrow) { } public DefaultToolExecutionExceptionProcessor build() { - return new DefaultToolExecutionExceptionProcessor(alwaysThrow); + return new DefaultToolExecutionExceptionProcessor(this.alwaysThrow); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/ToolExecutionException.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/ToolExecutionException.java index f76acd1d637..617905786d7 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/ToolExecutionException.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/ToolExecutionException.java @@ -34,7 +34,7 @@ public ToolExecutionException(ToolDefinition toolDefinition, Throwable cause) { } public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/function/FunctionToolCallback.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/function/FunctionToolCallback.java index 86ada49479f..98a5d4731eb 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/function/FunctionToolCallback.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/function/FunctionToolCallback.java @@ -78,12 +78,12 @@ public FunctionToolCallback(ToolDefinition toolDefinition, @Nullable ToolMetadat @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override public ToolMetadata getToolMetadata() { - return toolMetadata; + return this.toolMetadata; } @Override @@ -95,19 +95,20 @@ public String call(String toolInput) { public String call(String toolInput, @Nullable ToolContext toolContext) { Assert.hasText(toolInput, "toolInput cannot be null or empty"); - logger.debug("Starting execution of tool: {}", toolDefinition.name()); + logger.debug("Starting execution of tool: {}", this.toolDefinition.name()); - I request = JsonParser.fromJson(toolInput, toolInputType); - O response = toolFunction.apply(request, toolContext); + I request = JsonParser.fromJson(toolInput, this.toolInputType); + O response = this.toolFunction.apply(request, toolContext); - logger.debug("Successful execution of tool: {}", toolDefinition.name()); + logger.debug("Successful execution of tool: {}", this.toolDefinition.name()); - return toolCallResultConverter.convert(response, null); + return this.toolCallResultConverter.convert(response, null); } @Override public String toString() { - return "FunctionToolCallback{" + "toolDefinition=" + toolDefinition + ", toolMetadata=" + toolMetadata + '}'; + return "FunctionToolCallback{" + "toolDefinition=" + this.toolDefinition + ", toolMetadata=" + this.toolMetadata + + '}'; } /** @@ -146,7 +147,7 @@ public static Builder builder(String name, Consumer consumer) { return builder(name, function); } - public static class Builder { + public static final class Builder { private String name; @@ -201,16 +202,16 @@ public Builder toolCallResultConverter(ToolCallResultConverter toolCallRes } public FunctionToolCallback build() { - Assert.notNull(inputType, "inputType cannot be null"); + Assert.notNull(this.inputType, "inputType cannot be null"); var toolDefinition = ToolDefinition.builder() - .name(name) - .description( - StringUtils.hasText(description) ? description : ToolUtils.getToolDescriptionFromName(name)) - .inputSchema( - StringUtils.hasText(inputSchema) ? inputSchema : JsonSchemaGenerator.generateForType(inputType)) + .name(this.name) + .description(StringUtils.hasText(this.description) ? this.description + : ToolUtils.getToolDescriptionFromName(this.name)) + .inputSchema(StringUtils.hasText(this.inputSchema) ? this.inputSchema + : JsonSchemaGenerator.generateForType(this.inputType)) .build(); - return new FunctionToolCallback<>(toolDefinition, toolMetadata, inputType, toolFunction, - toolCallResultConverter); + return new FunctionToolCallback<>(toolDefinition, this.toolMetadata, this.inputType, this.toolFunction, + this.toolCallResultConverter); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/metadata/DefaultToolMetadata.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/metadata/DefaultToolMetadata.java index 64bc6414069..9d63bcabb70 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/metadata/DefaultToolMetadata.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/metadata/DefaultToolMetadata.java @@ -28,7 +28,7 @@ public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private boolean returnDirect = false; @@ -41,7 +41,7 @@ public Builder returnDirect(boolean returnDirect) { } public ToolMetadata build() { - return new DefaultToolMetadata(returnDirect); + return new DefaultToolMetadata(this.returnDirect); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/method/MethodToolCallback.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/method/MethodToolCallback.java index a3b5f41d0bf..ffc2d0e7542 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/method/MethodToolCallback.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/method/MethodToolCallback.java @@ -46,7 +46,7 @@ * @author Thomas Vitale * @since 1.0.0 */ -public class MethodToolCallback implements ToolCallback { +public final class MethodToolCallback implements ToolCallback { private static final Logger logger = LoggerFactory.getLogger(MethodToolCallback.class); @@ -81,12 +81,12 @@ public MethodToolCallback(ToolDefinition toolDefinition, @Nullable ToolMetadata @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override public ToolMetadata getToolMetadata() { - return toolMetadata; + return this.toolMetadata; } @Override @@ -98,7 +98,7 @@ public String call(String toolInput) { public String call(String toolInput, @Nullable ToolContext toolContext) { Assert.hasText(toolInput, "toolInput cannot be null or empty"); - logger.debug("Starting execution of tool: {}", toolDefinition.name()); + logger.debug("Starting execution of tool: {}", this.toolDefinition.name()); validateToolContextSupport(toolContext); @@ -108,16 +108,16 @@ public String call(String toolInput, @Nullable ToolContext toolContext) { Object result = callMethod(methodArguments); - logger.debug("Successful execution of tool: {}", toolDefinition.name()); + logger.debug("Successful execution of tool: {}", this.toolDefinition.name()); - Type returnType = toolMethod.getGenericReturnType(); + Type returnType = this.toolMethod.getGenericReturnType(); - return toolCallResultConverter.convert(result, returnType); + return this.toolCallResultConverter.convert(result, returnType); } private void validateToolContextSupport(@Nullable ToolContext toolContext) { var isNonEmptyToolContextProvided = toolContext != null && !CollectionUtils.isEmpty(toolContext.getContext()); - var isToolContextAcceptedByMethod = Stream.of(toolMethod.getParameterTypes()) + var isToolContextAcceptedByMethod = Stream.of(this.toolMethod.getParameterTypes()) .anyMatch(type -> ClassUtils.isAssignable(type, ToolContext.class)); if (isToolContextAcceptedByMethod && !isNonEmptyToolContextProvided) { throw new IllegalArgumentException("ToolContext is required by the method as an argument"); @@ -131,7 +131,7 @@ private Map extractToolArguments(String toolInput) { // Based on the implementation in MethodInvokingFunctionCallback. private Object[] buildMethodArguments(Map toolInputArguments, @Nullable ToolContext toolContext) { - return Stream.of(toolMethod.getParameters()).map(parameter -> { + return Stream.of(this.toolMethod.getParameters()).map(parameter -> { if (parameter.getType().isAssignableFrom(ToolContext.class)) { return toolContext; } @@ -151,40 +151,41 @@ private Object buildTypedArgument(@Nullable Object value, Class type) { @Nullable private Object callMethod(Object[] methodArguments) { if (isObjectNotPublic() || isMethodNotPublic()) { - toolMethod.setAccessible(true); + this.toolMethod.setAccessible(true); } Object result; try { - result = toolMethod.invoke(toolObject, methodArguments); + result = this.toolMethod.invoke(this.toolObject, methodArguments); } catch (IllegalAccessException ex) { throw new IllegalStateException("Could not access method: " + ex.getMessage(), ex); } catch (InvocationTargetException ex) { - throw new ToolExecutionException(toolDefinition, ex.getCause()); + throw new ToolExecutionException(this.toolDefinition, ex.getCause()); } return result; } private boolean isObjectNotPublic() { - return toolObject != null && !Modifier.isPublic(toolObject.getClass().getModifiers()); + return this.toolObject != null && !Modifier.isPublic(this.toolObject.getClass().getModifiers()); } private boolean isMethodNotPublic() { - return !Modifier.isPublic(toolMethod.getModifiers()); + return !Modifier.isPublic(this.toolMethod.getModifiers()); } @Override public String toString() { - return "MethodToolCallback{" + "toolDefinition=" + toolDefinition + ", toolMetadata=" + toolMetadata + '}'; + return "MethodToolCallback{" + "toolDefinition=" + this.toolDefinition + ", toolMetadata=" + this.toolMetadata + + '}'; } public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private ToolDefinition toolDefinition; @@ -225,8 +226,8 @@ public Builder toolCallResultConverter(ToolCallResultConverter toolCallResultCon } public MethodToolCallback build() { - return new MethodToolCallback(toolDefinition, toolMetadata, toolMethod, toolObject, - toolCallResultConverter); + return new MethodToolCallback(this.toolDefinition, this.toolMetadata, this.toolMethod, this.toolObject, + this.toolCallResultConverter); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/method/MethodToolCallbackProvider.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/method/MethodToolCallbackProvider.java index 3df65662bfa..91b8eb5cc6d 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/method/MethodToolCallbackProvider.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/method/MethodToolCallbackProvider.java @@ -46,7 +46,7 @@ * @author Thomas Vitale * @since 1.0.0 */ -public class MethodToolCallbackProvider implements ToolCallbackProvider { +public final class MethodToolCallbackProvider implements ToolCallbackProvider { private static final Logger logger = LoggerFactory.getLogger(MethodToolCallbackProvider.class); @@ -60,7 +60,7 @@ private MethodToolCallbackProvider(List toolObjects) { @Override public ToolCallback[] getToolCallbacks() { - var toolCallbacks = toolObjects.stream() + var toolCallbacks = this.toolObjects.stream() .map(toolObject -> Stream .of(ReflectionUtils.getDeclaredMethods( AopUtils.isAopProxy(toolObject) ? AopUtils.getTargetClass(toolObject) : toolObject.getClass())) @@ -100,7 +100,7 @@ private void validateToolCallbacks(ToolCallback[] toolCallbacks) { if (!duplicateToolNames.isEmpty()) { throw new IllegalStateException("Multiple tools with the same name (%s) found in sources: %s".formatted( String.join(", ", duplicateToolNames), - toolObjects.stream().map(o -> o.getClass().getName()).collect(Collectors.joining(", ")))); + this.toolObjects.stream().map(o -> o.getClass().getName()).collect(Collectors.joining(", ")))); } } @@ -108,7 +108,7 @@ public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private List toolObjects; @@ -122,7 +122,7 @@ public Builder toolObjects(Object... toolObjects) { } public MethodToolCallbackProvider build() { - return new MethodToolCallbackProvider(toolObjects); + return new MethodToolCallbackProvider(this.toolObjects); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/DelegatingToolCallbackResolver.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/DelegatingToolCallbackResolver.java index de10aca7d26..28ce9da98e0 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/DelegatingToolCallbackResolver.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/DelegatingToolCallbackResolver.java @@ -44,7 +44,7 @@ public DelegatingToolCallbackResolver(List toolCallbackRes public FunctionCallback resolve(String toolName) { Assert.hasText(toolName, "toolName cannot be null or empty"); - for (ToolCallbackResolver toolCallbackResolver : toolCallbackResolvers) { + for (ToolCallbackResolver toolCallbackResolver : this.toolCallbackResolvers) { FunctionCallback toolCallback = toolCallbackResolver.resolve(toolName); if (toolCallback != null) { return toolCallback; diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/SpringBeanToolCallbackResolver.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/SpringBeanToolCallbackResolver.java index 01893049ff4..7f9bf83e960 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/SpringBeanToolCallbackResolver.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/SpringBeanToolCallbackResolver.java @@ -88,12 +88,12 @@ public ToolCallback resolve(String toolName) { return resolvedToolCallback; } - ResolvableType toolType = TypeResolverHelper.resolveBeanType(applicationContext, toolName); + ResolvableType toolType = TypeResolverHelper.resolveBeanType(this.applicationContext, toolName); ResolvableType toolInputType = (ResolvableType.forType(Supplier.class).isAssignableFrom(toolType)) ? ResolvableType.forType(Void.class) : TypeResolverHelper.getFunctionArgumentType(toolType, 0); String toolDescription = resolveToolDescription(toolName, toolInputType.toClass()); - Object bean = applicationContext.getBean(toolName); + Object bean = this.applicationContext.getBean(toolName); resolvedToolCallback = buildToolCallback(toolName, toolType, toolInputType, toolDescription, bean); @@ -103,11 +103,11 @@ public ToolCallback resolve(String toolName) { } public SchemaType getSchemaType() { - return schemaType; + return this.schemaType; } private String resolveToolDescription(String toolName, Class toolInputType) { - Description descriptionAnnotation = applicationContext.findAnnotationOnBean(toolName, Description.class); + Description descriptionAnnotation = this.applicationContext.findAnnotationOnBean(toolName, Description.class); if (descriptionAnnotation != null && StringUtils.hasText(descriptionAnnotation.value())) { return descriptionAnnotation.value(); } @@ -180,13 +180,39 @@ private ToolCallback buildToolCallback(String toolName, ResolvableType toolType, } private String generateSchema(ResolvableType toolInputType) { - if (schemaType == SchemaType.OPEN_API_SCHEMA) { + if (this.schemaType == SchemaType.OPEN_API_SCHEMA) { return JsonSchemaGenerator.generateForType(toolInputType.getType(), JsonSchemaGenerator.SchemaOption.UPPER_CASE_TYPE_VALUES); } return JsonSchemaGenerator.generateForType(toolInputType.getType()); } + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private GenericApplicationContext applicationContext; + + private SchemaType schemaType; + + public Builder applicationContext(GenericApplicationContext applicationContext) { + this.applicationContext = applicationContext; + return this; + } + + public Builder schemaType(SchemaType schemaType) { + this.schemaType = schemaType; + return this; + } + + public SpringBeanToolCallbackResolver build() { + return new SpringBeanToolCallbackResolver(this.applicationContext, this.schemaType); + } + + } + private static final class KotlinDelegate { public static boolean isKotlinSupplier(Class clazz) { @@ -218,30 +244,4 @@ public static boolean isKotlinBiFunction(Class clazz) { } - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - - private GenericApplicationContext applicationContext; - - private SchemaType schemaType; - - public Builder applicationContext(GenericApplicationContext applicationContext) { - this.applicationContext = applicationContext; - return this; - } - - public Builder schemaType(SchemaType schemaType) { - this.schemaType = schemaType; - return this; - } - - public SpringBeanToolCallbackResolver build() { - return new SpringBeanToolCallbackResolver(applicationContext, schemaType); - } - - } - } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/StaticToolCallbackResolver.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/StaticToolCallbackResolver.java index d180257ce87..3b2a77b64de 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/StaticToolCallbackResolver.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/StaticToolCallbackResolver.java @@ -55,7 +55,7 @@ public StaticToolCallbackResolver(List toolCallbacks) { public FunctionCallback resolve(String toolName) { Assert.hasText(toolName, "toolName cannot be null or empty"); logger.debug("ToolCallback resolution attempt from static registry"); - return toolCallbacks.get(toolName); + return this.toolCallbacks.get(toolName); } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/TypeResolverHelper.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/TypeResolverHelper.java index ebdc3c4d878..7a427749b44 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/TypeResolverHelper.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/resolution/TypeResolverHelper.java @@ -47,6 +47,10 @@ */ public final class TypeResolverHelper { + private TypeResolverHelper() { + // Avoids instantiation + } + /** * Returns the input class of a given Consumer class. * @param consumerClass The consumer class. diff --git a/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/JsonSchemaGenerator.java b/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/JsonSchemaGenerator.java index 9e3c1382a3c..27fae0fcc55 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/JsonSchemaGenerator.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/JsonSchemaGenerator.java @@ -38,6 +38,7 @@ import com.github.victools.jsonschema.module.jackson.JacksonOption; import com.github.victools.jsonschema.module.swagger2.Swagger2Module; import io.swagger.v3.oas.annotations.media.Schema; + import org.springframework.ai.chat.model.ToolContext; import org.springframework.ai.tool.annotation.ToolParam; import org.springframework.ai.util.json.JsonParser; @@ -296,7 +297,7 @@ public enum SchemaOption { /** * Convert all "type" values to upper case. */ - UPPER_CASE_TYPE_VALUES; + UPPER_CASE_TYPE_VALUES } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/SchemaType.java b/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/SchemaType.java index 29b4df27834..ad0691b9504 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/SchemaType.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/SchemaType.java @@ -32,6 +32,6 @@ public enum SchemaType { /** * Open API schema. */ - OPEN_API_SCHEMA; + OPEN_API_SCHEMA } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/SpringAiSchemaModule.java b/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/SpringAiSchemaModule.java index 5cc40027c39..2182fc6b25b 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/SpringAiSchemaModule.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/util/json/schema/SpringAiSchemaModule.java @@ -121,7 +121,7 @@ public enum Option { * Properties are only required if marked as such via one of the supported * annotations. */ - PROPERTY_REQUIRED_FALSE_BY_DEFAULT; + PROPERTY_REQUIRED_FALSE_BY_DEFAULT } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessorTests.java b/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessorTests.java index c5eabe2e352..ab67165a0bf 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessorTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessorTests.java @@ -17,6 +17,7 @@ package org.springframework.ai.aot; import org.junit.jupiter.api.Test; + import org.springframework.ai.tool.annotation.Tool; import org.springframework.aot.generate.GenerationContext; import org.springframework.aot.hint.RuntimeHints; @@ -55,7 +56,7 @@ void shouldProcessAnnotatedClass() { } private void process(Class beanClass) { - when(generationContext.getRuntimeHints()).thenReturn(runtimeHints); + when(this.generationContext.getRuntimeHints()).thenReturn(this.runtimeHints); BeanRegistrationAotContribution contribution = createContribution(beanClass); if (contribution != null) { contribution.applyTo(this.generationContext, mock()); diff --git a/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolRuntimeHintsTests.java b/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolRuntimeHintsTests.java index c5a37471a2d..3485a0e9fd6 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolRuntimeHintsTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolRuntimeHintsTests.java @@ -17,6 +17,7 @@ package org.springframework.ai.aot; import org.junit.jupiter.api.Test; + import org.springframework.ai.tool.execution.DefaultToolCallResultConverter; import org.springframework.aot.hint.RuntimeHints; diff --git a/spring-ai-model/src/test/java/org/springframework/ai/chat/metadata/DefaultUsageTests.java b/spring-ai-model/src/test/java/org/springframework/ai/chat/metadata/DefaultUsageTests.java index 0fedfefc3d3..8f1f39deca7 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/chat/metadata/DefaultUsageTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/chat/metadata/DefaultUsageTests.java @@ -16,12 +16,12 @@ package org.springframework.ai.chat.metadata; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Test; - import java.util.HashMap; import java.util.Map; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + import static org.assertj.core.api.Assertions.assertThat; public class DefaultUsageTests { @@ -259,4 +259,4 @@ void testCalculatedTotalTokens() { // value } -} \ No newline at end of file +} diff --git a/spring-ai-model/src/test/java/org/springframework/ai/image/observation/DefaultImageModelObservationConventionTests.java b/spring-ai-model/src/test/java/org/springframework/ai/image/observation/DefaultImageModelObservationConventionTests.java index b1696576a82..845a032461a 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/image/observation/DefaultImageModelObservationConventionTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/image/observation/DefaultImageModelObservationConventionTests.java @@ -22,8 +22,6 @@ import org.springframework.ai.image.ImageOptionsBuilder; import org.springframework.ai.image.ImagePrompt; -import org.springframework.ai.image.observation.DefaultImageModelObservationConvention; -import org.springframework.ai.image.observation.ImageModelObservationContext; import org.springframework.ai.observation.conventions.AiObservationAttributes; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelObservationContextTests.java b/spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelObservationContextTests.java index 1671f4d29be..6d2da149402 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelObservationContextTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelObservationContextTests.java @@ -20,7 +20,6 @@ import org.springframework.ai.image.ImageOptionsBuilder; import org.springframework.ai.image.ImagePrompt; -import org.springframework.ai.image.observation.ImageModelObservationContext; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelPromptContentObservationFilterTests.java b/spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelPromptContentObservationFilterTests.java index 791a6e5d82b..075cb660060 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelPromptContentObservationFilterTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelPromptContentObservationFilterTests.java @@ -25,8 +25,6 @@ import org.springframework.ai.image.ImageMessage; import org.springframework.ai.image.ImageOptionsBuilder; import org.springframework.ai.image.ImagePrompt; -import org.springframework.ai.image.observation.ImageModelObservationContext; -import org.springframework.ai.image.observation.ImageModelPromptContentObservationFilter; import org.springframework.ai.observation.conventions.AiObservationAttributes; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-ai-model/src/test/java/org/springframework/ai/metadata/UsageTests.java b/spring-ai-model/src/test/java/org/springframework/ai/metadata/UsageTests.java index 287da34762f..72b1c6cc169 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/metadata/UsageTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/metadata/UsageTests.java @@ -87,4 +87,4 @@ void totalTokensEqualsPromptTokensPlusGenerationTokens() { verifyUsage(usage); } -} \ No newline at end of file +} diff --git a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolCallingManagerTests.java b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolCallingManagerTests.java index 76b9c951020..760bc3bc88c 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolCallingManagerTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolCallingManagerTests.java @@ -322,24 +322,24 @@ static class TestToolCallback implements ToolCallback { private final ToolMetadata toolMetadata; - public TestToolCallback(String name) { + TestToolCallback(String name) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); this.toolMetadata = ToolMetadata.builder().build(); } - public TestToolCallback(String name, boolean returnDirect) { + TestToolCallback(String name, boolean returnDirect) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); this.toolMetadata = ToolMetadata.builder().returnDirect(returnDirect).build(); } @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override public ToolMetadata getToolMetadata() { - return toolMetadata; + return this.toolMetadata; } @Override @@ -353,18 +353,18 @@ static class FailingToolCallback implements ToolCallback { private final ToolDefinition toolDefinition; - public FailingToolCallback(String name) { + FailingToolCallback(String name) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); } @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override public String call(String toolInput) { - throw new ToolExecutionException(toolDefinition, new IllegalStateException("You failed this city!")); + throw new ToolExecutionException(this.toolDefinition, new IllegalStateException("You failed this city!")); } } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolExecutionEligibilityPredicateTests.java b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolExecutionEligibilityPredicateTests.java index 44ca434b124..021a88ca606 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolExecutionEligibilityPredicateTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolExecutionEligibilityPredicateTests.java @@ -13,18 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.model.tool; +import java.util.List; +import java.util.Map; + import org.junit.jupiter.api.Test; + import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.model.function.FunctionCallingOptions; -import java.util.List; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; /** @@ -47,7 +49,7 @@ void whenToolExecutionEnabledAndHasToolCalls() { ChatResponse chatResponse = new ChatResponse(List.of(new Generation(assistantMessage))); // Test the predicate - boolean result = predicate.test(options, chatResponse); + boolean result = this.predicate.test(options, chatResponse); assertThat(result).isTrue(); } @@ -61,7 +63,7 @@ void whenToolExecutionEnabledAndNoToolCalls() { ChatResponse chatResponse = new ChatResponse(List.of(new Generation(assistantMessage))); // Test the predicate - boolean result = predicate.test(options, chatResponse); + boolean result = this.predicate.test(options, chatResponse); assertThat(result).isFalse(); } @@ -76,7 +78,7 @@ void whenToolExecutionDisabledAndHasToolCalls() { ChatResponse chatResponse = new ChatResponse(List.of(new Generation(assistantMessage))); // Test the predicate - boolean result = predicate.test(options, chatResponse); + boolean result = this.predicate.test(options, chatResponse); assertThat(result).isFalse(); } @@ -90,7 +92,7 @@ void whenToolExecutionDisabledAndNoToolCalls() { ChatResponse chatResponse = new ChatResponse(List.of(new Generation(assistantMessage))); // Test the predicate - boolean result = predicate.test(options, chatResponse); + boolean result = this.predicate.test(options, chatResponse); assertThat(result).isFalse(); } @@ -106,7 +108,7 @@ void whenFunctionCallingOptionsAndToolExecutionEnabled() { ChatResponse chatResponse = new ChatResponse(List.of(new Generation(assistantMessage))); // Test the predicate - boolean result = predicate.test(options, chatResponse); + boolean result = this.predicate.test(options, chatResponse); assertThat(result).isTrue(); } @@ -122,7 +124,7 @@ void whenFunctionCallingOptionsAndToolExecutionDisabled() { ChatResponse chatResponse = new ChatResponse(List.of(new Generation(assistantMessage))); // Test the predicate - boolean result = predicate.test(options, chatResponse); + boolean result = this.predicate.test(options, chatResponse); assertThat(result).isFalse(); } @@ -139,7 +141,7 @@ void whenRegularChatOptionsAndHasToolCalls() { // Test the predicate - should use default value (true) for internal tool // execution - boolean result = predicate.test(options, chatResponse); + boolean result = this.predicate.test(options, chatResponse); assertThat(result).isTrue(); } @@ -149,7 +151,7 @@ void whenNullChatResponse() { ToolCallingChatOptions options = ToolCallingChatOptions.builder().internalToolExecutionEnabled(true).build(); // Test the predicate with null ChatResponse - boolean result = predicate.test(options, null); + boolean result = this.predicate.test(options, null); assertThat(result).isFalse(); } @@ -162,7 +164,7 @@ void whenEmptyGenerationsList() { ChatResponse chatResponse = new ChatResponse(List.of()); // Test the predicate - boolean result = predicate.test(options, chatResponse); + boolean result = this.predicate.test(options, chatResponse); assertThat(result).isFalse(); } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/LegacyToolCallingManagerTests.java b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/LegacyToolCallingManagerTests.java index 048f8f8a982..89a57cf02cb 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/LegacyToolCallingManagerTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/LegacyToolCallingManagerTests.java @@ -175,13 +175,13 @@ static class TestToolCallback implements ToolCallback { private final ToolDefinition toolDefinition; - public TestToolCallback(String name) { + TestToolCallback(String name) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); } @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override @@ -195,18 +195,18 @@ static class FailingToolCallback implements ToolCallback { private final ToolDefinition toolDefinition; - public FailingToolCallback(String name) { + FailingToolCallback(String name) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); } @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override public String call(String toolInput) { - throw new ToolExecutionException(toolDefinition, new IllegalStateException("You failed this city!")); + throw new ToolExecutionException(this.toolDefinition, new IllegalStateException("You failed this city!")); } } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolCallingChatOptionsTests.java b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolCallingChatOptionsTests.java index c8a07a9865c..b8aeff06d14 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolCallingChatOptionsTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolCallingChatOptionsTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.model.tool; import java.util.List; @@ -200,13 +201,13 @@ static class TestToolCallback implements ToolCallback { private final ToolDefinition toolDefinition; - public TestToolCallback(String name) { + TestToolCallback(String name) { this.toolDefinition = ToolDefinition.builder().name(name).inputSchema("{}").build(); } @Override public ToolDefinition getToolDefinition() { - return toolDefinition; + return this.toolDefinition; } @Override diff --git a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicateTests.java b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicateTests.java index 124b0e8f687..d347f9190f1 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicateTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicateTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.model.tool; import java.util.List; diff --git a/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolCallResultConverterTests.java b/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolCallResultConverterTests.java index 69c081da56b..b6d2ee20c57 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolCallResultConverterTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolCallResultConverterTests.java @@ -1,11 +1,21 @@ -package org.springframework.ai.tool.execution; +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import org.junit.jupiter.api.Test; -import org.springframework.ai.util.json.JsonParser; -import org.springframework.util.MimeType; -import org.springframework.util.MimeTypeUtils; +package org.springframework.ai.tool.execution; -import javax.imageio.ImageIO; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; @@ -14,6 +24,14 @@ import java.util.List; import java.util.Map; +import javax.imageio.ImageIO; + +import org.junit.jupiter.api.Test; + +import org.springframework.ai.util.json.JsonParser; +import org.springframework.util.MimeType; +import org.springframework.util.MimeTypeUtils; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -27,32 +45,32 @@ class DefaultToolCallResultConverterTests { @Test void convertWithNullReturnTypeShouldReturn() { - String result = converter.convert(null, null); + String result = this.converter.convert(null, null); assertThat(result).isEqualTo("null"); } @Test void convertVoidReturnTypeShouldReturnDone() { - String result = converter.convert(null, void.class); + String result = this.converter.convert(null, void.class); assertThat(result).isEqualTo("Done"); } @Test void convertStringReturnTypeShouldReturnJson() { - String result = converter.convert("test", String.class); + String result = this.converter.convert("test", String.class); assertThat(result).isEqualTo("\"test\""); } @Test void convertNullReturnValueShouldReturnNullJson() { - String result = converter.convert(null, String.class); + String result = this.converter.convert(null, String.class); assertThat(result).isEqualTo("null"); } @Test void convertObjectReturnTypeShouldReturnJson() { TestObject testObject = new TestObject("test", 42); - String result = converter.convert(testObject, TestObject.class); + String result = this.converter.convert(testObject, TestObject.class); assertThat(result).containsIgnoringWhitespaces(""" "name": "test" """).containsIgnoringWhitespaces(""" @@ -63,7 +81,7 @@ void convertObjectReturnTypeShouldReturnJson() { @Test void convertCollectionReturnTypeShouldReturnJson() { List testList = List.of("one", "two", "three"); - String result = converter.convert(testList, List.class); + String result = this.converter.convert(testList, List.class); assertThat(result).isEqualTo(""" ["one","two","three"] """.trim()); @@ -72,7 +90,7 @@ void convertCollectionReturnTypeShouldReturnJson() { @Test void convertMapReturnTypeShouldReturnJson() { Map testMap = Map.of("one", 1, "two", 2); - String result = converter.convert(testMap, Map.class); + String result = this.converter.convert(testMap, Map.class); assertThat(result).containsIgnoringWhitespaces(""" "one": 1 """).containsIgnoringWhitespaces(""" @@ -90,7 +108,7 @@ void convertImageShouldReturnBase64Image() throws IOException { g.setColor(Color.WHITE); g.fillRect(0, 0, 64, 64); g.dispose(); - String result = converter.convert(img, BufferedImage.class); + String result = this.converter.convert(img, BufferedImage.class); var b64Struct = JsonParser.fromJson(result, Base64Wrapper.class); assertThat(b64Struct.mimeType).isEqualTo(MimeTypeUtils.IMAGE_PNG); @@ -120,11 +138,11 @@ static class TestObject { } public String getName() { - return name; + return this.name; } public int getValue() { - return value; + return this.value; } } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java b/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java index 71c7b09209b..6c475606a87 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2023-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.util.json; import java.lang.reflect.Type; @@ -5,8 +21,6 @@ import com.fasterxml.jackson.core.type.TypeReference; import org.junit.jupiter.api.Test; -import org.springframework.ai.util.json.JsonParser; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonSchemaGeneratorTests.java b/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonSchemaGeneratorTests.java index e644f262eee..c0c61f7eab6 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonSchemaGeneratorTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonSchemaGeneratorTests.java @@ -30,9 +30,9 @@ import com.fasterxml.jackson.databind.JsonNode; import io.swagger.v3.oas.annotations.media.Schema; import org.junit.jupiter.api.Test; + import org.springframework.ai.chat.model.ToolContext; import org.springframework.ai.tool.annotation.ToolParam; -import org.springframework.ai.util.json.JsonParser; import org.springframework.ai.util.json.schema.JsonSchemaGenerator; import org.springframework.lang.Nullable; @@ -696,27 +696,33 @@ public void contextMethod(String deliveryStatus, LocalDateTime expectedDelivery, } record TestData(int id, @ToolParam(description = "The special name") String name) { + } @JsonClassDescription("Much more data") record MoreTestData(int id, @Schema(description = "Even more special name") String name) { + } record AnnotatedPerson(@ToolParam int id, @ToolParam String name, @ToolParam(required = false, description = "The email of the person") String email) { + } record JacksonPerson(@JsonProperty(required = true) int id, @JsonProperty(required = true) String name, @JsonProperty String email) { + } record OpenApiPerson(@Schema(requiredMode = Schema.RequiredMode.REQUIRED) int id, @Schema(requiredMode = Schema.RequiredMode.REQUIRED) String name, @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = "The email of the person") String email) { + } record NullablePerson(int id, String name, @Nullable String email) { + } static class Person { @@ -728,7 +734,7 @@ static class Person { private String email; public int getId() { - return id; + return this.id; } public void setId(int id) { @@ -736,7 +742,7 @@ public void setId(int id) { } public String getName() { - return name; + return this.name; } public void setName(String name) { @@ -744,7 +750,7 @@ public void setName(String name) { } public String getEmail() { - return email; + return this.email; } public void setEmail(String email) { diff --git a/spring-ai-test/src/main/java/org/springframework/ai/test/vectorstore/BaseVectorStoreTests.java b/spring-ai-test/src/main/java/org/springframework/ai/test/vectorstore/BaseVectorStoreTests.java index 17b0604ba8e..5bfa12c1d16 100644 --- a/spring-ai-test/src/main/java/org/springframework/ai/test/vectorstore/BaseVectorStoreTests.java +++ b/spring-ai-test/src/main/java/org/springframework/ai/test/vectorstore/BaseVectorStoreTests.java @@ -16,11 +16,6 @@ package org.springframework.ai.test.vectorstore; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; - import java.time.Duration; import java.util.HashMap; import java.util.List; @@ -29,11 +24,16 @@ import java.util.function.Consumer; import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; + import org.springframework.ai.document.Document; import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.ai.vectorstore.filter.Filter; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + /** * Base test class for VectorStore implementations. Provides common test scenarios for * delete operations. diff --git a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStoreContent.java b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStoreContent.java index 62b833ccd6a..28b3ad52b36 100644 --- a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStoreContent.java +++ b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStoreContent.java @@ -25,11 +25,11 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.ai.content.Content; import org.springframework.ai.document.Document; import org.springframework.ai.document.DocumentMetadata; import org.springframework.ai.document.id.IdGenerator; import org.springframework.ai.document.id.RandomIdGenerator; -import org.springframework.ai.content.Content; import org.springframework.util.Assert; /** diff --git a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SpringAIVectorStoreTypes.java b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SpringAIVectorStoreTypes.java index 1dfc06f9930..4e8f8913b7a 100644 --- a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SpringAIVectorStoreTypes.java +++ b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SpringAIVectorStoreTypes.java @@ -16,7 +16,11 @@ package org.springframework.ai.vectorstore; -public class SpringAIVectorStoreTypes { +public final class SpringAIVectorStoreTypes { + + private SpringAIVectorStoreTypes() { + // Avoids instantiation + } public static final String VECTOR_STORE_PREFIX = "spring.ai.vectorstore"; diff --git a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/converter/SimpleVectorStoreFilterExpressionConverter.java b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/converter/SimpleVectorStoreFilterExpressionConverter.java index 27b5920b445..266dd4d6a0c 100644 --- a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/converter/SimpleVectorStoreFilterExpressionConverter.java +++ b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/converter/SimpleVectorStoreFilterExpressionConverter.java @@ -16,9 +16,6 @@ package org.springframework.ai.vectorstore.filter.converter; -import org.springframework.ai.vectorstore.filter.Filter; -import org.springframework.ai.vectorstore.filter.Filter.Expression; - import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -26,6 +23,9 @@ import java.util.TimeZone; import java.util.regex.Pattern; +import org.springframework.ai.vectorstore.filter.Filter; +import org.springframework.ai.vectorstore.filter.Filter.Expression; + /** * Converts {@link Expression} into SpEL metadata filter expression format. * (https://docs.spring.io/spring-framework/reference/core/expressions.html) @@ -99,9 +99,9 @@ protected void doValue(Filter.Value filterValue, StringBuilder context) { private void appendSpELContains(StringBuilder formattedList, StringBuilder context) { int metadataStart = context.lastIndexOf("#metadata"); - if (metadataStart == -1) + if (metadataStart == -1) { throw new RuntimeException("Wrong SpEL expression: " + context); - + } int metadataEnd = context.indexOf(" ", metadataStart); String metadata = context.substring(metadataStart, metadataEnd); context.setLength(context.lastIndexOf("in ")); diff --git a/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreWithFilterTests.java b/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreWithFilterTests.java index afa2aa52cf6..27e7ac6079c 100644 --- a/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreWithFilterTests.java +++ b/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreWithFilterTests.java @@ -16,20 +16,21 @@ package org.springframework.ai.vectorstore; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.CleanupMode; import org.junit.jupiter.api.io.TempDir; + import org.springframework.ai.document.Document; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.ai.vectorstore.filter.Filter; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; diff --git a/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/filter/converter/SimpleVectorStoreFilterExpressionConverterTests.java b/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/filter/converter/SimpleVectorStoreFilterExpressionConverterTests.java index 1fed696abdb..e4e2cf9c8b8 100644 --- a/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/filter/converter/SimpleVectorStoreFilterExpressionConverterTests.java +++ b/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/filter/converter/SimpleVectorStoreFilterExpressionConverterTests.java @@ -16,18 +16,19 @@ package org.springframework.ai.vectorstore.filter.converter; +import java.util.Date; +import java.util.List; +import java.util.Map; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; + import org.springframework.ai.vectorstore.filter.Filter; import org.springframework.ai.vectorstore.filter.FilterExpressionConverter; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; -import java.util.Date; -import java.util.List; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND; import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.EQ; diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index 76ad238e203..cfb80a1532b 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -36,6 +36,10 @@ + + + + diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index 8162ac427a4..343ae144ac9 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -100,7 +100,7 @@ + value="org.springframework.ai.model.openai.autoconfigure.OpenAIAutoConfigurationUtil.*, org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.AudioParameters.Voice.*, org.springframework.ai.mistralai.api.MistralAiModerationApi.*, org.springframework.ai.util.LoggingMarkers.*, org.springframework.ai.embedding.observation.EmbeddingModelObservationDocumentation.*, org.springframework.ai.test.vectorstore.ObservationTestUtil.*, org.springframework.ai.autoconfigure.vectorstore.observation.ObservationTestUtil.*, org.awaitility.Awaitility.*, org.springframework.ai.aot.AiRuntimeHints.*, org.springframework.ai.openai.metadata.support.OpenAiApiResponseHeaders.*, org.springframework.ai.image.observation.ImageModelObservationDocumentation.*, org.springframework.ai.observation.embedding.EmbeddingModelObservationDocumentation.*, org.springframework.aot.hint.predicate.RuntimeHintsPredicates.*, org.springframework.ai.vectorstore.filter.Filter.ExpressionType.*, org.springframework.ai.chat.observation.ChatModelObservationDocumentation.*, org.assertj.core.groups.Tuple.*, org.assertj.core.api.AssertionsForClassTypes.*, org.junit.jupiter.api.Assertions.*, org.assertj.core.api.Assertions.*, org.junit.Assert.*, org.junit.Assume.*, org.junit.internal.matchers.ThrowableMessageMatcher.*, org.hamcrest.CoreMatchers.*, org.hamcrest.Matchers.*, org.springframework.boot.configurationprocessor.ConfigurationMetadataMatchers.*, org.springframework.boot.configurationprocessor.TestCompiler.*, org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.*, org.mockito.Mockito.*, org.mockito.BDDMockito.*, org.mockito.Matchers.*, org.mockito.ArgumentMatchers.*, org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*, org.springframework.test.web.servlet.result.MockMvcResultMatchers.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*, org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*, org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo, org.springframework.test.web.client.match.MockRestRequestMatchers.*, org.springframework.test.web.client.response.MockRestResponseCreators.*, org.springframework.web.reactive.function.server.RequestPredicates.*, org.springframework.web.reactive.function.server.RouterFunctions.*, org.springframework.test.web.servlet.setup.MockMvcBuilders.*"/> diff --git a/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java b/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java index 902d42036b6..1c5a41c1b68 100644 --- a/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java +++ b/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java @@ -235,7 +235,7 @@ protected CassandraVectorStore(Builder builder) { this.executor = Executors.newFixedThreadPool(builder.fixedThreadPoolExecutorSize); this.closeSessionOnClose = builder.closeSessionOnClose; - ensureSchemaExists(embeddingModel.dimensions()); + ensureSchemaExists(this.embeddingModel.dimensions()); prepareAddStatement(Set.of()); this.deleteStmt = prepareDeleteStatement(); diff --git a/vector-stores/spring-ai-couchbase-store/src/main/java/org/springframework/ai/vectorstore/CouchbaseSearchVectorStore.java b/vector-stores/spring-ai-couchbase-store/src/main/java/org/springframework/ai/vectorstore/CouchbaseSearchVectorStore.java index 58fabf5ec3c..bf35f2828d8 100644 --- a/vector-stores/spring-ai-couchbase-store/src/main/java/org/springframework/ai/vectorstore/CouchbaseSearchVectorStore.java +++ b/vector-stores/spring-ai-couchbase-store/src/main/java/org/springframework/ai/vectorstore/CouchbaseSearchVectorStore.java @@ -98,9 +98,9 @@ protected CouchbaseSearchVectorStore(Builder builder) { this.embeddingModel = builder.embeddingModel; this.filterExpressionConverter = builder.filterExpressionConverter; this.cluster = builder.cluster; - this.bucket = cluster.bucket(builder.bucketName); - this.scope = bucket.scope(builder.scopeName); - this.collection = scope.collection(builder.collectionName); + this.bucket = this.cluster.bucket(builder.bucketName); + this.scope = this.bucket.scope(builder.scopeName); + this.collection = this.scope.collection(builder.collectionName); this.vectorIndexName = builder.vectorIndexName; this.collectionName = builder.collectionName; this.bucketName = builder.bucketName; @@ -136,14 +136,14 @@ public void doAdd(List documents) { for (Document document : documents) { CouchbaseDocument cbDoc = new CouchbaseDocument(document.getId(), document.getText(), document.getMetadata(), embeddings.get(documents.indexOf(document))); - collection.upsert(document.getId(), cbDoc); + this.collection.upsert(document.getId(), cbDoc); } } @Override public void doDelete(List idList) { for (String id : idList) { - collection.remove(id); + this.collection.remove(id); } } @@ -152,8 +152,8 @@ public void doDelete(Filter.Expression filterExpression) { Assert.notNull(filterExpression, "Filter expression must not be null"); try { String nativeFilter = this.filterExpressionConverter.convertExpression(filterExpression); - String sql = String.format("DELETE FROM %s WHERE %s", collection.name(), nativeFilter); - scope.query(sql, QueryOptions.queryOptions().metrics(true)); + String sql = String.format("DELETE FROM %s WHERE %s", this.collection.name(), nativeFilter); + this.scope.query(sql, QueryOptions.queryOptions().metrics(true)); } catch (Exception e) { logger.error("Failed to delete documents by filter: {}", e.getMessage(), e); @@ -180,7 +180,7 @@ WHERE SEARCH_SCORE() > %s AND SEARCH(`c`, {"query": {"match_none": {}}, "knn": [ this.collectionName, similarityThreshold, topK, Arrays.toString(embeddings), this.bucketName, this.scopeName, this.vectorIndexName, nativeFilterExpression); - QueryResult result = scope.query(statement, QueryOptions.queryOptions()); + QueryResult result = this.scope.query(statement, QueryOptions.queryOptions()); return result.rowsAs(Document.class); } @@ -340,21 +340,21 @@ public CouchbaseSearchVectorStore build() { public void initCluster() throws InterruptedException { // init scope, collection, indexes - BucketSettings bs = cluster.buckets().getAllBuckets().get(this.bucketName); + BucketSettings bs = this.cluster.buckets().getAllBuckets().get(this.bucketName); if (bs == null) { - cluster.buckets().createBucket(BucketSettings.create(this.bucketName)); + this.cluster.buckets().createBucket(BucketSettings.create(this.bucketName)); } logger.info("Created bucket"); - Bucket b = cluster.bucket(this.bucketName); + Bucket b = this.cluster.bucket(this.bucketName); b.waitUntilReady(Duration.ofSeconds(20)); logger.info("Opened Bucket"); boolean scopeExist = b.collections().getAllScopes().stream().anyMatch(sc -> sc.name().equals(this.scopeName)); if (!scopeExist) { b.collections().createScope(this.scopeName); } - ConsistencyUtil.waitUntilScopePresent(cluster.core(), this.bucketName, this.scopeName); + ConsistencyUtil.waitUntilScopePresent(this.cluster.core(), this.bucketName, this.scopeName); Scope s = b.scope(this.scopeName); - boolean collectionExist = bucket.collections() + boolean collectionExist = this.bucket.collections() .getAllScopes() .stream() .map(ScopeSpec::collections) @@ -364,7 +364,7 @@ public void initCluster() throws InterruptedException { .anyMatch(this.collectionName::equals); if (!collectionExist) { b.collections().createCollection(this.scopeName, this.collectionName); - ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), this.bucketName, this.scopeName, + ConsistencyUtil.waitUntilCollectionPresent(this.cluster.core(), this.bucketName, this.scopeName, this.collectionName); Collection c = s.collection(this.collectionName); Mono.empty() diff --git a/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStoreOptions.java b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStoreOptions.java index 8b558bc3539..321463ca4d1 100644 --- a/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStoreOptions.java +++ b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStoreOptions.java @@ -71,7 +71,7 @@ public void setSimilarity(SimilarityFunction similarity) { } public String getEmbeddingFieldName() { - return embeddingFieldName; + return this.embeddingFieldName; } public void setEmbeddingFieldName(String embeddingFieldName) { diff --git a/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStoreTest.java b/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStoreTest.java index 1eadd100198..003e60c86c7 100644 --- a/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStoreTest.java +++ b/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStoreTest.java @@ -47,7 +47,7 @@ class MilvusVectorStoreTest { @BeforeEach void setUp() { - vectorStore = MilvusVectorStore.builder(milvusClient, embeddingModel).build(); + this.vectorStore = MilvusVectorStore.builder(this.milvusClient, this.embeddingModel).build(); } @Test @@ -130,14 +130,14 @@ private SearchParam performSimilaritySearch(MockedStatic mockedE when(mockResults.getResults()).thenReturn(SearchResultData.getDefaultInstance()); R mockResponse = R.success(mockResults); - when(milvusClient.search(any(SearchParam.class))).thenReturn(mockResponse); + when(this.milvusClient.search(any(SearchParam.class))).thenReturn(mockResponse); ArgumentCaptor searchParamCaptor = ArgumentCaptor.forClass(SearchParam.class); - List results = vectorStore.doSimilaritySearch(request); + List results = this.vectorStore.doSimilaritySearch(request); assertThat(results).isNotNull(); - verify(milvusClient).search(searchParamCaptor.capture()); + verify(this.milvusClient).search(searchParamCaptor.capture()); return searchParamCaptor.getValue(); }