diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java index 5d1a8b12b..8037cf680 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java @@ -72,7 +72,7 @@ public class OpenAiApi { * @param openAiToken OpenAI apiKey. */ public OpenAiApi(String baseUrl, String openAiToken) { - this(baseUrl, openAiToken, RestClient.builder()); + this(baseUrl, openAiToken, RestClient.builder(), WebClient.builder()); } /** @@ -82,8 +82,8 @@ public class OpenAiApi { * @param openAiToken OpenAI apiKey. * @param restClientBuilder RestClient builder. */ - public OpenAiApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder) { - this(baseUrl, openAiToken, restClientBuilder, RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER); + public OpenAiApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder) { + this(baseUrl, openAiToken, restClientBuilder, webClientBuilder, RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER); } /** @@ -94,7 +94,7 @@ public class OpenAiApi { * @param restClientBuilder RestClient builder. * @param responseErrorHandler Response error handler. */ - public OpenAiApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { + public OpenAiApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) { this.restClient = restClientBuilder .baseUrl(baseUrl) @@ -102,7 +102,7 @@ public class OpenAiApi { .defaultStatusHandler(responseErrorHandler) .build(); - this.webClient = WebClient.builder() + this.webClient = webClientBuilder .baseUrl(baseUrl) .defaultHeaders(ApiUtils.getJsonContentHeaders(openAiToken)) .build(); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelWithChatResponseMetadataTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelWithChatResponseMetadataTests.java index 0ad40d6ff..4afeca476 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelWithChatResponseMetadataTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelWithChatResponseMetadataTests.java @@ -39,6 +39,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestClient; +import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.client.match.MockRestRequestMatchers.header; @@ -166,8 +167,8 @@ public class OpenAiChatModelWithChatResponseMetadataTests { static class Config { @Bean - public OpenAiApi chatCompletionApi(RestClient.Builder builder) { - return new OpenAiApi("", TEST_API_KEY, builder); + public OpenAiApi chatCompletionApi(RestClient.Builder builder, WebClient.Builder webClientBuilder) { + return new OpenAiApi("", TEST_API_KEY, builder, webClientBuilder); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.java index 3a601abb2..aba2e1eb4 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.java @@ -39,6 +39,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; +import org.springframework.web.reactive.function.client.WebClient; /** * @author Christian Tzolov @@ -56,11 +57,13 @@ public class OpenAiAutoConfiguration { matchIfMissing = true) public OpenAiChatModel openAiChatModel(OpenAiConnectionProperties commonProperties, OpenAiChatProperties chatProperties, RestClient.Builder restClientBuilder, - List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext, - RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) { + WebClient.Builder webClientBuilder, List toolFunctionCallbacks, + FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate, + ResponseErrorHandler responseErrorHandler) { var openAiApi = openAiApi(chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), - chatProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, responseErrorHandler); + chatProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, webClientBuilder, + responseErrorHandler); if (!CollectionUtils.isEmpty(toolFunctionCallbacks)) { chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks); @@ -75,17 +78,20 @@ public class OpenAiAutoConfiguration { matchIfMissing = true) public OpenAiEmbeddingModel openAiEmbeddingModel(OpenAiConnectionProperties commonProperties, OpenAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder, - RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) { + WebClient.Builder webClientBuilder, RetryTemplate retryTemplate, + ResponseErrorHandler responseErrorHandler) { var openAiApi = openAiApi(embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(), - embeddingProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, responseErrorHandler); + embeddingProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, webClientBuilder, + responseErrorHandler); return new OpenAiEmbeddingModel(openAiApi, embeddingProperties.getMetadataMode(), embeddingProperties.getOptions(), retryTemplate); } private OpenAiApi openAiApi(String baseUrl, String commonBaseUrl, String apiKey, String commonApiKey, - RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { + RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, + ResponseErrorHandler responseErrorHandler) { String resolvedBaseUrl = StringUtils.hasText(baseUrl) ? baseUrl : commonBaseUrl; Assert.hasText(resolvedBaseUrl, "OpenAI base URL must be set"); @@ -93,7 +99,8 @@ public class OpenAiAutoConfiguration { String resolvedApiKey = StringUtils.hasText(apiKey) ? apiKey : commonApiKey; Assert.hasText(resolvedApiKey, "OpenAI API key must be set"); - return new OpenAiApi(resolvedBaseUrl, resolvedApiKey, restClientBuilder, responseErrorHandler); + return new OpenAiApi(resolvedBaseUrl, resolvedApiKey, restClientBuilder, webClientBuilder, + responseErrorHandler); } @Bean @@ -122,6 +129,7 @@ public class OpenAiAutoConfiguration { @ConditionalOnMissingBean public OpenAiAudioTranscriptionModel openAiAudioTranscriptionModel(OpenAiConnectionProperties commonProperties, OpenAiAudioTranscriptionProperties transcriptionProperties, RetryTemplate retryTemplate, + RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) { String apiKey = StringUtils.hasText(transcriptionProperties.getApiKey()) ? transcriptionProperties.getApiKey() @@ -133,7 +141,8 @@ public class OpenAiAutoConfiguration { Assert.hasText(apiKey, "OpenAI API key must be set"); Assert.hasText(baseUrl, "OpenAI base URL must be set"); - var openAiAudioApi = new OpenAiAudioApi(baseUrl, apiKey, RestClient.builder(), responseErrorHandler); + var openAiAudioApi = new OpenAiAudioApi(baseUrl, apiKey, restClientBuilder, webClientBuilder, + responseErrorHandler); OpenAiAudioTranscriptionModel openAiChatModel = new OpenAiAudioTranscriptionModel(openAiAudioApi, transcriptionProperties.getOptions(), retryTemplate); @@ -143,8 +152,9 @@ public class OpenAiAutoConfiguration { @Bean @ConditionalOnMissingBean - public OpenAiAudioSpeechModel openAiAudioSpeechModel(OpenAiConnectionProperties commonProperties, - OpenAiAudioSpeechProperties speechProperties, ResponseErrorHandler responseErrorHandler) { + public OpenAiAudioSpeechModel openAiAudioSpeechClient(OpenAiConnectionProperties commonProperties, + OpenAiAudioSpeechProperties speechProperties, RestClient.Builder restClientBuilder, + WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) { String apiKey = StringUtils.hasText(speechProperties.getApiKey()) ? speechProperties.getApiKey() : commonProperties.getApiKey(); @@ -155,7 +165,8 @@ public class OpenAiAutoConfiguration { Assert.hasText(apiKey, "OpenAI API key must be set"); Assert.hasText(baseUrl, "OpenAI base URL must be set"); - var openAiAudioApi = new OpenAiAudioApi(baseUrl, apiKey, RestClient.builder(), responseErrorHandler); + var openAiAudioApi = new OpenAiAudioApi(baseUrl, apiKey, restClientBuilder, webClientBuilder, + responseErrorHandler); OpenAiAudioSpeechModel openAiSpeechModel = new OpenAiAudioSpeechModel(openAiAudioApi, speechProperties.getOptions()); diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiPropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiPropertiesTests.java index 0956020dc..bb54bf80a 100644 --- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiPropertiesTests.java +++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiPropertiesTests.java @@ -30,6 +30,7 @@ import org.springframework.ai.openai.api.OpenAiApi.FunctionTool.Type; import org.springframework.ai.openai.api.OpenAiAudioApi; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; +import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -55,7 +56,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.chat.options.temperature=0.55") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var chatProperties = context.getBean(OpenAiChatProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -82,7 +83,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.audio.transcription.options.temperature=0.55") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -111,7 +112,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.chat.options.temperature=0.55") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var chatProperties = context.getBean(OpenAiChatProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -140,7 +141,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.audio.transcription.options.temperature=0.55") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -169,7 +170,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.audio.speech.options.speed=0.75") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var speechProperties = context.getBean(OpenAiAudioSpeechProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -201,7 +202,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.audio.speech.options.speed=0.75") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var speechProperties = context.getBean(OpenAiAudioSpeechProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -232,7 +233,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.audio.speech.options.speed=0.5") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var speechProperties = context.getBean(OpenAiAudioSpeechProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -261,7 +262,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.embedding.options.model=MODEL_XYZ") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -288,7 +289,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.embedding.options.model=MODEL_XYZ") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -313,7 +314,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.image.options.n=3") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var imageProperties = context.getBean(OpenAiImageProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -341,7 +342,7 @@ public class OpenAiPropertiesTests { "spring.ai.openai.image.options.n=3") // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var imageProperties = context.getBean(OpenAiImageProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -410,7 +411,7 @@ public class OpenAiPropertiesTests { ) // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var chatProperties = context.getBean(OpenAiChatProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -464,7 +465,7 @@ public class OpenAiPropertiesTests { ) // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -498,7 +499,7 @@ public class OpenAiPropertiesTests { ) // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var connectionProperties = context.getBean(OpenAiConnectionProperties.class); var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class); @@ -531,7 +532,7 @@ public class OpenAiPropertiesTests { ) // @formatter:on .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { var imageProperties = context.getBean(OpenAiImageProperties.class); var connectionProperties = context.getBean(OpenAiConnectionProperties.class); @@ -558,7 +559,7 @@ public class OpenAiPropertiesTests { .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL", "spring.ai.openai.embedding.enabled=false") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiEmbeddingModel.class)).isEmpty(); @@ -567,7 +568,7 @@ public class OpenAiPropertiesTests { new ApplicationContextRunner() .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiEmbeddingModel.class)).isNotEmpty(); @@ -577,7 +578,7 @@ public class OpenAiPropertiesTests { .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL", "spring.ai.openai.embedding.enabled=true") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiEmbeddingModel.class)).isNotEmpty(); @@ -590,7 +591,7 @@ public class OpenAiPropertiesTests { .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL", "spring.ai.openai.chat.enabled=false") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiChatModel.class)).isEmpty(); @@ -599,7 +600,7 @@ public class OpenAiPropertiesTests { new ApplicationContextRunner() .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiChatModel.class)).isNotEmpty(); @@ -609,7 +610,7 @@ public class OpenAiPropertiesTests { .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL", "spring.ai.openai.chat.enabled=true") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiChatModel.class)).isNotEmpty(); @@ -623,7 +624,7 @@ public class OpenAiPropertiesTests { .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL", "spring.ai.openai.image.enabled=false") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiImageModel.class)).isEmpty(); @@ -632,7 +633,7 @@ public class OpenAiPropertiesTests { new ApplicationContextRunner() .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiImageModel.class)).isNotEmpty(); @@ -642,7 +643,7 @@ public class OpenAiPropertiesTests { .withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL", "spring.ai.openai.image.enabled=true") .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, - RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) + RestClientAutoConfiguration.class, WebClientAutoConfiguration.class, OpenAiAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(OpenAiImageModel.class)).isNotEmpty();