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<RestClient.Builder> and WebClient.Builder injections with ObjectProvider<WebClient.Builder> - 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 - Adjust import order Resolves #1066 Resolves #524
This commit is contained in:
committed by
Mark Pollack
parent
a69f6bb57b
commit
2e0a51fac5
@@ -29,12 +29,6 @@
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring-framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
|
||||
@@ -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 <a href="https://www.minimaxi.com/document/guides/chat-model/V2">MiniMax Chat Completion API</a> and
|
||||
@@ -98,15 +102,20 @@ public class MiniMaxApi {
|
||||
*/
|
||||
public MiniMaxApi(String baseUrl, String miniMaxToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
|
||||
|
||||
Consumer<HttpHeaders> 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -41,12 +41,6 @@
|
||||
<version>${oci-sdk-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- NOTE: Required only by the @ConstructorBinding. -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
|
||||
@@ -22,11 +22,6 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-core</artifactId>
|
||||
@@ -34,14 +29,9 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-retry</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-retry</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!-- production dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.ai.openai.api;
|
||||
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.openai.api.common.OpenAiApiConstants;
|
||||
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 class OpenAiApi {
|
||||
this.completionsPath = completionsPath;
|
||||
this.embeddingsPath = embeddingsPath;
|
||||
// @formatter:off
|
||||
Consumer<HttpHeaders> 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
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,10 @@ package org.springframework.ai.openai.api;
|
||||
|
||||
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.util.MultiValueMap;
|
||||
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 class OpenAiAudioApi {
|
||||
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<HttpHeaders> 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 class OpenAiAudioApi {
|
||||
RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder,
|
||||
ResponseErrorHandler responseErrorHandler) {
|
||||
|
||||
// @formatter:off
|
||||
this.restClient = restClientBuilder
|
||||
.baseUrl(baseUrl)
|
||||
.defaultHeaders(h -> {
|
||||
h.setBearerAuth(apiKey);
|
||||
h.addAll(headers);
|
||||
})
|
||||
.defaultStatusHandler(responseErrorHandler).build();
|
||||
Consumer<HttpHeaders> authHeaders = h -> {
|
||||
h.setBearerAuth(apiKey);
|
||||
h.addAll(headers);
|
||||
// h.setContentType(MediaType.APPLICATION_JSON);
|
||||
};
|
||||
|
||||
this.webClient = webClientBuilder
|
||||
.baseUrl(baseUrl)
|
||||
.defaultHeaders(h -> {
|
||||
h.setBearerAuth(apiKey);
|
||||
h.addAll(headers);
|
||||
})
|
||||
.defaultHeaders(ApiUtils.getJsonContentHeaders(apiKey)).build();
|
||||
// @formatter:on
|
||||
this.restClient = restClientBuilder.baseUrl(baseUrl)
|
||||
.defaultHeaders(authHeaders)
|
||||
.defaultStatusHandler(responseErrorHandler)
|
||||
.build();
|
||||
|
||||
this.webClient = webClientBuilder.baseUrl(baseUrl).defaultHeaders(authHeaders).build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
@@ -61,15 +57,10 @@ public class OpenAiModerationApi {
|
||||
|
||||
this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
Consumer<HttpHeaders> 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
|
||||
|
||||
@@ -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.http.MediaType;
|
||||
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
|
||||
*/
|
||||
@@ -53,7 +55,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 +74,7 @@ public class OpenAiTranscriptionModelWithTranscriptionResponseMetadataTests {
|
||||
|
||||
AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile);
|
||||
|
||||
AudioTranscriptionResponse response = this.openAiTranscriptionClient.call(transcriptionRequest);
|
||||
AudioTranscriptionResponse response = this.openAiTranscriptionModel.call(transcriptionRequest);
|
||||
|
||||
assertThat(response).isNotNull();
|
||||
|
||||
|
||||
@@ -58,13 +58,6 @@
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring-framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Spring Framework -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
||||
@@ -58,12 +58,6 @@
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring-framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Spring Framework -->
|
||||
<dependency>
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring-framework.version}</version>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- NOTE: Required only by the @ConstructorBinding. -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
@@ -38,11 +39,6 @@
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- production dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
|
||||
@@ -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 <a href="https://open.bigmodel.cn/dev/api#http">ZhiPuAI Chat Completion API</a> and
|
||||
@@ -99,15 +103,20 @@ public class ZhiPuAiApi {
|
||||
*/
|
||||
public ZhiPuAiApi(String baseUrl, String zhiPuAiToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
|
||||
|
||||
Consumer<HttpHeaders> 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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,10 +70,10 @@ public class ZhiPuAiImageApi {
|
||||
public ZhiPuAiImageApi(String baseUrl, String zhiPuAiToken, RestClient.Builder restClientBuilder,
|
||||
ResponseErrorHandler responseErrorHandler) {
|
||||
|
||||
this.restClient = restClientBuilder.baseUrl(baseUrl)
|
||||
.defaultHeaders(ApiUtils.getJsonContentHeaders(zhiPuAiToken))
|
||||
.defaultStatusHandler(responseErrorHandler)
|
||||
.build();
|
||||
this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(h -> {
|
||||
h.setBearerAuth(zhiPuAiToken);
|
||||
// h.setContentType(MediaType.APPLICATION_JSON);
|
||||
}).defaultStatusHandler(responseErrorHandler).build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
11
pom.xml
11
pom.xml
@@ -148,7 +148,6 @@
|
||||
<!-- production dependencies -->
|
||||
<spring-cloud-function-context.version>4.1.3</spring-cloud-function-context.version>
|
||||
<spring-boot.version>3.3.4</spring-boot.version>
|
||||
<spring-framework.version>6.1.4</spring-framework.version>
|
||||
<ST4.version>4.3.4</ST4.version>
|
||||
<azure-open-ai-client.version>1.0.0-beta.10</azure-open-ai-client.version>
|
||||
<jtokkit.version>1.1.0</jtokkit.version>
|
||||
@@ -163,21 +162,21 @@
|
||||
<djl.version>0.30.0</djl.version>
|
||||
<onnxruntime.version>1.19.2</onnxruntime.version>
|
||||
<oci-sdk-version>3.46.1</oci-sdk-version>
|
||||
<com.google.cloud.version>26.41.0</com.google.cloud.version>
|
||||
<com.google.cloud.version>26.48.0</com.google.cloud.version>
|
||||
<qdrant.version>1.9.1</qdrant.version>
|
||||
<spring-retry.version>2.0.5</spring-retry.version>
|
||||
<spring-retry.version>2.0.9</spring-retry.version>
|
||||
<ibm.sdk.version>9.20.0</ibm.sdk.version>
|
||||
<jsonschema.version>4.35.0</jsonschema.version>
|
||||
<swagger-annotations.version>2.2.20</swagger-annotations.version>
|
||||
<spring-cloud-bindings.version>2.0.2</spring-cloud-bindings.version>
|
||||
<spring-cloud-bindings.version>2.0.3</spring-cloud-bindings.version>
|
||||
|
||||
<!-- Protobuf -->
|
||||
<protobuf-java.version>3.25.2</protobuf-java.version>
|
||||
|
||||
<!-- readers/writer/stores dependencies-->
|
||||
<cassandra.java-driver.version>4.18.1</cassandra.java-driver.version>
|
||||
<pdfbox.version>3.0.1</pdfbox.version>
|
||||
<pgvector.version>0.1.4</pgvector.version>
|
||||
<pdfbox.version>3.0.3</pdfbox.version>
|
||||
<pgvector.version>0.1.6</pgvector.version>
|
||||
<sap.hanadb.version>2.20.11</sap.hanadb.version>
|
||||
<oracle.version>23.4.0.24.05</oracle.version>
|
||||
<postgresql.version>42.7.2</postgresql.version>
|
||||
|
||||
@@ -74,11 +74,6 @@
|
||||
<artifactId>spring-messaging</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-core</artifactId>
|
||||
|
||||
@@ -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<HttpHeaders> getJsonContentHeaders(String apiKey) {
|
||||
return (headers) -> {
|
||||
headers.setBearerAuth(apiKey);
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
<artifactId>spring-retry</artifactId>
|
||||
<version>${spring-retry.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.ai.autoconfigure.anthropic;
|
||||
|
||||
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.ResponseErrorHandler;
|
||||
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
|
||||
@@ -57,11 +58,12 @@ public class AnthropicAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AnthropicApi anthropicApi(AnthropicConnectionProperties connectionProperties,
|
||||
RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder,
|
||||
ResponseErrorHandler responseErrorHandler) {
|
||||
ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
ObjectProvider<WebClient.Builder> 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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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.ApplicationContext;
|
||||
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<RestClient.Builder> restClientBuilderProvider,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler,
|
||||
ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<ChatModelObservationConvention> 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 class MiniMaxAutoConfiguration {
|
||||
@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> observationRegistry,
|
||||
MiniMaxEmbeddingProperties embeddingProperties,
|
||||
ObjectProvider<RestClient.Builder> restClientBuilderProvider, RetryTemplate retryTemplate,
|
||||
ResponseErrorHandler responseErrorHandler, ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<EmbeddingModelObservationConvention> 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,
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.ai.autoconfigure.mistralai;
|
||||
|
||||
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.util.StringUtils;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
|
||||
/**
|
||||
* @author Ricken Bazolo
|
||||
* @author Christian Tzolov
|
||||
@@ -62,14 +63,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> observationRegistry,
|
||||
MistralAiEmbeddingProperties embeddingProperties,
|
||||
ObjectProvider<RestClient.Builder> restClientBuilderProvider, RetryTemplate retryTemplate,
|
||||
ResponseErrorHandler responseErrorHandler, ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<EmbeddingModelObservationConvention> 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 +86,15 @@ public class MistralAiAutoConfiguration {
|
||||
@ConditionalOnProperty(prefix = MistralAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public MistralAiChatModel mistralAiChatModel(MistralAiCommonProperties commonProperties,
|
||||
MistralAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
|
||||
MistralAiChatProperties chatProperties, ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler,
|
||||
ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<ChatModelObservationConvention> 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));
|
||||
|
||||
@@ -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.util.StringUtils;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import java.util.List;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
|
||||
/**
|
||||
* @author Geng Rong
|
||||
@@ -52,14 +53,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<RestClient.Builder> restClientBuilderProvider,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler,
|
||||
ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<ChatModelObservationConvention> 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));
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.ai.autoconfigure.ollama;
|
||||
|
||||
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.context.annotation.Bean;
|
||||
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.
|
||||
*
|
||||
@@ -62,9 +63,12 @@ public class OllamaAutoConfiguration {
|
||||
|
||||
@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<RestClient.Builder> restClientBuilderProvider,
|
||||
ObjectProvider<WebClient.Builder> webClientBuilderProvider) {
|
||||
return new OllamaApi(connectionDetails.getBaseUrl(),
|
||||
restClientBuilderProvider.getIfAvailable(RestClient::builder),
|
||||
webClientBuilderProvider.getIfAvailable(WebClient::builder));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -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<FunctionCallback> toolFunctionCallbacks,
|
||||
OpenAiChatProperties chatProperties, ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
ObjectProvider<WebClient.Builder> webClientBuilderProvider, List<FunctionCallback> toolFunctionCallbacks,
|
||||
FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate,
|
||||
ResponseErrorHandler responseErrorHandler, ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<ChatModelObservationConvention> 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 class OpenAiAutoConfiguration {
|
||||
@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> observationRegistry,
|
||||
OpenAiEmbeddingProperties embeddingProperties, ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
ObjectProvider<WebClient.Builder> webClientBuilderProvider, RetryTemplate retryTemplate,
|
||||
ResponseErrorHandler responseErrorHandler, ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<EmbeddingModelObservationConvention> 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 @@ public class OpenAiAutoConfiguration {
|
||||
@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> observationRegistry,
|
||||
OpenAiImageProperties imageProperties, ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler,
|
||||
ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<ImageModelObservationConvention> 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 class OpenAiAutoConfiguration {
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
public OpenAiAudioTranscriptionModel openAiAudioTranscriptionModel(OpenAiConnectionProperties commonProperties,
|
||||
OpenAiAudioTranscriptionProperties transcriptionProperties, RetryTemplate retryTemplate,
|
||||
RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder,
|
||||
ResponseErrorHandler responseErrorHandler) {
|
||||
ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
ObjectProvider<WebClient.Builder> 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 class OpenAiAutoConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
public OpenAiModerationModel openAiModerationClient(OpenAiConnectionProperties commonProperties,
|
||||
OpenAiModerationProperties moderationProperties, RetryTemplate retryTemplate,
|
||||
RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
|
||||
ObjectProvider<RestClient.Builder> 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 class OpenAiAutoConfiguration {
|
||||
matchIfMissing = true)
|
||||
public OpenAiAudioSpeechModel openAiAudioSpeechClient(OpenAiConnectionProperties commonProperties,
|
||||
OpenAiAudioSpeechProperties speechProperties, RetryTemplate retryTemplate,
|
||||
RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder,
|
||||
ResponseErrorHandler responseErrorHandler) {
|
||||
ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
ObjectProvider<WebClient.Builder> 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());
|
||||
}
|
||||
|
||||
@@ -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.util.StringUtils;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
|
||||
/**
|
||||
* @author Geng Rong
|
||||
*/
|
||||
@@ -55,13 +56,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> observationRegistry,
|
||||
QianFanChatProperties chatProperties, ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler,
|
||||
ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<ChatModelObservationConvention> 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 +79,15 @@ public class QianFanAutoConfiguration {
|
||||
@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> observationRegistry,
|
||||
QianFanEmbeddingProperties embeddingProperties,
|
||||
ObjectProvider<RestClient.Builder> restClientBuilderProvider, RetryTemplate retryTemplate,
|
||||
ResponseErrorHandler responseErrorHandler, ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<EmbeddingModelObservationConvention> 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 +103,9 @@ public class QianFanAutoConfiguration {
|
||||
@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> observationRegistry,
|
||||
QianFanImageProperties imageProperties, ObjectProvider<RestClient.Builder> restClientBuilderProvider,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler,
|
||||
ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<ImageModelObservationConvention> observationConvention) {
|
||||
|
||||
String apiKey = StringUtils.hasText(imageProperties.getApiKey()) ? imageProperties.getApiKey()
|
||||
@@ -116,7 +121,8 @@ public class QianFanAutoConfiguration {
|
||||
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));
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.ai.autoconfigure.stabilityai;
|
||||
|
||||
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.boot.context.properties.EnableConfigurationProperties
|
||||
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<RestClient.Builder> restClientBuilderProvider) {
|
||||
|
||||
String apiKey = StringUtils.hasText(imageProperties.getApiKey()) ? imageProperties.getApiKey()
|
||||
: commonProperties.getApiKey();
|
||||
@@ -51,7 +53,8 @@ public class StabilityAiImageAutoConfiguration {
|
||||
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
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
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 @@ public class ChromaVectorStoreAutoConfiguration {
|
||||
|
||||
@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<RestClient.Builder> 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());
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import com.google.cloud.vertexai.VertexAI;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration
|
||||
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<RestClient.Builder> restClientBuilderProvider) {
|
||||
|
||||
return new VertexAiPaLm2Api(connectionProperties.getBaseUrl(), connectionProperties.getApiKey(),
|
||||
chatProperties.getModel(), embeddingAiProperties.getModel(), restClientBuilder);
|
||||
chatProperties.getModel(), embeddingAiProperties.getModel(),
|
||||
restClientBuilderProvider.getIfAvailable(RestClient::builder));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.ai.autoconfigure.watsonxai;
|
||||
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<RestClient.Builder> restClientBuilderProvider) {
|
||||
return new WatsonxAiApi(properties.getBaseUrl(), properties.getStreamEndpoint(), properties.getTextEndpoint(),
|
||||
properties.getEmbeddingEndpoint(), properties.getProjectId(), properties.getIAMToken(),
|
||||
restClientBuilder);
|
||||
restClientBuilderProvider.getIfAvailable(RestClient::builder));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -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.util.StringUtils;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import java.util.List;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
|
||||
/**
|
||||
* @author Geng Rong
|
||||
@@ -57,14 +58,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<RestClient.Builder> restClientBuilderProvider,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler,
|
||||
ObjectProvider<ObservationRegistry> observationRegistry,
|
||||
ObjectProvider<ChatModelObservationConvention> 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));
|
||||
|
||||
@@ -48,7 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
"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
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- TESTING -->
|
||||
|
||||
@@ -69,10 +69,10 @@ public class ChromaApi {
|
||||
}
|
||||
|
||||
public ChromaApi(String baseUrl, RestClient.Builder restClientBuilder, ObjectMapper objectMapper) {
|
||||
Consumer<HttpHeaders> 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user