Miscellaneous checkstyle fixes

Signed-off-by: Soby Chacko <soby.chacko@broadcom.com>
This commit is contained in:
Soby Chacko
2025-04-13 21:54:46 -04:00
committed by Ilayaperumal Gopinathan
parent 318bdfc7c1
commit d9e7ace996
212 changed files with 1206 additions and 945 deletions

View File

@@ -21,6 +21,10 @@ import java.util.List;
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.CallAroundAdvisor;
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;

View File

@@ -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));
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 class Neo4jChatMemoryProperties {
}
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) {

View File

@@ -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;

View File

@@ -20,16 +20,16 @@ import io.micrometer.observation.ObservationRegistry;
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;

View File

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

View File

@@ -121,9 +121,7 @@ public class AnthropicPropertiesTests {
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());
}
}

View File

@@ -27,12 +27,12 @@ import org.slf4j.LoggerFactory;
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;

View File

@@ -26,10 +26,10 @@ import org.slf4j.LoggerFactory;
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;

View File

@@ -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;

View File

@@ -22,7 +22,6 @@ import org.springframework.ai.azure.openai.AzureOpenAiAudioTranscriptionModel;
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;

View File

@@ -28,7 +28,6 @@ import com.azure.core.util.ClientOptions;
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;

View File

@@ -25,7 +25,6 @@ import org.springframework.ai.model.SpringAIModelProperties;
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;

View File

@@ -22,7 +22,6 @@ import org.springframework.ai.azure.openai.AzureOpenAiImageModel;
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;

View File

@@ -34,7 +34,6 @@ import com.azure.core.http.HttpRequest;
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;

View File

@@ -20,12 +20,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
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;

View File

@@ -22,18 +22,18 @@ import software.amazon.awssdk.regions.providers.AwsRegionProvider;
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;

View File

@@ -20,12 +20,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
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;

View File

@@ -21,14 +21,14 @@ import java.util.List;
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;

View File

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

View File

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

View File

@@ -24,14 +24,14 @@ import org.apache.commons.logging.LogFactory;
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;

View File

@@ -25,13 +25,13 @@ import org.slf4j.Logger;
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;

View File

@@ -22,13 +22,13 @@ import org.junit.jupiter.api.Test;
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;

View File

@@ -22,13 +22,13 @@ import java.util.List;
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;

View File

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

View File

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

View File

@@ -26,7 +26,6 @@ import org.slf4j.Logger;
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.chat.prompt.Prompt;
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;

View File

@@ -25,13 +25,13 @@ import org.junit.jupiter.api.Test;
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;

View File

@@ -20,11 +20,11 @@ import org.junit.jupiter.api.Test;
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;

View File

@@ -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;

View File

@@ -18,8 +18,8 @@ package org.springframework.ai.model.mistralai.autoconfigure;
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;

View File

@@ -67,9 +67,7 @@ public class MistralModelConfigurationTests {
@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")

View File

@@ -20,15 +20,15 @@ import java.util.List;
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;

View File

@@ -25,11 +25,11 @@ import org.junit.jupiter.api.Test;
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;

View File

@@ -18,8 +18,8 @@ package org.springframework.ai.model.moonshot.autoconfigure;
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;

View File

@@ -25,16 +25,16 @@ import org.slf4j.Logger;
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;

View File

@@ -26,16 +26,16 @@ import org.slf4j.Logger;
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;

View File

@@ -26,16 +26,16 @@ import org.slf4j.Logger;
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;

View File

@@ -27,9 +27,13 @@ import org.springframework.util.CollectionUtils;
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()

View File

@@ -59,7 +59,7 @@ public class FunctionCallbackInPrompt2IT {
.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")

View File

@@ -24,11 +24,11 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
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;

View File

@@ -23,10 +23,10 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
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;

View File

@@ -23,10 +23,10 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
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;

View File

@@ -128,12 +128,6 @@ class ToolCallingAutoConfigurationTests {
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<Request, Response> weatherFunction1() {
@@ -188,6 +182,12 @@ class ToolCallingAutoConfigurationTests {
.build();
}
public record Request(String location) {
}
public record Response(String temperature) {
}
}
}

View File

@@ -77,7 +77,7 @@ public class CouchbaseSearchVectorStoreProperties extends CommonVectorStorePrope
}
public String getCollectionName() {
return collectionName;
return this.collectionName;
}
public void setCollectionName(String collectionName) {
@@ -85,7 +85,7 @@ public class CouchbaseSearchVectorStoreProperties extends CommonVectorStorePrope
}
public String getScopeName() {
return scopeName;
return this.scopeName;
}
public void setScopeName(String scopeName) {
@@ -93,7 +93,7 @@ public class CouchbaseSearchVectorStoreProperties extends CommonVectorStorePrope
}
public String getBucketName() {
return bucketName;
return this.bucketName;
}
public void setBucketName(String bucketName) {
@@ -101,7 +101,7 @@ public class CouchbaseSearchVectorStoreProperties extends CommonVectorStorePrope
}
public Integer getDimensions() {
return dimensions;
return this.dimensions;
}
public void setDimensions(Integer dimensions) {
@@ -109,7 +109,7 @@ public class CouchbaseSearchVectorStoreProperties extends CommonVectorStorePrope
}
public CouchbaseSimilarityFunction getSimilarity() {
return similarity;
return this.similarity;
}
public void setSimilarity(CouchbaseSimilarityFunction similarity) {
@@ -117,7 +117,7 @@ public class CouchbaseSearchVectorStoreProperties extends CommonVectorStorePrope
}
public CouchbaseIndexOptimization getOptimization() {
return optimization;
return this.optimization;
}
public void setOptimization(CouchbaseIndexOptimization optimization) {

View File

@@ -79,7 +79,7 @@ class CouchbaseSearchVectorStoreAutoConfigurationIT {
@Test
public void addAndSearchWithFilters() {
contextRunner.run(context -> {
this.contextRunner.run(context -> {
VectorStore vectorStore = context.getBean(VectorStore.class);

View File

@@ -77,7 +77,7 @@ public class ElasticsearchVectorStoreProperties extends CommonVectorStorePropert
}
public String getEmbeddingFieldName() {
return embeddingFieldName;
return this.embeddingFieldName;
}
public void setEmbeddingFieldName(String embeddingFieldName) {

View File

@@ -108,7 +108,7 @@ public class MariaDbStoreProperties extends CommonVectorStoreProperties {
}
public String getEmbeddingFieldName() {
return embeddingFieldName;
return this.embeddingFieldName;
}
public void setEmbeddingFieldName(String embeddingFieldName) {
@@ -116,7 +116,7 @@ public class MariaDbStoreProperties extends CommonVectorStoreProperties {
}
public String getIdFieldName() {
return idFieldName;
return this.idFieldName;
}
public void setIdFieldName(String idFieldName) {
@@ -124,7 +124,7 @@ public class MariaDbStoreProperties extends CommonVectorStoreProperties {
}
public String getMetadataFieldName() {
return metadataFieldName;
return this.metadataFieldName;
}
public void setMetadataFieldName(String metadataFieldName) {
@@ -132,7 +132,7 @@ public class MariaDbStoreProperties extends CommonVectorStoreProperties {
}
public String getContentFieldName() {
return contentFieldName;
return this.contentFieldName;
}
public void setContentFieldName(String contentFieldName) {

View File

@@ -102,7 +102,7 @@ public class PgVectorStoreProperties extends CommonVectorStoreProperties {
}
public PgVectorStore.PgIdType getIdType() {
return idType;
return this.idType;
}
public void setIdType(PgVectorStore.PgIdType idType) {

View File

@@ -68,7 +68,7 @@ public class JsoupDocumentReader implements DocumentReader {
@Override
public List<Document> get() {
try (InputStream inputStream = htmlResource.getInputStream()) {
try (InputStream inputStream = this.htmlResource.getInputStream()) {
org.jsoup.nodes.Document doc = Jsoup.parse(inputStream, this.config.charset, "");
List<Document> documents = new ArrayList<>();
@@ -104,7 +104,7 @@ public class JsoupDocumentReader implements DocumentReader {
}
catch (IOException e) {
throw new RuntimeException("Failed to read HTML resource: " + htmlResource, e);
throw new RuntimeException("Failed to read HTML resource: " + this.htmlResource, e);
}
}

View File

@@ -112,7 +112,7 @@ public class PagePdfDocumentReader implements DocumentReader {
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 class PagePdfDocumentReader implements DocumentReader {
readDocuments.add(toDocument(lastPage, pageTextGroupList.stream().collect(Collectors.joining()),
startPageNumber, pageNumber));
}
logger.info("Processing {} pages", totalPages);
this.logger.info("Processing {} pages", totalPages);
return readDocuments;
}

View File

@@ -133,7 +133,7 @@ public class ParagraphPdfDocumentReader implements DocumentReader {
List<Document> 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<Paragraph> itr = paragraphs.iterator();
var current = itr.next();
@@ -152,7 +152,7 @@ public class ParagraphPdfDocumentReader implements DocumentReader {
}
}
}
logger.info("End processing paragraphs from PDF");
this.logger.info("End processing paragraphs from PDF");
return documents;
}

View File

@@ -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 class AsyncMcpToolCallbackProvider implements ToolCallbackProvider {
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();

View File

@@ -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 reactor.core.scheduler.Schedulers;
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;

View File

@@ -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 class SyncMcpToolCallbackProvider implements ToolCallbackProvider {
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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 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 org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
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 @@ class SyncMcpToolCallbackProviderTests {
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 @@ class SyncMcpToolCallbackProviderTests {
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 @@ class SyncMcpToolCallbackProviderTests {
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 @@ class SyncMcpToolCallbackProviderTests {
@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 @@ class SyncMcpToolCallbackProviderTests {
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 @@ class SyncMcpToolCallbackProviderTests {
@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 @@ class SyncMcpToolCallbackProviderTests {
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 @@ class SyncMcpToolCallbackProviderTests {
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<McpSyncClient, Tool> 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 @@ class SyncMcpToolCallbackProviderTests {
@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 @@ class SyncMcpToolCallbackProviderTests {
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<McpSyncClient, Tool> 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();

View File

@@ -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 @@ class SyncMcpToolCallbackTests {
// 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 @@ class SyncMcpToolCallbackTests {
// 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")));

View File

@@ -22,7 +22,11 @@ import java.sql.SQLException;
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;

View File

@@ -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")

View File

@@ -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;

View File

@@ -32,7 +32,11 @@ import org.testcontainers.junit.jupiter.Testcontainers;
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;

View File

@@ -49,7 +49,7 @@ class JdbcChatMemoryRuntimeHintsTest {
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();
}

View File

@@ -30,7 +30,7 @@ public enum MediaAttributes {
}
public String getValue() {
return value;
return this.value;
}
}

View File

@@ -26,7 +26,7 @@ public enum MessageAttributes {
private final String value;
public String getValue() {
return value;
return this.value;
}
MessageAttributes(String value) {

View File

@@ -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.Media;
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 class Neo4jChatMemory implements ChatMemory {
@Override
public void add(String conversationId, List<Message> 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 @@ public class Neo4jChatMemory implements ChatMemory {
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 @@ public class Neo4jChatMemory implements ChatMemory {
}
public Neo4jChatMemoryConfig getConfig() {
return config;
return this.config;
}
@Override
@@ -132,9 +134,10 @@ public class Neo4jChatMemory implements ChatMemory {
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 @@ public class Neo4jChatMemory implements ChatMemory {
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<String, Object> attributes = new HashMap<>();
attributes.put(MessageAttributes.MESSAGE_TYPE.getValue(), message.getMessageType().getValue());
@@ -163,7 +167,7 @@ public class Neo4jChatMemory implements ChatMemory {
CREATE (metadataNode:%s)
CREATE (msg)-[:HAS_METADATA]->(metadataNode)
SET metadataNode = $metadata
""".formatted(config.getMetadataLabel()));
""".formatted(this.config.getMetadataLabel()));
Map<String, Object> metadataCopy = new HashMap<>(message.getMetadata());
metadataCopy.remove("messageType");
queryParameters.put("metadata", metadataCopy);
@@ -174,7 +178,7 @@ public class Neo4jChatMemory implements ChatMemory {
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<Map<String, Object>> toolCallMaps = new ArrayList<>();
for (int i = 0; i < assistantMessage.getToolCalls().size(); i++) {
AssistantMessage.ToolCall tc = assistantMessage.getToolCalls().get(i);
@@ -202,7 +206,7 @@ public class Neo4jChatMemory implements ChatMemory {
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 @@ public class Neo4jChatMemory implements ChatMemory {
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);

View File

@@ -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 @@ public final class Neo4jChatMemoryConfig {
}
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 final class Neo4jChatMemoryConfig {
}
public Driver getDriver() {
return driver;
return this.driver;
}
public Builder withDriver(Driver driver) {

View File

@@ -30,7 +30,7 @@ public enum ToolCallAttributes {
}
public String getValue() {
return value;
return this.value;
}
}

View File

@@ -30,7 +30,7 @@ public enum ToolResponseAttributes {
}
public String getValue() {
return value;
return this.value;
}
}

View File

@@ -269,7 +269,8 @@ public class AnthropicChatModel implements ChatModel {
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 class AnthropicChatModel implements ChatModel {
}
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);
}
}

View File

@@ -217,7 +217,7 @@ public class AnthropicChatOptions implements ToolCallingChatOptions {
@Nullable
@JsonIgnore
public Boolean isInternalToolExecutionEnabled() {
return internalToolExecutionEnabled;
return this.internalToolExecutionEnabled;
}
@Override
@@ -293,7 +293,7 @@ public class AnthropicChatOptions implements ToolCallingChatOptions {
@JsonIgnore
public Map<String, String> getHttpHeaders() {
return httpHeaders;
return this.httpHeaders;
}
public void setHttpHeaders(Map<String, String> httpHeaders) {
@@ -328,8 +328,9 @@ public class AnthropicChatOptions implements ToolCallingChatOptions {
@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 {

View File

@@ -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;

View File

@@ -32,7 +32,6 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
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;

View File

@@ -23,7 +23,6 @@ import java.util.List;
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.model.StreamingChatModel;
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 @@ class AnthropicChatModelIT {
validateChatResponseMetadata(response, "claude-3-5-sonnet-latest");
}
record ActorsFilmsRecord(String actor, List<String> movies) {
}
@Test
void thinkingTest() {
UserMessage userMessage = new UserMessage(
@@ -451,6 +446,10 @@ class AnthropicChatModelIT {
}
}
record ActorsFilmsRecord(String actor, List<String> movies) {
}
@SpringBootConfiguration
public static class Config {

View File

@@ -19,12 +19,12 @@ package org.springframework.ai.anthropic;
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}.
*

View File

@@ -221,7 +221,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
TestFunctionClass targetObject = new TestFunctionClass();
// @formatter:off
// @formatter:off
var toolMethod = ReflectionUtils.findMethod(
TestFunctionClass.class, "turnLivingRoomLightOn");
@@ -231,7 +231,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
.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 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
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)

View File

@@ -368,7 +368,7 @@ public class AzureOpenAiChatModel implements ChatModel {
});
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 class AzureOpenAiChatModel implements ChatModel {
/**
* Builder to construct {@link AzureOpenAiChatModel}.
*/
public static class Builder {
public static final class Builder {
private OpenAIClientBuilder openAIClientBuilder;
@@ -968,12 +968,12 @@ public class AzureOpenAiChatModel implements ChatModel {
}
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);
}
}

View File

@@ -232,7 +232,7 @@ public class AzureOpenAiChatOptions implements ToolCallingChatOptions {
@Nullable
@JsonIgnore
public Boolean isInternalToolExecutionEnabled() {
return internalToolExecutionEnabled;
return this.internalToolExecutionEnabled;
}
@Override

View File

@@ -671,7 +671,7 @@ public class BedrockProxyChatModel implements ChatModel {
Flux<ChatResponse> 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

View File

@@ -42,10 +42,10 @@ import org.springframework.ai.chat.model.StreamingChatModel;
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;

View File

@@ -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;

View File

@@ -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.io.IOException;
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 @@ public class BedrockNovaChatClientIT {
@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 @@ public class BedrockNovaChatClientIT {
Set<String> 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 @@ public class BedrockNovaChatClientIT {
() -> 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 @@ public class BedrockNovaChatClientIT {
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 @@ public class BedrockNovaChatClientIT {
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 {

View File

@@ -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;

View File

@@ -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;

View File

@@ -27,13 +27,6 @@ import io.micrometer.observation.ObservationRegistry;
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.ChatModelObservationDocumentation
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;
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 class MistralAiChatModel implements ChatModel {
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 class MistralAiChatModel implements ChatModel {
// @formatter:off
Flux<ChatResponse> 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 class MistralAiChatModel implements ChatModel {
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 class MistralAiChatModel implements ChatModel {
return new Builder();
}
public static class Builder {
public static final class Builder {
private MistralAiApi mistralAiApi;
@@ -588,12 +588,12 @@ public class MistralAiChatModel implements ChatModel {
}
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);
}
}

View File

@@ -288,7 +288,7 @@ public class MistralAiChatOptions implements ToolCallingChatOptions {
@Nullable
@JsonIgnore
public Boolean isInternalToolExecutionEnabled() {
return internalToolExecutionEnabled;
return this.internalToolExecutionEnabled;
}
@Override

View File

@@ -720,9 +720,12 @@ public class MistralAiApi {
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
}

View File

@@ -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.util.Assert;
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 class MistralAiModerationApi {
@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());
}
}

View File

@@ -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.Mistra
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
*/

View File

@@ -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;

View File

@@ -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.ToolCallback;
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 @@ public class MistralAiChatCompletionRequestTest {
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

View File

@@ -43,11 +43,11 @@ import org.springframework.ai.chat.prompt.ChatOptions;
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;

View File

@@ -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;

View File

@@ -29,7 +29,6 @@ import org.springframework.aot.hint.TypeReference;
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 {

Some files were not shown because too many files have changed in this diff Show More