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 2437b35eebb..55a2d80af50 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
@@ -24,6 +24,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.core.publisher.Flux;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi.AnthropicChatRequest;
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi.AnthropicChatResponse;
@@ -32,6 +33,7 @@
/**
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
// @formatter:off
@@ -92,6 +94,20 @@ public AnthropicChatBedrockApi(String modelId, AwsCredentialsProvider credential
super(modelId, credentialsProvider, region, objectMapper, timeout);
}
+ /**
+ * 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, Region 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 983894267ff..0148b498373 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
@@ -26,6 +26,7 @@
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
import java.time.Duration;
import java.util.List;
@@ -39,6 +40,7 @@
*
* @author Ben Middleton
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 1.0.0
*/
// @formatter:off
@@ -96,6 +98,20 @@ public Anthropic3ChatBedrockApi(String modelId, AwsCredentialsProvider credentia
super(modelId, credentialsProvider, region, objectMapper, timeout);
}
+ /**
+ * 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, Region 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/api/AbstractBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java
index 74f4249f04f..17e0eed79b7 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
@@ -61,6 +61,7 @@
* @see Model Parameters
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
public abstract class AbstractBedrockApi {
@@ -69,7 +70,7 @@ public abstract class AbstractBedrockApi {
private final String modelId;
private final ObjectMapper objectMapper;
- private final String region;
+ private final Region region;
private final BedrockRuntimeClient client;
private final BedrockRuntimeAsyncClient clientStreaming;
@@ -93,7 +94,7 @@ 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.
@@ -105,6 +106,7 @@ public AbstractBedrockApi(String modelId, AwsCredentialsProvider credentialsProv
ObjectMapper objectMapper) {
this(modelId, credentialsProvider, region, objectMapper, Duration.ofMinutes(5));
}
+
/**
* Create a new AbstractBedrockApi instance using the provided credentials provider, region and object mapper.
*
@@ -118,10 +120,26 @@ public AbstractBedrockApi(String modelId, AwsCredentialsProvider credentialsProv
*/
public AbstractBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region,
ObjectMapper objectMapper, Duration timeout) {
+ this(modelId, credentialsProvider, Region.of(region), objectMapper, timeout);
+ }
+
+ /**
+ * 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, Region 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(region, "Region must not be empty");
Assert.notNull(objectMapper, "Object mapper must not be null");
Assert.notNull(timeout, "Timeout must not be null");
@@ -131,13 +149,13 @@ public AbstractBedrockApi(String modelId, AwsCredentialsProvider credentialsProv
this.client = BedrockRuntimeClient.builder()
- .region(Region.of(this.region))
+ .region(this.region)
.credentialsProvider(credentialsProvider)
.overrideConfiguration(c -> c.apiCallTimeout(timeout))
.build();
this.clientStreaming = BedrockRuntimeAsyncClient.builder()
- .region(Region.of(this.region))
+ .region(this.region)
.credentialsProvider(credentialsProvider)
.overrideConfiguration(c -> c.apiCallTimeout(timeout))
.build();
@@ -153,7 +171,7 @@ public String getModelId() {
/**
* @return The AWS region.
*/
- public String getRegion() {
+ public Region getRegion() {
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 b3b02b6993f..5b133a9976c 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
@@ -25,6 +25,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.core.publisher.Flux;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
import org.springframework.ai.bedrock.api.AbstractBedrockApi;
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi.CohereChatRequest;
@@ -36,6 +37,7 @@
* https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-cohere.html
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
public class CohereChatBedrockApi extends
@@ -91,6 +93,20 @@ public CohereChatBedrockApi(String modelId, AwsCredentialsProvider credentialsPr
super(modelId, credentialsProvider, region, objectMapper, 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, Region 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 7d0fa442cde..13752cc4486 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
@@ -24,6 +24,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
import org.springframework.ai.bedrock.api.AbstractBedrockApi;
import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi.CohereEmbeddingRequest;
@@ -34,6 +35,7 @@
* https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-cohere.html#model-parameters-embed
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
public class CohereEmbeddingBedrockApi extends
@@ -91,6 +93,21 @@ public CohereEmbeddingBedrockApi(String modelId, AwsCredentialsProvider credenti
super(modelId, credentialsProvider, region, objectMapper, 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, Region region,
+ ObjectMapper objectMapper, Duration timeout) {
+ super(modelId, credentialsProvider, region, objectMapper, timeout);
+ }
+
/**
* The Cohere Embed model request.
*
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 fa505176350..0ec58c8bd2c 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
@@ -29,12 +29,14 @@
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatResponse;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
/**
* Java client for the Bedrock Jurassic2 chat model.
* https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-jurassic2.html
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
public class Ai21Jurassic2ChatBedrockApi extends
@@ -92,6 +94,20 @@ public Ai21Jurassic2ChatBedrockApi(String modelId, AwsCredentialsProvider creden
super(modelId, credentialsProvider, region, objectMapper, 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, Region 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 af10d69bdfb..390ad28fffe 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
@@ -21,6 +21,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.core.publisher.Flux;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
import org.springframework.ai.bedrock.api.AbstractBedrockApi;
import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatRequest;
@@ -34,6 +35,7 @@
* https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-meta.html
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
public class Llama2ChatBedrockApi extends
@@ -89,6 +91,20 @@ public Llama2ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsPr
super(modelId, credentialsProvider, region, objectMapper, 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, Region 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 498b34bf3d8..f4a219a8d99 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
@@ -24,6 +24,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.core.publisher.Flux;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
import org.springframework.ai.bedrock.api.AbstractBedrockApi;
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi.TitanChatRequest;
@@ -38,6 +39,7 @@
* https://docs.aws.amazon.com/bedrock/latest/userguide/titan-text-models.html
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
// @formatter:off
@@ -92,6 +94,20 @@ public TitanChatBedrockApi(String modelId, AwsCredentialsProvider credentialsPro
super(modelId, credentialsProvider, region, objectMapper, 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, Region 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 9c1dcb3b267..5901799c32f 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
@@ -23,6 +23,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
import org.springframework.ai.bedrock.api.AbstractBedrockApi;
import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi.TitanEmbeddingRequest;
@@ -34,6 +35,7 @@
* https://docs.aws.amazon.com/bedrock/latest/userguide/titan-multiemb-models.html
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
// @formatter:off
@@ -65,6 +67,20 @@ public TitanEmbeddingBedrockApi(String modelId, AwsCredentialsProvider credentia
super(modelId, credentialsProvider, region, objectMapper, timeout);
}
+ /**
+ * Create a new TitanEmbeddingBedrockApi instance.
+ *
+ * @param modelId The model id to use. See the {@link TitanEmbeddingModel} 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 TitanEmbeddingBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, Region region,
+ ObjectMapper objectMapper, Duration timeout) {
+ super(modelId, credentialsProvider, region, objectMapper, timeout);
+ }
+
/**
* Titan Embedding request parameters.
*
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 4da2b06f7d0..89e3190b091 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
@@ -63,6 +63,18 @@ AWS credentials are resolved in the following order:
6. Credentials delivered through the Amazon EC2 container service if the `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` environment variable is set and the security manager has permission to access the variable.
7. Instance profile credentials delivered through the Amazon EC2 metadata service or set the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables.
+AWS region is resolved in the following order:
+
+1. Spring-AI Bedrock `spring.ai.bedrock.aws.region` property.
+2. Java System Properties - `aws.region`.
+3. Environment Variables - `AWS_REGION`.
+4. Credential profiles file at the default location (`~/.aws/credentials`) shared by all AWS SDKs and the AWS CLI.
+5. Instance profile region delivered through the Amazon EC2 metadata service.
+
+In addition to the standard Spring-AI Bedrock credentials and region properties configuration, Spring-AI provides support for custom `AwsCredentialsProvider` and `AwsRegionProvider` beans.
+
+NOTE: For example, using Spring-AI and https://spring.io/projects/spring-cloud-aws[Spring Cloud for Amazon Web Services] at the same time. Spring-AI is compatible with Spring Cloud for Amazon Web Services credential configuration.
+
=== Enable selected Bedrock model
NOTE: By default, all models are disabled. You have to enable the chosen Bedrock models explicitly using the `spring.ai.bedrock...enabled=true` property.
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfiguration.java
index 9cfd634d13b..46ee804056d 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfiguration.java
@@ -19,6 +19,9 @@
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
+import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -28,6 +31,7 @@
/**
* @author Christian Tzolov
+ * @author Wei Jiang
*/
@Configuration
@EnableConfigurationProperties({ BedrockAwsConnectionProperties.class })
@@ -45,4 +49,38 @@ public AwsCredentialsProvider credentialsProvider(BedrockAwsConnectionProperties
return DefaultCredentialsProvider.create();
}
+ @Bean
+ @ConditionalOnMissingBean
+ public AwsRegionProvider regionProvider(BedrockAwsConnectionProperties properties) {
+
+ if (StringUtils.hasText(properties.getRegion())) {
+ return new StaticRegionProvider(properties.getRegion());
+ }
+
+ return DefaultAwsRegionProviderChain.builder().build();
+ }
+
+ /**
+ * @author Wei Jiang
+ */
+ static class StaticRegionProvider implements AwsRegionProvider {
+
+ private final Region region;
+
+ public StaticRegionProvider(String region) {
+ try {
+ this.region = Region.of(region);
+ }
+ catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("The region '" + region + "' is not a valid region!", e);
+ }
+ }
+
+ @Override
+ public Region getRegion() {
+ return this.region;
+ }
+
+ }
+
}
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 9a74161b050..7b3d4d2d545 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
@@ -21,6 +21,7 @@
import org.springframework.ai.bedrock.anthropic.BedrockAnthropicChatClient;
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -28,6 +29,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
/**
* {@link AutoConfiguration Auto-configuration} for Bedrock Anthropic Chat Client.
@@ -35,6 +37,7 @@
* Leverages the Spring Cloud AWS to resolve the {@link AwsCredentialsProvider}.
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
@AutoConfiguration
@@ -46,16 +49,18 @@ public class BedrockAnthropicChatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
public AnthropicChatBedrockApi anthropicApi(AwsCredentialsProvider credentialsProvider,
- BedrockAnthropicChatProperties properties, BedrockAwsConnectionProperties awsProperties) {
- return new AnthropicChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ AwsRegionProvider regionProvider, BedrockAnthropicChatProperties properties,
+ BedrockAwsConnectionProperties awsProperties) {
+ return new AnthropicChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
new ObjectMapper(), awsProperties.getTimeout());
}
@Bean
+ @ConditionalOnBean(AnthropicChatBedrockApi.class)
public BedrockAnthropicChatClient anthropicChatClient(AnthropicChatBedrockApi anthropicApi,
BedrockAnthropicChatProperties properties) {
-
return new BedrockAnthropicChatClient(anthropicApi, properties.getOptions());
}
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 7d04798d033..60e5cdce69c 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
@@ -21,6 +21,7 @@
import org.springframework.ai.bedrock.anthropic3.BedrockAnthropic3ChatClient;
import org.springframework.ai.bedrock.anthropic3.api.Anthropic3ChatBedrockApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -28,6 +29,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
/**
* {@link AutoConfiguration Auto-configuration} for Bedrock Anthropic Chat Client.
@@ -47,13 +49,16 @@ public class BedrockAnthropic3ChatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
public Anthropic3ChatBedrockApi anthropic3Api(AwsCredentialsProvider credentialsProvider,
- BedrockAnthropic3ChatProperties properties, BedrockAwsConnectionProperties awsProperties) {
- return new Anthropic3ChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ AwsRegionProvider regionProvider, BedrockAnthropic3ChatProperties properties,
+ BedrockAwsConnectionProperties awsProperties) {
+ return new Anthropic3ChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
new ObjectMapper(), awsProperties.getTimeout());
}
@Bean
+ @ConditionalOnBean(Anthropic3ChatBedrockApi.class)
public BedrockAnthropic3ChatClient anthropic3ChatClient(Anthropic3ChatBedrockApi anthropicApi,
BedrockAnthropic3ChatProperties properties) {
return new BedrockAnthropic3ChatClient(anthropicApi, properties.getOptions());
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 3ee34f90fa1..66b6d5e5e77 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
@@ -21,6 +21,7 @@
import org.springframework.ai.bedrock.cohere.BedrockCohereChatClient;
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -28,11 +29,13 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
/**
* {@link AutoConfiguration Auto-configuration} for Bedrock Cohere Chat Client.
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
@AutoConfiguration
@@ -44,13 +47,16 @@ public class BedrockCohereChatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
public CohereChatBedrockApi cohereChatApi(AwsCredentialsProvider credentialsProvider,
- BedrockCohereChatProperties properties, BedrockAwsConnectionProperties awsProperties) {
- return new CohereChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ AwsRegionProvider regionProvider, BedrockCohereChatProperties properties,
+ BedrockAwsConnectionProperties awsProperties) {
+ return new CohereChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
new ObjectMapper(), awsProperties.getTimeout());
}
@Bean
+ @ConditionalOnBean(CohereChatBedrockApi.class)
public BedrockCohereChatClient cohereChatClient(CohereChatBedrockApi cohereChatApi,
BedrockCohereChatProperties properties) {
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 95ecba88858..76e3ea6033d 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
@@ -17,12 +17,14 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
import org.springframework.ai.bedrock.cohere.BedrockCohereEmbeddingClient;
import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -34,6 +36,7 @@
* {@link AutoConfiguration Auto-configuration} for Bedrock Cohere Embedding Client.
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
@AutoConfiguration
@@ -45,14 +48,17 @@ public class BedrockCohereEmbeddingAutoConfiguration {
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
public CohereEmbeddingBedrockApi cohereEmbeddingApi(AwsCredentialsProvider credentialsProvider,
- BedrockCohereEmbeddingProperties properties, BedrockAwsConnectionProperties awsProperties) {
- return new CohereEmbeddingBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ AwsRegionProvider regionProvider, BedrockCohereEmbeddingProperties properties,
+ BedrockAwsConnectionProperties awsProperties) {
+ return new CohereEmbeddingBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
new ObjectMapper(), awsProperties.getTimeout());
}
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean(CohereEmbeddingBedrockApi.class)
public BedrockCohereEmbeddingClient cohereEmbeddingClient(CohereEmbeddingBedrockApi cohereEmbeddingApi,
BedrockCohereEmbeddingProperties properties) {
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 f7c50657238..e8266a0e417 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
@@ -22,6 +22,7 @@
import org.springframework.ai.bedrock.jurassic2.BedrockAi21Jurassic2ChatClient;
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -29,11 +30,13 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
/**
* {@link AutoConfiguration Auto-configuration} for Bedrock Jurassic2 Chat Client.
*
* @author Ahmed Yousri
+ * @author Wei Jiang
* @since 1.0.0
*/
@AutoConfiguration
@@ -46,13 +49,16 @@ public class BedrockAi21Jurassic2ChatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
public Ai21Jurassic2ChatBedrockApi ai21Jurassic2ChatBedrockApi(AwsCredentialsProvider credentialsProvider,
- BedrockAi21Jurassic2ChatProperties properties, BedrockAwsConnectionProperties awsProperties) {
- return new Ai21Jurassic2ChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ AwsRegionProvider regionProvider, BedrockAi21Jurassic2ChatProperties properties,
+ BedrockAwsConnectionProperties awsProperties) {
+ return new Ai21Jurassic2ChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
new ObjectMapper(), awsProperties.getTimeout());
}
@Bean
+ @ConditionalOnBean(Ai21Jurassic2ChatBedrockApi.class)
public BedrockAi21Jurassic2ChatClient jurassic2ChatClient(Ai21Jurassic2ChatBedrockApi ai21Jurassic2ChatBedrockApi,
BedrockAi21Jurassic2ChatProperties properties) {
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 314e3671be2..ef3d53e4faa 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
@@ -17,12 +17,14 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
import org.springframework.ai.bedrock.llama2.BedrockLlama2ChatClient;
import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -36,6 +38,7 @@
* Leverages the Spring Cloud AWS to resolve the {@link AwsCredentialsProvider}.
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
@AutoConfiguration
@@ -47,13 +50,15 @@ public class BedrockLlama2ChatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public Llama2ChatBedrockApi llama2Api(AwsCredentialsProvider credentialsProvider,
+ @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
+ public Llama2ChatBedrockApi llama2Api(AwsCredentialsProvider credentialsProvider, AwsRegionProvider regionProvider,
BedrockLlama2ChatProperties properties, BedrockAwsConnectionProperties awsProperties) {
- return new Llama2ChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ return new Llama2ChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
new ObjectMapper(), awsProperties.getTimeout());
}
@Bean
+ @ConditionalOnBean(Llama2ChatBedrockApi.class)
public BedrockLlama2ChatClient llama2ChatClient(Llama2ChatBedrockApi llama2Api,
BedrockLlama2ChatProperties properties) {
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 e24ec3696ab..67995b9e39c 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
@@ -21,6 +21,7 @@
import org.springframework.ai.bedrock.titan.BedrockTitanChatClient;
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -28,11 +29,13 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
/**
* {@link AutoConfiguration Auto-configuration} for Bedrock Titan Chat Client.
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
@AutoConfiguration
@@ -44,14 +47,16 @@ public class BedrockTitanChatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
public TitanChatBedrockApi titanChatBedrockApi(AwsCredentialsProvider credentialsProvider,
- BedrockTitanChatProperties properties, BedrockAwsConnectionProperties awsProperties) {
-
- return new TitanChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ AwsRegionProvider regionProvider, BedrockTitanChatProperties properties,
+ BedrockAwsConnectionProperties awsProperties) {
+ return new TitanChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
new ObjectMapper(), awsProperties.getTimeout());
}
@Bean
+ @ConditionalOnBean(TitanChatBedrockApi.class)
public BedrockTitanChatClient titanChatClient(TitanChatBedrockApi titanChatApi,
BedrockTitanChatProperties properties) {
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 f36c6e427fd..5ea79d4513a 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
@@ -17,12 +17,14 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
import org.springframework.ai.bedrock.titan.BedrockTitanEmbeddingClient;
import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -34,6 +36,7 @@
* {@link AutoConfiguration Auto-configuration} for Bedrock Titan Embedding Client.
*
* @author Christian Tzolov
+ * @author Wei Jiang
* @since 0.8.0
*/
@AutoConfiguration
@@ -45,14 +48,17 @@ public class BedrockTitanEmbeddingAutoConfiguration {
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
public TitanEmbeddingBedrockApi titanEmbeddingBedrockApi(AwsCredentialsProvider credentialsProvider,
- BedrockTitanEmbeddingProperties properties, BedrockAwsConnectionProperties awsProperties) {
- return new TitanEmbeddingBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ AwsRegionProvider regionProvider, BedrockTitanEmbeddingProperties properties,
+ BedrockAwsConnectionProperties awsProperties) {
+ return new TitanEmbeddingBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
new ObjectMapper(), awsProperties.getTimeout());
}
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean(TitanEmbeddingBedrockApi.class)
public BedrockTitanEmbeddingClient titanEmbeddingClient(TitanEmbeddingBedrockApi titanEmbeddingApi,
BedrockTitanEmbeddingProperties properties) {
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfigurationIT.java
new file mode 100644
index 00000000000..bea58ce80e3
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfigurationIT.java
@@ -0,0 +1,139 @@
+/*
+ * 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.autoconfigure.bedrock;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Import;
+
+import software.amazon.awssdk.auth.credentials.AwsCredentials;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.regions.providers.AwsRegionProvider;
+
+/**
+ * @author Wei Jiang
+ * @since 0.8.1
+ */
+@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
+@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
+public class BedrockAwsConnectionConfigurationIT {
+
+ @Test
+ public void autoConfigureAWSCredentialAndRegionProvider() {
+ new ApplicationContextRunner()
+ .withPropertyValues("spring.ai.bedrock.aws.access-key=" + System.getenv("AWS_ACCESS_KEY_ID"),
+ "spring.ai.bedrock.aws.secret-key=" + System.getenv("AWS_SECRET_ACCESS_KEY"),
+ "spring.ai.bedrock.aws.region=" + Region.US_EAST_1.id())
+ .withConfiguration(AutoConfigurations.of(TestAutoConfiguration.class))
+ .run((context) -> {
+ var awsCredentialsProvider = context.getBean(AwsCredentialsProvider.class);
+ var awsRegionProvider = context.getBean(AwsRegionProvider.class);
+
+ assertThat(awsCredentialsProvider).isNotNull();
+ assertThat(awsRegionProvider).isNotNull();
+
+ var credentials = awsCredentialsProvider.resolveCredentials();
+ assertThat(credentials).isNotNull();
+ assertThat(credentials.accessKeyId()).isEqualTo(System.getenv("AWS_ACCESS_KEY_ID"));
+ assertThat(credentials.secretAccessKey()).isEqualTo(System.getenv("AWS_SECRET_ACCESS_KEY"));
+
+ assertThat(awsRegionProvider.getRegion()).isEqualTo(Region.US_EAST_1);
+ });
+ }
+
+ @Test
+ public void autoConfigureWithCustomAWSCredentialAndRegionProvider() {
+ new ApplicationContextRunner()
+ .withPropertyValues("spring.ai.bedrock.aws.access-key=" + System.getenv("AWS_ACCESS_KEY_ID"),
+ "spring.ai.bedrock.aws.secret-key=" + System.getenv("AWS_SECRET_ACCESS_KEY"),
+ "spring.ai.bedrock.aws.region=" + Region.US_EAST_1.id())
+ .withConfiguration(AutoConfigurations.of(TestAutoConfiguration.class,
+ CustomAwsCredentialsProviderAndAwsRegionProviderAutoConfiguration.class))
+ .run((context) -> {
+ var awsCredentialsProvider = context.getBean(AwsCredentialsProvider.class);
+ var awsRegionProvider = context.getBean(AwsRegionProvider.class);
+
+ assertThat(awsCredentialsProvider).isNotNull();
+ assertThat(awsRegionProvider).isNotNull();
+
+ var credentials = awsCredentialsProvider.resolveCredentials();
+ assertThat(credentials).isNotNull();
+ assertThat(credentials.accessKeyId()).isEqualTo("CUSTOM_ACCESS_KEY");
+ assertThat(credentials.secretAccessKey()).isEqualTo("CUSTOM_SECRET_ACCESS_KEY");
+
+ assertThat(awsRegionProvider.getRegion()).isEqualTo(Region.AWS_GLOBAL);
+ });
+ }
+
+ @EnableConfigurationProperties({ BedrockAwsConnectionProperties.class })
+ @Import(BedrockAwsConnectionConfiguration.class)
+ static class TestAutoConfiguration {
+
+ }
+
+ @AutoConfiguration
+ static class CustomAwsCredentialsProviderAndAwsRegionProviderAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public AwsCredentialsProvider credentialsProvider() {
+ return new AwsCredentialsProvider() {
+
+ @Override
+ public AwsCredentials resolveCredentials() {
+ return new AwsCredentials() {
+
+ @Override
+ public String accessKeyId() {
+ return "CUSTOM_ACCESS_KEY";
+ }
+
+ @Override
+ public String secretAccessKey() {
+ return "CUSTOM_SECRET_ACCESS_KEY";
+ }
+
+ };
+ }
+
+ };
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public AwsRegionProvider regionProvider() {
+ return new AwsRegionProvider() {
+
+ @Override
+ public Region getRegion() {
+ return Region.AWS_GLOBAL;
+ }
+
+ };
+ }
+
+ }
+
+}