diff --git a/dotnet/src/Connectors/Connectors.Amazon.UnitTests/Extensions/BedrockKernelBuilderExtensionTests.cs b/dotnet/src/Connectors/Connectors.Amazon.UnitTests/Extensions/BedrockKernelBuilderExtensionTests.cs
index e1692b4ea218..3f5879d9bdb4 100644
--- a/dotnet/src/Connectors/Connectors.Amazon.UnitTests/Extensions/BedrockKernelBuilderExtensionTests.cs
+++ b/dotnet/src/Connectors/Connectors.Amazon.UnitTests/Extensions/BedrockKernelBuilderExtensionTests.cs
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
+using System;
using Amazon.BedrockRuntime;
using Amazon.Runtime;
using Microsoft.SemanticKernel.ChatCompletion;
@@ -18,13 +19,15 @@ public class BedrockKernelBuilderExtensionTests
///
/// Checks that AddBedrockTextGenerationService builds a proper kernel with a null bedrockRuntime.
///
- [Fact]
- public void AddBedrockTextGenerationCreatesServiceWithNonNullBedrockRuntime()
+ [Theory]
+ [InlineData("amazon.titan-text-premier-v1:0")]
+ [InlineData("us.amazon.titan-text-premier-v1:0")]
+ public void AddBedrockTextGenerationCreatesServiceWithNonNullBedrockRuntime(string modelId)
{
// Arrange
var bedrockRuntime = new Mock().Object;
var builder = Kernel.CreateBuilder();
- builder.AddBedrockTextGenerationService("amazon.titan-text-premier-v1:0", bedrockRuntime);
+ builder.AddBedrockTextGenerationService(modelId, bedrockRuntime);
// Act
var kernel = builder.Build();
@@ -37,13 +40,15 @@ public void AddBedrockTextGenerationCreatesServiceWithNonNullBedrockRuntime()
///
/// Checks that AddBedrockChatCompletionService builds a proper kernel with a non-null bedrockRuntime.
///
- [Fact]
- public void AddBedrockChatCompletionCreatesServiceWithNonNullBedrockRuntime()
+ [Theory]
+ [InlineData("amazon.titan-text-premier-v1:0")]
+ [InlineData("us.amazon.titan-text-premier-v1:0")]
+ public void AddBedrockChatCompletionCreatesServiceWithNonNullBedrockRuntime(string modelId)
{
// Arrange
var bedrockRuntime = new Mock().Object;
var builder = Kernel.CreateBuilder();
- builder.AddBedrockChatCompletionService("amazon.titan-text-premier-v1:0", bedrockRuntime);
+ builder.AddBedrockChatCompletionService(modelId, bedrockRuntime);
// Act
var kernel = builder.Build();
@@ -65,4 +70,22 @@ public void AwsServiceClientBeforeServiceRequestDoesNothingForNonWebServiceReque
// Assert
// No exceptions should be thrown
}
+
+ [Theory]
+ [InlineData("unknown.titan-text-premier-v1:0")]
+ [InlineData("us.unknown.titan-text-premier-v1:0")]
+ public void AwsUnknownBedrockTextCompletionModelShouldThrowException(string modelId)
+ {
+ // Arrange
+ var bedrockRuntime = new Mock().Object;
+ var builder = Kernel.CreateBuilder();
+ builder.AddBedrockTextGenerationService(modelId, bedrockRuntime);
+
+ // Act & Assert
+ Assert.Throws(() =>
+ {
+ var kernel = builder.Build();
+ kernel.GetRequiredService();
+ });
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Amazon/Bedrock/Core/BedrockServiceFactory.cs b/dotnet/src/Connectors/Connectors.Amazon/Bedrock/Core/BedrockServiceFactory.cs
index e5b59f0c465a..7bc9178c69c6 100644
--- a/dotnet/src/Connectors/Connectors.Amazon/Bedrock/Core/BedrockServiceFactory.cs
+++ b/dotnet/src/Connectors/Connectors.Amazon/Bedrock/Core/BedrockServiceFactory.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
+using System.Linq;
namespace Microsoft.SemanticKernel.Connectors.Amazon.Core;
@@ -9,6 +10,30 @@ namespace Microsoft.SemanticKernel.Connectors.Amazon.Core;
///
internal sealed class BedrockServiceFactory
{
+ ///
+ /// Represents an array of region prefixes used to identify different cross-region configurations
+ /// for service operations. The prefixes correspond to general geographic areas such as
+ /// "us" (United States), "eu" (Europe), and "apac" (Asia-Pacific).
+ /// (sourced from https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html)
+ ///
+ private static readonly string[] s_crossRegionPrefixes = ["us.", "eu.", "apac."];
+
+ ///
+ /// Removes the cross-region prefix from the provided model identifier if it exists.
+ ///
+ /// The model identifier, which may contain a cross-region prefix.
+ /// The model identifier without the cross-region prefix.
+ private static string ScrubCrossRegionPrefix(string modelId)
+ {
+ var prefix = s_crossRegionPrefixes.FirstOrDefault(prefix => modelId.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase));
+ if (!string.IsNullOrWhiteSpace(prefix))
+ {
+ modelId = modelId.Substring(prefix.Length);
+ }
+
+ return modelId;
+ }
+
///
/// Gets the model service for body conversion.
///
@@ -17,7 +42,7 @@ internal sealed class BedrockServiceFactory
/// Thrown if provider or model is not supported for text generation.
internal IBedrockTextGenerationService CreateTextGenerationService(string modelId)
{
- (string modelProvider, string modelName) = this.GetModelProviderAndName(modelId);
+ (string modelProvider, string modelName) = this.GetModelProviderAndName(ScrubCrossRegionPrefix(modelId));
switch (modelProvider.ToUpperInvariant())
{
@@ -79,7 +104,7 @@ internal IBedrockTextGenerationService CreateTextGenerationService(string modelI
/// Thrown if provider or model is not supported for chat completion.
internal IBedrockChatCompletionService CreateChatCompletionService(string modelId)
{
- (string modelProvider, string modelName) = this.GetModelProviderAndName(modelId);
+ (string modelProvider, string modelName) = this.GetModelProviderAndName(ScrubCrossRegionPrefix(modelId));
switch (modelProvider.ToUpperInvariant())
{