Spring Boot 4.0 changes
Signed-off-by: Ilayaperumal Gopinathan <ilayaperumal.gopinathan@broadcom.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.springframework.ai.retry.autoconfigure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -30,6 +31,7 @@ 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.HttpMethod;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.retry.RetryCallback;
|
||||
@@ -87,7 +89,8 @@ public class SpringAiRetryAutoConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleError(@NonNull ClientHttpResponse response) throws IOException {
|
||||
public void handleError(URI uri, HttpMethod httpMethod, @NonNull ClientHttpResponse response)
|
||||
throws IOException {
|
||||
if (!response.getStatusCode().isError()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ public final class AnthropicApi {
|
||||
|
||||
return this.restClient.post()
|
||||
.uri(this.completionsPath)
|
||||
.headers(headers -> headers.addAll(additionalHttpHeader))
|
||||
.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
|
||||
.body(chatRequest)
|
||||
.retrieve()
|
||||
.toEntity(ChatCompletionResponse.class);
|
||||
@@ -198,7 +198,7 @@ public final class AnthropicApi {
|
||||
|
||||
return this.webClient.post()
|
||||
.uri(this.completionsPath)
|
||||
.headers(headers -> headers.addAll(additionalHttpHeader))
|
||||
.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
|
||||
.body(Mono.just(chatRequest), ChatCompletionRequest.class)
|
||||
.retrieve()
|
||||
.bodyToFlux(String.class)
|
||||
|
||||
@@ -94,7 +94,7 @@ public class DeepSeekApi {
|
||||
Consumer<HttpHeaders> finalHeaders = h -> {
|
||||
h.setBearerAuth(apiKey.getValue());
|
||||
h.setContentType(MediaType.APPLICATION_JSON);
|
||||
h.addAll(headers);
|
||||
h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
|
||||
};
|
||||
this.restClient = restClientBuilder.baseUrl(baseUrl)
|
||||
.defaultHeaders(finalHeaders)
|
||||
@@ -153,7 +153,7 @@ public class DeepSeekApi {
|
||||
|
||||
return this.webClient.post()
|
||||
.uri(this.getEndpoint(chatRequest))
|
||||
.headers(headers -> headers.addAll(additionalHttpHeader))
|
||||
.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
|
||||
.body(Mono.just(chatRequest), ChatCompletionRequest.class)
|
||||
.retrieve()
|
||||
.bodyToFlux(String.class)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<dependency>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>2.2.15</version>
|
||||
<version>2.2.32</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -133,7 +133,7 @@ public class OpenAiApi {
|
||||
}
|
||||
|
||||
h.setContentType(MediaType.APPLICATION_JSON);
|
||||
h.addAll(headers);
|
||||
h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
|
||||
};
|
||||
this.restClient = restClientBuilder.clone()
|
||||
.baseUrl(baseUrl)
|
||||
@@ -181,7 +181,7 @@ public class OpenAiApi {
|
||||
|
||||
return this.restClient.post()
|
||||
.uri(this.completionsPath)
|
||||
.headers(headers -> headers.addAll(additionalHttpHeader))
|
||||
.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
|
||||
.body(chatRequest)
|
||||
.retrieve()
|
||||
.toEntity(ChatCompletion.class);
|
||||
@@ -215,7 +215,7 @@ public class OpenAiApi {
|
||||
|
||||
return this.webClient.post()
|
||||
.uri(this.completionsPath)
|
||||
.headers(headers -> headers.addAll(additionalHttpHeader))
|
||||
.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
|
||||
.body(Mono.just(chatRequest), ChatCompletionRequest.class)
|
||||
.retrieve()
|
||||
.bodyToFlux(String.class)
|
||||
|
||||
@@ -74,7 +74,7 @@ public class OpenAiAudioApi {
|
||||
if (!(apiKey instanceof NoopApiKey)) {
|
||||
h.setBearerAuth(apiKey.getValue());
|
||||
}
|
||||
h.addAll(headers);
|
||||
h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
|
||||
// h.setContentType(MediaType.APPLICATION_JSON);
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.ai.model.NoopApiKey;
|
||||
import org.springframework.ai.model.SimpleApiKey;
|
||||
import org.springframework.ai.openai.api.common.OpenAiApiConstants;
|
||||
import org.springframework.ai.retry.RetryUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -68,7 +69,7 @@ public class OpenAiImageApi {
|
||||
h.setBearerAuth(apiKey.getValue());
|
||||
}
|
||||
h.setContentType(MediaType.APPLICATION_JSON);
|
||||
h.addAll(headers);
|
||||
h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
|
||||
})
|
||||
.defaultStatusHandler(responseErrorHandler)
|
||||
.build();
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.ai.model.NoopApiKey;
|
||||
import org.springframework.ai.model.SimpleApiKey;
|
||||
import org.springframework.ai.openai.api.common.OpenAiApiConstants;
|
||||
import org.springframework.ai.retry.RetryUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -69,7 +70,7 @@ public class OpenAiModerationApi {
|
||||
h.setBearerAuth(apiKey.getValue());
|
||||
}
|
||||
h.setContentType(MediaType.APPLICATION_JSON);
|
||||
h.addAll(headers);
|
||||
h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
|
||||
}).defaultStatusHandler(responseErrorHandler).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ public final class OpenAiResponseHeaderExtractor {
|
||||
|
||||
private static Duration getHeaderAsDuration(ResponseEntity<?> response, String headerName) {
|
||||
var headers = response.getHeaders();
|
||||
if (headers.containsKey(headerName)) {
|
||||
if (headers.containsHeader(headerName)) {
|
||||
var values = headers.get(headerName);
|
||||
if (!CollectionUtils.isEmpty(values)) {
|
||||
return DurationFormatter.TIME_UNIT.parse(values.get(0));
|
||||
@@ -82,7 +82,7 @@ public final class OpenAiResponseHeaderExtractor {
|
||||
|
||||
private static Long getHeaderAsLong(ResponseEntity<?> response, String headerName) {
|
||||
var headers = response.getHeaders();
|
||||
if (headers.containsKey(headerName)) {
|
||||
if (headers.containsHeader(headerName)) {
|
||||
var values = headers.get(headerName);
|
||||
if (!CollectionUtils.isEmpty(values)) {
|
||||
return parseLong(headerName, values.get(0));
|
||||
|
||||
6
pom.xml
6
pom.xml
@@ -162,7 +162,7 @@
|
||||
<module>models/spring-ai-azure-openai</module>
|
||||
<module>models/spring-ai-bedrock</module>
|
||||
<module>models/spring-ai-bedrock-converse</module>
|
||||
<module>models/spring-ai-huggingface</module>
|
||||
<!-- <module>models/spring-ai-huggingface</module>-->
|
||||
<module>models/spring-ai-minimax</module>
|
||||
<module>models/spring-ai-mistral-ai</module>
|
||||
<module>models/spring-ai-oci-genai</module>
|
||||
@@ -253,12 +253,12 @@
|
||||
<kotlin.compiler.jvmTarget>${java.version}</kotlin.compiler.jvmTarget>
|
||||
|
||||
<!-- production dependencies -->
|
||||
<spring-boot.version>3.4.5</spring-boot.version>
|
||||
<spring-boot.version>4.0.0-SNAPSHOT</spring-boot.version>
|
||||
<ST4.version>4.3.4</ST4.version>
|
||||
<azure-open-ai-client.version>1.0.0-beta.16</azure-open-ai-client.version>
|
||||
<jtokkit.version>1.1.0</jtokkit.version>
|
||||
<victools.version>4.37.0</victools.version>
|
||||
<kotlin.version>1.9.25</kotlin.version>
|
||||
<kotlin.version>2.1.0</kotlin.version>
|
||||
|
||||
<!-- NOTE: keep bedrockruntime and awssdk versions aligned -->
|
||||
<bedrockruntime.version>2.31.26</bedrockruntime.version>
|
||||
|
||||
@@ -25,8 +25,8 @@ import org.springframework.core.ParameterizedTypeReference
|
||||
* @author Josh Long
|
||||
*/
|
||||
|
||||
inline fun <reified T> ChatClient.CallResponseSpec.entity(): T =
|
||||
inline fun <reified T : Any> ChatClient.CallResponseSpec.entity(): T =
|
||||
entity(object : ParameterizedTypeReference<T>() {}) as T
|
||||
|
||||
inline fun <reified T> ChatClient.CallResponseSpec.responseEntity(): ResponseEntity<ChatResponse, T> =
|
||||
responseEntity(object : ParameterizedTypeReference<T>() {})
|
||||
inline fun <reified T : Any> ChatClient.CallResponseSpec.responseEntity(): ResponseEntity<ChatResponse, T> =
|
||||
responseEntity(object : ParameterizedTypeReference<T>() {})
|
||||
|
||||
@@ -39,7 +39,7 @@ class TypeResolverHelperKotlinIT {
|
||||
val functionType = TypeResolverHelper.resolveBeanType(this.applicationContext, beanName);
|
||||
val functionInputClass = TypeResolverHelper.getFunctionArgumentType(functionType, 0).rawClass;
|
||||
assertThat(functionInputClass).isNotNull();
|
||||
assertThat(functionInputClass.typeName).isEqualTo(WeatherRequest::class.java.getName());
|
||||
assertThat(functionInputClass!!.typeName).isEqualTo(WeatherRequest::class.java.name)
|
||||
}
|
||||
|
||||
class Outer {
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
package org.springframework.ai.retry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.retry.RetryCallback;
|
||||
@@ -49,7 +51,7 @@ public abstract class RetryUtils {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleError(@NonNull ClientHttpResponse response) throws IOException {
|
||||
public void handleError(URI uri, HttpMethod method, @NonNull ClientHttpResponse response) throws IOException {
|
||||
if (response.getStatusCode().isError()) {
|
||||
String error = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
|
||||
String message = String.format("%s - %s", response.getStatusCode().value(), error);
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||
import co.elastic.clients.elasticsearch._types.mapping.DenseVectorSimilarity;
|
||||
import co.elastic.clients.elasticsearch.core.BulkRequest;
|
||||
import co.elastic.clients.elasticsearch.core.BulkResponse;
|
||||
import co.elastic.clients.elasticsearch.core.SearchResponse;
|
||||
@@ -331,7 +332,8 @@ public class ElasticsearchVectorStore extends AbstractObservationVectorStore imp
|
||||
this.elasticsearchClient.indices()
|
||||
.create(cr -> cr.index(this.options.getIndexName())
|
||||
.mappings(map -> map.properties(this.options.getEmbeddingFieldName(),
|
||||
p -> p.denseVector(dv -> dv.similarity(this.options.getSimilarity().toString())
|
||||
p -> p.denseVector(dv -> dv
|
||||
.similarity(DenseVectorSimilarity.valueOf(this.options.getSimilarity().toString()))
|
||||
.dims(this.options.getDimensions())))));
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
||||
Reference in New Issue
Block a user