1856 lines
74 KiB
Plaintext
1856 lines
74 KiB
Plaintext
---
|
||
title: "AWS Bedrock"
|
||
description: "AWS Bedrock API conversion guide - model families, parameter mapping, message handling, reasoning/thinking, tool conversion, and AWS authentication"
|
||
icon: "aws"
|
||
---
|
||
|
||
## Overview
|
||
|
||
AWS Bedrock supports multiple model families (Claude, Nova, Mistral, Llama, Cohere, Titan) with significant structural differences from OpenAI's format. Bifrost performs extensive conversion including:
|
||
|
||
- **Model family detection** - Automatic routing based on model ID to handle family-specific parameters
|
||
- **Parameter renaming** - e.g., `max_completion_tokens` → `maxTokens`, `stop` → `stopSequences`
|
||
- **Reasoning transformation** - `reasoning` parameters mapped to model-specific thinking/reasoning structures (Anthropic, Nova)
|
||
- **Tool restructuring** - Function definitions converted to Bedrock's ToolConfig format
|
||
- **Message conversion** - System message extraction, tool message grouping, image format adaptation (base64 only)
|
||
- **AWS authentication** - Automatic SigV4 request signing with credential chain support
|
||
- **Structured output** - `response_format` converted to specialized tool definitions
|
||
- **Service tier & guardrails** - Support for Bedrock-specific performance and safety configurations
|
||
|
||
### Model Family Support
|
||
|
||
| Family | Chat | Responses | Text | Embeddings | Image Generation | Image Edit | Image Variation |
|
||
| ---------------------- | ---- | --------- | ---- | ---------- | ---------------- | ---------- | --------------- |
|
||
| **Claude (Anthropic)** | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||
| **Nova (Anthropic)** | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ |
|
||
| **Mistral** | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||
| **Llama** | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||
| **Cohere** | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
||
| **Titan** | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
|
||
| **Stability AI** | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
|
||
|
||
### Supported Operations
|
||
|
||
| Operation | Non-Streaming | Streaming | Endpoint |
|
||
| -------------------- | ------------- | --------- | ---------------------- |
|
||
| Chat Completions | ✅ | ✅ | `converse` |
|
||
| Responses API | ✅ | ✅ | `converse` |
|
||
| Text Completions | ✅ | ❌ | `invoke` |
|
||
| Embeddings | ✅ | - | `invoke` |
|
||
| Files | ✅ | - | S3 (via SDK) |
|
||
| Batch | ✅ | - | `batch` |
|
||
| List Models | ✅ | - | `listFoundationModels` |
|
||
| Image Generation | ✅ | ❌ | `invoke` |
|
||
| Image Edit | ✅ | ❌ | `invoke` |
|
||
| Image Variation | ✅ | ❌ | `invoke` |
|
||
| Count Tokens | ✅ | - | `count-tokens` |
|
||
| Speech (TTS) | ❌ | ❌ | - |
|
||
| Transcriptions (STT) | ❌ | ❌ | - |
|
||
|
||
<Note>
|
||
**Unsupported Operations** (❌): Speech (TTS) and Transcriptions (STT) are not supported by the upstream AWS Bedrock API. These return `UnsupportedOperationError`.
|
||
|
||
**Limitations**: Images must be in base64 or data URI format (remote URLs not supported). Text completion streaming is not supported.
|
||
|
||
</Note>
|
||
|
||
---
|
||
|
||
## Setup & Configuration
|
||
|
||
Bedrock supports both SigV4-based authentication and direct API-key authentication. Four authentication flows are supported — choose the one that matches your deployment environment.
|
||
|
||
<Note>
|
||
The `aliases` field (mapping model names to inference profile IDs, ARNs, or
|
||
deployment identifiers) requires **v1.5.0-prerelease2 or later**. On v1.4.x,
|
||
use `deployments` inside `bedrock_key_config` instead — see the [v1.5.0
|
||
Migration
|
||
Guide](/migration-guides/v1.5.0#breaking-change-9-provider-deployments-removed-migrate-to-aliases)
|
||
for details.
|
||
</Note>
|
||
|
||
### 1. Explicit Credentials
|
||
|
||
Provide `access_key` and `secret_key` directly. Optionally include `session_token` for temporary credentials.
|
||
|
||
<Tabs>
|
||
|
||
<Tab title="Web UI">
|
||
|
||
<Frame>
|
||
<img
|
||
src="/media/ui-bedrock-explicit-credentials-auth-setup.png"
|
||
alt="AWS Bedrock explicit credentials authentication setup in the Bifrost Web UI showing Access Key, Secret Key, Session Token, and Region fields"
|
||
/>
|
||
</Frame>
|
||
|
||
1. Navigate to **"Model Providers"** → **"Configurations"** → **"AWS Bedrock"**
|
||
2. Click **"Add Key"** (or edit an existing key)
|
||
3. Under **Authentication Method**, select **"Explicit Credentials"**
|
||
4. Set **Access Key**: Your AWS access key ID
|
||
5. Set **Secret Key**: Your AWS secret access key
|
||
6. Set **Session Token** (Optional): For temporary/assumed credentials
|
||
7. Set **Region**: e.g., `us-east-1`
|
||
8. Configure **Aliases**: Map model names to inference profile IDs
|
||
9. Save
|
||
|
||
</Tab>
|
||
|
||
<Tab title="API">
|
||
|
||
```bash
|
||
# Step 1: Create the provider
|
||
curl -X POST http://localhost:8080/api/providers \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"provider": "bedrock"}'
|
||
|
||
# Step 2: Create a key (Explicit Credentials)
|
||
curl -X POST http://localhost:8080/api/providers/bedrock/keys \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "bedrock-key",
|
||
"models": ["*"],
|
||
"weight": 1.0,
|
||
"aliases": {
|
||
"claude-3-5-sonnet": "us.anthropic.claude-3-5-sonnet-20241022-v2:0"
|
||
},
|
||
"bedrock_key_config": {
|
||
"access_key": "env.AWS_ACCESS_KEY_ID",
|
||
"secret_key": "env.AWS_SECRET_ACCESS_KEY",
|
||
"session_token": "env.AWS_SESSION_TOKEN",
|
||
"region": "us-east-1"
|
||
}
|
||
}'
|
||
```
|
||
|
||
<Note>
|
||
**On v1.4.x**, two differences apply:
|
||
- Pass `keys` directly in the `POST /api/providers` body — there is no separate `/api/providers/{provider}/keys` endpoint.
|
||
- Replace the top-level `aliases` with `"deployments"` inside `bedrock_key_config`:
|
||
```json
|
||
"bedrock_key_config": {
|
||
"access_key": "env.AWS_ACCESS_KEY_ID",
|
||
"secret_key": "env.AWS_SECRET_ACCESS_KEY",
|
||
"region": "us-east-1",
|
||
"deployments": {
|
||
"claude-3-5-sonnet": "arn:aws:bedrock:us-east-1::foundation-model/..."
|
||
}
|
||
}
|
||
```
|
||
</Note>
|
||
|
||
</Tab>
|
||
|
||
<Tab title="config.json">
|
||
|
||
```json
|
||
{
|
||
"providers": {
|
||
"bedrock": {
|
||
"keys": [
|
||
{
|
||
"name": "bedrock-key",
|
||
"models": ["*"],
|
||
"weight": 1.0,
|
||
"aliases": {
|
||
"claude-3-5-sonnet": "us.anthropic.claude-3-5-sonnet-20241022-v2:0"
|
||
},
|
||
"bedrock_key_config": {
|
||
"access_key": "env.AWS_ACCESS_KEY_ID",
|
||
"secret_key": "env.AWS_SECRET_ACCESS_KEY",
|
||
"session_token": "env.AWS_SESSION_TOKEN",
|
||
"region": "us-east-1"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
<Note>
|
||
On **v1.4.x**, use `deployments` inside `bedrock_key_config` instead of the
|
||
top-level `aliases` field.
|
||
</Note>
|
||
|
||
</Tab>
|
||
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
func (a *MyAccount) GetKeysForProvider(ctx *context.Context, provider schemas.ModelProvider) ([]schemas.Key, error) {
|
||
switch provider {
|
||
case schemas.Bedrock:
|
||
return []schemas.Key{
|
||
{
|
||
Models: []string{"*"},
|
||
Weight: 1.0,
|
||
Aliases: schemas.KeyAliases{
|
||
"claude-3-5-sonnet": "us.anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
},
|
||
BedrockKeyConfig: &schemas.BedrockKeyConfig{
|
||
AccessKey: *schemas.NewEnvVar("env.AWS_ACCESS_KEY_ID"),
|
||
SecretKey: *schemas.NewEnvVar("env.AWS_SECRET_ACCESS_KEY"),
|
||
SessionToken: schemas.NewEnvVar("env.AWS_SESSION_TOKEN"),
|
||
Region: schemas.NewEnvVar("us-east-1"),
|
||
},
|
||
},
|
||
}, nil
|
||
}
|
||
return nil, fmt.Errorf("provider %s not supported", provider)
|
||
}
|
||
```
|
||
|
||
</Tab>
|
||
|
||
</Tabs>
|
||
|
||
### 2. Inherited AWS Credentials / IAM Role
|
||
|
||
Uses AWS's default credential chain when static credentials are not configured. That includes IAM roles (IRSA in EKS, ECS task role, EC2 instance profile), environment variables (`AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`), and shared credential files.
|
||
|
||
<Tabs>
|
||
|
||
<Tab title="Web UI">
|
||
|
||
<Frame>
|
||
<img
|
||
src="/media/ui-bedrock-sts-assume-role-auth-setup.png"
|
||
alt="AWS Bedrock IAM Role authentication setup in the Bifrost Web UI showing optional Assume Role ARN, External ID, and Session Name fields"
|
||
/>
|
||
</Frame>
|
||
|
||
1. Navigate to **"Model Providers"** → **"Configurations"** → **"AWS Bedrock"**
|
||
2. Click **"Add Key"** (or edit an existing key)
|
||
3. Under **Authentication Method**, select **"IAM Role (Inherited)"**
|
||
4. Set **Region**: e.g., `us-east-1`
|
||
5. Configure **Aliases** if needed
|
||
6. _(Optional)_ Set **Assume Role ARN**: to assume an IAM role before signing (e.g., `arn:aws:iam::123456789012:role/BedrockRole`)
|
||
7. _(Optional)_ Set **External ID**: required when the role's trust policy demands it
|
||
8. _(Optional)_ Set **Session Name**: identifies the session in CloudTrail (default: `bifrost-session`)
|
||
9. Save
|
||
|
||
For system identity, leave steps 6–8 blank. Ensure your workload has an IAM role with Bedrock permissions attached (via IRSA, ECS task role, or EC2 instance profile), or that `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` are set in the environment.
|
||
|
||
</Tab>
|
||
|
||
<Tab title="API">
|
||
|
||
```bash
|
||
# Step 1: Create the provider
|
||
curl -X POST http://localhost:8080/api/providers \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"provider": "bedrock"}'
|
||
|
||
# Step 2a: System identity — leave credentials empty
|
||
curl -X POST http://localhost:8080/api/providers/bedrock/keys \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "bedrock-iam",
|
||
"models": ["*"],
|
||
"weight": 1.0,
|
||
"aliases": {
|
||
"claude-3-5-sonnet": "us.anthropic.claude-3-5-sonnet-20241022-v2:0"
|
||
},
|
||
"bedrock_key_config": {
|
||
"region": "us-east-1"
|
||
}
|
||
}'
|
||
|
||
# Step 2b: AssumeRole — add role_arn on top
|
||
curl -X POST http://localhost:8080/api/providers/bedrock/keys \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "bedrock-assume-role",
|
||
"models": ["*"],
|
||
"weight": 1.0,
|
||
"bedrock_key_config": {
|
||
"region": "us-east-1",
|
||
"role_arn": "env.AWS_ROLE_ARN",
|
||
"external_id": "env.AWS_EXTERNAL_ID",
|
||
"session_name": "bifrost-session"
|
||
}
|
||
}'
|
||
```
|
||
|
||
<Note>
|
||
**On v1.4.x**, two differences apply: - Pass `keys` directly in the `POST
|
||
/api/providers` body — there is no separate `/api/providers/{provider}/keys`
|
||
endpoint. - Replace the top-level `aliases` with `"deployments"` inside
|
||
`bedrock_key_config`.
|
||
</Note>
|
||
|
||
</Tab>
|
||
|
||
<Tab title="config.json">
|
||
|
||
```json
|
||
{
|
||
"providers": {
|
||
"bedrock": {
|
||
"keys": [
|
||
{
|
||
"name": "bedrock-iam",
|
||
"models": ["*"],
|
||
"weight": 1.0,
|
||
"aliases": {
|
||
"claude-3-5-sonnet": "us.anthropic.claude-3-5-sonnet-20241022-v2:0"
|
||
},
|
||
"bedrock_key_config": {
|
||
"region": "us-east-1",
|
||
"role_arn": "env.AWS_ROLE_ARN",
|
||
"external_id": "env.AWS_EXTERNAL_ID",
|
||
"session_name": "bifrost-session"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
<Note>
|
||
Omit `role_arn`, `external_id`, and `session_name` for plain system identity
|
||
with no role assumption.
|
||
</Note>
|
||
|
||
</Tab>
|
||
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
func (a *MyAccount) GetKeysForProvider(ctx *context.Context, provider schemas.ModelProvider) ([]schemas.Key, error) {
|
||
switch provider {
|
||
case schemas.Bedrock:
|
||
return []schemas.Key{
|
||
{
|
||
Models: []string{"*"},
|
||
Weight: 1.0,
|
||
Aliases: schemas.KeyAliases{
|
||
"claude-3-5-sonnet": "us.anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
},
|
||
BedrockKeyConfig: &schemas.BedrockKeyConfig{
|
||
// Leave AccessKey and SecretKey empty — resolved from IRSA/instance profile/env vars
|
||
Region: schemas.NewEnvVar("us-east-1"),
|
||
RoleARN: schemas.NewEnvVar("env.AWS_ROLE_ARN"), // optional
|
||
ExternalID: schemas.NewEnvVar("env.AWS_EXTERNAL_ID"), // optional
|
||
RoleSessionName: schemas.NewEnvVar("bifrost-session"), // optional
|
||
},
|
||
},
|
||
}, nil
|
||
}
|
||
return nil, fmt.Errorf("provider %s not supported", provider)
|
||
}
|
||
```
|
||
|
||
</Tab>
|
||
|
||
</Tabs>
|
||
|
||
### 3. API Key
|
||
|
||
Set `value` to a Bearer token for direct API key authentication. This method uses a Bearer token instead of SigV4 signing and does not support STS AssumeRole.
|
||
|
||
<Tabs>
|
||
|
||
<Tab title="Web UI">
|
||
|
||
<Frame>
|
||
<img
|
||
src="/media/ui-bedrock-api-key-auth-setup.png"
|
||
alt="AWS Bedrock API Key authentication setup in the Bifrost Web UI showing the API Key field and Region"
|
||
/>
|
||
</Frame>
|
||
|
||
1. Navigate to **"Model Providers"** → **"Configurations"** → **"AWS Bedrock"**
|
||
2. Click **"Add Key"** (or edit an existing key)
|
||
3. Under **Authentication Method**, select **"API Key"**
|
||
4. Set **API Key**: Your Bedrock API key (Bearer token)
|
||
5. Set **Region**: e.g., `us-east-1`
|
||
6. Configure **Aliases** if needed
|
||
7. Save
|
||
|
||
</Tab>
|
||
|
||
<Tab title="API">
|
||
|
||
```bash
|
||
# Step 1: Create the provider
|
||
curl -X POST http://localhost:8080/api/providers \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"provider": "bedrock"}'
|
||
|
||
# Step 2: Create a key (API Key / Bearer token)
|
||
curl -X POST http://localhost:8080/api/providers/bedrock/keys \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "bedrock-api-key",
|
||
"value": "env.BEDROCK_API_KEY",
|
||
"models": ["*"],
|
||
"weight": 1.0,
|
||
"bedrock_key_config": {
|
||
"region": "us-east-1"
|
||
}
|
||
}'
|
||
```
|
||
|
||
</Tab>
|
||
|
||
<Tab title="config.json">
|
||
|
||
```json
|
||
{
|
||
"providers": {
|
||
"bedrock": {
|
||
"keys": [
|
||
{
|
||
"name": "bedrock-api-key",
|
||
"value": "env.BEDROCK_API_KEY",
|
||
"models": ["*"],
|
||
"weight": 1.0,
|
||
"bedrock_key_config": {
|
||
"region": "us-east-1"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
</Tab>
|
||
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
func (a *MyAccount) GetKeysForProvider(ctx *context.Context, provider schemas.ModelProvider) ([]schemas.Key, error) {
|
||
switch provider {
|
||
case schemas.Bedrock:
|
||
return []schemas.Key{
|
||
{
|
||
Value: *schemas.NewEnvVar("env.BEDROCK_API_KEY"),
|
||
Models: []string{"*"},
|
||
Weight: 1.0,
|
||
BedrockKeyConfig: &schemas.BedrockKeyConfig{
|
||
Region: schemas.NewEnvVar("us-east-1"),
|
||
},
|
||
},
|
||
}, nil
|
||
}
|
||
return nil, fmt.Errorf("provider %s not supported", provider)
|
||
}
|
||
```
|
||
|
||
</Tab>
|
||
|
||
</Tabs>
|
||
|
||
**`bedrock_key_config` fields:**
|
||
|
||
| Field | Required | Default | Description |
|
||
| --------------- | -------- | ----------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||
| `region` | Yes | — | AWS region (e.g., `us-east-1`) |
|
||
| `access_key` | No | — | AWS access key ID |
|
||
| `secret_key` | No | — | AWS secret access key |
|
||
| `session_token` | No | — | AWS session token (for temporary credentials) |
|
||
| `arn` | No | — | ARN prefix for constructing inference profile URLs (see [Inference Profiles](#inference-profiles--arn-configuration)) |
|
||
| `role_arn` | No | — | IAM role ARN for STS AssumeRole |
|
||
| `external_id` | No | — | External ID for AssumeRole (when required by trust policy) |
|
||
| `session_name` | No | `bifrost-session` | Session name for AssumeRole CloudTrail logs |
|
||
|
||
**Key-level fields:**
|
||
|
||
| Field | Required | Description |
|
||
| --------- | -------- | ----------------------------------------------------------------------------------- |
|
||
| `aliases` | No | Map model names to inference profile IDs or Bedrock model IDs (v1.5.0-prerelease2+) |
|
||
| `models` | Yes | Models this key can serve; use `["*"]` to allow all |
|
||
|
||
---
|
||
|
||
## Beta Headers
|
||
|
||
For Claude models on Bedrock, Bifrost validates `anthropic-beta` headers and drops unsupported headers from the request.
|
||
|
||
**Supported**: `computer-use-*`, `structured-outputs-*`, `compact-*`, `context-management-*`, `interleaved-thinking-*`, `context-1m-*`
|
||
|
||
**Not supported**: `advanced-tool-use-*`, `mcp-client-*`, `prompt-caching-scope-*`, `files-api-*`, `skills-*`, `fast-mode-*`, `redact-thinking-*`
|
||
|
||
You can override these defaults per provider via the **Beta Headers** tab in provider configuration or via [`beta_header_overrides`](/quickstart/gateway/provider-configuration#beta-header-overrides). See the full support matrix in the [Anthropic provider docs](/providers/supported-providers/anthropic#beta-headers).
|
||
|
||
<Frame>
|
||
<img
|
||
src="/media/aws-bedrock-anthropic-beta-headers.png"
|
||
alt="AWS bedrock Beta Headers configuration tab showing supported and unsupported Anthropic beta features with override options"
|
||
/>
|
||
</Frame>
|
||
|
||
---
|
||
|
||
# 1. Chat Completions
|
||
|
||
## Request Parameters
|
||
|
||
### Parameter Mapping
|
||
|
||
| Parameter | Transformation | Notes |
|
||
| ----------------------- | --------------------------------------------------------------------------------- | -------------------------- |
|
||
| `max_completion_tokens` | → `inferenceConfig.maxTokens` | Required field in Bedrock |
|
||
| `temperature`, `top_p` | Direct pass-through to `inferenceConfig` | |
|
||
| `stop` | → `inferenceConfig.stopSequences` | Array of strings |
|
||
| `response_format` | → Structured output tool (see [Structured Output](#structured-output)) | Creates `bf_so_*` tool |
|
||
| `tools` | Schema restructured (see [Tool Conversion](#tool-conversion)) | |
|
||
| `tool_choice` | Type mapped (see [Tool Conversion](#tool-conversion)) | |
|
||
| `reasoning` | Model-specific thinking config (see [Reasoning / Thinking](#reasoning--thinking)) | |
|
||
| `user` | → `metadata.userID` (if provided) | Bedrock-specific metadata |
|
||
| `service_tier` | → `serviceModelTier` (if provided) | Performance tier selection |
|
||
| `top_k` | Via `extra_params` (model-specific) | Bedrock-specific sampling |
|
||
|
||
### Dropped Parameters
|
||
|
||
The following parameters are silently ignored: `frequency_penalty`, `presence_penalty`, `logit_bias`, `logprobs`, `top_logprobs`, `seed`, `parallel_tool_calls`
|
||
|
||
### Extra Parameters
|
||
|
||
Use `extra_params` (SDK) or pass directly in request body (Gateway) for Bedrock-specific fields:
|
||
|
||
<Tabs>
|
||
<Tab title="Gateway">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/chat/completions \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
"messages": [{"role": "user", "content": "Hello"}],
|
||
"guardrailConfig": {
|
||
"guardrailIdentifier": "guardrail-id",
|
||
"guardrailVersion": "1",
|
||
"trace": "enabled"
|
||
},
|
||
"performanceConfig": {
|
||
"latency": "optimized"
|
||
}
|
||
}'
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
resp, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
|
||
Provider: schemas.Bedrock,
|
||
Model: "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
Input: messages,
|
||
Params: &schemas.ChatParameters{
|
||
ExtraParams: map[string]interface{}{
|
||
"guardrailConfig": map[string]interface{}{
|
||
"guardrailIdentifier": "guardrail-id",
|
||
"guardrailVersion": "1",
|
||
"trace": "enabled",
|
||
},
|
||
"performanceConfig": map[string]interface{}{
|
||
"latency": "optimized",
|
||
},
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
</Tab>
|
||
</Tabs>
|
||
|
||
**Available Extra Parameters:**
|
||
|
||
- `guardrailConfig` - Bedrock guardrail configuration with `guardrailIdentifier`, `guardrailVersion`, `trace`
|
||
- `performanceConfig` - Performance optimization with `latency` ("optimized" or "standard")
|
||
- `additionalModelRequestFieldPaths` - Pass-through for model-specific fields not in standard schema
|
||
- `promptVariables` - Variables for prompt templates (if using prompt caching)
|
||
- `requestMetadata` - Custom metadata for request tracking
|
||
|
||
### Cache Control
|
||
|
||
Prompt caching is supported via cache control directives:
|
||
|
||
<Tabs>
|
||
<Tab title="Gateway">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/chat/completions \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
"messages": [
|
||
{
|
||
"role": "user",
|
||
"content": [
|
||
{
|
||
"type": "text",
|
||
"text": "This context will be cached",
|
||
"cache_control": {"type": "ephemeral"}
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"system": [
|
||
{
|
||
"type": "text",
|
||
"text": "You are a helpful assistant",
|
||
"cache_control": {"type": "ephemeral"}
|
||
}
|
||
]
|
||
}'
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
resp, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
|
||
Provider: schemas.Bedrock,
|
||
Model: "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
Input: []schemas.ChatMessage{
|
||
{
|
||
Role: schemas.ChatMessageRoleUser,
|
||
Content: &schemas.ChatMessageContent{
|
||
ContentBlocks: []schemas.ChatContentBlock{
|
||
{
|
||
Text: schemas.Ptr("This context will be cached"),
|
||
CacheControl: &schemas.CacheControl{
|
||
Type: schemas.Ptr("ephemeral"),
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
SystemMessages: []schemas.ChatMessage{
|
||
{
|
||
Role: schemas.ChatMessageRoleSystem,
|
||
Content: &schemas.ChatMessageContent{
|
||
ContentBlocks: []schemas.ChatContentBlock{
|
||
{
|
||
Text: schemas.Ptr("You are a helpful assistant"),
|
||
CacheControl: &schemas.CacheControl{
|
||
Type: schemas.Ptr("ephemeral"),
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
</Tab>
|
||
</Tabs>
|
||
|
||
## Reasoning / Thinking
|
||
|
||
**Documentation**: See [Bifrost Reasoning Reference](/providers/reasoning)
|
||
|
||
Reasoning/thinking support varies by model family:
|
||
|
||
### Anthropic Claude Models
|
||
|
||
**Parameter Mapping:**
|
||
|
||
- `reasoning.effort` → `thinkingConfig.type = "enabled"` (always enabled when reasoning present)
|
||
- `reasoning.max_tokens` → `thinkingConfig.budgetTokens` (token budget for thinking)
|
||
|
||
**Critical Constraints:**
|
||
|
||
- **Minimum budget**: 1024 tokens required; requests below this **fail with error**
|
||
- **Dynamic budget**: `-1` is converted to `1024` automatically
|
||
|
||
```json
|
||
// Request
|
||
{"reasoning": {"effort": "high", "max_tokens": 2048}}
|
||
|
||
// Bedrock conversion
|
||
{"thinkingConfig": {"type": "enabled", "budgetTokens": 2048}}
|
||
```
|
||
|
||
### Anthropic Nova Models
|
||
|
||
**Parameter Mapping:**
|
||
|
||
- `reasoning.effort` → `reasoningConfig.thinkingLevel` ("low" → `low`, "high" → `high`)
|
||
- `reasoning.max_tokens` → Max reasoning tokens (affects inference configuration)
|
||
|
||
```json
|
||
// Request
|
||
{"reasoning": {"effort": "high", "max_tokens": 10000}}
|
||
|
||
// Bedrock conversion
|
||
{"reasoningConfig": {"type": "enabled", "thinkingLevel": "high"}}
|
||
```
|
||
|
||
## Message Conversion
|
||
|
||
### Critical Caveats
|
||
|
||
- **System message extraction**: System messages are **removed from messages array** and placed in separate `system` field
|
||
- **Tool message grouping**: Consecutive tool messages are **merged into single user message** with tool result content blocks
|
||
- **Image format**: **Only base64/data URI supported**; remote image URLs are **not supported** by Bedrock Converse API
|
||
- **Document support**: Bifrost's Bedrock conversion path currently supports PDF, CSV, DOC, DOCX, XLS, XLSX, HTML, TXT, MD formats
|
||
|
||
### Supported Chat Content Blocks
|
||
|
||
The Chat Completions request format is OpenAI-compatible for standard blocks (`type: "text"`, `type: "image_url"`, `type: "file"`). Bifrost converts these blocks to Bedrock Converse blocks internally. Bedrock-specific extensions (for example, standalone `cachePoint`) are also accepted when using the Bedrock provider.
|
||
|
||
| Block Type | Request Shape (Bifrost/OpenAI) | Bedrock Handling | Support |
|
||
| ---------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------- |
|
||
| Text | `{"type":"text","text":"..."}` | Converted to Bedrock `text` block | ✅ |
|
||
| Image | `{"type":"image_url","image_url":{"url":"data:image/png;base64,..."}}` | Converted to Bedrock `image.source.bytes` | ✅ (base64/data URI only) |
|
||
| File | `{"type":"file","file":{...}}` | Converted to Bedrock `document` block | ✅ |
|
||
| Input audio | `{"type":"input_audio",...}` | Returns `audio input not supported in Bedrock Converse API` | ❌ |
|
||
| Standalone cache point | `{"cachePoint":{"type":"default"}}` (no outer `type` field) | Converted to Bedrock `cachePoint` marker | ✅ (Bedrock-specific extension) |
|
||
|
||
### Image Conversion
|
||
|
||
- **Request shape (client → Bifrost)**: `type: "image_url"` with `image_url.url` set to a data URI/base64 image
|
||
- **Internal Bedrock shape (Bifrost → Bedrock)**: Converted to `image: { format, source: { bytes } }`
|
||
- **URL images**: ❌ **Not supported** - Will fail if attempted
|
||
- **Documents**: Converted to document content blocks with MIME types
|
||
|
||
### Image Block Example (`image_url`)
|
||
|
||
<Tabs>
|
||
<Tab title="Gateway">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/chat/completions \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
"messages": [
|
||
{
|
||
"role": "user",
|
||
"content": [
|
||
{"type": "text", "text": "What is in this image?"},
|
||
{
|
||
"type": "image_url",
|
||
"image_url": {
|
||
"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}'
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
// Note: In the Go SDK, ChatContentBlockTypeImage maps to the OpenAI-compatible "image_url" block.
|
||
resp, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
|
||
Provider: schemas.Bedrock,
|
||
Model: "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
Input: []schemas.ChatMessage{
|
||
{
|
||
Role: schemas.ChatMessageRoleUser,
|
||
Content: &schemas.ChatMessageContent{
|
||
ContentBlocks: []schemas.ChatContentBlock{
|
||
{
|
||
Type: schemas.ChatContentBlockTypeText,
|
||
Text: schemas.Ptr("What is in this image?"),
|
||
},
|
||
{
|
||
Type: schemas.ChatContentBlockTypeImage,
|
||
ImageURLStruct: &schemas.ChatInputImage{
|
||
URL: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
</Tab>
|
||
</Tabs>
|
||
|
||
### File Block Example (`file` → Bedrock `document`)
|
||
|
||
<Tabs>
|
||
<Tab title="Gateway">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/chat/completions \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
"messages": [
|
||
{
|
||
"role": "user",
|
||
"content": [
|
||
{"type": "text", "text": "Summarize this document."},
|
||
{
|
||
"type": "file",
|
||
"file": {
|
||
"file_data": "JVBERi0xLjQKJcfs...",
|
||
"filename": "report.pdf",
|
||
"file_type": "application/pdf"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}'
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
resp, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
|
||
Provider: schemas.Bedrock,
|
||
Model: "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
Input: []schemas.ChatMessage{
|
||
{
|
||
Role: schemas.ChatMessageRoleUser,
|
||
Content: &schemas.ChatMessageContent{
|
||
ContentBlocks: []schemas.ChatContentBlock{
|
||
{
|
||
Type: schemas.ChatContentBlockTypeText,
|
||
Text: schemas.Ptr("Summarize this document."),
|
||
},
|
||
{
|
||
Type: schemas.ChatContentBlockTypeFile,
|
||
File: &schemas.ChatInputFile{
|
||
FileData: schemas.Ptr("JVBERi0xLjQKJcfs..."),
|
||
Filename: schemas.Ptr("report.pdf"),
|
||
FileType: schemas.Ptr("application/pdf"),
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
</Tab>
|
||
</Tabs>
|
||
|
||
Note: `file_data` is raw base64-encoded content (no `data:` URI prefix, unlike `image_url`).
|
||
|
||
Formats currently supported by Bifrost's Bedrock document conversion path: `pdf`, `txt`, `md`, `html`, `csv`, `doc`, `docx`, `xls`, `xlsx`.
|
||
|
||
### Standalone Cache Point Example (Bedrock-specific)
|
||
|
||
```json
|
||
{
|
||
"role": "system",
|
||
"content": [
|
||
{ "type": "text", "text": "Long context to cache" },
|
||
{ "cachePoint": { "type": "default" } }
|
||
]
|
||
}
|
||
```
|
||
|
||
This standalone `cachePoint` block is a Bifrost/Bedrock extension (not OpenAI-standard) and should be used only with the Bedrock provider.
|
||
|
||
### Unsupported Block Notes
|
||
|
||
- `input_audio` blocks are not supported by Bedrock Converse and return an error.
|
||
- For chat content conversion, use `file.file_data` for document payloads. `file_url` and `file_id` are not the documented Bedrock chat-content path here.
|
||
|
||
### Cache Control Locations
|
||
|
||
Cache directives supported on:
|
||
|
||
- System content blocks (entire system message)
|
||
- User message content blocks (specific parts)
|
||
- Tool definitions within tool configuration
|
||
|
||
## Tool Conversion
|
||
|
||
Tool definitions are restructured:
|
||
|
||
- `function.name` → `name` (preserved)
|
||
- `function.parameters` → `inputSchema` (Schema format)
|
||
- `function.strict` → Dropped (not supported by Bedrock)
|
||
|
||
### Tool Choice Mapping
|
||
|
||
| OpenAI | Bedrock |
|
||
| ------------- | ---------------------------------- |
|
||
| `"auto"` | `auto` (default) |
|
||
| `"none"` | Omitted (not explicitly supported) |
|
||
| `"required"` | `any` |
|
||
| Specific tool | `{type: "tool", name: "X"}` |
|
||
|
||
### Tool Call Handling
|
||
|
||
Tool calls are converted between formats:
|
||
|
||
- **Bifrost → Bedrock**: Tool call arguments converted from JSON object to `input` field
|
||
- **Bedrock → Bifrost**: Tool use results with `toolUseId`, converted back to Bifrost format
|
||
- **Tool results**: Merged consecutive tool messages into single user message
|
||
|
||
## Structured Output
|
||
|
||
Structured output uses a special tool-based approach:
|
||
|
||
```json
|
||
// Request with structured output
|
||
{
|
||
"response_format": {
|
||
"type": "json_schema",
|
||
"json_schema": {
|
||
"name": "response",
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {"type": "string"},
|
||
"age": {"type": "number"}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Bedrock conversion (internal)
|
||
{
|
||
"tools": [{
|
||
"name": "bf_so_response",
|
||
"description": "Structured output tool",
|
||
"inputSchema": {
|
||
"type": "object",
|
||
"properties": {...}
|
||
}
|
||
}],
|
||
"toolChoice": {"type": "tool", "name": "bf_so_response"}
|
||
}
|
||
|
||
// Response extraction
|
||
// Tool use input is extracted and returned as contentStr
|
||
```
|
||
|
||
## Response Conversion
|
||
|
||
### Field Mapping
|
||
|
||
- `stopReason` → `finish_reason`: `endTurn`/`stopSequence` → `stop`, `maxTokens` → `length`, `toolUse` → `tool_calls`
|
||
- `usage.inputTokens + usage.cacheReadInputTokens + usage.cacheWriteInputTokens` → `prompt_tokens` (all cache counts rolled into the total)
|
||
- Cache token breakdown surfaced in `prompt_tokens_details`:
|
||
- `usage.cacheReadInputTokens` → `prompt_tokens_details.cached_read_tokens`
|
||
- `usage.cacheWriteInputTokens` → `prompt_tokens_details.cached_write_tokens`
|
||
- `usage.outputTokens` → `completion_tokens`
|
||
- `reasoning`/`thinking` blocks → `reasoning_details` with index, type, text, and signature
|
||
- Tool call `input` (object) → `arguments` (JSON string)
|
||
|
||
### Structured Output Response
|
||
|
||
When structured output is detected:
|
||
|
||
- Tool call with name `bf_so_*` is treated as structured output
|
||
- `input` object is extracted and returned as `contentStr`
|
||
- Removed from `toolCalls` array
|
||
|
||
## Streaming
|
||
|
||
### Chat Completions Streaming
|
||
|
||
Event sequence from Bedrock Converse Stream API:
|
||
|
||
1. **Initial message role**: `contentBlockIndex` and role information
|
||
2. **Content block starts**: `toolUse` blocks with `toolUseId`, `name`
|
||
3. **Content block deltas**:
|
||
- Text delta: Incremental text content
|
||
- Tool use delta: Accumulated tool call arguments (JSON)
|
||
- Reasoning delta: Reasoning text and optional signature
|
||
4. **Message completion**: `stopReason` and final token counts
|
||
5. **Usage metrics**: Token counts, cached tokens, performance metrics
|
||
|
||
**Streaming event conversion**:
|
||
|
||
- Each Bedrock streaming event → Multiple Bifrost chunks as needed
|
||
- Tool arguments accumulated across deltas and emitted on block end
|
||
- Reasoning content emitted with signature if present
|
||
|
||
### Text Completion Streaming
|
||
|
||
❌ **Not supported** - AWS Bedrock's text completion API does not support streaming.
|
||
|
||
### Responses API Streaming
|
||
|
||
Streaming responses use OpenAI-compatible lifecycle events:
|
||
|
||
- `response.created`
|
||
- `response.in_progress`
|
||
- `content_part.start`
|
||
- `content_part.delta`
|
||
- `content_part.done`
|
||
- `function_call_arguments.delta`
|
||
- `function_call_arguments.done`
|
||
- `output_item.done`
|
||
|
||
Special handling:
|
||
|
||
- Tool arguments accumulated across deltas
|
||
- Content block indices mapped to output indices
|
||
- Synthetic events emitted for text/reasoning content
|
||
|
||
---
|
||
|
||
# 2. Responses API
|
||
|
||
The Responses API uses the same underlying `converse` endpoint but converts between OpenAI's Responses format and Bedrock's Messages format.
|
||
|
||
## Request Parameters
|
||
|
||
### Parameter Mapping
|
||
|
||
| Parameter | Transformation |
|
||
| ---------------------- | -------------------------------------------------------------------------------------- |
|
||
| `max_output_tokens` | Renamed to `maxTokens` (via `inferenceConfig`) |
|
||
| `temperature`, `top_p` | Direct pass-through |
|
||
| `instructions` | Becomes system message |
|
||
| `tools` | Schema restructured (see [Chat Completions](#1-chat-completions)) |
|
||
| `tool_choice` | Type mapped (see [Chat Completions](#1-chat-completions)) |
|
||
| `reasoning` | Mapped to thinking/reasoning config (see [Reasoning / Thinking](#reasoning--thinking)) |
|
||
| `text` | Converted to `output_format` (Bedrock-specific) |
|
||
| `include` | Via `extra_params` (Bedrock-specific) |
|
||
| `stop` | Via `extra_params`, renamed to `stopSequences` |
|
||
| `truncation` | Auto-set to `"auto"` for computer tools |
|
||
|
||
### Extra Parameters
|
||
|
||
Use `extra_params` (SDK) or pass directly in request body (Gateway):
|
||
|
||
<Tabs>
|
||
<Tab title="Gateway">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/responses \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
"input": "Hello, how are you?",
|
||
"stop": ["###"]
|
||
}'
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
resp, err := client.ResponsesRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostResponsesRequest{
|
||
Provider: schemas.Bedrock,
|
||
Model: "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||
Input: messages,
|
||
Params: &schemas.ResponsesParameters{
|
||
ExtraParams: map[string]interface{}{
|
||
"stop": []string{"###"},
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
</Tab>
|
||
</Tabs>
|
||
|
||
## Input & Instructions
|
||
|
||
- **Input**: String wrapped as user message or array converted to messages
|
||
- **Instructions**: Becomes system message (same extraction as [Chat Completions](#1-chat-completions))
|
||
- **Cache control**: Supported on instructions (system) and input messages
|
||
|
||
## Response Conversion
|
||
|
||
- `stopReason` → `status`: `endTurn`/`stopSequence` → `completed`, `maxTokens` → `incomplete`
|
||
- `usage.inputTokens` is aggregated into `input_tokens` (same semantics as [Chat](#1-chat-completions): Bedrock's `inputTokens` + `cacheReadInputTokens` + `cacheWriteInputTokens` rolled up into `input_tokens`); `usage.outputTokens` → `output_tokens` (preserved as-is)
|
||
- Cache tokens: `cacheReadInputTokens` → `input_tokens_details.cached_read_tokens` | `cacheWriteInputTokens` → `input_tokens_details.cached_write_tokens`
|
||
- Output items: `text` → `message` | `toolUse` → `function_call` | `thinking` → `reasoning`
|
||
|
||
## Streaming
|
||
|
||
Event sequence: `response.created` → `response.in_progress` → `content_part.start` → `content_part.delta` → `content_part.done` → `output_item.done`
|
||
|
||
---
|
||
|
||
# 3. Text Completions (Legacy)
|
||
|
||
<Warning>
|
||
Legacy API using `invoke` endpoint. Streaming not supported. Only Claude
|
||
(Anthropic) and Mistral models supported.
|
||
</Warning>
|
||
|
||
**Request conversion**:
|
||
|
||
- **Claude models**: Uses Anthropic's `/v1/complete` format with prompt wrapping
|
||
- `prompt` auto-wrapped with `\n\nHuman: {prompt}\n\nAssistant:`
|
||
- `max_tokens` → `max_tokens_to_sample`
|
||
- `temperature`, `top_p` direct pass-through
|
||
- `top_k`, `stop` via `extra_params`
|
||
|
||
- **Mistral models**: Uses standard format
|
||
- `max_tokens` → `max_tokens`
|
||
- `temperature`, `top_p` direct pass-through
|
||
- `stop` → `stop`
|
||
|
||
**Response conversion**:
|
||
|
||
- **Claude**: `completion` → `choices[0].text`
|
||
- **Mistral**: `outputs[].text` → `choices[]` (supports multiple)
|
||
- `stopReason` → `finish_reason`
|
||
|
||
---
|
||
|
||
# 4. Embeddings
|
||
|
||
Supported embedding models: **Titan**, **Cohere**
|
||
|
||
## Request Parameters
|
||
|
||
### Parameter Mapping
|
||
|
||
| Parameter | Transformation | Notes |
|
||
| ----------------- | ------------------- | ------------------------------------ |
|
||
| `input` | Direct pass-through | Text or array of texts |
|
||
| `dimensions` | ⚠️ Not supported | Titan has fixed dimensions per model |
|
||
| `encoding_format` | Via `extra_params` | "base64" or "float" |
|
||
|
||
**Titan-specific**:
|
||
|
||
- No dimension customization
|
||
- Fixed output size per model version
|
||
|
||
**Cohere-specific**:
|
||
|
||
- Reuses Cohere format conversion
|
||
- Similar parameter mapping to standard Cohere
|
||
|
||
## Response Conversion
|
||
|
||
- **Titan**: `embedding` → single embedding vector
|
||
- **Cohere**: Reuses Cohere response format with `embeddings` array
|
||
- `usage.inputTokens` → `usage.prompt_tokens`
|
||
|
||
---
|
||
|
||
# 5. Image Generation
|
||
|
||
Supported image generation models: **Titan Image Generator v1**, **Titan Image Generator v2**, **Nova Canvas v1**
|
||
|
||
## Request Conversion
|
||
|
||
| Parameter(Bifrost) | Transformation (Bedrock) |
|
||
| ------------------ | ------------------------------------------------------------------------- |
|
||
| `prompt` | `textToImageParams.text` |
|
||
| `n` | `imageGenerationConfig.numberOfImages` |
|
||
| `negativePrompt` | `textToImageParams.negativeText` |
|
||
| `seed` | `imageGenerationConfig.seed` |
|
||
| `quality` | `imageGenerationConfig.quality` (see [Quality Mapping](#quality-mapping)) |
|
||
| `style` | `textToImageParams.style` |
|
||
| `size` | `imageGenerationConfig.width` & `imageGenerationConfig.height` |
|
||
|
||
### Quality Mapping
|
||
|
||
The `quality` parameter is automatically mapped to Bedrock's expected format:
|
||
|
||
| Input Value | Bedrock Value | Notes |
|
||
| ----------- | ------------- | --------------------------------- |
|
||
| `"low"` | `"standard"` | Mapped automatically |
|
||
| `"medium"` | `"standard"` | Mapped automatically |
|
||
| `"high"` | `"premium"` | Mapped automatically |
|
||
| `"default"` | `"standard"` | Passed through (case-insensitive) |
|
||
| `"premium"` | `"premium"` | Passed through (case-insensitive) |
|
||
|
||
## Response Conversion
|
||
|
||
| Parameter(Bedrock) | Transformation (Bifrost) |
|
||
| ------------------ | ------------------------ |
|
||
| `images` | `data.b64_json` |
|
||
|
||
### Example Request
|
||
|
||
<Tabs>
|
||
<Tab title="Gateway">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/images/generations \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "bedrock/amazon.nova-canvas-v1:0",
|
||
"prompt": "A futuristic cityscape with a flying car",
|
||
"size": "1024x1024",
|
||
"seed": 123,
|
||
"negative_prompt": "bikes",
|
||
"n": 2
|
||
}'
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
resp, err := client.ImageGenerationRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostImageGenerationRequest{
|
||
Provider: schemas.Bedrock,
|
||
Model: "amazon.nova-canvas-v1:0",
|
||
Input: &schemas.ImageGenerationInput{
|
||
Prompt: "A futuristic cityscape with a flying car",
|
||
},
|
||
Params: &schemas.ImageGenerationParameters{
|
||
N: schemas.Ptr(2),
|
||
Seed: schemas.Ptr(123),
|
||
NegativePrompt: schemas.Ptr("bikes"),
|
||
Quality: schemas.Ptr("auto"),
|
||
Style: schemas.Ptr("natural"),
|
||
Size: schemas.Ptr("1024x1024"),
|
||
},
|
||
})
|
||
```
|
||
|
||
</Tab>
|
||
</Tabs>
|
||
|
||
## Stability AI models
|
||
|
||
Supported generation models: **`stability.stable-image-core-v1:1`**, **`stability.stable-image-ultra-v1:1`**
|
||
|
||
These models use a flat JSON body (not the nested Bedrock `taskType` structure). Bifrost detects them automatically — any model ID containing `"stability."` is converted via `ToStabilityAIImageGenerationRequest`.
|
||
|
||
**Request Parameters**
|
||
|
||
| Parameter | Type | Required | Notes |
|
||
| ----------------- | ------ | -------- | -------------------------------------------------------------------------------------------- |
|
||
| `prompt` | string | ✅ | Text description of the image |
|
||
| `negative_prompt` | string | ❌ | What to exclude |
|
||
| `seed` | int | ❌ | Reproducibility seed |
|
||
| `aspect_ratio` | string | ❌ | e.g. `"16:9"`, `"1:1"`, `"21:9"` — via `aspect_ratio` param or `ExtraParams["aspect_ratio"]` |
|
||
| `output_format` | string | ❌ | `"png"`, `"jpeg"`, `"webp"` — via `output_format` param |
|
||
|
||
### Example Request
|
||
|
||
<Tabs>
|
||
<Tab title="Gateway">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/images/generations \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "bedrock/us.stability.stable-image-ultra-v1:1",
|
||
"prompt": "A majestic mountain range at golden hour",
|
||
"negative_prompt": "blurry, low quality",
|
||
"aspect_ratio": "16:9",
|
||
"output_format": "png",
|
||
"seed": 42
|
||
}'
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Go SDK">
|
||
|
||
```go
|
||
resp, err := client.ImageGenerationRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostImageGenerationRequest{
|
||
Provider: schemas.Bedrock,
|
||
Model: "us.stability.stable-image-ultra-v1:1",
|
||
Input: &schemas.ImageGenerationInput{
|
||
Prompt: "A majestic mountain range at golden hour",
|
||
},
|
||
Params: &schemas.ImageGenerationParameters{
|
||
NegativePrompt: schemas.Ptr("blurry, low quality"),
|
||
AspectRatio: schemas.Ptr("16:9"),
|
||
OutputFormat: schemas.Ptr("png"),
|
||
Seed: schemas.Ptr(42),
|
||
},
|
||
})
|
||
```
|
||
|
||
</Tab>
|
||
</Tabs>
|
||
|
||
---
|
||
|
||
# 6. Image Edit
|
||
|
||
<Warning>Requests use **multipart/form-data**, not JSON.</Warning>
|
||
|
||
Supported image edit models: **Titan Image Generator v1**, **Titan Image Generator v2**, **Nova Canvas v1**
|
||
|
||
Bedrock supports three image edit task types: **INPAINTING**, **OUTPAINTING**, and **BACKGROUND_REMOVAL**. The `type` field is required and must be one of these values.
|
||
|
||
**Request Parameters**
|
||
|
||
| Parameter | Type | Required | Notes |
|
||
| ------------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------- |
|
||
| `model` | string | ✅ | Model identifier (must be Titan or Nova Canvas model) |
|
||
| `type` | string | ✅ | Edit type: `"inpainting"`, `"outpainting"`, or `"background_removal"` |
|
||
| `prompt` | string | ❌ | Text description of the edit (required for inpainting/outpainting) |
|
||
| `image[]` | binary | ✅ | Image file(s) to edit (only first image used) |
|
||
| `mask` | binary | ❌ | Mask image file (for inpainting/outpainting) |
|
||
| `n` | int | ❌ | Number of images to generate (1-10, for inpainting/outpainting only) |
|
||
| `size` | string | ❌ | Image size: `"WxH"` format (e.g., `"1024x1024"`, for inpainting/outpainting only) |
|
||
| `quality` | string | ❌ | Image quality (for inpainting/outpainting only). See [Quality Mapping](#quality-mapping) for supported values. |
|
||
| `cfgScale` | float | ❌ | CFG scale (via `ExtraParams["cfgScale"]`, for inpainting/outpainting only) |
|
||
| `negative_text` | string | ❌ | Negative prompt (via `ExtraParams["negative_text"]`, for inpainting/outpainting only) |
|
||
| `mask_prompt` | string | ❌ | Mask prompt (via `ExtraParams["mask_prompt"]`, for inpainting/outpainting only) |
|
||
| `return_mask` | bool | ❌ | Return mask in response (via `ExtraParams["return_mask"]`, for inpainting/outpainting only) |
|
||
| `outpainting_mode` | string | ❌ | Outpainting mode (via `ExtraParams["outpainting_mode"]`, outpainting only): `"DEFAULT"` or `"PRECISE"` |
|
||
|
||
---
|
||
|
||
**Request Conversion**
|
||
|
||
- **Task Type Mapping**: `Params.Type` is mapped to `taskType`:
|
||
- `"inpainting"` → `"INPAINTING"`
|
||
- `"outpainting"` → `"OUTPAINTING"`
|
||
- `"background_removal"` → `"BACKGROUND_REMOVAL"`
|
||
- Any other value returns an error: `"unsupported type for Bedrock"`
|
||
- **Image Conversion**: First image in `Input.Images` is converted to base64: `image.Image` → base64 string
|
||
- **Task-Specific Parameters**:
|
||
- **INPAINTING**: Uses `inPaintingParams`:
|
||
- `prompt` → `inPaintingParams.text`
|
||
- `image` (base64) → `inPaintingParams.image`
|
||
- `mask` (if present) → `inPaintingParams.maskImage` (base64)
|
||
- `negative_text` (via `ExtraParams`) → `inPaintingParams.negativeText`
|
||
- `mask_prompt` (via `ExtraParams`) → `inPaintingParams.maskPrompt`
|
||
- `return_mask` (via `ExtraParams`) → `inPaintingParams.returnMask`
|
||
- **OUTPAINTING**: Uses `outPaintingParams`:
|
||
- `prompt` → `outPaintingParams.text`
|
||
- `image` (base64) → `outPaintingParams.image`
|
||
- `mask` (if present) → `outPaintingParams.maskImage` (base64)
|
||
- `negative_text` (via `ExtraParams`) → `outPaintingParams.negativeText`
|
||
- `mask_prompt` (via `ExtraParams`) → `outPaintingParams.maskPrompt`
|
||
- `return_mask` (via `ExtraParams`) → `outPaintingParams.returnMask`
|
||
- `outpainting_mode` (via `ExtraParams`, validated to `"DEFAULT"` or `"PRECISE"`) → `outPaintingParams.outPaintingMode`
|
||
- **BACKGROUND_REMOVAL**: Uses `backgroundRemovalParams`:
|
||
- `image` (base64) → `backgroundRemovalParams.image`
|
||
- No other parameters supported
|
||
- **Image Generation Config** (for INPAINTING and OUTPAINTING only):
|
||
- `n` → `imageGenerationConfig.numberOfImages`
|
||
- `size` → `imageGenerationConfig.width` and `imageGenerationConfig.height` (parsed from `"WxH"` format)
|
||
- `quality` → `imageGenerationConfig.quality` (see [Quality Mapping](#quality-mapping))
|
||
- `cfgScale` (via `ExtraParams["cfgScale"]`) → `imageGenerationConfig.cfgScale`
|
||
|
||
**Response Conversion**
|
||
|
||
- Uses the same response structure as image generation: `BedrockImageGenerationResponse` → `BifrostImageGenerationResponse`
|
||
- Response includes:
|
||
- `images[]`: Array of base64-encoded images
|
||
- `maskImage`: Base64-encoded mask image (if `return_mask` was true)
|
||
- `error`: Error message (if present)
|
||
|
||
**Endpoint**: Same as image generation: `invoke` endpoint
|
||
|
||
**Streaming**: Image edit streaming is not supported by Bedrock.
|
||
|
||
---
|
||
|
||
## Stability AI models
|
||
|
||
<Warning>Requests use **multipart/form-data**, not JSON.</Warning>
|
||
|
||
Stability AI edit models are automatically detected by their model ID (contains `"stability."`). The **task type is inferred from the model name** by default, but you can also set the `type` field explicitly — useful when using deployment aliases. See [Type values for explicit task selection](#type-values-for-explicit-task-selection) below.
|
||
|
||
### Supported models
|
||
|
||
| Model ID | Task | Images required | Prompt |
|
||
| ----------------------------------------------- | -------------------- | ----------------- | ------ |
|
||
| `stability.stable-image-inpaint-v1:0` | inpaint | 1 + mask | ✅ |
|
||
| `stability.stable-outpaint-v1:0` | outpaint | 1 (optional mask) | ✅ |
|
||
| `stability.stable-image-search-recolor-v1:0` | recolor | 1 | ✅ |
|
||
| `stability.stable-image-search-replace-v1:0` | search-replace | 1 | ✅ |
|
||
| `stability.stable-image-erase-object-v1:0` | erase-object | 1 + mask | ❌ |
|
||
| `stability.stable-image-remove-background-v1:0` | remove-bg | 1 | ❌ |
|
||
| `stability.stable-image-control-sketch-v1:0` | control-sketch | 1 | ✅ |
|
||
| `stability.stable-image-control-structure-v1:0` | control-structure | 1 | ✅ |
|
||
| `stability.stable-image-style-guide-v1:0` | style-guide | 1 | ✅ |
|
||
| `stability.stable-style-transfer-v1:0` | style-transfer | **2 required** | ✅ |
|
||
| `stability.stable-creative-upscale-v1:0` | upscale-creative | 1 | ✅ |
|
||
| `stability.stable-conservative-upscale-v1:0` | upscale-conservative | 1 | ✅ |
|
||
| `stability.stable-fast-upscale-v1:0` | upscale-fast | 1 | ❌ |
|
||
|
||
### Common parameters
|
||
|
||
| Parameter | Type | Required | Notes |
|
||
| ----------------- | ------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
| `model` | string | ✅ | Stability AI model ID (see table above) |
|
||
| `image[]` | binary | ✅ | Input image(s). `style-transfer` requires exactly 2. |
|
||
| `prompt` | string | task-dependent | Required for all tasks except `remove-bg`, `upscale-fast`, and `erase-object`. For these no-prompt operations, set `type` to `remove_background`, `upscale_fast`, or `erase_object` to skip prompt validation at the gateway level. |
|
||
| `negative_prompt` | string | ❌ | Not applied for: `remove-bg`, `upscale-fast`, `erase-object` |
|
||
| `seed` | int | ❌ | Not applied for: `remove-bg`, `upscale-fast` |
|
||
| `mask` | binary | task-dependent | Required for: `inpaint`, `erase-object`; ignored for others |
|
||
|
||
### Task-specific extra parameters
|
||
|
||
Pass these via `extra_params` (Go SDK) or as top-level form fields (Gateway).
|
||
|
||
| Extra parameter | Type | Task(s) |
|
||
| ----------------------------- | ------ | ------------------------------------------------------------------------------------------------------------ |
|
||
| `output_format` | string | All — `"png"`, `"jpeg"`, `"webp"` |
|
||
| `style_preset` | string | inpaint, outpaint, recolor, search-replace, control-sketch, control-structure, style-guide, upscale-creative |
|
||
| `grow_mask` | int | inpaint, recolor, search-replace, erase-object |
|
||
| `left`, `right`, `up`, `down` | int | outpaint — pixels to expand in each direction |
|
||
| `creativity` | float | upscale-creative, upscale-conservative, outpaint |
|
||
| `select_prompt` | string | recolor — which region to recolor |
|
||
| `search_prompt` | string | search-replace — what object to find and replace |
|
||
| `control_strength` | float | control-sketch, control-structure — 0.0–1.0 |
|
||
| `aspect_ratio` | string | style-guide — output aspect ratio |
|
||
| `fidelity` | float | style-guide — 0.0–1.0 |
|
||
| `style_strength` | float | style-transfer — 0.0–1.0 |
|
||
| `composition_fidelity` | float | style-transfer — 0.0–1.0 |
|
||
| `change_strength` | float | style-transfer — 0.0–1.0 |
|
||
|
||
<Note>
|
||
**Style-transfer image order matters.** The first image (`image[0]`) becomes
|
||
`init_image` (the content to transform) and the second (`image[1]`) becomes
|
||
`style_image` (the artistic reference). Both images must be non-empty.
|
||
</Note>
|
||
|
||
### Type values for explicit task selection
|
||
|
||
You can set the `type` field to override model-name inference. This is especially useful with deployment aliases where the alias name may not contain the Stability AI model pattern.
|
||
|
||
| `type` value | Stability AI task |
|
||
| ---------------------------------------------------------- | -------------------- |
|
||
| `inpainting` or `inpaint` | inpaint |
|
||
| `outpainting` or `outpaint` | outpaint |
|
||
| `background_removal` or `remove_background` or `remove_bg` | remove-bg |
|
||
| `erase_object` | erase-object |
|
||
| `upscale_fast` | upscale-fast |
|
||
| `upscale_creative` | upscale-creative |
|
||
| `upscale_conservative` | upscale-conservative |
|
||
| `recolor` | recolor |
|
||
| `search_replace` | search-replace |
|
||
| `control_sketch` | control-sketch |
|
||
| `control_structure` | control-structure |
|
||
| `style_guide` | style-guide |
|
||
| `style_transfer` | style-transfer |
|
||
|
||
### Example requests
|
||
|
||
<Tabs>
|
||
<Tab title="Inpaint">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/images/edits \
|
||
-F "model=bedrock/us.stability.stable-image-inpaint-v1:0" \
|
||
-F "image[]=@photo.png;type=image/png" \
|
||
-F "mask=@mask.png;type=image/png" \
|
||
-F "prompt=A beautiful garden replacing the masked area" \
|
||
-F "negative_prompt=ugly, blurry" \
|
||
-F "output_format=png"
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Style transfer">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/images/edits \
|
||
-F "model=bedrock/us.stability.stable-style-transfer-v1:0" \
|
||
-F "image[]=@content.png;type=image/png" \
|
||
-F "image[]=@style.png;type=image/png" \
|
||
-F "prompt=Apply the artistic style to the content image" \
|
||
-F "style_strength=0.8" \
|
||
-F "composition_fidelity=0.5" \
|
||
-F "change_strength=0.4" \
|
||
-F "output_format=png"
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Outpaint">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/images/edits \
|
||
-F "model=bedrock/us.stability.stable-outpaint-v1:0" \
|
||
-F "image[]=@photo.png;type=image/png" \
|
||
-F "prompt=Extend the scene naturally" \
|
||
-F "left=200" \
|
||
-F "right=200" \
|
||
-F "output_format=png"
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Remove background">
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/images/edits \
|
||
-F "model=bedrock/us.stability.stable-image-remove-background-v1:0" \
|
||
-F "image[]=@photo.png;type=image/png" \
|
||
-F "output_format=png"
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Erase object">
|
||
|
||
No prompt required. Set `type=erase_object` to skip gateway prompt validation.
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/images/edits \
|
||
-F "model=bedrock/us.stability.stable-image-erase-object-v1:0" \
|
||
-F "image[]=@photo.png;type=image/png" \
|
||
-F "mask=@mask.png;type=image/png" \
|
||
-F "type=erase_object" \
|
||
-F "output_format=png"
|
||
```
|
||
|
||
</Tab>
|
||
<Tab title="Fast upscale">
|
||
|
||
No prompt required. Set `type=upscale_fast` to skip gateway prompt validation.
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/v1/images/edits \
|
||
-F "model=bedrock/us.stability.stable-fast-upscale-v1:0" \
|
||
-F "image[]=@photo.png;type=image/png" \
|
||
-F "type=upscale_fast" \
|
||
-F "output_format=png"
|
||
```
|
||
|
||
</Tab>
|
||
</Tabs>
|
||
|
||
**Endpoint**: `invoke` endpoint (same as all other Bedrock image operations)
|
||
|
||
**Streaming**: Not supported.
|
||
|
||
---
|
||
|
||
# 7. Image Variation
|
||
|
||
<Warning>Requests use **multipart/form-data**, not JSON.</Warning>
|
||
|
||
Supported image variation models: **Titan Image Generator v1**, **Titan Image Generator v2**, **Nova Canvas v1**
|
||
|
||
**Request Parameters**
|
||
|
||
| Parameter | Type | Required | Notes |
|
||
| -------------------- | ------ | -------- | ------------------------------------------------------------------------------- |
|
||
| `model` | string | ✅ | Model identifier (must be Titan or Nova Canvas model) |
|
||
| `image` | binary | ✅ | Image file to create variations from (supports multiple images via `image[]`) |
|
||
| `n` | int | ❌ | Number of images to generate (1-10) |
|
||
| `size` | string | ❌ | Image size: `"WxH"` format (e.g., `"1024x1024"`) |
|
||
| `quality` | string | ❌ | Image quality. See [Quality Mapping](#quality-mapping) for supported values. |
|
||
| `cfgScale` | float | ❌ | CFG scale (via `ExtraParams["cfgScale"]`) |
|
||
| `prompt` | string | ❌ | Prompt/text for variation (via `ExtraParams["prompt"]`) |
|
||
| `negativeText` | string | ❌ | Negative prompt (via `ExtraParams["negativeText"]`) |
|
||
| `similarityStrength` | float | ❌ | Similarity strength (via `ExtraParams["similarityStrength"]`): Range 0.2 to 1.0 |
|
||
|
||
---
|
||
|
||
**Request Conversion**
|
||
|
||
- **Task Type**: `taskType` is set to `"IMAGE_VARIATION"`
|
||
- **Image Conversion**: All images are converted to base64 strings:
|
||
- Primary image: `Input.Image.Image` → base64 string → `imageVariationParams.images[0]`
|
||
- Additional images: `ExtraParams["images"]` (stored as `[][]byte` by HTTP handler) → base64 strings → appended to `imageVariationParams.images[]`
|
||
- **Image Variation Parameters**:
|
||
- `prompt` (via `ExtraParams["prompt"]`) → `imageVariationParams.text`
|
||
- `negativeText` (via `ExtraParams["negativeText"]`) → `imageVariationParams.negativeText`
|
||
- `similarityStrength` (via `ExtraParams["similarityStrength"]`) → `imageVariationParams.similarityStrength` (validated to range [0.2, 1.0])
|
||
- **Image Generation Config**:
|
||
- `n` → `imageGenerationConfig.numberOfImages`
|
||
- `size` → `imageGenerationConfig.width` and `imageGenerationConfig.height` (parsed from `"WxH"` format)
|
||
- `quality` (via `ExtraParams["quality"]`) → `imageGenerationConfig.quality` (see [Quality Mapping](#quality-mapping))
|
||
- `cfgScale` (via `ExtraParams["cfgScale"]`) → `imageGenerationConfig.cfgScale`
|
||
|
||
**Response Conversion**
|
||
|
||
- Uses the same response structure as image generation: `BedrockImageGenerationResponse` → `BifrostImageGenerationResponse`
|
||
- Response includes:
|
||
- `images[]`: Array of base64-encoded image variations
|
||
- `error`: Error message (if present)
|
||
|
||
**Endpoint**: Same as image generation: `invoke` endpoint
|
||
|
||
**Streaming**: Image variation streaming is not supported by Bedrock.
|
||
|
||
---
|
||
|
||
# 8. Batch API
|
||
|
||
**Request formats**: `requests` array (CustomID + Params) or `input_file_id`
|
||
|
||
**Pagination**: Cursor-based with `afterId`, `beforeId`, `limit`
|
||
|
||
**Endpoints**:
|
||
|
||
- POST `/batch` - Create batch
|
||
- GET `/batch` - List batches
|
||
- GET `/batch/{batch_id}` - Retrieve batch
|
||
- POST `/batch/{batch_id}/cancel` - Cancel batch
|
||
|
||
**Response**: JSONL format with `{recordId, modelOutput: {...}}` or `{recordId, error: {...}}`
|
||
|
||
**Status mapping**:
|
||
| Bedrock Status | Bifrost Mapping |
|
||
|---|---|
|
||
| `Submitted`, `Validating` | `Validating` |
|
||
| `InProgress` | `InProgress` |
|
||
| `Completed` | `Completed` |
|
||
| `Failed`, `PartiallyCompleted` | `Failed` |
|
||
| `Stopping` | `Cancelling` |
|
||
| `Stopped` | `Cancelled` |
|
||
| `Expired` | `Expired` |
|
||
|
||
**Note**: RFC3339Nano timestamps converted to Unix timestamps, multi-key retry supported
|
||
|
||
---
|
||
|
||
# 9. Files API
|
||
|
||
<Note>
|
||
S3-backed file operations. Files are stored in S3 buckets integrated with
|
||
Bedrock.
|
||
</Note>
|
||
|
||
**Upload**: Multipart/form-data with `file` (required) and `filename` (optional)
|
||
|
||
**Field mapping**:
|
||
|
||
- `id` (file ID)
|
||
- `filename`
|
||
- `size_bytes` (from S3 object size)
|
||
- `created_at` (Unix timestamp from S3 LastModified)
|
||
- `mime_type` (derived from content or explicitly set)
|
||
|
||
**Endpoints**:
|
||
|
||
- POST `/v1/files` - Upload
|
||
- GET `/v1/files` - List (cursor pagination)
|
||
- GET `/v1/files/{file_id}` - Retrieve metadata
|
||
- DELETE `/v1/files/{file_id}` - Delete
|
||
- GET `/v1/files/{file_id}/content` - Download content
|
||
|
||
**Note**: File purpose always `"batch"`, status always `"processed"`
|
||
|
||
---
|
||
|
||
# 10. List Models
|
||
|
||
**Request**: GET `/v1/models` (no body)
|
||
|
||
**Field mapping**:
|
||
|
||
- `id` (model name with deployment prefix if applicable)
|
||
- `display_name` → `name`
|
||
- `created_at` (Unix timestamp)
|
||
|
||
**Pagination**: Token-based with `NextPageToken`, `FirstID`, `LastID`
|
||
|
||
**Filtering**:
|
||
|
||
- Region-based model filtering
|
||
- Deployment mapping from configuration
|
||
- Model allowlist support (`allowed_models` config)
|
||
|
||
**Multi-key support**: Results aggregated from all keys, filtered by the key-level `models` allowlist if configured
|
||
|
||
---
|
||
|
||
# 11. AWS Authentication & Configuration
|
||
|
||
Bifrost signs every Bedrock request with AWS Signature Version 4 (SigV4). Credentials are resolved in the following priority order, and STS AssumeRole can be layered on top of any of them.
|
||
|
||
## Authentication Methods
|
||
|
||
### 1. Explicit Credentials
|
||
|
||
Provide `access_key` and `secret_key` directly in `bedrock_key_config`. Optionally include a `session_token` for pre-obtained temporary credentials.
|
||
|
||
```json
|
||
{
|
||
"bedrock_key_config": {
|
||
"access_key": "your-aws-access-key",
|
||
"secret_key": "your-aws-secret-key",
|
||
"session_token": "optional-session-token",
|
||
"region": "us-east-1"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. Default Credential Chain (IAM Role / Instance Profile)
|
||
|
||
Leave `access_key` and `secret_key` empty (or omit them). Bifrost calls AWS `LoadDefaultConfig` which automatically resolves credentials from the environment in this order:
|
||
|
||
- Environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`)
|
||
- EKS IRSA (`AWS_WEB_IDENTITY_TOKEN_FILE` + `AWS_ROLE_ARN`)
|
||
- ECS task role
|
||
- EC2 instance profile (IMDS)
|
||
- `~/.aws/credentials` default profile
|
||
|
||
```json
|
||
{
|
||
"bedrock_key_config": {
|
||
"region": "us-east-1"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. STS AssumeRole
|
||
|
||
Set `role_arn` to assume an IAM role before signing requests. AssumeRole requires a valid source identity — it works when credentials are available either via explicit `access_key`/`secret_key` in key config, or via the default credential chain (environment variables, EC2 instance profile, ECS task role, EKS IRSA, etc.). **If no credentials are available from either source, AssumeRole will fail.**
|
||
|
||
```json
|
||
{
|
||
"bedrock_key_config": {
|
||
"role_arn": "arn:aws:iam::123456789012:role/BedrockRole",
|
||
"external_id": "optional-external-id",
|
||
"session_name": "my-session",
|
||
"region": "us-east-1"
|
||
}
|
||
}
|
||
```
|
||
|
||
| Field | Required | Default | Notes |
|
||
| -------------- | ------------- | ----------------- | ------------------------------------------------ |
|
||
| `role_arn` | Yes (for STS) | - | IAM role ARN to assume |
|
||
| `external_id` | No | - | Required when the role's trust policy demands it |
|
||
| `session_name` | No | `bifrost-session` | Identifies the session in CloudTrail logs |
|
||
|
||
## Inference Profiles & ARN Configuration
|
||
|
||
### How to Use ARNs and Application Inference Profiles
|
||
|
||
When using AWS Bedrock inference profiles or application inference profiles, you must split the configuration correctly to avoid `UnknownOperationException`:
|
||
|
||
| Field | Purpose |
|
||
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||
| **`arn`** | The ARN prefix (everything before the final `/resource-id`). Required for URL formation when using inference profiles. |
|
||
| **`aliases`** | Map logical model names to the **model ID or inference profile resource ID only** — not the full ARN. Set at the key level, not inside `bedrock_key_config`. |
|
||
|
||
<Warning>
|
||
**Do not** put the full ARN in the aliases mapping. The resource ID (e.g.,
|
||
`abc12xyz`) goes in `aliases`; the ARN prefix goes in the dedicated `arn`
|
||
field inside `bedrock_key_config`. Putting the full ARN in `aliases` causes
|
||
malformed URLs and `UnknownOperationException`.
|
||
</Warning>
|
||
|
||
**Application inference profiles** — use the resource ID (short alphanumeric suffix) in aliases:
|
||
|
||
```json
|
||
{
|
||
"aliases": {
|
||
"claude-opus-4-6": "ghi56rst",
|
||
"claude-sonnet-4-5": "jkl78mno"
|
||
},
|
||
"bedrock_key_config": {
|
||
"access_key": "your-aws-access-key",
|
||
"secret_key": "your-aws-secret-key",
|
||
"session_token": "optional-session-token",
|
||
"region": "eu-west-1",
|
||
"arn": "arn:aws:bedrock:eu-west-1:123456789012:application-inference-profile"
|
||
}
|
||
}
|
||
```
|
||
|
||
**Cross-region inference profiles** — use the model identifier (e.g., `us.anthropic.claude-3-5-sonnet-v1:0`) in aliases:
|
||
|
||
```json
|
||
{
|
||
"aliases": {
|
||
"claude-sonnet": "us.anthropic.claude-3-5-sonnet-v1:0"
|
||
},
|
||
"bedrock_key_config": {
|
||
"access_key": "your-aws-access-key",
|
||
"secret_key": "your-aws-secret-key",
|
||
"session_token": "optional-session-token",
|
||
"region": "us-east-1",
|
||
"arn": "arn:aws:bedrock:us-east-1:123456789012:inference-profile"
|
||
}
|
||
}
|
||
```
|
||
|
||
### Endpoints
|
||
|
||
- **Runtime API**: `bedrock-runtime.{region}.amazonaws.com/model/{path}`
|
||
- **Control Plane**: `bedrock.{region}.amazonaws.com` (list models)
|
||
- **Batch API**: Via bedrock-runtime
|
||
|
||
---
|
||
|
||
# 12. Error Handling
|
||
|
||
**HTTP Status Mapping**:
|
||
|
||
| Status | Bifrost Error Type | Notes |
|
||
| ------ | ------------------------- | ------------------------------- |
|
||
| 400 | `invalid_request_error` | Bad request parameters |
|
||
| 401 | `authentication_error` | Invalid/expired credentials |
|
||
| 403 | `permission_denied_error` | Access denied to model/resource |
|
||
| 404 | `not_found_error` | Model or resource not found |
|
||
| 429 | `rate_limit_error` | Rate limit exceeded |
|
||
| 500 | `api_error` | Server error |
|
||
| 529 | `overloaded_error` | Service overloaded |
|
||
|
||
**Error Response Structure**:
|
||
|
||
```go
|
||
type BifrostError struct {
|
||
IsBifrostError bool
|
||
StatusCode *int
|
||
Error: {
|
||
Type: string // Error classification
|
||
Message: string // Human-readable message
|
||
Error: error // Underlying error
|
||
}
|
||
}
|
||
```
|
||
|
||
**Special Cases**:
|
||
|
||
- Context cancellation → `RequestCancelled`
|
||
- Request timeout → `ErrProviderRequestTimedOut`
|
||
- Streaming errors → Sent via channel with stream end indicator
|
||
- Response unmarshalling → `ErrProviderResponseUnmarshal`
|
||
|
||
---
|
||
|
||
## Caveats
|
||
|
||
<Accordion title="Image Format Restriction">
|
||
**Severity**: High **Behavior**: Only base64/data URI images supported; remote
|
||
URLs not supported **Impact**: Requests with URL-based images fail **Code**:
|
||
`chat.go:image handling`
|
||
</Accordion>
|
||
|
||
<Accordion title="Minimum Reasoning Budget (Claude)">
|
||
**Severity**: High
|
||
**Behavior**: `reasoning.max_tokens` must be >= 1024
|
||
**Impact**: Requests with lower values fail with error
|
||
**Code**: `chat.go:reasoning validation`
|
||
</Accordion>
|
||
|
||
<Accordion title="System Message Extraction">
|
||
**Severity**: High **Behavior**: System messages removed from array, placed in
|
||
separate `system` field **Impact**: Message array structure differs from input
|
||
**Code**: `chat.go:message conversion`
|
||
</Accordion>
|
||
|
||
<Accordion title="Tool Message Grouping">
|
||
**Severity**: High **Behavior**: Consecutive tool messages merged into single
|
||
user message **Impact**: Message count and structure changes **Code**:
|
||
`chat.go:tool message handling`
|
||
</Accordion>
|
||
|
||
<Accordion title="Model Family-Specific Parameters">
|
||
**Severity**: Medium **Behavior**: Reasoning/thinking config varies
|
||
significantly by model family **Impact**: Parameter mapping differs for Claude
|
||
vs Nova vs other families **Code**: `chat.go, utils.go:model detection`
|
||
</Accordion>
|
||
|
||
<Accordion title="Text Completion Streaming Not Supported">
|
||
**Severity**: Medium **Behavior**: Text completion streaming returns error
|
||
**Impact**: Streaming not available for legacy completions API **Code**:
|
||
`text.go:streaming`
|
||
</Accordion>
|
||
|
||
<Accordion title="Structured Output via Tool">
|
||
**Severity**: Low **Behavior**: `response_format` converted to special
|
||
`bf_so_*` tool **Impact**: Tool call count and structure changes internally
|
||
**Code**: `chat.go:structured output handling`
|
||
</Accordion>
|
||
|
||
<Accordion title="Deployment Region Prefix Handling">
|
||
**Severity**: Low **Behavior**: Model IDs with region prefixes matched against
|
||
deployment config **Impact**: Model availability depends on deployment
|
||
configuration **Code**: `models.go:deployment matching`
|
||
</Accordion>
|