Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ LLM_Z_AI_API_KEY=your_zai_key_here

# AWS Bedrock
LLM_AWS_BEDROCK_API_KEY=your_aws_bedrock_key_here
# AWS Bedrock Region (options: us-east-1, us-west-2, eu-west-1, eu-central-1, ap-northeast-1, ap-southeast-1)
# LLM_AWS_BEDROCK_REGION=us-east-1

# Azure
LLM_AZURE_API_KEY=your_azure_key_here
Expand Down
20 changes: 20 additions & 0 deletions apps/api/src/routes/keys-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ const providerKeySchema = z.object({
options: z
.object({
aws_bedrock_region_prefix: z.enum(["us.", "global.", "eu."]).optional(),
aws_bedrock_region: z
.enum([
"us-east-1",
"us-west-2",
"eu-west-1",
"eu-central-1",
"ap-northeast-1",
"ap-southeast-1",
])
.optional(),
azure_resource: z.string().optional(),
azure_api_version: z.string().optional(),
azure_deployment_type: z.enum(["openai", "ai-foundry"]).optional(),
Expand Down Expand Up @@ -59,6 +69,16 @@ const createProviderKeySchema = z.object({
options: z
.object({
aws_bedrock_region_prefix: z.enum(["us.", "global.", "eu."]).optional(),
aws_bedrock_region: z
.enum([
"us-east-1",
"us-west-2",
"eu-west-1",
"eu-central-1",
"ap-northeast-1",
"ap-southeast-1",
])
.optional(),
azure_resource: z.string().optional(),
azure_api_version: z.string().optional(),
azure_deployment_type: z.enum(["openai", "ai-foundry"]).optional(),
Expand Down
8 changes: 8 additions & 0 deletions apps/code/src/lib/api/v1.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4516,6 +4516,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4553,6 +4555,8 @@ export interface paths {
options?: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4583,6 +4587,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4701,6 +4707,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down
10 changes: 10 additions & 0 deletions apps/gateway/src/lib/costs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ export async function calculateCosts(
) as ModelDefinition;
}

// Fallback: search expanded providers for region-suffixed model names
// (e.g., "anthropic.claude-3-5-haiku-20241022-v1:0:us-east-1")
if (!modelInfo) {
modelInfo = models.find((m) =>
expandAllProviderRegions(m.providers as ProviderModelMapping[]).some(
(p) => p.modelName === model,
),
) as ModelDefinition;
}

if (!modelInfo) {
return {
inputCost: null,
Expand Down
19 changes: 17 additions & 2 deletions apps/playground/src/components/model-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -462,11 +462,26 @@ export function ModelSelector({
const [selectedProviderId, selectedModelIdRaw] = raw.includes("/")
? (raw.split("/") as [string, string])
: ["", raw];
// Strip :region suffix for root model lookup, keep raw for mapping match
// Strip :region suffix for root model lookup, keep raw for mapping match.
// Model names can contain colons (e.g., "anthropic.claude-3-5-haiku-20241022-v1:0"),
// so we first try a direct match, then fall back to stripping the last colon segment.
const selectedModelId = selectedModelIdRaw.includes(":")
? selectedModelIdRaw.split(":")[0]
: selectedModelIdRaw;
const selectedModel = models.find((m) => m.id === selectedModelId);
// Direct lookup by model.id, then fallback: search all models for a mapping
// that matches the raw provider model name (handles region-expanded names like
// "anthropic.claude-3-5-haiku-20241022-v1:0:us-east-1")
const selectedModel =
models.find((m) => m.id === selectedModelId) ??
(selectedProviderId
? models.find((m) =>
m.mappings.some(
(p) =>
p.providerId === selectedProviderId &&
p.modelName === selectedModelIdRaw,
),
)
: undefined);
const selectedProviderDef = providers.find(
(p) => p.id === selectedProviderId,
);
Expand Down
8 changes: 8 additions & 0 deletions apps/playground/src/lib/api/v1.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4516,6 +4516,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4553,6 +4555,8 @@ export interface paths {
options?: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4583,6 +4587,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4701,6 +4707,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down
3 changes: 2 additions & 1 deletion apps/ui/src/components/provider-keys/provider-keys-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ interface ProviderKeysListProps {

function formatOptionLabel(key: string, value: string): string {
const labels: Record<string, string> = {
aws_bedrock_region_prefix: "Region",
aws_bedrock_region_prefix: "Cross-Region Prefix",
aws_bedrock_region: "Region",
azure_resource: "Resource",
azure_api_version: "API Version",
azure_deployment_type: "Deployment",
Expand Down
8 changes: 8 additions & 0 deletions apps/ui/src/lib/api/v1.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4516,6 +4516,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4553,6 +4555,8 @@ export interface paths {
options?: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4583,6 +4587,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4701,6 +4707,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down
8 changes: 8 additions & 0 deletions ee/admin/src/lib/api/v1.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4516,6 +4516,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4553,6 +4555,8 @@ export interface paths {
options?: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4583,6 +4587,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down Expand Up @@ -4701,6 +4707,8 @@ export interface paths {
options: {
/** @enum {string} */
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
/** @enum {string} */
aws_bedrock_region?: "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-northeast-1" | "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
/** @enum {string} */
Expand Down
42 changes: 37 additions & 5 deletions packages/actions/src/get-provider-endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ import {

import type { ProviderKeyOptions } from "@llmgateway/db";

/**
* Derive the AWS Bedrock cross-region inference prefix from a region ID.
* Many newer models are only available through cross-region inference profiles.
*/
function bedrockRegionPrefix(region: string): string {
if (region.startsWith("us-")) {
return "us.";
}
if (region.startsWith("eu-")) {
return "eu.";
}
if (region.startsWith("ap-")) {
return "apac.";
}
if (region.startsWith("me-")) {
return "apac.";
}
return "us.";
}

function buildVertexCompatibleEndpoint(
provider: "google-vertex" | "quartz",
url: string,
Expand Down Expand Up @@ -220,12 +240,14 @@ export function getProviderEndpoint(
break;
case "aws-bedrock":
url =
regionBaseUrl ??
getProviderEnvValue(
"aws-bedrock",
"baseUrl",
configIndex,
"https://bedrock-runtime.us-east-1.amazonaws.com",
) ?? "https://bedrock-runtime.us-east-1.amazonaws.com";
) ??
"https://bedrock-runtime.us-east-1.amazonaws.com";
break;
case "azure": {
const resource =
Expand Down Expand Up @@ -330,10 +352,20 @@ export function getProviderEndpoint(
}
return `${url}/api/paas/v4/chat/completions`;
case "aws-bedrock": {
const prefix =
providerKeyOptions?.aws_bedrock_region_prefix ??
getProviderEnvValue("aws-bedrock", "region", configIndex, "global.") ??
"global.";
// When a specific region is selected (via regionConfig), derive the
// cross-region inference prefix from the region. Many newer models
// (Claude Sonnet 4, Opus 4.5, etc.) are CR-only and require a prefix.
// Fall back to the legacy explicit prefix for backward compatibility.
const prefix = region
? bedrockRegionPrefix(region)
: (providerKeyOptions?.aws_bedrock_region_prefix ??
getProviderEnvValue(
"aws-bedrock",
"region",
configIndex,
"global.",
) ??
"global.");

const endpoint = stream ? "converse-stream" : "converse";
return `${url}/model/${prefix}${modelName}/${endpoint}`;
Expand Down
7 changes: 7 additions & 0 deletions packages/db/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,13 @@ export const apiKeyIamRule = pgTable(

export interface ProviderKeyOptions {
aws_bedrock_region_prefix?: "us." | "global." | "eu.";
aws_bedrock_region?:
| "us-east-1"
| "us-west-2"
| "eu-west-1"
| "eu-central-1"
| "ap-northeast-1"
| "ap-southeast-1";
azure_resource?: string;
azure_api_version?: string;
azure_deployment_type?: "openai" | "ai-foundry";
Expand Down
Loading
Loading