15 KiB
Bedrock Model Identification
This document explains how model information is identified and managed in the Amazon Bedrock provider implementation (bedrock.ts). It focuses on the sequence of operations that determine the costModelConfig property, which is crucial for token counting, pricing, and other features.
Model Identification Flow
The costModelConfig property is set through different paths depending on the input configuration and response data from Bedrock. Below is a sequence diagram of how model identification works:
sequenceDiagram
participant Constructor
participant parseArn
participant parseBaseModelId
participant getModelById
participant getModel
Constructor->>parseArn: Initialize (if awsCustomArn provided)
parseArn->>parseBaseModelId: Extract region prefix from modelId
parseBaseModelId-->>parseArn: Return modelId without prefix
parseArn->>parseArn: Determine if cross-region inference
parseArn-->>Constructor: Return arnInfo with modelId and crossRegionInference flag
Constructor->>getModel: Call getModel()
getModel->>getModelById: Lookup model
getModelById-->>getModel: Return model info
getModel-->>Constructor: Return model config
Constructor->>Constructor: Set this.costModelConfig
During Stream Processing (with Prompt Router)
sequenceDiagram
participant createMessage
participant parseArn
participant getModelById
createMessage->>parseArn: Process stream event with invokedModelId
parseArn->>parseArn: Extract modelId
parseArn-->>createMessage: Return invokedModelArn
createMessage->>getModelById: Call getModelById with invokedModelArn.modelId
getModelById-->>createMessage: Return invokedModel
createMessage->>createMessage: Set invokedModel.id = modelConfig.id
createMessage->>createMessage: Set this.costModelConfig = invokedModel
Input Examples and Resulting Values
Example 1: Standard Model Selection
Input:
const handler = new AwsBedrockHandler({
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
awsAccessKey: "ACCESS_KEY",
awsSecretKey: "SECRET_KEY",
awsRegion: "us-east-1",
})
Sequence:
- Constructor initializes with options
- Constructor calls
getModel() getModel()callsgetModelById("anthropic.claude-3-5-sonnet-20241022-v2:0")getModelById()looks up the model inbedrockModelsthis.costModelConfigis set to:{ id: "anthropic.claude-3-5-sonnet-20241022-v2:0", info: { maxTokens: 4096, contextWindow: 128000, inputPrice: 3, outputPrice: 15, // other model properties... } }
Example 2: Custom ARN for Foundation Model
Input:
const handler = new AwsBedrockHandler({
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
awsAccessKey: "ACCESS_KEY",
awsSecretKey: "SECRET_KEY",
awsRegion: "us-east-1",
awsCustomArn: "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0",
})
Sequence:
- Constructor initializes with options
- Constructor calls
parseArn("arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0") parseArn()extracts:{ isValid: true, region: "us-east-1", modelType: "foundation-model", modelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", crossRegionInference: false }- Constructor sets
this.arnInfoto the result - Constructor calls
getModel() getModel()callsgetModelById("anthropic.claude-3-5-sonnet-20241022-v2:0")getModelById()looks up the model inbedrockModelsthis.costModelConfigis set to:{ id: "anthropic.claude-3-5-sonnet-20241022-v2:0", // Note: ID is not the ARN since it's a foundation-model info: { maxTokens: 4096, contextWindow: 128000, inputPrice: 3, outputPrice: 15, // other model properties... } }
Example 3: Custom ARN for Prompt Router
Input:
const handler = new AwsBedrockHandler({
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
awsAccessKey: "ACCESS_KEY",
awsSecretKey: "SECRET_KEY",
awsRegion: "us-west-2",
awsCustomArn: "arn:aws:bedrock:us-west-2:123456789012:prompt-router/my-router",
})
Sequence:
- Constructor initializes with options
- Constructor calls
parseArn("arn:aws:bedrock:us-west-2:123456789012:prompt-router/my-router") parseArn()extracts:{ isValid: true, region: "us-west-2", modelType: "prompt-router", modelId: "my-router", crossRegionInference: false }- Constructor sets
this.arnInfoto the result - Constructor calls
getModel() getModel()callsgetModelById("my-router")getModelById()doesn't find "my-router" inbedrockModels, returns default model info- Since
this.arnInfo.modelTypeis "prompt-router" (not "foundation-model"),getModel()sets the ID to the full ARN this.costModelConfigis set to:{ id: "arn:aws:bedrock:us-west-2:123456789012:prompt-router/my-router", // Full ARN as ID info: { // Default model info for prompt routers maxTokens: 4096, contextWindow: 128000, inputPrice: 3, outputPrice: 15, // other model properties... } }
Example 4: Cross-Region Inference
Input:
const handler = new AwsBedrockHandler({
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
awsAccessKey: "ACCESS_KEY",
awsSecretKey: "SECRET_KEY",
awsRegion: "eu-west-1",
awsUseCrossRegionInference: true,
})
Sequence:
- Constructor initializes with options
- Constructor calls
getModel() getModel()callsgetModelById("anthropic.claude-3-5-sonnet-20241022-v2:0")getModelById()looks up the model inbedrockModels- Since
awsUseCrossRegionInferenceis true,getModel()gets the prefix for "eu-west-1" (which is "eu.") getModel()prepends "eu." to the model IDthis.costModelConfigis set to:{ id: "eu.anthropic.claude-3-5-sonnet-20241022-v2:0", // Note the "eu." prefix info: { maxTokens: 4096, contextWindow: 128000, inputPrice: 3, outputPrice: 15, // other model properties... } }
Example 5: Prompt Router with invokedModelId in Stream
Initial Input:
const handler = new AwsBedrockHandler({
awsAccessKey: "ACCESS_KEY",
awsSecretKey: "SECRET_KEY",
awsRegion: "us-west-2",
awsCustomArn: "arn:aws:bedrock:us-west-2:123456789012:prompt-router/my-router",
})
Initial Sequence (same as Example 3):
this.costModelConfigis initially set to:{ id: "arn:aws:bedrock:us-west-2:123456789012:prompt-router/my-router", info: { // Default model info for prompt routers maxTokens: 4096, contextWindow: 128000, inputPrice: 3, outputPrice: 15, // other properties... } }
Stream Event with invokedModelId:
{
trace: {
promptRouter: {
invokedModelId: "arn:aws:bedrock:us-west-2:123456789012:inference-profile/anthropic.claude-3-5-sonnet-20241022-v2:0",
usage: {
inputTokens: 150,
outputTokens: 250
}
}
}
}
Stream Processing Sequence:
createMessage()encounters the stream event withinvokedModelId- It calls
parseArn("arn:aws:bedrock:us-west-2:123456789012:inference-profile/anthropic.claude-3-5-sonnet-20241022-v2:0") parseArn()extracts:{ isValid: true, region: "us-west-2", modelType: "inference-profile", modelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", crossRegionInference: false }createMessage()callsgetModelById("anthropic.claude-3-5-sonnet-20241022-v2:0")getModelById()looks up the model inbedrockModelsand returns the model infocreateMessage()setsinvokedModel.idto the original router IDthis.costModelConfigis updated to:{ id: "arn:aws:bedrock:us-west-2:123456789012:prompt-router/my-router", // Keeps router ID info: { // Claude 3.5 Sonnet model info maxTokens: 4096, contextWindow: 128000, inputPrice: 3, outputPrice: 15, // other Claude-specific properties... } }
This ensures that:
- Subsequent requests continue to use the prompt router
- Token counting and pricing use the actual model's rates
- Context window and other model-specific properties are correctly set
Example 6: Cross-Region ARN with Region Prefix
Input:
const handler = new AwsBedrockHandler({
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
awsAccessKey: "ACCESS_KEY",
awsSecretKey: "SECRET_KEY",
awsRegion: "us-east-1",
awsCustomArn:
"arn:aws:bedrock:us-west-2:123456789012:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0",
})
Sequence:
- Constructor initializes with options
- Constructor calls
parseArn("arn:aws:bedrock:us-west-2:123456789012:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0") parseArn()extracts region and callsparseBaseModelId("us.anthropic.claude-3-5-sonnet-20241022-v2:0")parseBaseModelId()recognizes "us." as a region prefix and removes itparseArn()returns:{ isValid: true, region: "us-west-2", modelType: "inference-profile", modelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", // Note: prefix removed crossRegionInference: true // Detected cross-region }- Constructor sets
this.arnInfoto the result and updatesthis.options.awsRegionto "us-west-2" - Constructor calls
getModel() getModel()callsgetModelById("anthropic.claude-3-5-sonnet-20241022-v2:0")getModelById()looks up the model inbedrockModels- Since
this.arnInfo.modelTypeis "inference-profile" (not "foundation-model"),getModel()sets the ID to the full ARN this.costModelConfigis set to:{ id: "arn:aws:bedrock:us-west-2:123456789012:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0", // Full ARN info: { maxTokens: 4096, contextWindow: 128000, inputPrice: 3, outputPrice: 15, // other model properties... } }
Example 7: Single-Region ARN with Region Prefix (apne3)
Input:
const handler = new AwsBedrockHandler({
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
awsAccessKey: "ACCESS_KEY",
awsSecretKey: "SECRET_KEY",
awsRegion: "ap-northeast-3", // Osaka region
awsCustomArn:
"arn:aws:bedrock:ap-northeast-3:123456789012:inference-profile/apne3.anthropic.claude-3-5-sonnet-20241022-v2:0",
})
Sequence:
- Constructor initializes with options
- Constructor calls
parseArn("arn:aws:bedrock:ap-northeast-3:123456789012:inference-profile/apne3.anthropic.claude-3-5-sonnet-20241022-v2:0") parseArn()extracts region and callsparseBaseModelId("apne3.anthropic.claude-3-5-sonnet-20241022-v2:0")parseBaseModelId()recognizes "apne3." as a region prefix and removes itparseArn()returns:{ isValid: true, region: "ap-northeast-3", modelType: "inference-profile", modelId: "anthropic.claude-3-5-sonnet-20241022-v2:0", // Note: prefix removed crossRegionInference: false // Not a cross-region prefix since apne3 maps to a single region }- Constructor sets
this.arnInfoto the result - Constructor calls
getModel() getModel()callsgetModelById("anthropic.claude-3-5-sonnet-20241022-v2:0")getModelById()looks up the model inbedrockModels- Since
this.arnInfo.modelTypeis "inference-profile" (not "foundation-model"),getModel()sets the ID to the full ARN this.costModelConfigis set to:{ id: "arn:aws:bedrock:ap-northeast-3:123456789012:inference-profile/apne3.anthropic.claude-3-5-sonnet-20241022-v2:0", // Full ARN info: { maxTokens: 4096, contextWindow: 128000, inputPrice: 3, outputPrice: 15, // other model properties... } }
Region Prefixes
The system recognizes these region prefixes for cross-region inference:
| Prefix | Region ID | Description | Multi-Region |
|---|---|---|---|
| "us." | "us-east-1" | US East (N. Virginia) | Yes |
| "use1." | "us-east-1" | US East (N. Virginia) | No |
| "use2." | "us-east-2" | US East (Ohio) | No |
| "usw2." | "us-west-2" | US West (Oregon) | No |
| "eu." | "eu-west-1" | Europe (Ireland) | Yes |
| "euw1." | "eu-west-1" | Europe (Ireland) | No |
| "ap." | "ap-southeast-1" | Asia Pacific (Singapore) | Yes |
| "apne1." | "ap-northeast-1" | Asia Pacific (Tokyo) | No |
| "apne3." | "ap-northeast-3" | Asia Pacific (Osaka) | No |
| "ca." | "ca-central-1" | Canada (Central) | Yes |
| "sa." | "sa-east-1" | South America (São Paulo) | Yes |
| "apac." | "ap-southeast-1" | Default APAC region | Yes |
| "emea." | "eu-west-1" | Default EMEA region | Yes |
| "amer." | "us-east-1" | Default Americas region | Yes |
These prefixes are used to:
- Identify and strip region prefixes from model IDs in
parseBaseModelId() - Add appropriate region prefixes when cross-region inference is enabled in
getModel()
Note on Multi-Region Prefixes:
- Prefixes marked as "Multi-Region" (like "us.", "eu.", "ap.", etc.) set the
crossRegionInferenceflag totruewhen detected in an ARN - These prefixes typically represent a geographic area with multiple AWS regions
- Single-region prefixes (like "apne3.", "use1.", etc.) set the
crossRegionInferenceflag tofalse - The
crossRegionInferenceflag affects how the system handles region-specific model configurations
Summary
The Bedrock provider's model identification system follows these key principles:
- ARN Parsing: Extracts model ID, region, and resource type from ARNs
- Model Lookup: Uses the extracted model ID to find model information
- ID Preservation:
- For foundation models: Uses the model ID directly
- For other resources (prompt routers, inference profiles): Uses the full ARN as the ID
- Cross-Region Handling: Adds or removes region prefixes as needed
- Dynamic Updates: Updates model information when a prompt router provides an invokedModelId
This system ensures that:
- The correct model ID is used for API requests
- Accurate model information is used for token counting and pricing
- Cross-region inference works correctly
- Prompt routers can dynamically select models while maintaining proper tracking