Skip to content

Commit 65230f1

Browse files
hannesrudolphellipsis-dev[bot]roomote
authored
feat: Global Inference for Bedrock models (#8750) (#8940)
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> Co-authored-by: Roo Code <[email protected]>
1 parent 39448f4 commit 65230f1

File tree

24 files changed

+104
-13
lines changed

24 files changed

+104
-13
lines changed

packages/types/src/provider-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ const bedrockSchema = apiModelIdProviderModelSchema.extend({
220220
awsSessionToken: z.string().optional(),
221221
awsRegion: z.string().optional(),
222222
awsUseCrossRegionInference: z.boolean().optional(),
223+
awsUseGlobalInference: z.boolean().optional(), // Enable Global Inference profile routing when supported
223224
awsUsePromptCache: z.boolean().optional(),
224225
awsProfile: z.string().optional(),
225226
awsUseProfile: z.boolean().optional(),

packages/types/src/providers/bedrock.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -401,17 +401,22 @@ export const BEDROCK_DEFAULT_CONTEXT = 128_000
401401
// https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html
402402
// This mapping is pre-ordered by pattern length (descending) to ensure more specific patterns match first
403403
export const AWS_INFERENCE_PROFILE_MAPPING: Array<[string, string]> = [
404-
// US Government Cloud → ug. inference profile (most specific prefix first)
404+
// Australia regions (Sydney and Melbourne) → au. inference profile (most specific - 14 chars)
405+
["ap-southeast-2", "au."],
406+
["ap-southeast-4", "au."],
407+
// Japan regions (Tokyo and Osaka) → jp. inference profile (13 chars)
408+
["ap-northeast-", "jp."],
409+
// US Government Cloud → ug. inference profile (7 chars)
405410
["us-gov-", "ug."],
406-
// Americas regions → us. inference profile
411+
// Americas regions → us. inference profile (3 chars)
407412
["us-", "us."],
408-
// Europe regions → eu. inference profile
413+
// Europe regions → eu. inference profile (3 chars)
409414
["eu-", "eu."],
410-
// Asia Pacific regions → apac. inference profile
415+
// Asia Pacific regions → apac. inference profile (3 chars)
411416
["ap-", "apac."],
412-
// Canada regions → ca. inference profile
417+
// Canada regions → ca. inference profile (3 chars)
413418
["ca-", "ca."],
414-
// South America regions → sa. inference profile
419+
// South America regions → sa. inference profile (3 chars)
415420
["sa-", "sa."],
416421
]
417422

@@ -448,3 +453,14 @@ export const BEDROCK_1M_CONTEXT_MODEL_IDS = [
448453
"anthropic.claude-sonnet-4-20250514-v1:0",
449454
"anthropic.claude-sonnet-4-5-20250929-v1:0",
450455
] as const
456+
457+
// Amazon Bedrock models that support Global Inference profiles
458+
// As of Oct 2025, AWS supports Global Inference for:
459+
// - Claude Sonnet 4
460+
// - Claude Sonnet 4.5
461+
// - Claude Haiku 4.5
462+
export const BEDROCK_GLOBAL_INFERENCE_MODEL_IDS = [
463+
"anthropic.claude-sonnet-4-20250514-v1:0",
464+
"anthropic.claude-sonnet-4-5-20250929-v1:0",
465+
"anthropic.claude-haiku-4-5-20251001-v1:0",
466+
] as const

src/api/providers/__tests__/bedrock-inference-profiles.spec.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ describe("Amazon Bedrock Inference Profiles", () => {
3030
describe("AWS_INFERENCE_PROFILE_MAPPING constant", () => {
3131
it("should contain all expected region mappings", () => {
3232
expect(AWS_INFERENCE_PROFILE_MAPPING).toEqual([
33+
["ap-southeast-2", "au."],
34+
["ap-southeast-4", "au."],
35+
["ap-northeast-", "jp."],
3336
["us-gov-", "ug."],
3437
["us-", "us."],
3538
["eu-", "eu."],
@@ -47,7 +50,7 @@ describe("Amazon Bedrock Inference Profiles", () => {
4750

4851
it("should have valid inference profile prefixes", () => {
4952
AWS_INFERENCE_PROFILE_MAPPING.forEach(([regionPattern, inferenceProfile]) => {
50-
expect(regionPattern).toMatch(/^[a-z-]+$/)
53+
expect(regionPattern).toMatch(/^[a-z0-9-]+$/)
5154
expect(inferenceProfile).toMatch(/^[a-z]+\.$/)
5255
})
5356
})
@@ -77,8 +80,14 @@ describe("Amazon Bedrock Inference Profiles", () => {
7780

7881
it("should return correct prefix for Asia Pacific regions", () => {
7982
const handler = createHandler()
83+
// Australia regions (Sydney and Melbourne) get au. prefix
84+
expect((handler as any).constructor.getPrefixForRegion("ap-southeast-2")).toBe("au.")
85+
expect((handler as any).constructor.getPrefixForRegion("ap-southeast-4")).toBe("au.")
86+
// Japan regions (Tokyo and Osaka) get jp. prefix
87+
expect((handler as any).constructor.getPrefixForRegion("ap-northeast-1")).toBe("jp.")
88+
expect((handler as any).constructor.getPrefixForRegion("ap-northeast-3")).toBe("jp.")
89+
// Other APAC regions get apac. prefix
8090
expect((handler as any).constructor.getPrefixForRegion("ap-southeast-1")).toBe("apac.")
81-
expect((handler as any).constructor.getPrefixForRegion("ap-northeast-1")).toBe("apac.")
8291
expect((handler as any).constructor.getPrefixForRegion("ap-south-1")).toBe("apac.")
8392
expect((handler as any).constructor.getPrefixForRegion("ap-east-1")).toBe("apac.")
8493
})

src/api/providers/__tests__/bedrock.spec.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,14 @@ describe("AwsBedrockHandler", () => {
114114
it("should return correct prefix for APAC regions", () => {
115115
const getPrefixForRegion = (AwsBedrockHandler as any).getPrefixForRegion
116116

117+
// Australia regions (Sydney and Melbourne) get au. prefix
118+
expect(getPrefixForRegion("ap-southeast-2")).toBe("au.")
119+
expect(getPrefixForRegion("ap-southeast-4")).toBe("au.")
120+
// Japan regions (Tokyo and Osaka) get jp. prefix
121+
expect(getPrefixForRegion("ap-northeast-1")).toBe("jp.")
122+
expect(getPrefixForRegion("ap-northeast-3")).toBe("jp.")
123+
// Other APAC regions get apac. prefix
117124
expect(getPrefixForRegion("ap-southeast-1")).toBe("apac.")
118-
expect(getPrefixForRegion("ap-northeast-1")).toBe("apac.")
119125
expect(getPrefixForRegion("ap-south-1")).toBe("apac.")
120126
})
121127

src/api/providers/bedrock.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
BEDROCK_DEFAULT_CONTEXT,
2323
AWS_INFERENCE_PROFILE_MAPPING,
2424
BEDROCK_1M_CONTEXT_MODEL_IDS,
25+
BEDROCK_GLOBAL_INFERENCE_MODEL_IDS,
2526
} from "@roo-code/types"
2627

2728
import { ApiStream } from "../transform/stream"
@@ -887,6 +888,11 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
887888
}
888889
}
889890

891+
// Also strip Global Inference profile prefix if present
892+
if (modelId.startsWith("global.")) {
893+
return modelId.substring("global.".length)
894+
}
895+
890896
// Return the model ID as-is for all other cases
891897
return modelId
892898
}
@@ -964,8 +970,16 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
964970
//a model was selected from the drop down
965971
modelConfig = this.getModelById(this.options.apiModelId as string)
966972

967-
// Add cross-region inference prefix if enabled
968-
if (this.options.awsUseCrossRegionInference && this.options.awsRegion) {
973+
// Apply Global Inference prefix if enabled and supported (takes precedence over cross-region)
974+
const baseIdForGlobal = this.parseBaseModelId(modelConfig.id)
975+
if (
976+
this.options.awsUseGlobalInference &&
977+
BEDROCK_GLOBAL_INFERENCE_MODEL_IDS.includes(baseIdForGlobal as any)
978+
) {
979+
modelConfig.id = `global.${baseIdForGlobal}`
980+
}
981+
// Otherwise, add cross-region inference prefix if enabled
982+
else if (this.options.awsUseCrossRegionInference && this.options.awsRegion) {
969983
const prefix = AwsBedrockHandler.getPrefixForRegion(this.options.awsRegion)
970984
if (prefix) {
971985
modelConfig.id = `${prefix}${modelConfig.id}`

webview-ui/src/components/settings/providers/Bedrock.tsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@ import { useCallback, useState, useEffect } from "react"
22
import { Checkbox } from "vscrui"
33
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
44

5-
import { type ProviderSettings, type ModelInfo, BEDROCK_REGIONS, BEDROCK_1M_CONTEXT_MODEL_IDS } from "@roo-code/types"
5+
import {
6+
type ProviderSettings,
7+
type ModelInfo,
8+
BEDROCK_REGIONS,
9+
BEDROCK_1M_CONTEXT_MODEL_IDS,
10+
BEDROCK_GLOBAL_INFERENCE_MODEL_IDS,
11+
} from "@roo-code/types"
612

713
import { useAppTranslation } from "@src/i18n/TranslationContext"
814
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StandardTooltip } from "@src/components/ui"
@@ -23,6 +29,11 @@ export const Bedrock = ({ apiConfiguration, setApiConfigurationField, selectedMo
2329
const supports1MContextBeta =
2430
!!apiConfiguration?.apiModelId && BEDROCK_1M_CONTEXT_MODEL_IDS.includes(apiConfiguration.apiModelId as any)
2531

32+
// Check if the selected model supports Global Inference profile routing
33+
const supportsGlobalInference =
34+
!!apiConfiguration?.apiModelId &&
35+
BEDROCK_GLOBAL_INFERENCE_MODEL_IDS.includes(apiConfiguration.apiModelId as any)
36+
2637
// Update the endpoint enabled state when the configuration changes
2738
useEffect(() => {
2839
setAwsEndpointSelected(!!apiConfiguration?.awsBedrockEndpointEnabled)
@@ -138,9 +149,25 @@ export const Bedrock = ({ apiConfiguration, setApiConfigurationField, selectedMo
138149
</SelectContent>
139150
</Select>
140151
</div>
152+
{supportsGlobalInference && (
153+
<Checkbox
154+
checked={apiConfiguration?.awsUseGlobalInference || false}
155+
disabled={apiConfiguration?.awsUseCrossRegionInference || false}
156+
onChange={(checked: boolean) => {
157+
// Enabling Global Inference should disable cross-region inference
158+
setApiConfigurationField("awsUseGlobalInference", checked)
159+
if (checked) setApiConfigurationField("awsUseCrossRegionInference", false)
160+
}}>
161+
{t("settings:providers.awsGlobalInference")}
162+
</Checkbox>
163+
)}
141164
<Checkbox
142165
checked={apiConfiguration?.awsUseCrossRegionInference || false}
143-
onChange={handleInputChange("awsUseCrossRegionInference", noTransform)}>
166+
disabled={apiConfiguration?.awsUseGlobalInference || false}
167+
onChange={(checked: boolean) => {
168+
setApiConfigurationField("awsUseCrossRegionInference", checked)
169+
if (checked) setApiConfigurationField("awsUseGlobalInference", false)
170+
}}>
144171
{t("settings:providers.awsCrossRegion")}
145172
</Checkbox>
146173
{selectedModelInfo?.supportsPromptCache && (

webview-ui/src/i18n/locales/ca/settings.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/de/settings.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/en/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@
349349
"awsSessionToken": "AWS Session Token",
350350
"awsRegion": "AWS Region",
351351
"awsCrossRegion": "Use cross-region inference",
352+
"awsGlobalInference": "Use Global inference (auto-select optimal AWS Region)",
352353
"awsBedrockVpc": {
353354
"useCustomVpcEndpoint": "Use custom VPC endpoint",
354355
"vpcEndpointUrlPlaceholder": "Enter VPC Endpoint URL (optional)",

webview-ui/src/i18n/locales/es/settings.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)