From 5c3ed1152a7a9318d431183b42f5ebf37a99ee90 Mon Sep 17 00:00:00 2001 From: sinsy <550569627@qq.com> Date: Thu, 28 Mar 2024 10:59:08 +0800 Subject: [PATCH] Add support of Bedrock API timeout Configure the amount of time to allow the client to complete the execution of an API call. This timeout covers the entire client execution except for marshalling. This includes request handler execution, all HTTP requests including retries, unmarshalling, etc. This value should always be positive, if present. - Add timeout filed to the AbstractBedrockApi, used to initialize the BedrockRuntimeClient and the BedrockStreamingRuntimeClient. Update all classes that extend the AbstractBedrockApi. - Keep the previous constructors for backward compatibility using timeout value of 5 min. - Add a common AWS connection timeout auto-config property and update the documentation. Defaults to 5 min. Additional changes: - Fix Anthropic 3 straming response - add bedrock metrics field. - Increate the default timeout to 5 min. Update the docs. - Increase the ITs. --- .../api/AnthropicChatBedrockApi.java | 25 +++++++++ .../api/Anthropic3ChatBedrockApi.java | 44 ++++++++++++--- .../ai/bedrock/api/AbstractBedrockApi.java | 56 +++++++++++++++---- .../cohere/api/CohereChatBedrockApi.java | 27 +++++++++ .../cohere/api/CohereEmbeddingBedrockApi.java | 29 ++++++++++ .../api/Ai21Jurassic2ChatBedrockApi.java | 27 +++++++++ .../llama2/api/Llama2ChatBedrockApi.java | 28 ++++++++++ .../titan/api/TitanChatBedrockApi.java | 32 +++++++++++ .../titan/api/TitanEmbeddingBedrockApi.java | 11 ++-- .../BedrockAnthropicChatClientIT.java | 4 +- .../BedrockAnthropicCreateRequestTests.java | 3 +- .../api/AnthropicChatBedrockApiIT.java | 4 +- .../BedrockAnthropic3ChatClientIT.java | 4 +- .../BedrockAnthropic3CreateRequestTests.java | 3 +- .../api/Anthropic3ChatBedrockApiIT.java | 8 ++- .../cohere/BedrockCohereChatClientIT.java | 4 +- .../BedrockCohereChatCreateRequestTests.java | 4 +- .../BedrockCohereEmbeddingClientIT.java | 4 +- .../cohere/api/CohereChatBedrockApiIT.java | 3 +- .../api/CohereEmbeddingBedrockApiIT.java | 3 +- .../api/Ai21Jurassic2ChatBedrockApiIT.java | 3 +- .../api/BedrockAi21Jurassic2ChatClientIT.java | 4 +- .../llama2/BedrockLlama2ChatClientIT.java | 4 +- .../BedrockLlama2CreateRequestTests.java | 5 +- .../llama2/api/Llama2ChatBedrockApiIT.java | 3 +- .../titan/BedrockTitanChatClientIT.java | 4 +- .../BedrockTitanChatCreateRequestTests.java | 4 +- .../titan/BedrockTitanEmbeddingClientIT.java | 4 +- .../titan/api/TitanChatBedrockApiIT.java | 3 +- .../titan/api/TitanEmbeddingBedrockApiIT.java | 5 +- .../ai/model/ModelOptionsUtils.java | 2 +- .../modules/ROOT/pages/api/bedrock.adoc | 11 ++-- .../api/chat/bedrock/bedrock-anthropic.adoc | 9 ++- .../api/chat/bedrock/bedrock-anthropic3.adoc | 9 ++- .../api/chat/bedrock/bedrock-cohere.adoc | 12 +++- .../api/chat/bedrock/bedrock-jurassic2.adoc | 12 +++- .../api/chat/bedrock/bedrock-llama2.adoc | 12 +++- .../pages/api/chat/bedrock/bedrock-titan.adoc | 10 +++- .../BedrockAwsConnectionProperties.java | 15 +++++ ...BedrockAnthropicChatAutoConfiguration.java | 2 +- ...edrockAnthropic3ChatAutoConfiguration.java | 2 +- .../BedrockCohereChatAutoConfiguration.java | 2 +- ...drockCohereEmbeddingAutoConfiguration.java | 2 +- ...ockAi21Jurassic2ChatAutoConfiguration.java | 2 +- .../BedrockLlama2ChatAutoConfiguration.java | 2 +- .../BedrockTitanChatAutoConfiguration.java | 2 +- ...edrockTitanEmbeddingAutoConfiguration.java | 2 +- 47 files changed, 391 insertions(+), 79 deletions(-) diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java index 324580a5f..2437b35ee 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.anthropic.api; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude; @@ -54,6 +55,16 @@ public class AnthropicChatBedrockApi extends super(modelId, region); } + /** + * Create a new AnthropicChatBedrockApi instance using the default credentials provider chain, the default object. + * @param modelId The model id to use. See the {@link AnthropicChatModel} for the supported models. + * @param region The AWS region to use. + * @param timeout The timeout to use. + */ + public AnthropicChatBedrockApi(String modelId, String region, Duration timeout) { + super(modelId, region, timeout); + } + /** * Create a new AnthropicChatBedrockApi instance using the provided credentials provider, region and object mapper. * @@ -67,6 +78,20 @@ public class AnthropicChatBedrockApi extends super(modelId, credentialsProvider, region, objectMapper); } + /** + * Create a new AnthropicChatBedrockApi instance using the provided credentials provider, region and object mapper. + * + * @param modelId The model id to use. See the {@link AnthropicChatModel} for the supported models. + * @param credentialsProvider The credentials provider to connect to AWS. + * @param region The AWS region to use. + * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout The timeout to use. + */ + public AnthropicChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + ObjectMapper objectMapper, Duration timeout) { + super(modelId, credentialsProvider, region, objectMapper, timeout); + } + // https://github.com/build-on-aws/amazon-bedrock-java-examples/blob/main/example_code/bedrock-runtime/src/main/java/aws/community/examples/InvokeBedrockStreamingAsync.java // https://docs.anthropic.com/claude/reference/complete_post diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic3/api/Anthropic3ChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic3/api/Anthropic3ChatBedrockApi.java index 28cbd25f2..e76bfcbef 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic3/api/Anthropic3ChatBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic3/api/Anthropic3ChatBedrockApi.java @@ -27,6 +27,7 @@ import org.springframework.util.Assert; import reactor.core.publisher.Flux; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; +import java.time.Duration; import java.util.List; /** @@ -58,6 +59,16 @@ public class Anthropic3ChatBedrockApi extends super(modelId, region); } + /** + * Create a new AnthropicChatBedrockApi instance using the default credentials provider chain, the default object. + * @param modelId The model id to use. See the {@link AnthropicChatModel} for the supported models. + * @param region The AWS region to use. + * @param timeout The timeout to use. + */ + public Anthropic3ChatBedrockApi(String modelId, String region, Duration timeout) { + super(modelId, region, timeout); + } + /** * Create a new AnthropicChatBedrockApi instance using the provided credentials provider, region and object mapper. * @@ -71,6 +82,20 @@ public class Anthropic3ChatBedrockApi extends super(modelId, credentialsProvider, region, objectMapper); } + /** + * Create a new AnthropicChatBedrockApi instance using the provided credentials provider, region and object mapper. + * + * @param modelId The model id to use. See the {@link AnthropicChatModel} for the supported models. + * @param credentialsProvider The credentials provider to connect to AWS. + * @param region The AWS region to use. + * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout The timeout to use. + */ + public Anthropic3ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + ObjectMapper objectMapper, Duration timeout) { + super(modelId, credentialsProvider, region, objectMapper, timeout); + } + // https://github.com/build-on-aws/amazon-bedrock-java-examples/blob/main/example_code/bedrock-runtime/src/main/java/aws/community/examples/InvokeBedrockStreamingAsync.java // https://docs.anthropic.com/claude/reference/complete_post @@ -307,10 +332,12 @@ public class Anthropic3ChatBedrockApi extends * @param usage Metrics about the model invocation. */ @JsonInclude(Include.NON_NULL) - public record AnthropicChatResponse(@JsonProperty("id") String id, @JsonProperty("model") String model, - @JsonProperty("type") String type, @JsonProperty("role") String role, - @JsonProperty("content") List content, @JsonProperty("stop_reason") String stopReason, - @JsonProperty("stop_sequence") String stopSequence, @JsonProperty("usage") AnthropicUsage usage) { + public record AnthropicChatResponse(// formatter:off + @JsonProperty("id") String id, @JsonProperty("model") String model, @JsonProperty("type") String type, + @JsonProperty("role") String role, @JsonProperty("content") List content, + @JsonProperty("stop_reason") String stopReason, @JsonProperty("stop_sequence") String stopSequence, + @JsonProperty("usage") AnthropicUsage usage, + @JsonProperty("amazon-bedrock-invocationMetrics") AmazonBedrockInvocationMetrics amazonBedrockInvocationMetrics) { // formatter:on } /** @@ -326,10 +353,11 @@ public class Anthropic3ChatBedrockApi extends * @param usage The usage data. */ @JsonInclude(Include.NON_NULL) - public record AnthropicChatStreamingResponse(@JsonProperty("type") StreamingType type, - @JsonProperty("message") AnthropicChatResponse message, @JsonProperty("index") Integer index, - @JsonProperty("content_block") MediaContent contentBlock, @JsonProperty("delta") Delta delta, - @JsonProperty("usage") AnthropicUsage usage) { + public record AnthropicChatStreamingResponse(// formatter:off + @JsonProperty("type") StreamingType type, @JsonProperty("message") AnthropicChatResponse message, + @JsonProperty("index") Integer index, @JsonProperty("content_block") MediaContent contentBlock, + @JsonProperty("delta") Delta delta, @JsonProperty("usage") AnthropicUsage usage, + @JsonProperty("amazon-bedrock-invocationMetrics") AmazonBedrockInvocationMetrics amazonBedrockInvocationMetrics) { // formatter:on /** * The streaming type of this message. diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java index 0618b6ef5..74f4249f0 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java @@ -24,7 +24,6 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,6 +43,9 @@ import software.amazon.awssdk.services.bedrockruntime.model.InvokeModelWithRespo import software.amazon.awssdk.services.bedrockruntime.model.InvokeModelWithResponseStreamResponseHandler; import software.amazon.awssdk.services.bedrockruntime.model.ResponseStream; +import org.springframework.ai.model.ModelOptionsUtils; +import org.springframework.util.Assert; + /** * Abstract class for the Bedrock API. It provides the basic functionality to invoke the chat completion model and * receive the response for streaming and non-streaming requests. @@ -67,7 +69,6 @@ public abstract class AbstractBedrockApi { private final String modelId; private final ObjectMapper objectMapper; - private final AwsCredentialsProvider credentialsProvider; private final String region; private final BedrockRuntimeClient client; private final BedrockRuntimeAsyncClient clientStreaming; @@ -79,10 +80,20 @@ public abstract class AbstractBedrockApi { * @param region The AWS region to use. */ public AbstractBedrockApi(String modelId, String region) { - this(modelId, ProfileCredentialsProvider.builder().build(), region, new ObjectMapper()); + this(modelId, ProfileCredentialsProvider.builder().build(), region, ModelOptionsUtils.OBJECT_MAPPER, Duration.ofMinutes(5)); + } + /** + * Create a new AbstractBedrockApi instance using default credentials provider and object mapper. + * + * @param modelId The model id to use. + * @param region The AWS region to use. + * @param timeout The timeout to use. + */ + public AbstractBedrockApi(String modelId, String region, Duration timeout) { + this(modelId, ProfileCredentialsProvider.builder().build(), region, ModelOptionsUtils.OBJECT_MAPPER, timeout); } - /** + /** * Create a new AbstractBedrockApi instance using the provided credentials provider, region and object mapper. * * @param modelId The model id to use. @@ -91,21 +102,44 @@ public abstract class AbstractBedrockApi { * @param objectMapper The object mapper to use for JSON serialization and deserialization. */ public AbstractBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, - ObjectMapper objectMapper) { + ObjectMapper objectMapper) { + this(modelId, credentialsProvider, region, objectMapper, Duration.ofMinutes(5)); + } + /** + * Create a new AbstractBedrockApi instance using the provided credentials provider, region and object mapper. + * + * @param modelId The model id to use. + * @param credentialsProvider The credentials provider to connect to AWS. + * @param region The AWS region to use. + * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout Configure the amount of time to allow the client to complete the execution of an API call. + * This timeout covers the entire client execution except for marshalling. This includes request handler execution, + * all HTTP requests including retries, unmarshalling, etc. This value should always be positive, if present. + */ + public AbstractBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + ObjectMapper objectMapper, Duration timeout) { + + Assert.hasText(modelId, "Model id must not be empty"); + Assert.notNull(credentialsProvider, "Credentials provider must not be null"); + Assert.hasText(region, "Region must not be empty"); + Assert.notNull(objectMapper, "Object mapper must not be null"); + Assert.notNull(timeout, "Timeout must not be null"); this.modelId = modelId; - this.objectMapper = objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - this.credentialsProvider = credentialsProvider; + this.objectMapper = objectMapper; this.region = region; + this.client = BedrockRuntimeClient.builder() .region(Region.of(this.region)) - .credentialsProvider(this.credentialsProvider) + .credentialsProvider(credentialsProvider) + .overrideConfiguration(c -> c.apiCallTimeout(timeout)) .build(); this.clientStreaming = BedrockRuntimeAsyncClient.builder() .region(Region.of(this.region)) - .credentialsProvider(this.credentialsProvider) + .credentialsProvider(credentialsProvider) + .overrideConfiguration(c -> c.apiCallTimeout(timeout)) .build(); } @@ -113,14 +147,14 @@ public abstract class AbstractBedrockApi { * @return The model id. */ public String getModelId() { - return modelId; + return this.modelId; } /** * @return The AWS region. */ public String getRegion() { - return region; + return this.region; } /** diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApi.java index cc9cc67e6..b3b02b699 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApi.java @@ -16,6 +16,7 @@ // @formatter:off package org.springframework.ai.bedrock.cohere.api; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude; @@ -64,6 +65,32 @@ public class CohereChatBedrockApi extends super(modelId, credentialsProvider, region, objectMapper); } + /** + * Create a new CohereChatBedrockApi instance using the default credentials provider chain, the default object + * mapper, default temperature and topP values. + * + * @param modelId The model id to use. See the {@link CohereChatModel} for the supported models. + * @param region The AWS region to use. + * @param timeout The timeout to use. + */ + public CohereChatBedrockApi(String modelId, String region, Duration timeout) { + super(modelId, region, timeout); + } + + /** + * Create a new CohereChatBedrockApi instance using the provided credentials provider, region and object mapper. + * + * @param modelId The model id to use. See the {@link CohereChatModel} for the supported models. + * @param credentialsProvider The credentials provider to connect to AWS. + * @param region The AWS region to use. + * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout The timeout to use. + */ + public CohereChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + ObjectMapper objectMapper, Duration timeout) { + super(modelId, credentialsProvider, region, objectMapper, timeout); + } + /** * CohereChatRequest encapsulates the request parameters for the Cohere command model. * diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java index 9bd928a4a..7d0fa442c 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java @@ -16,6 +16,7 @@ // @formatter:off package org.springframework.ai.bedrock.cohere.api; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude; @@ -63,6 +64,33 @@ public class CohereEmbeddingBedrockApi extends super(modelId, credentialsProvider, region, objectMapper); } + /** + * Create a new CohereEmbeddingBedrockApi instance using the default credentials provider chain, the default object + * mapper, default temperature and topP values. + * + * @param modelId The model id to use. See the {@link CohereEmbeddingModel} for the supported models. + * @param region The AWS region to use. + * @param timeout The timeout to use. + */ + public CohereEmbeddingBedrockApi(String modelId, String region, Duration timeout) { + super(modelId, region, timeout); + } + + /** + * Create a new CohereEmbeddingBedrockApi instance using the provided credentials provider, region and object + * mapper. + * + * @param modelId The model id to use. See the {@link CohereEmbeddingModel} for the supported models. + * @param credentialsProvider The credentials provider to connect to AWS. + * @param region The AWS region to use. + * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout The timeout to use. + */ + public CohereEmbeddingBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + ObjectMapper objectMapper, Duration timeout) { + super(modelId, credentialsProvider, region, objectMapper, timeout); + } + /** * The Cohere Embed model request. * @@ -140,6 +168,7 @@ public class CohereEmbeddingBedrockApi extends @JsonProperty("id") String id, @JsonProperty("embeddings") List> embeddings, @JsonProperty("texts") List texts, + @JsonProperty("response_type") String responseType, // For future use: Currently bedrock doesn't return invocationMetrics for the cohere embedding model. @JsonProperty("amazon-bedrock-invocationMetrics") AmazonBedrockInvocationMetrics amazonBedrockInvocationMetrics) { } diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java index 451dd2346..fa5051763 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java @@ -16,6 +16,7 @@ // @formatter:off package org.springframework.ai.bedrock.jurassic2.api; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude; @@ -64,6 +65,32 @@ public class Ai21Jurassic2ChatBedrockApi extends super(modelId, credentialsProvider, region, objectMapper); } + /** + * Create a new Ai21Jurassic2ChatBedrockApi instance using the default credentials provider chain, the default + * object mapper, default temperature and topP values. + * + * @param modelId The model id to use. See the {@link Ai21Jurassic2ChatModel} for the supported models. + * @param region The AWS region to use. + * @param timeout The timeout to use. + */ + public Ai21Jurassic2ChatBedrockApi(String modelId, String region, Duration timeout) { + super(modelId, region, timeout); + } + + + /** + * Create a new Ai21Jurassic2ChatBedrockApi instance. + * + * @param modelId The model id to use. See the {@link Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatModel} for the supported models. + * @param credentialsProvider The credentials provider to connect to AWS. + * @param region The AWS region to use. + * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout The timeout to use. + */ + public Ai21Jurassic2ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + ObjectMapper objectMapper, Duration timeout) { + super(modelId, credentialsProvider, region, objectMapper, timeout); + } /** * AI21 Jurassic2 chat request parameters. diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java index 3d631732a..af10d69bd 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java @@ -26,6 +26,8 @@ import org.springframework.ai.bedrock.api.AbstractBedrockApi; import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatRequest; import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatResponse; +import java.time.Duration; + // @formatter:off /** * Java client for the Bedrock Llama2 chat model. @@ -61,6 +63,32 @@ public class Llama2ChatBedrockApi extends super(modelId, credentialsProvider, region, objectMapper); } + /** + * Create a new Llama2ChatBedrockApi instance using the default credentials provider chain, the default object + * mapper, default temperature and topP values. + * + * @param modelId The model id to use. See the {@link Llama2ChatModel} for the supported models. + * @param region The AWS region to use. + * @param timeout The timeout to use. + */ + public Llama2ChatBedrockApi(String modelId, String region, Duration timeout) { + super(modelId, region, timeout); + } + + /** + * Create a new Llama2ChatBedrockApi instance using the provided credentials provider, region and object mapper. + * + * @param modelId The model id to use. See the {@link Llama2ChatModel} for the supported models. + * @param credentialsProvider The credentials provider to connect to AWS. + * @param region The AWS region to use. + * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout The timeout to use. + */ + public Llama2ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + ObjectMapper objectMapper, Duration timeout) { + super(modelId, credentialsProvider, region, objectMapper, timeout); + } + /** * Llama2ChatRequest encapsulates the request parameters for the Meta Llama2 chat model. * diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java index 988d52b2c..498b34bf3 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.titan.api; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude; @@ -43,6 +44,12 @@ import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi.TitanChatRes public class TitanChatBedrockApi extends AbstractBedrockApi { + /** + * Create a new TitanChatBedrockApi instance using the default credentials provider chain, the default object mapper. + * + * @param modelId The model id to use. See the {@link TitanChatModel} for the supported models. + * @param region The AWS region to use. + */ public TitanChatBedrockApi(String modelId, String region) { super(modelId, region); } @@ -60,6 +67,31 @@ public class TitanChatBedrockApi extends super(modelId, credentialsProvider, region, objectMapper); } + /** + * Create a new TitanChatBedrockApi instance using the default credentials provider chain, the default object mapper. + * + * @param modelId The model id to use. See the {@link TitanChatModel} for the supported models. + * @param region The AWS region to use. + * @param timeout The timeout to use. + */ + public TitanChatBedrockApi(String modelId, String region, Duration timeout) { + super(modelId, region, timeout); + } + + /** + * Create a new TitanChatBedrockApi instance using the provided credentials provider, region and object mapper. + * + * @param modelId The model id to use. See the {@link TitanChatModel} for the supported models. + * @param credentialsProvider The credentials provider to connect to AWS. + * @param region The AWS region to use. + * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout The timeout to use. + */ + public TitanChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + ObjectMapper objectMapper, Duration timeout) { + super(modelId, credentialsProvider, region, objectMapper, timeout); + } + /** * TitanChatRequest encapsulates the request parameters for the Titan chat model. * diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApi.java index 5f2db0072..9c1dcb3b2 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApi.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.titan.api; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude; @@ -44,9 +45,10 @@ public class TitanEmbeddingBedrockApi extends * mapper. * @param modelId The model id to use. See the {@link TitanEmbeddingModel} for the supported models. * @param region The AWS region to use. + * @param timeout The timeout to use. */ - public TitanEmbeddingBedrockApi(String modelId, String region) { - super(modelId, region); + public TitanEmbeddingBedrockApi(String modelId, String region, Duration timeout) { + super(modelId, region, timeout); } /** @@ -56,10 +58,11 @@ public class TitanEmbeddingBedrockApi extends * @param credentialsProvider The credentials provider to connect to AWS. * @param region The AWS region to use. * @param objectMapper The object mapper to use for JSON serialization and deserialization. + * @param timeout The timeout to use. */ public TitanEmbeddingBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, - ObjectMapper objectMapper) { - super(modelId, credentialsProvider, region, objectMapper); + ObjectMapper objectMapper, Duration timeout) { + super(modelId, credentialsProvider, region, objectMapper, timeout); } /** diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClientIT.java index 8935b47c0..9ec99a9db 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClientIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.anthropic; +import java.time.Duration; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -204,7 +205,8 @@ class BedrockAnthropicChatClientIT { @Bean public AnthropicChatBedrockApi anthropicApi() { return new AnthropicChatBedrockApi(AnthropicChatBedrockApi.AnthropicChatModel.CLAUDE_V2.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); } @Bean diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicCreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicCreateRequestTests.java index aea62fc48..928e183ad 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicCreateRequestTests.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicCreateRequestTests.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.anthropic; +import java.time.Duration; import java.util.List; import org.junit.jupiter.api.Test; @@ -32,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class BedrockAnthropicCreateRequestTests { private AnthropicChatBedrockApi anthropicChatApi = new AnthropicChatBedrockApi(AnthropicChatModel.CLAUDE_V2.id(), - Region.US_EAST_1.id()); + Region.US_EAST_1.id(), Duration.ofMillis(1000L)); @Test public void createRequestWithChatOptions() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApiIT.java index 11084c887..334efa48f 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApiIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.anthropic.api; +import java.time.Duration; import java.util.List; import java.util.stream.Collectors; @@ -43,7 +44,8 @@ public class AnthropicChatBedrockApiIT { private final Logger logger = LoggerFactory.getLogger(AnthropicChatBedrockApiIT.class); private AnthropicChatBedrockApi anthropicChatApi = new AnthropicChatBedrockApi(AnthropicChatModel.CLAUDE_V2.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_WEST_2.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); @Test public void chatCompletion() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3ChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3ChatClientIT.java index ed1af9804..c2050f18c 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3ChatClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3ChatClientIT.java @@ -49,6 +49,7 @@ import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsPro import software.amazon.awssdk.regions.Region; import java.io.IOException; +import java.time.Duration; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -223,7 +224,8 @@ class BedrockAnthropic3ChatClientIT { @Bean public Anthropic3ChatBedrockApi anthropicApi() { return new Anthropic3ChatBedrockApi(Anthropic3ChatBedrockApi.AnthropicChatModel.CLAUDE_V3_SONNET.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(5)); } @Bean diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3CreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3CreateRequestTests.java index 340c7a496..480f914c3 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3CreateRequestTests.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3CreateRequestTests.java @@ -21,6 +21,7 @@ import org.springframework.ai.bedrock.anthropic3.api.Anthropic3ChatBedrockApi.An import org.springframework.ai.chat.prompt.Prompt; import software.amazon.awssdk.regions.Region; +import java.time.Duration; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -31,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class BedrockAnthropic3CreateRequestTests { private Anthropic3ChatBedrockApi anthropicChatApi = new Anthropic3ChatBedrockApi(AnthropicChatModel.CLAUDE_V2.id(), - Region.EU_CENTRAL_1.id()); + Region.EU_CENTRAL_1.id(), Duration.ofMillis(1000L)); @Test public void createRequestWithChatOptions() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/api/Anthropic3ChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/api/Anthropic3ChatBedrockApiIT.java index dfd05da64..15ab3dd0f 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/api/Anthropic3ChatBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/api/Anthropic3ChatBedrockApiIT.java @@ -31,6 +31,7 @@ import reactor.core.publisher.Flux; import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.regions.Region; +import java.time.Duration; import java.util.List; import java.util.stream.Collectors; @@ -48,7 +49,7 @@ public class Anthropic3ChatBedrockApiIT { private Anthropic3ChatBedrockApi anthropicChatApi = new Anthropic3ChatBedrockApi( AnthropicChatModel.CLAUDE_INSTANT_V1.id(), EnvironmentVariableCredentialsProvider.create(), - Region.US_EAST_1.id(), new ObjectMapper()); + Region.US_EAST_1.id(), new ObjectMapper(), Duration.ofMinutes(2)); @Test public void chatCompletion() { @@ -64,7 +65,8 @@ public class Anthropic3ChatBedrockApiIT { AnthropicChatResponse response = anthropicChatApi.chatCompletion(request); - System.out.println(response.content()); + logger.info("" + response.content()); + assertThat(response).isNotNull(); assertThat(response.content().get(0).text()).isNotEmpty(); assertThat(response.content().get(0).text()).contains("Blackbeard"); @@ -103,7 +105,7 @@ public class Anthropic3ChatBedrockApiIT { AnthropicChatResponse response = anthropicChatApi.chatCompletion(request); - System.out.println(response.content()); + logger.info("" + response.content()); assertThat(response).isNotNull(); assertThat(response.content().get(0).text()).isNotEmpty(); assertThat(response.content().get(0).text()).contains("Blackbeard"); diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClientIT.java index f352ed456..95c700685 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClientIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.cohere; +import java.time.Duration; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -200,7 +201,8 @@ class BedrockCohereChatClientIT { @Bean public CohereChatBedrockApi cohereApi() { return new CohereChatBedrockApi(CohereChatModel.COHERE_COMMAND_V14.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); } @Bean diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatCreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatCreateRequestTests.java index 4eafef9ef..661c19e32 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatCreateRequestTests.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatCreateRequestTests.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.cohere; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; @@ -38,7 +39,8 @@ import static org.assertj.core.api.Assertions.assertThat; public class BedrockCohereChatCreateRequestTests { private CohereChatBedrockApi chatApi = new CohereChatBedrockApi(CohereChatModel.COHERE_COMMAND_V14.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); @Test public void createRequestWithChatOptions() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClientIT.java index 9dda3870c..1dab72ce3 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClientIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.cohere; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; @@ -87,7 +88,8 @@ class BedrockCohereEmbeddingClientIT { @Bean public CohereEmbeddingBedrockApi cohereEmbeddingApi() { return new CohereEmbeddingBedrockApi(CohereEmbeddingModel.COHERE_EMBED_MULTILINGUAL_V1.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); } @Bean diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApiIT.java index d56e7beb6..540a6bd2b 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApiIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.cohere.api; +import java.time.Duration; import java.util.List; import org.junit.jupiter.api.Test; @@ -39,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;; public class CohereChatBedrockApiIT { private CohereChatBedrockApi cohereChatApi = new CohereChatBedrockApi(CohereChatModel.COHERE_COMMAND_V14.id(), - Region.US_EAST_1.id()); + Region.US_EAST_1.id(), Duration.ofMinutes(2)); @Test public void requestBuilder() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApiIT.java index 721c78783..f96269fed 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApiIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.cohere.api; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; @@ -38,7 +39,7 @@ public class CohereEmbeddingBedrockApiIT { CohereEmbeddingBedrockApi api = new CohereEmbeddingBedrockApi( CohereEmbeddingModel.COHERE_EMBED_MULTILINGUAL_V1.id(), EnvironmentVariableCredentialsProvider.create(), - Region.US_EAST_1.id(), new ObjectMapper()); + Region.US_EAST_1.id(), new ObjectMapper(), Duration.ofMinutes(2)); @Test public void embedText() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApiIT.java index 6b58cb772..8525471d1 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApiIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.jurassic2.api; +import java.time.Duration; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; @@ -35,7 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class Ai21Jurassic2ChatBedrockApiIT { Ai21Jurassic2ChatBedrockApi api = new Ai21Jurassic2ChatBedrockApi(Ai21Jurassic2ChatModel.AI21_J2_ULTRA_V1.id(), - Region.US_EAST_1.id()); + Region.US_EAST_1.id(), Duration.ofMinutes(2)); @Test public void chatCompletion() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/BedrockAi21Jurassic2ChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/BedrockAi21Jurassic2ChatClientIT.java index 076eb3e68..0fca363d7 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/BedrockAi21Jurassic2ChatClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/BedrockAi21Jurassic2ChatClientIT.java @@ -39,6 +39,7 @@ import org.springframework.core.io.Resource; import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.regions.Region; +import java.time.Duration; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -146,7 +147,8 @@ class BedrockAi21Jurassic2ChatClientIT { public Ai21Jurassic2ChatBedrockApi jurassic2ChatBedrockApi() { return new Ai21Jurassic2ChatBedrockApi( Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatModel.AI21_J2_MID_V1.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); } @Bean diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java index 09864c76a..7cbf3f235 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.llama2; +import java.time.Duration; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -205,7 +206,8 @@ class BedrockLlama2ChatClientIT { @Bean public Llama2ChatBedrockApi llama2Api() { return new Llama2ChatBedrockApi(Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); } @Bean diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java index 876f3a303..1a3329016 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java @@ -24,6 +24,8 @@ import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi; import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatModel; import org.springframework.ai.chat.prompt.Prompt; +import java.time.Duration; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -32,7 +34,8 @@ import static org.assertj.core.api.Assertions.assertThat; public class BedrockLlama2CreateRequestTests { private Llama2ChatBedrockApi api = new Llama2ChatBedrockApi(Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); @Test public void createRequestWithChatOptions() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java index 19acc1d0f..dc97d8e7b 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.llama2.api; +import java.time.Duration; import java.util.List; import org.junit.jupiter.api.Test; @@ -36,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class Llama2ChatBedrockApiIT { private Llama2ChatBedrockApi llama2ChatApi = new Llama2ChatBedrockApi(Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), - Region.US_EAST_1.id()); + Region.US_EAST_1.id(), Duration.ofMinutes(2)); @Test public void chatCompletion() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClientIT.java index d8a04dd7f..f3a523be2 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClientIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.titan; +import java.time.Duration; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -206,7 +207,8 @@ class BedrockTitanChatClientIT { @Bean public TitanChatBedrockApi titanApi() { return new TitanChatBedrockApi(TitanChatModel.TITAN_TEXT_EXPRESS_V1.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); } @Bean diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatCreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatCreateRequestTests.java index b7907c11b..5f8065bc3 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatCreateRequestTests.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatCreateRequestTests.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.titan; +import java.time.Duration; import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; @@ -34,7 +35,8 @@ import static org.assertj.core.api.Assertions.assertThat; public class BedrockTitanChatCreateRequestTests { private TitanChatBedrockApi api = new TitanChatBedrockApi(TitanChatModel.TITAN_TEXT_EXPRESS_V1.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); @Test public void createRequestWithChatOptions() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClientIT.java index e6253e2db..dead75901 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClientIT.java @@ -16,6 +16,7 @@ package org.springframework.ai.bedrock.titan; import java.io.IOException; +import java.time.Duration; import java.util.Base64; import java.util.List; @@ -69,7 +70,8 @@ class BedrockTitanEmbeddingClientIT { @Bean public TitanEmbeddingBedrockApi titanEmbeddingApi() { - return new TitanEmbeddingBedrockApi(TitanEmbeddingModel.TITAN_EMBED_IMAGE_V1.id(), Region.US_EAST_1.id()); + return new TitanEmbeddingBedrockApi(TitanEmbeddingModel.TITAN_EMBED_IMAGE_V1.id(), Region.US_EAST_1.id(), + Duration.ofMinutes(2)); } @Bean diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApiIT.java index c60ce5dfc..e7bb1f8bf 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApiIT.java @@ -15,6 +15,7 @@ */ package org.springframework.ai.bedrock.titan.api; +import java.time.Duration; import java.util.List; import java.util.stream.Collectors; @@ -38,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class TitanChatBedrockApiIT { TitanChatBedrockApi titanBedrockApi = new TitanChatBedrockApi(TitanChatModel.TITAN_TEXT_EXPRESS_V1.id(), - Region.EU_CENTRAL_1.id()); + Region.EU_CENTRAL_1.id(), Duration.ofMinutes(2)); TitanChatRequest titanChatRequest = TitanChatRequest.builder("Give me the names of 3 famous pirates?") .withTemperature(0.5f) diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApiIT.java index 4595e6edf..a666793e0 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApiIT.java @@ -16,6 +16,7 @@ package org.springframework.ai.bedrock.titan.api; import java.io.IOException; +import java.time.Duration; import java.util.Base64; import org.junit.jupiter.api.Test; @@ -40,7 +41,7 @@ public class TitanEmbeddingBedrockApiIT { public void embedText() { TitanEmbeddingBedrockApi titanEmbedApi = new TitanEmbeddingBedrockApi( - TitanEmbeddingModel.TITAN_EMBED_TEXT_V1.id(), Region.US_EAST_1.id()); + TitanEmbeddingModel.TITAN_EMBED_TEXT_V1.id(), Region.US_EAST_1.id(), Duration.ofMinutes(2)); TitanEmbeddingRequest request = TitanEmbeddingRequest.builder().withInputText("I like to eat apples.").build(); @@ -55,7 +56,7 @@ public class TitanEmbeddingBedrockApiIT { public void embedImage() throws IOException { TitanEmbeddingBedrockApi titanEmbedApi = new TitanEmbeddingBedrockApi( - TitanEmbeddingModel.TITAN_EMBED_IMAGE_V1.id(), Region.US_EAST_1.id()); + TitanEmbeddingModel.TITAN_EMBED_IMAGE_V1.id(), Region.US_EAST_1.id(), Duration.ofMinutes(2)); byte[] image = new DefaultResourceLoader().getResource("classpath:/spring_framework.png") .getContentAsByteArray(); diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java index 458445fc9..bb48320b6 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java @@ -59,7 +59,7 @@ import org.springframework.util.CollectionUtils; */ public final class ModelOptionsUtils { - private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper() + public final static ObjectMapper OBJECT_MAPPER = new ObjectMapper() .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) .registerModule(new JavaTimeModule()); diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc index 45fa5dc5e..4da2b06f7 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc @@ -47,6 +47,8 @@ spring.ai.bedrock.aws.region=us-east-1 spring.ai.bedrock.aws.access-key=YOUR_ACCESS_KEY spring.ai.bedrock.aws.secret-key=YOUR_SECRET_KEY + +spring.ai.bedrock.aws.timeout=10m ---- The `region` property is compulsory. @@ -74,7 +76,8 @@ Here are the supported `` and `` combinations: | llama2 | Yes | Yes | No | jurassic2 | Yes | No | No | cohere | Yes | Yes | Yes -| anthropic | Yes | Yes | No +| anthropic 2 | Yes | Yes | No +| anthropic 3 | Yes | Yes | No | jurassic2 (WIP) | Yes | No | No | titan | Yes | Yes | Yes (however, no batch support) |==== @@ -85,13 +88,11 @@ Next, you can use the `spring.ai.bedrock...*` properties For more information, refer to the documentation below for each supported model. -* xref:api/chat/bedrock/bedrock-anthropic.adoc[Spring AI Bedrock Anthropic Chat]: `spring.ai.bedrock.anthropic.chat.enabled=true` +* xref:api/chat/bedrock/bedrock-anthropic.adoc[Spring AI Bedrock Anthropic 2 Chat]: `spring.ai.bedrock.anthropic.chat.enabled=true` +* xref:api/chat/bedrock/bedrock-anthropic3.adoc[Spring AI Bedrock Anthropic 3 Chat]: `spring.ai.bedrock.anthropic.chat.enabled=true` * xref:api/chat/bedrock/bedrock-llama2.adoc[Spring AI Bedrock Llama2 Chat]: `spring.ai.bedrock.llama2.chat.enabled=true` * xref:api/chat/bedrock/bedrock-cohere.adoc[Spring AI Bedrock Cohere Chat]: `spring.ai.bedrock.cohere.chat.enabled=true` * xref:api/embeddings/bedrock-cohere-embedding.adoc[Spring AI Bedrock Cohere Embeddings]: `spring.ai.bedrock.cohere.embedding.enabled=true` * xref:api/chat/bedrock/bedrock-titan.adoc[Spring AI Bedrock Titan Chat]: `spring.ai.bedrock.titan.chat.enabled=true` * xref:api/embeddings/bedrock-titan-embedding.adoc[Spring AI Bedrock Titan Embeddings]: `spring.ai.bedrock.titan.embedding.enabled=true` * xref:api/chat/bedrock/bedrock-jurassic2.adoc[Spring AI Bedrock Ai21 Jurassic2 Chat]: `spring.ai.bedrock.jurassic2.chat.enabled=true` - - -// * xref:api/chat/bedrock/bedrock-jurassic2-chat.adoc[(WIP)Spring AI Bedrock Jurassic Chat]: `spring.ai.bedrock.jurassic2.chat.enabled=true` diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic.adoc index 43b424d28..806b5d9eb 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic.adoc @@ -68,7 +68,8 @@ The prefix `spring.ai.bedrock.aws` is the property prefix to configure the conne |==== | Property | Description | Default -| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.timeout | AWS timeout to use. | 5m | spring.ai.bedrock.aws.access-key | AWS access key. | - | spring.ai.bedrock.aws.secret-key | AWS secret key. | - |==== @@ -126,6 +127,7 @@ Add a `application.properties` file, under the `src/main/resources` directory, t [source] ---- spring.ai.bedrock.aws.region=eu-central-1 +spring.ai.bedrock.aws.timeout=1000ms spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID} spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY} @@ -197,7 +199,8 @@ AnthropicChatBedrockApi anthropicApi = new AnthropicChatBedrockApi( AnthropicChatBedrockApi.AnthropicModel.CLAUDE_V2.id(), EnvironmentVariableCredentialsProvider.create(), Region.EU_CENTRAL_1.id(), - new ObjectMapper()); + new ObjectMapper(), + Duration.ofMillis(1000L)); BedrockAnthropicChatClient chatClient = new BedrockAnthropicChatClient(anthropicApi, AnthropicChatOptions.builder() @@ -231,7 +234,7 @@ Here is a simple snippet how to use the api programmatically: [source,java] ---- AnthropicChatBedrockApi anthropicChatApi = new AnthropicChatBedrockApi( - AnthropicModel.CLAUDE_V2.id(), Region.EU_CENTRAL_1.id()); + AnthropicModel.CLAUDE_V2.id(), Region.EU_CENTRAL_1.id(), Duration.ofMillis(1000L)); AnthropicChatRequest request = AnthropicChatRequest .builder(String.format(AnthropicChatBedrockApi.PROMPT_TEMPLATE, "Name 3 famous pirates")) diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic3.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic3.adoc index 583232787..c0d5f516d 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic3.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic3.adoc @@ -65,7 +65,8 @@ The prefix `spring.ai.bedrock.aws` is the property prefix to configure the conne |==== | Property | Description | Default -| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.timeout | AWS timeout to use. | 5m | spring.ai.bedrock.aws.access-key | AWS access key. | - | spring.ai.bedrock.aws.secret-key | AWS secret key. | - |==== @@ -167,6 +168,7 @@ Add a `application.properties` file, under the `src/main/resources` directory, t [source] ---- spring.ai.bedrock.aws.region=eu-central-1 +spring.ai.bedrock.aws.timeout=1000ms spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID} spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY} @@ -238,7 +240,8 @@ Anthropic3ChatBedrockApi anthropicApi = new Anthropic3ChatBedrockApi( AnthropicChatBedrockApi.AnthropicModel.CLAUDE_V3_SONNET.id(), EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), - new ObjectMapper()); + new ObjectMapper(), + Duration.ofMillis(1000L)); BedrockAnthropic3ChatClient chatClient = new BedrockAnthropic3ChatClient(anthropicApi, AnthropicChatOptions.builder() @@ -268,7 +271,7 @@ Here is a simple snippet how to use the api programmatically: [source,java] ---- Anthropic3ChatBedrockApi anthropicChatApi = new Anthropic3ChatBedrockApi( - AnthropicModel.CLAUDE_V2.id(), Region.EU_CENTRAL_1.id()); + AnthropicModel.CLAUDE_V2.id(), Region.EU_CENTRAL_1.id(), Duration.ofMillis(1000L)); AnthropicChatRequest request = AnthropicChatRequest .builder(String.format(Anthropic3ChatBedrockApi.PROMPT_TEMPLATE, "Name 3 famous pirates")) diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-cohere.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-cohere.adoc index c24d251c7..9f0c53592 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-cohere.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-cohere.adoc @@ -58,7 +58,8 @@ The prefix `spring.ai.bedrock.aws` is the property prefix to configure the conne |==== | Property | Description | Default -| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.timeout | AWS timeout to use. | 5m | spring.ai.bedrock.aws.access-key | AWS access key. | - | spring.ai.bedrock.aws.secret-key | AWS secret key. | - |==== @@ -119,6 +120,7 @@ Add a `application.properties` file, under the `src/main/resources` directory, t [source] ---- spring.ai.bedrock.aws.region=eu-central-1 +spring.ai.bedrock.aws.timeout=1000ms spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID} spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY} @@ -186,7 +188,10 @@ Next, create an https://github.com/spring-projects/spring-ai/blob/main/models/sp [source,java] ---- CohereChatBedrockApi api = new CohereChatBedrockApi(CohereChatModel.COHERE_COMMAND_V14.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), + Region.US_EAST_1.id(), + new ObjectMapper(), + Duration.ofMillis(1000L)); BedrockCohereChatClient chatClient = new BedrockCohereChatClient(api, BedrockCohereChatOptions.builder() @@ -220,7 +225,8 @@ Here is a simple snippet how to use the api programmatically: ---- CohereChatBedrockApi cohereChatApi = new CohereChatBedrockApi( CohereChatModel.COHERE_COMMAND_V14.id(), - Region.US_EAST_1.id()); + Region.US_EAST_1.id(), + Duration.ofMillis(1000L)); var request = CohereChatRequest .builder("What is the capital of Bulgaria and what is the size? What it the national anthem?") diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-jurassic2.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-jurassic2.adoc index f61756327..cf7a083de 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-jurassic2.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-jurassic2.adoc @@ -57,7 +57,8 @@ The prefix `spring.ai.bedrock.aws` is the property prefix to configure the conne |==== | Property | Description | Default -| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.timeout | AWS timeout to use. | 5m | spring.ai.bedrock.aws.access-key | AWS access key. | - | spring.ai.bedrock.aws.secret-key | AWS secret key. | - |==== @@ -112,6 +113,7 @@ Add a `application.properties` file, under the `src/main/resources` directory, t [source] ---- spring.ai.bedrock.aws.region=eu-central-1 +spring.ai.bedrock.aws.timeout=1000ms spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID} spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY} @@ -174,7 +176,10 @@ Next, create an https://github.com/spring-projects/spring-ai/blob/main/models/sp [source,java] ---- Ai21Jurassic2ChatBedrockApi api = new Ai21Jurassic2ChatBedrockApi(Ai21Jurassic2ChatModel.AI21_J2_MID_V1.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), + Region.US_EAST_1.id(), + new ObjectMapper(), + Duration.ofMillis(1000L)); BedrockAi21Jurassic2ChatClient chatClient = new BedrockAi21Jurassic2ChatClient(api, BedrockAi21Jurassic2ChatOptions.builder() @@ -200,7 +205,8 @@ Here is a simple snippet on how to use the API programmatically: ---- Ai21Jurassic2ChatBedrockApi jurassic2ChatApi = new Ai21Jurassic2ChatBedrockApi( Ai21Jurassic2ChatModel.AI21_J2_MID_V1.id(), - Region.US_EAST_1.id()); + Region.US_EAST_1.id(), + Duration.ofMillis(1000L)); Ai21Jurassic2ChatRequest request = Ai21Jurassic2ChatRequest.builder("Hello, my name is") .withTemperature(0.9f) diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc index 8b317cd4e..7f891e394 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc @@ -62,7 +62,8 @@ The prefix `spring.ai.bedrock.aws` is the property prefix to configure the conne |==== | Property | Description | Default -| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.timeout | AWS timeout to use. | 5m | spring.ai.bedrock.aws.access-key | AWS access key. | - | spring.ai.bedrock.aws.secret-key | AWS secret key. | - |==== @@ -117,6 +118,7 @@ Add a `application.properties` file, under the `src/main/resources` directory, t [source] ---- spring.ai.bedrock.aws.region=eu-central-1 +spring.ai.bedrock.aws.timeout=1000ms spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID} spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY} @@ -184,7 +186,10 @@ Next, create an https://github.com/spring-projects/spring-ai/blob/main/models/sp [source,java] ---- Llama2ChatBedrockApi api = new Llama2ChatBedrockApi(Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), - EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper()); + EnvironmentVariableCredentialsProvider.create(), + Region.US_EAST_1.id(), + new ObjectMapper(), + Duration.ofMillis(1000L)); BedrockLlama2ChatClient chatClient = new BedrockLlama2ChatClient(api, BedrockLlama2ChatOptions.builder() @@ -216,7 +221,8 @@ Here is a simple snippet how to use the api programmatically: ---- Llama2ChatBedrockApi llama2ChatApi = new Llama2ChatBedrockApi( Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), - Region.US_EAST_1.id()); + Region.US_EAST_1.id(), + Duration.ofMillis(1000L)); Llama2ChatRequest request = Llama2ChatRequest.builder("Hello, my name is") .withTemperature(0.9f) diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-titan.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-titan.adoc index 31f54dd5f..728d3b1e1 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-titan.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-titan.adoc @@ -59,7 +59,8 @@ The prefix `spring.ai.bedrock.aws` is the property prefix to configure the conne |==== | Property | Description | Default -| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1 +| spring.ai.bedrock.aws.timeout | AWS timeout to use. | 5m | spring.ai.bedrock.aws.access-key | AWS access key. | - | spring.ai.bedrock.aws.secret-key | AWS secret key. | - |==== @@ -115,6 +116,7 @@ Add a `application.properties` file, under the `src/main/resources` directory, t [source] ---- spring.ai.bedrock.aws.region=eu-central-1 +spring.ai.bedrock.aws.timeout=1000ms spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID} spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY} @@ -184,7 +186,9 @@ Next, create an https://github.com/spring-projects/spring-ai/blob/main/models/sp TitanChatBedrockApi titanApi = new TitanChatBedrockApi( TitanChatModel.TITAN_TEXT_EXPRESS_V1.id(), EnvironmentVariableCredentialsProvider.create(), - Region.US_EAST_1.id(), new ObjectMapper()); + Region.US_EAST_1.id(), + new ObjectMapper(), + Duration.ofMillis(1000L)); BedrockTitanChatClient chatClient = new BedrockTitanChatClient(titanApi, BedrockTitanChatOptions.builder() @@ -216,7 +220,7 @@ Here is a simple snippet how to use the api programmatically: [source,java] ---- TitanChatBedrockApi titanBedrockApi = new TitanChatBedrockApi(TitanChatCompletionModel.TITAN_TEXT_EXPRESS_V1.id(), - Region.EU_CENTRAL_1.id()); + Region.EU_CENTRAL_1.id(), Duration.ofMillis(1000L)); TitanChatRequest titanChatRequest = TitanChatRequest.builder("Give me the names of 3 famous pirates?") .withTemperature(0.5f) diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionProperties.java index 334cb53cc..da8d3f34f 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionProperties.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionProperties.java @@ -17,6 +17,8 @@ package org.springframework.ai.autoconfigure.bedrock; import org.springframework.boot.context.properties.ConfigurationProperties; +import java.time.Duration; + /** * Configuration properties for Bedrock AWS connection. * @@ -43,6 +45,11 @@ public class BedrockAwsConnectionProperties { */ private String secretKey; + /** + * Set model timeout, Defaults 5 min. + */ + private Duration timeout = Duration.ofMinutes(5L); + public String getRegion() { return region; } @@ -67,4 +74,12 @@ public class BedrockAwsConnectionProperties { this.secretKey = secretKey; } + public Duration getTimeout() { + return timeout; + } + + public void setTimeout(Duration timeout) { + this.timeout = timeout; + } + } diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfiguration.java index d573ab0a5..9a74161b0 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfiguration.java @@ -49,7 +49,7 @@ public class BedrockAnthropicChatAutoConfiguration { public AnthropicChatBedrockApi anthropicApi(AwsCredentialsProvider credentialsProvider, BedrockAnthropicChatProperties properties, BedrockAwsConnectionProperties awsProperties) { return new AnthropicChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(), - new ObjectMapper()); + new ObjectMapper(), awsProperties.getTimeout()); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic3/BedrockAnthropic3ChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic3/BedrockAnthropic3ChatAutoConfiguration.java index ae06251fa..31f18597c 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic3/BedrockAnthropic3ChatAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic3/BedrockAnthropic3ChatAutoConfiguration.java @@ -49,7 +49,7 @@ public class BedrockAnthropic3ChatAutoConfiguration { public Anthropic3ChatBedrockApi anthropicApi(AwsCredentialsProvider credentialsProvider, BedrockAnthropic3ChatProperties properties, BedrockAwsConnectionProperties awsProperties) { return new Anthropic3ChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(), - new ObjectMapper()); + new ObjectMapper(), awsProperties.getTimeout()); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfiguration.java index 32c94dff4..3ee34f90f 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfiguration.java @@ -47,7 +47,7 @@ public class BedrockCohereChatAutoConfiguration { public CohereChatBedrockApi cohereChatApi(AwsCredentialsProvider credentialsProvider, BedrockCohereChatProperties properties, BedrockAwsConnectionProperties awsProperties) { return new CohereChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(), - new ObjectMapper()); + new ObjectMapper(), awsProperties.getTimeout()); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfiguration.java index 7412eb2ae..95ecba888 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfiguration.java @@ -48,7 +48,7 @@ public class BedrockCohereEmbeddingAutoConfiguration { public CohereEmbeddingBedrockApi cohereEmbeddingApi(AwsCredentialsProvider credentialsProvider, BedrockCohereEmbeddingProperties properties, BedrockAwsConnectionProperties awsProperties) { return new CohereEmbeddingBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(), - new ObjectMapper()); + new ObjectMapper(), awsProperties.getTimeout()); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatAutoConfiguration.java index 75cd6962d..f7c506572 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatAutoConfiguration.java @@ -49,7 +49,7 @@ public class BedrockAi21Jurassic2ChatAutoConfiguration { public Ai21Jurassic2ChatBedrockApi ai21Jurassic2ChatBedrockApi(AwsCredentialsProvider credentialsProvider, BedrockAi21Jurassic2ChatProperties properties, BedrockAwsConnectionProperties awsProperties) { return new Ai21Jurassic2ChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(), - new ObjectMapper()); + new ObjectMapper(), awsProperties.getTimeout()); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java index b40b7f8a3..314e3671b 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java @@ -50,7 +50,7 @@ public class BedrockLlama2ChatAutoConfiguration { public Llama2ChatBedrockApi llama2Api(AwsCredentialsProvider credentialsProvider, BedrockLlama2ChatProperties properties, BedrockAwsConnectionProperties awsProperties) { return new Llama2ChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(), - new ObjectMapper()); + new ObjectMapper(), awsProperties.getTimeout()); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfiguration.java index c1415d218..e24ec3696 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfiguration.java @@ -48,7 +48,7 @@ public class BedrockTitanChatAutoConfiguration { BedrockTitanChatProperties properties, BedrockAwsConnectionProperties awsProperties) { return new TitanChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(), - new ObjectMapper()); + new ObjectMapper(), awsProperties.getTimeout()); } @Bean diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfiguration.java index d3c08b35b..f36c6e427 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfiguration.java @@ -48,7 +48,7 @@ public class BedrockTitanEmbeddingAutoConfiguration { public TitanEmbeddingBedrockApi titanEmbeddingBedrockApi(AwsCredentialsProvider credentialsProvider, BedrockTitanEmbeddingProperties properties, BedrockAwsConnectionProperties awsProperties) { return new TitanEmbeddingBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(), - new ObjectMapper()); + new ObjectMapper(), awsProperties.getTimeout()); } @Bean