From 3e60509ed5d536fcc0a09e25c6d996e21ccec692 Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Tue, 15 Oct 2024 15:52:44 +0200 Subject: [PATCH 1/2] Streamline dependencies and improve API consistency - Remove unnecessary spring-web dependencies - Update third-party library versions - Refactor API classes to use consistent header handling - Remove ApiUtils class and inline its functionality - Adjust RestClient and WebClient builder usage in autoconfiguration - Replace direct RestClient.Builder injections with ObjectProvider and WebClient.Builder injections with ObjectProvider - Update ChromaVectorStoreAutoConfiguration to use ObjectProvider - Rename MongoDbAtlasLocalContainerConnectionDetailsFactoryTest to IT - Switch spring-ai-chroma-store dependency from spring-web to spring-webflux - Simplify ChromaApi constructor by using method reference for default headers Resolves #1066 Resolves #524 --- models/spring-ai-bedrock/pom.xml | 6 --- .../ai/minimax/api/MiniMaxApi.java | 33 +++++++----- models/spring-ai-oci-genai/pom.xml | 6 --- models/spring-ai-ollama/pom.xml | 16 ++---- models/spring-ai-openai/pom.xml | 2 +- .../ai/openai/api/OpenAiApi.java | 19 ++++--- .../ai/openai/api/OpenAiAudioApi.java | 53 +++++++++---------- .../ai/openai/api/OpenAiModerationApi.java | 13 ++--- ...ithTranscriptionResponseMetadataTests.java | 4 +- models/spring-ai-vertex-ai-embedding/pom.xml | 7 --- models/spring-ai-vertex-ai-gemini/pom.xml | 6 --- models/spring-ai-vertex-ai-palm2/pom.xml | 3 +- models/spring-ai-watsonx-ai/pom.xml | 6 +-- models/spring-ai-zhipuai/pom.xml | 1 - .../ai/zhipuai/api/ZhiPuAiApi.java | 35 +++++++----- .../ai/zhipuai/api/ZhiPuAiImageApi.java | 17 ++++-- pom.xml | 11 ++-- spring-ai-core/pom.xml | 5 -- .../springframework/ai/util/api/ApiUtils.java | 41 -------------- spring-ai-retry/pom.xml | 1 + .../anthropic/AnthropicAutoConfiguration.java | 7 +-- .../minimax/MiniMaxAutoConfiguration.java | 23 ++++---- .../mistralai/MistralAiAutoConfiguration.java | 15 +++--- .../moonshot/MoonshotAutoConfiguration.java | 5 +- .../ollama/OllamaAutoConfiguration.java | 9 ++-- .../openai/OpenAiAutoConfiguration.java | 47 ++++++++-------- .../qianfan/QianFanAutoConfiguration.java | 25 +++++---- .../StabilityAiImageAutoConfiguration.java | 7 ++- .../ChromaVectorStoreAutoConfiguration.java | 14 ++--- .../palm2/VertexAiPalm2AutoConfiguration.java | 6 ++- .../watsonxai/WatsonxAiAutoConfiguration.java | 6 ++- .../zhipuai/ZhiPuAiAutoConfiguration.java | 5 +- ...lContainerConnectionDetailsFactoryIt.java} | 2 +- vector-stores/spring-ai-chroma-store/pom.xml | 2 +- .../springframework/ai/chroma/ChromaApi.java | 8 +-- 35 files changed, 206 insertions(+), 260 deletions(-) delete mode 100644 spring-ai-core/src/main/java/org/springframework/ai/util/api/ApiUtils.java rename spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/mongo/{MongoDbAtlasLocalContainerConnectionDetailsFactoryTest.java => MongoDbAtlasLocalContainerConnectionDetailsFactoryIt.java} (98%) diff --git a/models/spring-ai-bedrock/pom.xml b/models/spring-ai-bedrock/pom.xml index e3b79d30bda..51c458c6514 100644 --- a/models/spring-ai-bedrock/pom.xml +++ b/models/spring-ai-bedrock/pom.xml @@ -29,12 +29,6 @@ ${project.parent.version} - - org.springframework - spring-web - ${spring-framework.version} - - org.springframework spring-webflux diff --git a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java index d631f25355a..c254d07d6d0 100644 --- a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java +++ b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java @@ -15,30 +15,34 @@ */ package org.springframework.ai.minimax.api; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Predicate; + import org.springframework.ai.model.ChatModelDescription; import org.springframework.ai.model.ModelOptionsUtils; import org.springframework.ai.retry.RetryUtils; -import org.springframework.ai.util.api.ApiUtils; import org.springframework.boot.context.properties.bind.ConstructorBinding; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Predicate; - // @formatter:off /** * Single class implementation of the MiniMax Chat Completion API and @@ -98,15 +102,20 @@ public MiniMaxApi(String baseUrl, String miniMaxToken, RestClient.Builder restCl */ public MiniMaxApi(String baseUrl, String miniMaxToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { + Consumer authHeaders = (headers) -> { + headers.setBearerAuth(miniMaxToken); + headers.setContentType(MediaType.APPLICATION_JSON); + }; + this.restClient = restClientBuilder .baseUrl(baseUrl) - .defaultHeaders(ApiUtils.getJsonContentHeaders(miniMaxToken)) + .defaultHeaders(authHeaders) .defaultStatusHandler(responseErrorHandler) .build(); this.webClient = WebClient.builder() .baseUrl(baseUrl) - .defaultHeaders(ApiUtils.getJsonContentHeaders(miniMaxToken)) + .defaultHeaders(authHeaders) .build(); } diff --git a/models/spring-ai-oci-genai/pom.xml b/models/spring-ai-oci-genai/pom.xml index fc007e9f9b3..b4ab01cfea2 100644 --- a/models/spring-ai-oci-genai/pom.xml +++ b/models/spring-ai-oci-genai/pom.xml @@ -41,12 +41,6 @@ ${oci-sdk-version} - - - org.springframework.boot - spring-boot - - org.springframework spring-context-support diff --git a/models/spring-ai-ollama/pom.xml b/models/spring-ai-ollama/pom.xml index d950b86121f..69f64f8c9c8 100644 --- a/models/spring-ai-ollama/pom.xml +++ b/models/spring-ai-ollama/pom.xml @@ -22,11 +22,6 @@ - - org.springframework.boot - spring-boot - - org.springframework.ai spring-ai-core @@ -34,14 +29,9 @@ - org.springframework.ai - spring-ai-retry - ${project.parent.version} - - - - org.springframework - spring-webflux + org.springframework.ai + spring-ai-retry + ${project.parent.version} diff --git a/models/spring-ai-openai/pom.xml b/models/spring-ai-openai/pom.xml index cfb45f5862c..1019f915a55 100644 --- a/models/spring-ai-openai/pom.xml +++ b/models/spring-ai-openai/pom.xml @@ -21,7 +21,7 @@ - + org.springframework.ai 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 144c54f715f..31418268269 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 @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; import java.util.function.Predicate; import org.springframework.ai.model.ChatModelDescription; @@ -26,6 +27,7 @@ import org.springframework.ai.retry.RetryUtils; import org.springframework.boot.context.properties.bind.ConstructorBinding; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; @@ -154,22 +156,19 @@ public OpenAiApi(String baseUrl, String apiKey, MultiValueMap he this.completionsPath = completionsPath; this.embeddingsPath = embeddingsPath; // @formatter:off + Consumer finalHeaders = h -> { + h.setBearerAuth(apiKey); + h.setContentType(MediaType.APPLICATION_JSON); + h.addAll(headers); + }; this.restClient = restClientBuilder.baseUrl(baseUrl) - .defaultHeaders(h -> { - h.setBearerAuth(apiKey); - h.setContentType(MediaType.APPLICATION_JSON); - h.addAll(headers); - }) + .defaultHeaders(finalHeaders) .defaultStatusHandler(responseErrorHandler) .build(); this.webClient = webClientBuilder .baseUrl(baseUrl) - .defaultHeaders(h -> { - h.setBearerAuth(apiKey); - h.setContentType(MediaType.APPLICATION_JSON); - h.addAll(headers); - }) + .defaultHeaders(finalHeaders) .build();// @formatter:on } diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java index 83dee8850be..72161328ffe 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java @@ -17,14 +17,10 @@ import java.util.List; import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.function.Consumer; import org.springframework.ai.openai.api.common.OpenAiApiConstants; import org.springframework.ai.retry.RetryUtils; -import org.springframework.ai.util.api.ApiUtils; import org.springframework.core.io.ByteArrayResource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -36,6 +32,11 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -71,13 +72,14 @@ public OpenAiAudioApi(String openAiToken) { public OpenAiAudioApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { - this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(headers -> { - headers.setBearerAuth(openAiToken); - }).defaultStatusHandler(responseErrorHandler).build(); + Consumer authHeaders = h -> h.setBearerAuth(openAiToken); - this.webClient = WebClient.builder().baseUrl(baseUrl).defaultHeaders(headers -> { - headers.setBearerAuth(openAiToken); - }).defaultHeaders(ApiUtils.getJsonContentHeaders(openAiToken)).build(); + this.restClient = restClientBuilder.baseUrl(baseUrl) + .defaultHeaders(authHeaders) + .defaultStatusHandler(responseErrorHandler) + .build(); + + this.webClient = WebClient.builder().baseUrl(baseUrl).defaultHeaders(authHeaders).build(); } /** @@ -108,23 +110,18 @@ public OpenAiAudioApi(String baseUrl, String apiKey, MultiValueMap { - h.setBearerAuth(apiKey); - h.addAll(headers); - }) - .defaultStatusHandler(responseErrorHandler).build(); - - this.webClient = webClientBuilder - .baseUrl(baseUrl) - .defaultHeaders(h -> { - h.setBearerAuth(apiKey); - h.addAll(headers); - }) - .defaultHeaders(ApiUtils.getJsonContentHeaders(apiKey)).build(); - // @formatter:on + Consumer authHeaders = h -> { + h.setBearerAuth(apiKey); + h.addAll(headers); + // h.setContentType(MediaType.APPLICATION_JSON); + }; + + this.restClient = restClientBuilder.baseUrl(baseUrl) + .defaultHeaders(authHeaders) + .defaultStatusHandler(responseErrorHandler) + .build(); + + this.webClient = webClientBuilder.baseUrl(baseUrl).defaultHeaders(authHeaders).build(); } /** diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java index bb9465e9820..7628aebb3e6 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java @@ -61,15 +61,10 @@ public OpenAiModerationApi(String baseUrl, String openAiToken, RestClient.Builde this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - Consumer jsonContentHeaders = headers -> { - headers.setBearerAuth(openAiToken); - headers.setContentType(MediaType.APPLICATION_JSON); - }; - - this.restClient = restClientBuilder.baseUrl(baseUrl) - .defaultHeaders(jsonContentHeaders) - .defaultStatusHandler(responseErrorHandler) - .build(); + this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(h -> { + h.setBearerAuth(openAiToken); + h.setContentType(MediaType.APPLICATION_JSON); + }).defaultStatusHandler(responseErrorHandler).build(); } // @formatter:off diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests.java index 58a398a5af7..673f9e06969 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests.java @@ -53,7 +53,7 @@ public class OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests { private static String TEST_API_KEY = "sk-1234567890"; @Autowired - private OpenAiAudioTranscriptionModel openAiTranscriptionClient; + private OpenAiAudioTranscriptionModel openAiTranscriptionModel; @Autowired private MockRestServiceServer server; @@ -72,7 +72,7 @@ void aiResponseContainsAiMetadata() { AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile); - AudioTranscriptionResponse response = this.openAiTranscriptionClient.call(transcriptionRequest); + AudioTranscriptionResponse response = this.openAiTranscriptionModel.call(transcriptionRequest); assertThat(response).isNotNull(); diff --git a/models/spring-ai-vertex-ai-embedding/pom.xml b/models/spring-ai-vertex-ai-embedding/pom.xml index 5988fcf4476..b94de96bd87 100644 --- a/models/spring-ai-vertex-ai-embedding/pom.xml +++ b/models/spring-ai-vertex-ai-embedding/pom.xml @@ -58,13 +58,6 @@ ${project.parent.version} - - org.springframework - spring-web - ${spring-framework.version} - - - org.springframework diff --git a/models/spring-ai-vertex-ai-gemini/pom.xml b/models/spring-ai-vertex-ai-gemini/pom.xml index da9eb0beb6c..57f5dcd5ce7 100644 --- a/models/spring-ai-vertex-ai-gemini/pom.xml +++ b/models/spring-ai-vertex-ai-gemini/pom.xml @@ -58,12 +58,6 @@ ${project.parent.version} - - org.springframework - spring-web - ${spring-framework.version} - - diff --git a/models/spring-ai-vertex-ai-palm2/pom.xml b/models/spring-ai-vertex-ai-palm2/pom.xml index 448a3143fab..2c5123b3c2f 100644 --- a/models/spring-ai-vertex-ai-palm2/pom.xml +++ b/models/spring-ai-vertex-ai-palm2/pom.xml @@ -31,8 +31,7 @@ org.springframework - spring-web - ${spring-framework.version} + spring-web diff --git a/models/spring-ai-watsonx-ai/pom.xml b/models/spring-ai-watsonx-ai/pom.xml index 00ab9cb712d..e5fc7df00d8 100644 --- a/models/spring-ai-watsonx-ai/pom.xml +++ b/models/spring-ai-watsonx-ai/pom.xml @@ -21,6 +21,7 @@ + org.springframework.boot spring-boot @@ -38,11 +39,6 @@ ${project.parent.version} - - org.springframework - spring-webflux - - org.springframework.boot spring-boot-starter-logging diff --git a/models/spring-ai-zhipuai/pom.xml b/models/spring-ai-zhipuai/pom.xml index c0e5128ec48..4c2c6e1791c 100644 --- a/models/spring-ai-zhipuai/pom.xml +++ b/models/spring-ai-zhipuai/pom.xml @@ -21,7 +21,6 @@ - org.springframework.ai diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java index 363937cc3e0..0758d2e8f89 100644 --- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java +++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java @@ -15,31 +15,35 @@ */ package org.springframework.ai.zhipuai.api; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Predicate; + import org.springframework.ai.model.ChatModelDescription; import org.springframework.ai.model.ModelOptionsUtils; import org.springframework.ai.retry.RetryUtils; -import org.springframework.ai.util.api.ApiUtils; import org.springframework.boot.context.properties.bind.ConstructorBinding; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Predicate; - // @formatter:off /** * Single class implementation of the ZhiPuAI Chat Completion API and @@ -99,15 +103,20 @@ public ZhiPuAiApi(String baseUrl, String zhiPuAiToken, RestClient.Builder restCl */ public ZhiPuAiApi(String baseUrl, String zhiPuAiToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { + Consumer authHeaders = h -> { + h.setBearerAuth(zhiPuAiToken); + h.setContentType(MediaType.APPLICATION_JSON); + }; + this.restClient = restClientBuilder .baseUrl(baseUrl) - .defaultHeaders(ApiUtils.getJsonContentHeaders(zhiPuAiToken)) + .defaultHeaders(authHeaders) .defaultStatusHandler(responseErrorHandler) .build(); this.webClient = WebClient.builder() .baseUrl(baseUrl) - .defaultHeaders(ApiUtils.getJsonContentHeaders(zhiPuAiToken)) + .defaultHeaders(authHeaders) .build(); } diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiImageApi.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiImageApi.java index b64e4964b08..58fa938bb82 100644 --- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiImageApi.java +++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiImageApi.java @@ -15,16 +15,18 @@ */ package org.springframework.ai.zhipuai.api; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import java.util.function.Consumer; + import org.springframework.ai.retry.RetryUtils; -import org.springframework.ai.util.api.ApiUtils; +import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; -import java.util.List; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; /** * ZhiPuAI Image API. @@ -68,8 +70,13 @@ public ZhiPuAiImageApi(String baseUrl, String zhiPuAiToken, RestClient.Builder r public ZhiPuAiImageApi(String baseUrl, String zhiPuAiToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { + Consumer authHeaders = h -> { + h.setBearerAuth(zhiPuAiToken); + // h.setContentType(MediaType.APPLICATION_JSON); + }; + this.restClient = restClientBuilder.baseUrl(baseUrl) - .defaultHeaders(ApiUtils.getJsonContentHeaders(zhiPuAiToken)) + .defaultHeaders(authHeaders) .defaultStatusHandler(responseErrorHandler) .build(); } diff --git a/pom.xml b/pom.xml index edbe843c820..b3af8247d15 100644 --- a/pom.xml +++ b/pom.xml @@ -148,7 +148,6 @@ 4.1.3 3.3.4 - 6.1.4 4.3.4 1.0.0-beta.10 1.1.0 @@ -163,21 +162,21 @@ 0.30.0 1.19.2 3.46.1 - 26.41.0 + 26.48.0 1.9.1 - 2.0.5 + 2.0.9 9.20.0 4.35.0 2.2.20 - 2.0.2 + 2.0.3 3.25.2 4.18.1 - 3.0.1 - 0.1.4 + 3.0.3 + 0.1.6 2.20.11 23.4.0.24.05 42.7.2 diff --git a/spring-ai-core/pom.xml b/spring-ai-core/pom.xml index 10bfcbb4c4e..8a25edad098 100644 --- a/spring-ai-core/pom.xml +++ b/spring-ai-core/pom.xml @@ -74,11 +74,6 @@ spring-messaging - - org.springframework - spring-web - - io.micrometer micrometer-core diff --git a/spring-ai-core/src/main/java/org/springframework/ai/util/api/ApiUtils.java b/spring-ai-core/src/main/java/org/springframework/ai/util/api/ApiUtils.java deleted file mode 100644 index 3f1f98750e1..00000000000 --- a/spring-ai-core/src/main/java/org/springframework/ai/util/api/ApiUtils.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2023 - 2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.ai.util.api; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; - -import java.util.function.Consumer; - -/** - * The ApiUtils class provides utility methods for working with API requests and - * responses. - * - * @author Geng Rong - * @author Christian Tzolov - * @author Piotr Olaszewski - * @since 1.0.0 M1 - */ -public class ApiUtils { - - public static Consumer getJsonContentHeaders(String apiKey) { - return (headers) -> { - headers.setBearerAuth(apiKey); - headers.setContentType(MediaType.APPLICATION_JSON); - }; - } - -} diff --git a/spring-ai-retry/pom.xml b/spring-ai-retry/pom.xml index 75834506deb..c35268567f0 100644 --- a/spring-ai-retry/pom.xml +++ b/spring-ai-retry/pom.xml @@ -34,6 +34,7 @@ ${spring-retry.version} + org.springframework spring-webflux diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/anthropic/AnthropicAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/anthropic/AnthropicAutoConfiguration.java index 35c50730057..9989c0c3567 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/anthropic/AnthropicAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/anthropic/AnthropicAutoConfiguration.java @@ -57,11 +57,12 @@ public class AnthropicAutoConfiguration { @Bean @ConditionalOnMissingBean public AnthropicApi anthropicApi(AnthropicConnectionProperties connectionProperties, - RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, - ResponseErrorHandler responseErrorHandler) { + ObjectProvider restClientBuilderProvider, + ObjectProvider webClientBuilderProvider, ResponseErrorHandler responseErrorHandler) { return new AnthropicApi(connectionProperties.getBaseUrl(), connectionProperties.getApiKey(), - connectionProperties.getVersion(), restClientBuilder, webClientBuilder, responseErrorHandler, + connectionProperties.getVersion(), restClientBuilderProvider.getIfAvailable(RestClient::builder), + webClientBuilderProvider.getIfAvailable(WebClient::builder), responseErrorHandler, connectionProperties.getBetaVersion()); } diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/minimax/MiniMaxAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/minimax/MiniMaxAutoConfiguration.java index 43ea7928b84..e4c549140f0 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/minimax/MiniMaxAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/minimax/MiniMaxAutoConfiguration.java @@ -15,7 +15,8 @@ */ package org.springframework.ai.autoconfigure.minimax; -import io.micrometer.observation.ObservationRegistry; +import java.util.List; + import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.embedding.observation.EmbeddingModelObservationConvention; @@ -35,15 +36,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.retry.support.RetryTemplate; import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; +import io.micrometer.observation.ObservationRegistry; /** * @author Geng Rong @@ -59,14 +56,15 @@ public class MiniMaxAutoConfiguration { @ConditionalOnProperty(prefix = MiniMaxChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public MiniMaxChatModel miniMaxChatModel(MiniMaxConnectionProperties commonProperties, - MiniMaxChatProperties chatProperties, RestClient.Builder restClientBuilder, + MiniMaxChatProperties chatProperties, ObjectProvider restClientBuilderProvider, List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { var miniMaxApi = miniMaxApi(chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), - chatProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, responseErrorHandler); + chatProperties.getApiKey(), commonProperties.getApiKey(), + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); var chatModel = new MiniMaxChatModel(miniMaxApi, chatProperties.getOptions(), functionCallbackContext, toolFunctionCallbacks, retryTemplate, observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)); @@ -80,13 +78,14 @@ public MiniMaxChatModel miniMaxChatModel(MiniMaxConnectionProperties commonPrope @ConditionalOnProperty(prefix = MiniMaxEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public MiniMaxEmbeddingModel miniMaxEmbeddingModel(MiniMaxConnectionProperties commonProperties, - MiniMaxEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder, - RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, - ObjectProvider observationRegistry, + MiniMaxEmbeddingProperties embeddingProperties, + ObjectProvider restClientBuilderProvider, RetryTemplate retryTemplate, + ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { var miniMaxApi = miniMaxApi(embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(), - embeddingProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, responseErrorHandler); + embeddingProperties.getApiKey(), commonProperties.getApiKey(), + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); var embeddingModel = new MiniMaxEmbeddingModel(miniMaxApi, embeddingProperties.getMetadataMode(), embeddingProperties.getOptions(), retryTemplate, diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java index 6e40c5eaf3b..05b7be6f8e0 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java @@ -62,14 +62,14 @@ public class MistralAiAutoConfiguration { @ConditionalOnProperty(prefix = MistralAiEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public MistralAiEmbeddingModel mistralAiEmbeddingModel(MistralAiCommonProperties commonProperties, - MistralAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder, - RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, - ObjectProvider observationRegistry, + MistralAiEmbeddingProperties embeddingProperties, + ObjectProvider restClientBuilderProvider, RetryTemplate retryTemplate, + ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { var mistralAiApi = mistralAiApi(embeddingProperties.getApiKey(), commonProperties.getApiKey(), - embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(), restClientBuilder, - responseErrorHandler); + embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(), + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); var embeddingModel = new MistralAiEmbeddingModel(mistralAiApi, embeddingProperties.getMetadataMode(), embeddingProperties.getOptions(), retryTemplate, @@ -85,14 +85,15 @@ public MistralAiEmbeddingModel mistralAiEmbeddingModel(MistralAiCommonProperties @ConditionalOnProperty(prefix = MistralAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public MistralAiChatModel mistralAiChatModel(MistralAiCommonProperties commonProperties, - MistralAiChatProperties chatProperties, RestClient.Builder restClientBuilder, + MistralAiChatProperties chatProperties, ObjectProvider restClientBuilderProvider, List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { var mistralAiApi = mistralAiApi(chatProperties.getApiKey(), commonProperties.getApiKey(), - chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), restClientBuilder, responseErrorHandler); + chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); var chatModel = new MistralAiChatModel(mistralAiApi, chatProperties.getOptions(), functionCallbackContext, toolFunctionCallbacks, retryTemplate, observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)); diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/moonshot/MoonshotAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/moonshot/MoonshotAutoConfiguration.java index 7517705b1b3..9a750ec6ff5 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/moonshot/MoonshotAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/moonshot/MoonshotAutoConfiguration.java @@ -52,14 +52,15 @@ public class MoonshotAutoConfiguration { @ConditionalOnProperty(prefix = MoonshotChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public MoonshotChatModel moonshotChatModel(MoonshotCommonProperties commonProperties, - MoonshotChatProperties chatProperties, RestClient.Builder restClientBuilder, + MoonshotChatProperties chatProperties, ObjectProvider restClientBuilderProvider, List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { var moonshotApi = moonshotApi(chatProperties.getApiKey(), commonProperties.getApiKey(), - chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), restClientBuilder, responseErrorHandler); + chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); var chatModel = new MoonshotChatModel(moonshotApi, chatProperties.getOptions(), functionCallbackContext, toolFunctionCallbacks, retryTemplate, observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)); diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java index 106f04c3e51..6bd1cf46c17 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java @@ -62,9 +62,12 @@ public PropertiesOllamaConnectionDetails ollamaConnectionDetails(OllamaConnectio @Bean @ConditionalOnMissingBean - public OllamaApi ollamaApi(OllamaConnectionDetails connectionDetails, RestClient.Builder restClientBuilder, - WebClient.Builder webClientBuilder) { - return new OllamaApi(connectionDetails.getBaseUrl(), restClientBuilder, webClientBuilder); + public OllamaApi ollamaApi(OllamaConnectionDetails connectionDetails, + ObjectProvider restClientBuilderProvider, + ObjectProvider webClientBuilderProvider) { + return new OllamaApi(connectionDetails.getBaseUrl(), + restClientBuilderProvider.getIfAvailable(RestClient::builder), + webClientBuilderProvider.getIfAvailable(WebClient::builder)); } @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 e0586b50e20..d594460c5a2 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 @@ -78,14 +78,15 @@ public class OpenAiAutoConfiguration { @ConditionalOnProperty(prefix = OpenAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public OpenAiChatModel openAiChatModel(OpenAiConnectionProperties commonProperties, - OpenAiChatProperties chatProperties, RestClient.Builder restClientBuilder, - WebClient.Builder webClientBuilder, List toolFunctionCallbacks, + OpenAiChatProperties chatProperties, ObjectProvider restClientBuilderProvider, + ObjectProvider webClientBuilderProvider, List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { - var openAiApi = openAiApi(chatProperties, commonProperties, restClientBuilder, webClientBuilder, - responseErrorHandler, "chat"); + var openAiApi = openAiApi(chatProperties, commonProperties, + restClientBuilderProvider.getIfAvailable(RestClient::builder), + webClientBuilderProvider.getIfAvailable(WebClient::builder), responseErrorHandler, "chat"); var chatModel = new OpenAiChatModel(openAiApi, chatProperties.getOptions(), functionCallbackContext, toolFunctionCallbacks, retryTemplate, observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)); @@ -100,13 +101,14 @@ public OpenAiChatModel openAiChatModel(OpenAiConnectionProperties commonProperti @ConditionalOnProperty(prefix = OpenAiEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public OpenAiEmbeddingModel openAiEmbeddingModel(OpenAiConnectionProperties commonProperties, - OpenAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder, - WebClient.Builder webClientBuilder, RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, - ObjectProvider observationRegistry, + OpenAiEmbeddingProperties embeddingProperties, ObjectProvider restClientBuilderProvider, + ObjectProvider webClientBuilderProvider, RetryTemplate retryTemplate, + ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { - var openAiApi = openAiApi(embeddingProperties, commonProperties, restClientBuilder, webClientBuilder, - responseErrorHandler, "embedding"); + var openAiApi = openAiApi(embeddingProperties, commonProperties, + restClientBuilderProvider.getIfAvailable(RestClient::builder), + webClientBuilderProvider.getIfAvailable(WebClient::builder), responseErrorHandler, "embedding"); var embeddingModel = new OpenAiEmbeddingModel(openAiApi, embeddingProperties.getMetadataMode(), embeddingProperties.getOptions(), retryTemplate, @@ -146,14 +148,15 @@ private OpenAiApi openAiApi(OpenAiEmbeddingProperties embeddingProperties, @ConditionalOnProperty(prefix = OpenAiImageProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public OpenAiImageModel openAiImageModel(OpenAiConnectionProperties commonProperties, - OpenAiImageProperties imageProperties, RestClient.Builder restClientBuilder, RetryTemplate retryTemplate, - ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, + OpenAiImageProperties imageProperties, ObjectProvider restClientBuilderProvider, + RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, + ObjectProvider observationRegistry, ObjectProvider observationConvention) { ResolvedConnectionProperties resolved = resolveConnectionProperties(commonProperties, imageProperties, "image"); var openAiImageApi = new OpenAiImageApi(resolved.baseUrl(), resolved.apiKey(), resolved.headers(), - restClientBuilder, responseErrorHandler); + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); var imageModel = new OpenAiImageModel(openAiImageApi, imageProperties.getOptions(), retryTemplate, observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)); @@ -169,14 +172,15 @@ public OpenAiImageModel openAiImageModel(OpenAiConnectionProperties commonProper havingValue = "true", matchIfMissing = true) public OpenAiAudioTranscriptionModel openAiAudioTranscriptionModel(OpenAiConnectionProperties commonProperties, OpenAiAudioTranscriptionProperties transcriptionProperties, RetryTemplate retryTemplate, - RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, - ResponseErrorHandler responseErrorHandler) { + ObjectProvider restClientBuilderProvider, + ObjectProvider webClientBuilderProvider, ResponseErrorHandler responseErrorHandler) { ResolvedConnectionProperties resolved = resolveConnectionProperties(commonProperties, transcriptionProperties, "transcription"); var openAiAudioApi = new OpenAiAudioApi(resolved.baseUrl(), resolved.apiKey(), resolved.headers(), - restClientBuilder, webClientBuilder, responseErrorHandler); + restClientBuilderProvider.getIfAvailable(RestClient::builder), + webClientBuilderProvider.getIfAvailable(WebClient::builder), responseErrorHandler); return new OpenAiAudioTranscriptionModel(openAiAudioApi, transcriptionProperties.getOptions(), retryTemplate); @@ -186,13 +190,13 @@ public OpenAiAudioTranscriptionModel openAiAudioTranscriptionModel(OpenAiConnect @ConditionalOnMissingBean public OpenAiModerationModel openAiModerationClient(OpenAiConnectionProperties commonProperties, OpenAiModerationProperties moderationProperties, RetryTemplate retryTemplate, - RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { + ObjectProvider restClientBuilderProvider, ResponseErrorHandler responseErrorHandler) { ResolvedConnectionProperties resolved = resolveConnectionProperties(commonProperties, moderationProperties, "moderation"); - var openAiModerationApi = new OpenAiModerationApi(resolved.baseUrl, resolved.apiKey(), restClientBuilder, - responseErrorHandler); + var openAiModerationApi = new OpenAiModerationApi(resolved.baseUrl, resolved.apiKey(), + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); return new OpenAiModerationModel(openAiModerationApi, retryTemplate) .withDefaultOptions(moderationProperties.getOptions()); @@ -204,14 +208,15 @@ public OpenAiModerationModel openAiModerationClient(OpenAiConnectionProperties c matchIfMissing = true) public OpenAiAudioSpeechModel openAiAudioSpeechClient(OpenAiConnectionProperties commonProperties, OpenAiAudioSpeechProperties speechProperties, RetryTemplate retryTemplate, - RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, - ResponseErrorHandler responseErrorHandler) { + ObjectProvider restClientBuilderProvider, + ObjectProvider webClientBuilderProvider, ResponseErrorHandler responseErrorHandler) { ResolvedConnectionProperties resolved = resolveConnectionProperties(commonProperties, speechProperties, "speach"); var openAiAudioApi = new OpenAiAudioApi(resolved.baseUrl(), resolved.apiKey(), resolved.headers(), - restClientBuilder, webClientBuilder, responseErrorHandler); + restClientBuilderProvider.getIfAvailable(RestClient::builder), + webClientBuilderProvider.getIfAvailable(WebClient::builder), responseErrorHandler); return new OpenAiAudioSpeechModel(openAiAudioApi, speechProperties.getOptions()); } diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/qianfan/QianFanAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/qianfan/QianFanAutoConfiguration.java index 17e65f2a074..4c2b6100de0 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/qianfan/QianFanAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/qianfan/QianFanAutoConfiguration.java @@ -55,13 +55,15 @@ public class QianFanAutoConfiguration { @ConditionalOnProperty(prefix = QianFanChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public QianFanChatModel qianFanChatModel(QianFanConnectionProperties commonProperties, - QianFanChatProperties chatProperties, RestClient.Builder restClientBuilder, RetryTemplate retryTemplate, - ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, + QianFanChatProperties chatProperties, ObjectProvider restClientBuilderProvider, + RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, + ObjectProvider observationRegistry, ObjectProvider observationConvention) { var qianFanApi = qianFanApi(chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), chatProperties.getApiKey(), commonProperties.getApiKey(), chatProperties.getSecretKey(), - commonProperties.getSecretKey(), restClientBuilder, responseErrorHandler); + commonProperties.getSecretKey(), restClientBuilderProvider.getIfAvailable(RestClient::builder), + responseErrorHandler); var chatModel = new QianFanChatModel(qianFanApi, chatProperties.getOptions(), retryTemplate, observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)); @@ -76,14 +78,15 @@ public QianFanChatModel qianFanChatModel(QianFanConnectionProperties commonPrope @ConditionalOnProperty(prefix = QianFanEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public QianFanEmbeddingModel qianFanEmbeddingModel(QianFanConnectionProperties commonProperties, - QianFanEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder, - RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, - ObjectProvider observationRegistry, + QianFanEmbeddingProperties embeddingProperties, + ObjectProvider restClientBuilderProvider, RetryTemplate retryTemplate, + ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { var qianFanApi = qianFanApi(embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(), embeddingProperties.getApiKey(), commonProperties.getApiKey(), embeddingProperties.getSecretKey(), - commonProperties.getSecretKey(), restClientBuilder, responseErrorHandler); + commonProperties.getSecretKey(), restClientBuilderProvider.getIfAvailable(RestClient::builder), + responseErrorHandler); var embeddingModel = new QianFanEmbeddingModel(qianFanApi, embeddingProperties.getMetadataMode(), embeddingProperties.getOptions(), retryTemplate, @@ -99,8 +102,9 @@ public QianFanEmbeddingModel qianFanEmbeddingModel(QianFanConnectionProperties c @ConditionalOnProperty(prefix = QianFanImageProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public QianFanImageModel qianFanImageModel(QianFanConnectionProperties commonProperties, - QianFanImageProperties imageProperties, RestClient.Builder restClientBuilder, RetryTemplate retryTemplate, - ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, + QianFanImageProperties imageProperties, ObjectProvider restClientBuilderProvider, + RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, + ObjectProvider observationRegistry, ObjectProvider observationConvention) { String apiKey = StringUtils.hasText(imageProperties.getApiKey()) ? imageProperties.getApiKey() @@ -116,7 +120,8 @@ public QianFanImageModel qianFanImageModel(QianFanConnectionProperties commonPro Assert.hasText(secretKey, "QianFan secret key must be set. Use the property: spring.ai.qianfan.secret-key"); Assert.hasText(baseUrl, "QianFan base URL must be set. Use the property: spring.ai.qianfan.base-url"); - var qianFanImageApi = new QianFanImageApi(baseUrl, apiKey, secretKey, restClientBuilder, responseErrorHandler); + var qianFanImageApi = new QianFanImageApi(baseUrl, apiKey, secretKey, + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); var imageModel = new QianFanImageModel(qianFanImageApi, imageProperties.getOptions(), retryTemplate, observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)); diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageAutoConfiguration.java index 5983499f2cf..0a594ff0bc1 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageAutoConfiguration.java @@ -17,6 +17,7 @@ import org.springframework.ai.stabilityai.StabilityAiImageModel; import org.springframework.ai.stabilityai.api.StabilityAiApi; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -26,6 +27,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import org.springframework.web.client.RestClient; /** * @author Mark Pollack @@ -40,7 +42,7 @@ public class StabilityAiImageAutoConfiguration { @Bean @ConditionalOnMissingBean public StabilityAiApi stabilityAiApi(StabilityAiConnectionProperties commonProperties, - StabilityAiImageProperties imageProperties) { + StabilityAiImageProperties imageProperties, ObjectProvider restClientBuilderProvider) { String apiKey = StringUtils.hasText(imageProperties.getApiKey()) ? imageProperties.getApiKey() : commonProperties.getApiKey(); @@ -51,7 +53,8 @@ public StabilityAiApi stabilityAiApi(StabilityAiConnectionProperties commonPrope Assert.hasText(apiKey, "StabilityAI API key must be set"); Assert.hasText(baseUrl, "StabilityAI base URL must be set"); - return new StabilityAiApi(apiKey, imageProperties.getOptions().getModel(), baseUrl); + return new StabilityAiApi(apiKey, imageProperties.getOptions().getModel(), baseUrl, + restClientBuilderProvider.getIfAvailable(RestClient::builder)); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java index 14b3324853b..c6d031ec1bb 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java @@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; -import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.util.StringUtils; import org.springframework.web.client.RestClient; @@ -54,18 +53,13 @@ PropertiesChromaConnectionDetails chromaConnectionDetails(ChromaApiProperties pr @Bean @ConditionalOnMissingBean - public RestClient.Builder builder() { - return RestClient.builder().requestFactory(new SimpleClientHttpRequestFactory()); - } - - @Bean - @ConditionalOnMissingBean - public ChromaApi chromaApi(ChromaApiProperties apiProperties, RestClient.Builder restClientBuilder, - ChromaConnectionDetails connectionDetails) { + public ChromaApi chromaApi(ChromaApiProperties apiProperties, + ObjectProvider restClientBuilderProvider, ChromaConnectionDetails connectionDetails) { String chromaUrl = String.format("%s:%s", connectionDetails.getHost(), connectionDetails.getPort()); - var chromaApi = new ChromaApi(chromaUrl, restClientBuilder, new ObjectMapper()); + var chromaApi = new ChromaApi(chromaUrl, restClientBuilderProvider.getIfAvailable(RestClient::builder), + new ObjectMapper()); if (StringUtils.hasText(connectionDetails.getKeyToken())) { chromaApi.withKeyToken(connectionDetails.getKeyToken()); diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2AutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2AutoConfiguration.java index 4899f7a526f..e2ac02ed66a 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2AutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2AutoConfiguration.java @@ -19,6 +19,7 @@ import org.springframework.ai.vertexai.palm2.VertexAiPaLm2ChatModel; import org.springframework.ai.vertexai.palm2.VertexAiPaLm2EmbeddingModel; import org.springframework.ai.vertexai.palm2.api.VertexAiPaLm2Api; +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; @@ -42,10 +43,11 @@ public class VertexAiPalm2AutoConfiguration { @ConditionalOnMissingBean public VertexAiPaLm2Api vertexAiApi(VertexAiPalm2ConnectionProperties connectionProperties, VertexAiPalm2EmbeddingProperties embeddingAiProperties, VertexAiPlam2ChatProperties chatProperties, - RestClient.Builder restClientBuilder) { + ObjectProvider restClientBuilderProvider) { return new VertexAiPaLm2Api(connectionProperties.getBaseUrl(), connectionProperties.getApiKey(), - chatProperties.getModel(), embeddingAiProperties.getModel(), restClientBuilder); + chatProperties.getModel(), embeddingAiProperties.getModel(), + restClientBuilderProvider.getIfAvailable(RestClient::builder)); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/watsonxai/WatsonxAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/watsonxai/WatsonxAiAutoConfiguration.java index 8cb42373786..4d7f9f43637 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/watsonxai/WatsonxAiAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/watsonxai/WatsonxAiAutoConfiguration.java @@ -18,6 +18,7 @@ import org.springframework.ai.watsonx.WatsonxAiChatModel; import org.springframework.ai.watsonx.WatsonxAiEmbeddingModel; import org.springframework.ai.watsonx.api.WatsonxAiApi; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -45,10 +46,11 @@ public class WatsonxAiAutoConfiguration { @Bean @ConditionalOnMissingBean - public WatsonxAiApi watsonxApi(WatsonxAiConnectionProperties properties, RestClient.Builder restClientBuilder) { + public WatsonxAiApi watsonxApi(WatsonxAiConnectionProperties properties, + ObjectProvider restClientBuilderProvider) { return new WatsonxAiApi(properties.getBaseUrl(), properties.getStreamEndpoint(), properties.getTextEndpoint(), properties.getEmbeddingEndpoint(), properties.getProjectId(), properties.getIAMToken(), - restClientBuilder); + restClientBuilderProvider.getIfAvailable(RestClient::builder)); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/zhipuai/ZhiPuAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/zhipuai/ZhiPuAiAutoConfiguration.java index ca7d0724582..2426f1bb7e2 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/zhipuai/ZhiPuAiAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/zhipuai/ZhiPuAiAutoConfiguration.java @@ -57,14 +57,15 @@ public class ZhiPuAiAutoConfiguration { @ConditionalOnProperty(prefix = ZhiPuAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public ZhiPuAiChatModel zhiPuAiChatModel(ZhiPuAiConnectionProperties commonProperties, - ZhiPuAiChatProperties chatProperties, RestClient.Builder restClientBuilder, + ZhiPuAiChatProperties chatProperties, ObjectProvider restClientBuilderProvider, List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler, ObjectProvider observationRegistry, ObjectProvider observationConvention) { var zhiPuAiApi = zhiPuAiApi(chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), - chatProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, responseErrorHandler); + chatProperties.getApiKey(), commonProperties.getApiKey(), + restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler); var chatModel = new ZhiPuAiChatModel(zhiPuAiApi, chatProperties.getOptions(), functionCallbackContext, toolFunctionCallbacks, retryTemplate, observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)); diff --git a/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/mongo/MongoDbAtlasLocalContainerConnectionDetailsFactoryTest.java b/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/mongo/MongoDbAtlasLocalContainerConnectionDetailsFactoryIt.java similarity index 98% rename from spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/mongo/MongoDbAtlasLocalContainerConnectionDetailsFactoryTest.java rename to spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/mongo/MongoDbAtlasLocalContainerConnectionDetailsFactoryIt.java index b99f107b2d3..34b748de47e 100644 --- a/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/mongo/MongoDbAtlasLocalContainerConnectionDetailsFactoryTest.java +++ b/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/mongo/MongoDbAtlasLocalContainerConnectionDetailsFactoryIt.java @@ -48,7 +48,7 @@ "spring.ai.vectorstore.mongodb.initialize-schema=true", "spring.ai.vectorstore.mongodb.collection-name=test_collection", "spring.ai.vectorstore.mongodb.index-name=text_index" }) -class MongoDbAtlasLocalContainerConnectionDetailsFactoryTest { +class MongoDbAtlasLocalContainerConnectionDetailsFactoryIT { @Container @ServiceConnection diff --git a/vector-stores/spring-ai-chroma-store/pom.xml b/vector-stores/spring-ai-chroma-store/pom.xml index 84ef6383db2..c057ea33967 100644 --- a/vector-stores/spring-ai-chroma-store/pom.xml +++ b/vector-stores/spring-ai-chroma-store/pom.xml @@ -30,7 +30,7 @@ org.springframework - spring-web + spring-webflux diff --git a/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/ChromaApi.java b/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/ChromaApi.java index 9932b1fe897..2d5c09ef3e8 100644 --- a/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/ChromaApi.java +++ b/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/ChromaApi.java @@ -69,10 +69,10 @@ public ChromaApi(String baseUrl, RestClient.Builder restClientBuilder) { } public ChromaApi(String baseUrl, RestClient.Builder restClientBuilder, ObjectMapper objectMapper) { - Consumer defaultHeaders = headers -> { - headers.setContentType(MediaType.APPLICATION_JSON); - }; - this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(defaultHeaders).build(); + + this.restClient = restClientBuilder.baseUrl(baseUrl) + .defaultHeaders(h -> h.setContentType(MediaType.APPLICATION_JSON)) + .build(); this.objectMapper = objectMapper; } From 12d3382bbc02643ff53b56b6c456fc31770cf258 Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Wed, 16 Oct 2024 17:43:06 +0200 Subject: [PATCH 2/2] Adjust import order --- .../ai/openai/api/OpenAiModerationApi.java | 12 ++++-------- ...odelWithTranscriptionResponseMetadataTests.java | 14 ++++++++------ .../anthropic/AnthropicAutoConfiguration.java | 3 ++- .../mistralai/MistralAiAutoConfiguration.java | 3 ++- .../moonshot/MoonshotAutoConfiguration.java | 5 +++-- .../ollama/OllamaAutoConfiguration.java | 3 ++- .../qianfan/QianFanAutoConfiguration.java | 3 ++- .../gemini/VertexAiGeminiAutoConfiguration.java | 1 + .../zhipuai/ZhiPuAiAutoConfiguration.java | 5 +++-- 9 files changed, 27 insertions(+), 22 deletions(-) diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java index 7628aebb3e6..092cc62bc96 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java @@ -15,21 +15,17 @@ */ package org.springframework.ai.openai.api; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.ai.retry.RetryUtils; -import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; import org.springframework.util.Assert; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; -import java.io.IOException; -import java.util.function.Consumer; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; /** * OpenAI Moderation API. diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests.java index 673f9e06969..a7749a8f021 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests.java @@ -15,6 +15,14 @@ */ package org.springframework.ai.openai.audio.transcription; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.header; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; + +import java.time.Duration; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.ai.audio.transcription.AudioTranscriptionMetadata; @@ -38,12 +46,6 @@ import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestClient; -import java.time.Duration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - /** * @author Michael Lavelle */ diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/anthropic/AnthropicAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/anthropic/AnthropicAutoConfiguration.java index 9989c0c3567..ff311b7cab4 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/anthropic/AnthropicAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/anthropic/AnthropicAutoConfiguration.java @@ -17,7 +17,6 @@ import java.util.List; -import io.micrometer.observation.ObservationRegistry; import org.springframework.ai.anthropic.AnthropicChatModel; import org.springframework.ai.anthropic.api.AnthropicApi; import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration; @@ -40,6 +39,8 @@ import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; +import io.micrometer.observation.ObservationRegistry; + /** * @author Christian Tzolov * @author Thomas Vitale diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java index 05b7be6f8e0..be572d81919 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java @@ -17,7 +17,6 @@ import java.util.List; -import io.micrometer.observation.ObservationRegistry; import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.embedding.observation.EmbeddingModelObservationConvention; @@ -43,6 +42,8 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; +import io.micrometer.observation.ObservationRegistry; + /** * @author Ricken Bazolo * @author Christian Tzolov diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/moonshot/MoonshotAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/moonshot/MoonshotAutoConfiguration.java index 9a750ec6ff5..3bd4223f416 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/moonshot/MoonshotAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/moonshot/MoonshotAutoConfiguration.java @@ -15,7 +15,8 @@ */ package org.springframework.ai.autoconfigure.moonshot; -import io.micrometer.observation.ObservationRegistry; +import java.util.List; + import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.model.function.FunctionCallback; @@ -37,7 +38,7 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; -import java.util.List; +import io.micrometer.observation.ObservationRegistry; /** * @author Geng Rong diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java index 6bd1cf46c17..0e6bccb4816 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java @@ -17,7 +17,6 @@ import java.util.List; -import io.micrometer.observation.ObservationRegistry; import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.embedding.observation.EmbeddingModelObservationConvention; import org.springframework.ai.model.function.FunctionCallback; @@ -39,6 +38,8 @@ import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; +import io.micrometer.observation.ObservationRegistry; + /** * {@link AutoConfiguration Auto-configuration} for Ollama Chat Client. * diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/qianfan/QianFanAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/qianfan/QianFanAutoConfiguration.java index 4c2b6100de0..5a2efccae0f 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/qianfan/QianFanAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/qianfan/QianFanAutoConfiguration.java @@ -15,7 +15,6 @@ */ package org.springframework.ai.autoconfigure.qianfan; -import io.micrometer.observation.ObservationRegistry; import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.embedding.observation.EmbeddingModelObservationConvention; @@ -41,6 +40,8 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; +import io.micrometer.observation.ObservationRegistry; + /** * @author Geng Rong */ diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfiguration.java index 7f6496700f9..a6c83100a89 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfiguration.java @@ -40,6 +40,7 @@ import com.google.auth.oauth2.GoogleCredentials; import com.google.cloud.vertexai.VertexAI; + import io.micrometer.observation.ObservationRegistry; /** diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/zhipuai/ZhiPuAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/zhipuai/ZhiPuAiAutoConfiguration.java index 2426f1bb7e2..98afeaf79fe 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/zhipuai/ZhiPuAiAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/zhipuai/ZhiPuAiAutoConfiguration.java @@ -15,7 +15,8 @@ */ package org.springframework.ai.autoconfigure.zhipuai; -import io.micrometer.observation.ObservationRegistry; +import java.util.List; + import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration; import org.springframework.ai.chat.observation.ChatModelObservationConvention; import org.springframework.ai.embedding.observation.EmbeddingModelObservationConvention; @@ -41,7 +42,7 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; -import java.util.List; +import io.micrometer.observation.ObservationRegistry; /** * @author Geng Rong