From e9b06ea10b57bde276ab0e6bcda6d7b9dd1d080f Mon Sep 17 00:00:00 2001 From: LeeJaeHyeok97 Date: Sat, 24 May 2025 02:13:11 +0900 Subject: [PATCH] fix: omit temperature for search models and add tests Signed-off-by: LeeJaeHyeok97 --- .../OpenAiChatAutoConfiguration.java | 14 ++++- .../OpenAiChatAutoConfigurationTest.java | 59 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/OpenAiChatAutoConfigurationTest.java diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiChatAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiChatAutoConfiguration.java index d15a6469e41..4a218d0791c 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiChatAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiChatAutoConfiguration.java @@ -27,6 +27,7 @@ import org.springframework.ai.model.tool.ToolExecutionEligibilityPredicate; import org.springframework.ai.model.tool.autoconfigure.ToolCallingAutoConfiguration; import org.springframework.ai.openai.OpenAiChatModel; +import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.ai.openai.api.OpenAiApi; import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.beans.factory.ObjectProvider; @@ -72,7 +73,18 @@ public OpenAiChatModel openAiChatModel(OpenAiConnectionProperties commonProperti RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention, - ObjectProvider openAiToolExecutionEligibilityPredicate) { + ObjectProvider openAiToolExecutionEligibilityPredicate, + ObjectProvider userOptionsProvider) { + + OpenAiChatOptions defaultOptions = chatProperties.getOptions(); + OpenAiChatOptions userOptions = userOptionsProvider.getIfAvailable(); + + if (defaultOptions.getModel().startsWith("text-search-")) { + defaultOptions.setTemperature(null); + } + else if (userOptions != null && userOptions.getTemperature() != null) { + defaultOptions.setTemperature(userOptions.getTemperature()); + } var openAiApi = openAiApi(chatProperties, commonProperties, restClientBuilderProvider.getIfAvailable(RestClient::builder), diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/OpenAiChatAutoConfigurationTest.java b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/OpenAiChatAutoConfigurationTest.java new file mode 100644 index 00000000000..31cc5fbbad4 --- /dev/null +++ b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/test/java/org/springframework/ai/model/openai/autoconfigure/OpenAiChatAutoConfigurationTest.java @@ -0,0 +1,59 @@ +package org.springframework.ai.model.openai.autoconfigure; + +import org.junit.jupiter.api.Test; +import org.springframework.ai.chat.prompt.ChatOptions; +import org.springframework.ai.openai.OpenAiChatModel; +import org.springframework.ai.openai.OpenAiChatOptions; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +class OpenAiChatAutoConfigurationTest { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(OpenAiChatAutoConfiguration.class)) + .withPropertyValues("spring.ai.openai.apiKey=" + System.getenv("OPENAI_API_KEY"), + "spring.ai.openai.chat.options.temperature=0.8"); + + @Test + void whenUserDefinesTemperature_thenOverride() { + runner.withUserConfiguration(UserOptionsConfig.class) + .run(context -> { + assertThat(context).hasSingleBean(OpenAiChatModel.class); + ChatOptions opts = context.getBean(OpenAiChatModel.class).getDefaultOptions(); + assertThat(opts.getTemperature()).isEqualTo(0.42); + }); + } + + @Test + void whenNoUserOptions_thenDefaultTemperatureRetained() { + runner.run(context -> { + assertThat(context).hasSingleBean(OpenAiChatModel.class); + ChatOptions opts = context.getBean(OpenAiChatModel.class).getDefaultOptions(); + assertThat(opts.getTemperature()).isEqualTo(0.8); + }); + } + + @Test + void whenSearchModel_thenTemperatureOmitted() { + runner.withPropertyValues("spring.ai.openai.chat.options.model=text-search-abc") + .run(context -> { + assertThat(context).hasSingleBean(OpenAiChatModel.class); + ChatOptions opts = context.getBean(OpenAiChatModel.class).getDefaultOptions(); + assertThat(opts.getTemperature()).isNull(); + }); + } + + @Configuration + static class UserOptionsConfig { + @Bean + public OpenAiChatOptions userOptions() { + OpenAiChatOptions openAiChatOptions = new OpenAiChatOptions(); + openAiChatOptions.setTemperature(0.42); + return openAiChatOptions; + } + } +}