647 lines
22 KiB
Plaintext
647 lines
22 KiB
Plaintext
---
|
|
title: "Migrating to v1.5.0"
|
|
description: "Breaking changes and migration instructions for the v1.5.0 release"
|
|
---
|
|
|
|
v1.5.0 introduces several breaking changes across provider key configuration, Virtual Key semantics, the Go SDK, and the REST API. This page consolidates every breaking change with before/after examples and a migration checklist.
|
|
|
|
<Warning>
|
|
**Make a database backup before upgrading.** Automatic database migrations run on startup and are not revertible. A backup is the only way to restore a previous state if anything goes wrong. A database successfully migrated to v1.5.0 cannot be used to run v1.4.x.
|
|
</Warning>
|
|
|
|
---
|
|
|
|
## Automatic Database Migration
|
|
|
|
If you are running Bifrost with a database (SQLite or Postgres), existing data is automatically migrated on startup. You do not need to manually update your database records.
|
|
|
|
The following automatic migrations run on upgrade:
|
|
|
|
- Provider keys with `models: []` are converted to `models: ["*"]`
|
|
- Virtual Key provider configs with `allowed_models: []` are converted to `allowed_models: ["*"]`
|
|
- Virtual Keys with no `provider_configs` are backfilled with all currently configured providers (`allowed_models: ["*"]`, `key_ids: ["*"]`)
|
|
- Virtual Keys with no `mcp_configs` are backfilled with all currently connected MCP clients (`tools_to_execute: ["*"]`)
|
|
- Per-provider `deployments` maps (Azure, Bedrock, Vertex, Replicate) are migrated into the unified `aliases` field
|
|
|
|
**The automatic migration only protects your existing data.** Any new configuration created after upgrading — via `config.json` or the REST API — must follow the new semantics described below.
|
|
|
|
---
|
|
|
|
## Breaking Change 1: Empty Array Now Means "Deny All"
|
|
|
|
v1.5.0 flips the meaning of empty arrays across all allow-list fields:
|
|
|
|
| What you write | v1.4.x meaning | v1.5.0 meaning |
|
|
|---|---|---|
|
|
| `[]` (empty array) | Allow **all** | Allow **none** |
|
|
| `["*"]` (wildcard) | Not applicable | Allow **all** |
|
|
| `["a", "b"]` | Only `a` and `b` | Only `a` and `b` (unchanged) |
|
|
|
|
This affects four fields:
|
|
|
|
| Field | Where |
|
|
|---|---|
|
|
| `models` | Provider key |
|
|
| `allowed_models` | Virtual Key provider config |
|
|
| `key_ids` | Virtual Key provider config |
|
|
| `tools_to_execute` | Virtual Key MCP config |
|
|
|
|
### Provider key `models`
|
|
|
|
**Before:**
|
|
```json
|
|
{ "value": "env.OPENAI_API_KEY", "models": [] }
|
|
```
|
|
`models: []` → key served all models
|
|
|
|
**After:**
|
|
```json
|
|
{ "value": "env.OPENAI_API_KEY", "models": ["*"] }
|
|
```
|
|
|
|
### Virtual Key `allowed_models`
|
|
|
|
**Before:**
|
|
```json
|
|
{ "provider": "openai", "weight": 1.0 }
|
|
```
|
|
Missing `allowed_models` → all models allowed
|
|
|
|
**After:**
|
|
```json
|
|
{ "provider": "openai", "allowed_models": ["*"], "key_ids": ["*"], "weight": 1.0 }
|
|
```
|
|
|
|
### Virtual Key MCP `tools_to_execute`
|
|
|
|
**Before:**
|
|
```json
|
|
{ "mcp_client_name": "my-tools", "tools_to_execute": [] }
|
|
```
|
|
|
|
**After:**
|
|
```json
|
|
{ "mcp_client_name": "my-tools", "tools_to_execute": ["*"] }
|
|
```
|
|
|
|
---
|
|
|
|
## Breaking Change 2: `allowed_keys` Renamed to `key_ids`
|
|
|
|
The field used to restrict which provider API keys a Virtual Key can use has been renamed from `allowed_keys` to `key_ids`. The deny-by-default rule also applies — omitting the field or setting it to `[]` now blocks all keys.
|
|
|
|
<Note>
|
|
Unlike `allowed_models`, there is no automatic database migration for `key_ids`. An empty or omitted `key_ids` disables all key selection. You must explicitly use `["*"]` to restore allow-all behavior.
|
|
</Note>
|
|
|
|
**Before:**
|
|
```json
|
|
{ "provider": "openai", "allowed_keys": ["key-prod-001"], "weight": 1.0 }
|
|
```
|
|
|
|
**After:**
|
|
```json
|
|
{ "provider": "openai", "key_ids": ["key-prod-001"], "allowed_models": ["*"], "weight": 1.0 }
|
|
```
|
|
|
|
To allow all keys:
|
|
```json
|
|
{ "provider": "openai", "key_ids": ["*"], "allowed_models": ["*"], "weight": 1.0 }
|
|
```
|
|
|
|
---
|
|
|
|
## Breaking Change 3: Virtual Key `provider_configs` is Deny-by-Default
|
|
|
|
In v1.4.x, a Virtual Key with no `provider_configs` had access to all providers. In v1.5.0, it blocks all providers.
|
|
|
|
**Before:** `"provider_configs": []` → access to all providers
|
|
|
|
**After:** `"provider_configs": []` → no provider access
|
|
|
|
To allow all providers, list each one explicitly:
|
|
```json
|
|
{
|
|
"provider_configs": [
|
|
{ "provider": "openai", "allowed_models": ["*"], "key_ids": ["*"], "weight": 1.0 },
|
|
{ "provider": "anthropic", "allowed_models": ["*"], "key_ids": ["*"], "weight": 1.0 }
|
|
]
|
|
}
|
|
```
|
|
|
|
The automatic migration backfills all currently configured providers into any VK that has an empty `provider_configs`. However, any VK created after upgrading must include explicit provider configs.
|
|
|
|
---
|
|
|
|
## Breaking Change 4: WhiteList Validation
|
|
|
|
Two new validation rules are enforced on all allow-list fields. The API returns **HTTP 400** if either is violated.
|
|
|
|
**Rule 1: Wildcard cannot be mixed with other values**
|
|
```json
|
|
// ❌ Invalid
|
|
{ "allowed_models": ["*", "gpt-4o"] }
|
|
|
|
// ✅ Valid
|
|
{ "allowed_models": ["*"] }
|
|
```
|
|
|
|
**Rule 2: No duplicate values**
|
|
```json
|
|
// ❌ Invalid
|
|
{ "allowed_models": ["gpt-4o", "gpt-4o"] }
|
|
```
|
|
|
|
Applies to: `models`, `allowed_models`, `key_ids`, `tools_to_execute`, `tools_to_auto_execute`, `allowed_extra_headers`.
|
|
|
|
---
|
|
|
|
## Breaking Change 5: `weight` is Now Nullable
|
|
|
|
The `weight` field on a Virtual Key provider config was previously a required `float64`. It is now an optional `*float64`.
|
|
|
|
- `weight: 0.5` — provider participates in weighted load balancing
|
|
- `weight: null` / omitted — provider is accessible for direct routing but excluded from weighted selection
|
|
|
|
**API response change:** `weight` may now be `null`. Update any client code that assumes it is always a number.
|
|
|
|
---
|
|
|
|
## Breaking Change 6: Provider Keys API Separated
|
|
|
|
Provider key management now has dedicated endpoints. The `keys` field has been removed from all provider API requests and responses.
|
|
|
|
### What changed
|
|
|
|
| Before (v1.4.x) | After (v1.5.0) |
|
|
|---|---|
|
|
| `GET /api/providers/{p}` returns `keys` | `keys` field removed from provider response |
|
|
| `POST /api/providers` accepts `keys` | `keys` field ignored — create keys separately |
|
|
| `PUT /api/providers/{p}` accepts `keys` | `keys` field ignored — update keys via dedicated endpoints |
|
|
|
|
### New endpoints
|
|
|
|
| Method | Endpoint | Description |
|
|
|---|---|---|
|
|
| `GET` | `/api/providers/{provider}/keys` | List all keys |
|
|
| `GET` | `/api/providers/{provider}/keys/{key_id}` | Get a single key |
|
|
| `POST` | `/api/providers/{provider}/keys` | Create a key |
|
|
| `PUT` | `/api/providers/{provider}/keys/{key_id}` | Update a key |
|
|
| `DELETE` | `/api/providers/{provider}/keys/{key_id}` | Delete a key |
|
|
|
|
### How to update
|
|
|
|
**Creating a provider with keys:**
|
|
|
|
**Before:**
|
|
```bash
|
|
curl -X POST localhost:8080/api/providers -d '{
|
|
"provider": "openai",
|
|
"keys": [{"name": "main", "value": "sk-..."}]
|
|
}'
|
|
```
|
|
|
|
**After:** Create provider first, then add keys:
|
|
```bash
|
|
curl -X POST localhost:8080/api/providers -d '{"provider": "openai"}'
|
|
curl -X POST localhost:8080/api/providers/openai/keys -d '{"name": "main", "value": "sk-..."}'
|
|
```
|
|
|
|
**Reading keys:**
|
|
|
|
**Before:** `curl localhost:8080/api/providers/openai | jq '.keys'`
|
|
|
|
**After:** `curl localhost:8080/api/providers/openai/keys | jq '.keys'`
|
|
|
|
**Updating / deleting keys:**
|
|
|
|
**Before:** Bulk replace via provider update:
|
|
```bash
|
|
curl -X PUT localhost:8080/api/providers/openai -d '{"keys": [{"id": "key-1", "value": "sk-new"}]}'
|
|
```
|
|
|
|
**After:** Individual key operations:
|
|
```bash
|
|
curl -X PUT localhost:8080/api/providers/openai/keys/key-1 -d '{"name": "updated", "value": "sk-new"}'
|
|
curl -X DELETE localhost:8080/api/providers/openai/keys/key-2
|
|
```
|
|
|
|
---
|
|
|
|
## Breaking Change 7: Compact Plugin Restructured
|
|
|
|
The `enable_litellm_fallbacks` option has been removed and replaced with three granular options.
|
|
|
|
**Before:**
|
|
```json
|
|
{ "compat": { "enable_litellm_fallbacks": true } }
|
|
```
|
|
|
|
**After:**
|
|
```json
|
|
{
|
|
"compat": {
|
|
"convert_text_to_chat": true,
|
|
"convert_chat_to_responses": true,
|
|
"should_drop_params": true
|
|
}
|
|
}
|
|
```
|
|
|
|
| Old option | New option | Description |
|
|
|---|---|---|
|
|
| `enable_litellm_fallbacks` | `convert_text_to_chat` | Text completion → chat completion fallback |
|
|
| _(new)_ | `convert_chat_to_responses` | Chat completion → Responses API fallback |
|
|
| _(new)_ | `should_drop_params` | Drop unsupported OpenAI-compatible params |
|
|
|
|
**Response field changes:**
|
|
|
|
| Field | Change |
|
|
|---|---|
|
|
| `extra_fields.litellm_compat` | **Removed** |
|
|
| `extra_fields.dropped_compat_plugin_params` | **Added** — lists params dropped by this plugin |
|
|
| `extra_fields.converted_request_type` | **Added** — the request type it was converted to |
|
|
|
|
---
|
|
|
|
## Breaking Change 8: Replicate Image Edits Removed from Generations Endpoint
|
|
|
|
The `/v1/images/generations` endpoint on the Replicate provider no longer accepts image editing parameters (source image, mask). It now only handles text-to-image generation.
|
|
|
|
If you were passing image editing parameters to `/v1/images/generations` on Replicate, switch to `/v1/images/edits`.
|
|
|
|
<Note>
|
|
Support for image editing via `/v1/images/edits` on Replicate is also being removed in a follow-up release. Plan to migrate to an alternative provider.
|
|
</Note>
|
|
|
|
---
|
|
|
|
## Breaking Change 9: Provider `deployments` removed — migrate to `aliases`
|
|
|
|
Provider deployment mappings should now live in the top-level `aliases` field on each key. Aliases work across all providers and map any model name to a provider-specific identifier (deployment name, inference profile ARN, fine-tuned model ID, etc.).
|
|
|
|
The database migration runs automatically on startup, migrating existing deployment data into `aliases`. Only `config.json` files need to be updated manually.
|
|
|
|
### Azure
|
|
|
|
**Before:**
|
|
```json
|
|
{
|
|
"providers": {
|
|
"azure": {
|
|
"keys": [{
|
|
"value": "env.AZURE_API_KEY",
|
|
"azure_key_config": {
|
|
"endpoint": "env.AZURE_ENDPOINT",
|
|
"deployments": {
|
|
"gpt-4o": "my-gpt4o-deployment",
|
|
"gpt-4o-mini": "my-mini-deployment"
|
|
}
|
|
}
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**After:**
|
|
```json
|
|
{
|
|
"providers": {
|
|
"azure": {
|
|
"keys": [{
|
|
"value": "env.AZURE_API_KEY",
|
|
"azure_key_config": {
|
|
"endpoint": "env.AZURE_ENDPOINT"
|
|
},
|
|
"aliases": {
|
|
"gpt-4o": "my-gpt4o-deployment",
|
|
"gpt-4o-mini": "my-mini-deployment"
|
|
}
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Bedrock
|
|
|
|
<Warning>
|
|
`bedrock_key_config.deployments` is a legacy field and is **removed** in v1.5.0 config semantics. Some setups/builds may still accept it for backward compatibility, but do not rely on it — migrate to `aliases` to avoid silent breakage and future removal.
|
|
</Warning>
|
|
|
|
**Before:**
|
|
```json
|
|
{
|
|
"bedrock_key_config": {
|
|
"region": "env.AWS_REGION",
|
|
"deployments": {
|
|
"claude-3-5-sonnet": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**After:**
|
|
```json
|
|
{
|
|
"bedrock_key_config": {
|
|
"region": "env.AWS_REGION"
|
|
},
|
|
"aliases": {
|
|
"claude-3-5-sonnet": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Vertex
|
|
|
|
**Before:**
|
|
```json
|
|
{
|
|
"vertex_key_config": {
|
|
"project_id": "env.VERTEX_PROJECT_ID",
|
|
"project_number": "env.VERTEX_PROJECT_NUMBER",
|
|
"region": "env.VERTEX_REGION",
|
|
"auth_credentials": "env.VERTEX_AUTH_CREDENTIALS",
|
|
"deployments": {
|
|
"gemini-2.0-flash": "projects/my-project/locations/us-central1/endpoints/123456"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**After:**
|
|
```json
|
|
{
|
|
"vertex_key_config": {
|
|
"project_id": "env.VERTEX_PROJECT_ID",
|
|
"project_number": "env.VERTEX_PROJECT_NUMBER",
|
|
"region": "env.VERTEX_REGION",
|
|
"auth_credentials": "env.VERTEX_AUTH_CREDENTIALS"
|
|
},
|
|
"aliases": {
|
|
"gemini-2.0-flash": "projects/my-project/locations/us-central1/endpoints/123456"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Replicate
|
|
|
|
The Replicate key config is also restructured. The `deployments` map is gone. A new boolean `use_deployments_endpoint` controls whether requests are routed through the [Deployments API](https://replicate.com/docs/reference/http#deployments.predictions.create) (private, fixed hardware) or the standard Models API.
|
|
|
|
**Before:**
|
|
```json
|
|
{
|
|
"replicate_key_config": {
|
|
"deployments": {
|
|
"my-model": "owner/model-name/version-hash"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**After:**
|
|
```json
|
|
{
|
|
"replicate_key_config": {
|
|
"use_deployments_endpoint": true
|
|
},
|
|
"aliases": {
|
|
"my-model": "owner/model-name"
|
|
}
|
|
}
|
|
```
|
|
|
|
| Old field | New field | Notes |
|
|
|---|---|---|
|
|
| `replicate_key_config.deployments` | Removed | Use top-level `aliases` |
|
|
| _(new)_ | `replicate_key_config.use_deployments_endpoint` | `bool`, default `false` |
|
|
|
|
---
|
|
|
|
## Breaking Change 10: Go SDK — `ExtraFields` Model Fields Renamed
|
|
|
|
`ModelRequested string` has been replaced by two fields on `BifrostResponseExtraFields` and `BifrostErrorExtraFields`.
|
|
|
|
**Before:**
|
|
```go
|
|
model := response.ExtraFields.ModelRequested
|
|
```
|
|
|
|
**After:**
|
|
```go
|
|
// The alias the caller passed as "model" in the request
|
|
original := response.ExtraFields.OriginalModelRequested
|
|
|
|
// The actual identifier sent to the provider API
|
|
// Equals OriginalModelRequested when no alias is configured
|
|
resolved := response.ExtraFields.ResolvedModelUsed
|
|
```
|
|
|
|
The same rename applies to `BifrostErrorExtraFields`.
|
|
|
|
**JSON tag changes:**
|
|
|
|
| Old | New |
|
|
|---|---|
|
|
| `"model_requested"` | `"original_model_requested"` + `"resolved_model_used"` |
|
|
|
|
---
|
|
|
|
## Breaking Change 11: Go SDK — `StreamAccumulatorResult` Field Renamed
|
|
|
|
`Model string` has been replaced by two fields on `StreamAccumulatorResult` (returned by tracer streaming accumulation methods).
|
|
|
|
**Before:**
|
|
```go
|
|
result.Model
|
|
```
|
|
|
|
**After:**
|
|
```go
|
|
result.RequestedModel // original alias from the caller
|
|
result.ResolvedModel // actual model identifier used by the provider
|
|
```
|
|
|
|
---
|
|
|
|
## Breaking Change 12: `selected_key_id` Cleared on Terminal Retry Failures
|
|
|
|
With the introduction of multi-key retry rotation, `selected_key_id` (and `selected_key_name`) in the request context are **cleared when all retry attempts fail**. Previously, these fields always reflected the key that was selected for the request, even on error.
|
|
|
|
The `attempt_trail` is now the authoritative record of every key tried and why each attempt failed.
|
|
|
|
### What changed
|
|
|
|
| Field | Before | After |
|
|
|---|---|---|
|
|
| `selected_key_id` | Always set, even on error | Empty string when all retries exhausted |
|
|
| `selected_key_name` | Always set, even on error | Empty string when all retries exhausted |
|
|
| `attempt_trail` | Not present | Array of `{ key_id, key_name, fail_reason }` per attempt |
|
|
|
|
### Impact on logging and telemetry plugins
|
|
|
|
The built-in **logging plugin** writes `selected_key_id` and `selected_key_name` directly to each log record. For multi-key requests that exhaust all retries, both fields will be empty in the stored log entry. The `attempt_trail` column captures the full per-attempt key history and is the correct field to use for failure attribution.
|
|
|
|
The built-in **telemetry plugin** emits `selected_key_id` and `selected_key_name` as span attributes. For exhausted-retry failures these attributes will be empty strings on the error span. The `attempt_trail` span attribute contains the full rotation history.
|
|
|
|
If you run a custom plugin or downstream log consumer that filters or groups by `selected_key_id` to track which key caused a failure, you must update it to handle the empty-string case and read from `attempt_trail` when attribution is needed.
|
|
|
|
### How to update
|
|
|
|
**If you read `selected_key_id` from plugin context to attribute failed requests:**
|
|
|
|
**Before:**
|
|
```go
|
|
keyID, _ := ctx.Value(schemas.BifrostContextKeySelectedKeyID).(string)
|
|
// keyID was always populated, even on error
|
|
```
|
|
|
|
**After:**
|
|
```go
|
|
// Populated on success (or for single-key / pinned / sticky flows on error):
|
|
keyID, _ := ctx.Value(schemas.BifrostContextKeySelectedKeyID).(string)
|
|
|
|
// For full attribution across all retry attempts (including failures):
|
|
if trail, ok := ctx.Value(schemas.BifrostContextKeyAttemptTrail).([]schemas.KeyAttemptRecord); ok {
|
|
for _, record := range trail {
|
|
// record.KeyID, record.KeyName, record.FailReason
|
|
}
|
|
}
|
|
```
|
|
|
|
**If you consume `selected_key_id` from the logging REST API:**
|
|
|
|
The `selected_key_id` field on a `LogEntry` may now be an empty string when the request failed after exhausting all retries. Use `attempt_trail` for the full per-attempt key history.
|
|
|
|
<Note>
|
|
Single-key, pinned (`x-bf-key-id` / `x-bf-key-name`), and session-sticky requests are unaffected — they never rotate keys, so `selected_key_id` remains populated on failure for those flows.
|
|
</Note>
|
|
|
|
---
|
|
|
|
## Opting Out: `version: 1` Compatibility Mode
|
|
|
|
If you are not ready to adopt the new deny-by-default semantics, you can add a single field to `config.json` to restore v1.4.x behavior for all allow-list fields loaded from that file:
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"providers": { ... }
|
|
}
|
|
```
|
|
|
|
| Value | Behavior |
|
|
|---|---|
|
|
| `2` (default, omitted) | v1.5.0 semantics — empty = deny all, `["*"]` = allow all |
|
|
| `1` | v1.4.x semantics — empty = allow all |
|
|
|
|
**What `version: 1` normalizes at startup** (before any other processing):
|
|
|
|
| Field | Without `version: 1` | With `version: 1` |
|
|
|---|---|---|
|
|
| Provider key `models: []` | Deny all models | Allow all models (→ `["*"]`) |
|
|
| VK `provider_configs: []` | No providers allowed | All configured providers added with `allowed_models: ["*"]` |
|
|
| VK provider config `allowed_models: []` | Deny all models | Allow all models (→ `["*"]`) |
|
|
| VK provider config `key_ids: []` | No keys allowed | All keys allowed (→ `key_ids: ["*"]`) |
|
|
| VK `mcp_configs: []` | No MCP tools allowed | All configured MCP clients added with `tools_to_execute: ["*"]` |
|
|
|
|
<Note>
|
|
`version: 1` only applies to configuration loaded from `config.json`. Virtual Keys created or updated via the REST API always use v1.5.0 semantics regardless of this setting. The automatic database migration that runs on startup is also unaffected.
|
|
</Note>
|
|
|
|
<Warning>
|
|
`version: 1` is a temporary compatibility shim. Plan to migrate your `config.json` to explicit `["*"]` wildcards and remove the `version` field before the next major release.
|
|
</Warning>
|
|
|
|
---
|
|
|
|
## Complete Migration Checklist
|
|
|
|
<Steps>
|
|
<Step title="Backup your database">
|
|
Make a copy of your config store database before starting the upgrade.
|
|
</Step>
|
|
|
|
<Step title="Update provider key models in config.json">
|
|
Replace `"models": []` or missing `models` fields with `"models": ["*"]` on every provider key.
|
|
</Step>
|
|
|
|
<Step title="Add allowed_models and key_ids to every VK provider config">
|
|
Add `"allowed_models": ["*"]` and `"key_ids": ["*"]` to every `provider_configs` entry (or list specific values). Rename any `allowed_keys` fields to `key_ids`.
|
|
</Step>
|
|
|
|
<Step title="Ensure every VK has at least one provider config">
|
|
Any Virtual Key with `"provider_configs": []` or no `provider_configs` will block all traffic.
|
|
</Step>
|
|
|
|
<Step title="Update tools_to_execute for MCP configs">
|
|
Replace `"tools_to_execute": []` with `"tools_to_execute": ["*"]`. Ensure every VK that needs MCP access has at least one `mcp_configs` entry.
|
|
</Step>
|
|
|
|
<Step title="Handle nullable weight in API consumers">
|
|
Update any client code that processes `weight` to accept `null` in addition to numbers.
|
|
</Step>
|
|
|
|
<Step title="Fix invalid WhiteList values">
|
|
Ensure no list mixes `"*"` with specific values (e.g., `["*", "gpt-4o"]`) and no list has duplicate entries.
|
|
</Step>
|
|
|
|
<Step title="Migrate key management to dedicated endpoints">
|
|
Stop sending `keys` in provider create/update payloads and stop reading `keys` from provider responses. Use `/api/providers/{provider}/keys` for all key operations.
|
|
</Step>
|
|
|
|
<Step title="Update compact plugin config">
|
|
Replace `enable_litellm_fallbacks` with the appropriate combination of `convert_text_to_chat`, `convert_chat_to_responses`, and `should_drop_params`.
|
|
</Step>
|
|
|
|
<Step title="Migrate provider deployments to aliases">
|
|
Move deployment mappings from provider-specific `deployments` fields into the top-level `aliases` field on each key. For Replicate, set `use_deployments_endpoint: true` if you were using the deployments endpoint.
|
|
</Step>
|
|
|
|
<Step title="Update Go SDK references to ExtraFields.ModelRequested">
|
|
Replace `ExtraFields.ModelRequested` with `ExtraFields.OriginalModelRequested` (and optionally read `ExtraFields.ResolvedModelUsed`). Update JSON consumers reading `"model_requested"` to use `"original_model_requested"` and `"resolved_model_used"`.
|
|
</Step>
|
|
|
|
<Step title="Update Go SDK references to StreamAccumulatorResult.Model">
|
|
Replace `.Model` with `.RequestedModel` (and optionally `.ResolvedModel`) on any `StreamAccumulatorResult` usage.
|
|
</Step>
|
|
|
|
<Step title="Handle empty selected_key_id on terminal retry failures">
|
|
If your code reads `selected_key_id` / `selected_key_name` from the request context or log entries to attribute failed requests, add a null/empty check and fall back to `attempt_trail` for the full per-attempt key history.
|
|
</Step>
|
|
</Steps>
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
**All requests returning 403/blocked after upgrade**
|
|
|
|
A provider key has `models: []`, a Virtual Key has no `provider_configs`, or a provider config has `allowed_models: []`. Check Bifrost logs — a blocked request logs which rule denied it. Fix: add `"models": ["*"]` on provider keys, `"allowed_models": ["*"]` on VK provider configs.
|
|
|
|
**MCP tools not being injected / tool calls blocked**
|
|
|
|
The VK needs an `mcp_configs` entry for the MCP client with `"tools_to_execute": ["*"]` (or specific tools).
|
|
|
|
**API returning 400 on VK create/update**
|
|
|
|
A whitelist validation failure — either mixing `"*"` with specific values, or duplicate values in a list.
|
|
|
|
**"No keys available" or key selection errors**
|
|
|
|
A provider config with `key_ids` omitted or `[]` now blocks all keys (`allow_all_keys: false`). Add `"key_ids": ["*"]`.
|
|
|
|
**Provider create/update errors about `keys` field**
|
|
|
|
The `keys` field has been removed. Remove it from provider payloads and use `/api/providers/{provider}/keys` instead.
|
|
|
|
**Replicate requests failing after upgrade**
|
|
|
|
If you used `replicate_key_config.deployments`, move the mappings to the top-level `aliases` field and set `use_deployments_endpoint: true` if you were targeting the Deployments API.
|
|
|
|
**Go SDK compilation errors on `ModelRequested` or `StreamAccumulatorResult.Model`**
|
|
|
|
Rename to `OriginalModelRequested`/`ResolvedModelUsed` on ExtraFields, and `RequestedModel`/`ResolvedModel` on StreamAccumulatorResult.
|