fix: fail over with each candidate provider's own model

The failover loop resolved a single Model for the request and reused it
for every provider: a fallback provider was asked to serve the routing
winner's model id and billed at the winner's pricing and fee. The alias
map now keeps (model, provider) candidate pairs, the proxy rebinds both
per attempt, and forwarding, max-cost echo, and settlement all use the
candidate actually being tried. On a failover serve the response's
model field now names the serving candidate's id.

The unified candidate lookup also applies the version-suffix strip
(-YYYYMMDD) that model resolution already had, so version-suffixed
requests no longer resolve a model yet 400 with "no provider found".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jeroen Ubbink
2026-07-22 15:12:21 +02:00
co-authored by Claude Fable 5
parent 02cd2cfeec
commit df4d4c44e6
7 changed files with 485 additions and 57 deletions
+5 -5
View File
@@ -142,7 +142,7 @@ def test_create_model_mappings_includes_db_override_for_missing_cached_model(
)
assert "azure/gpt-4o" in model_instances
assert provider_map["azure/gpt-4o"] == [provider]
assert [p for _, p in provider_map["azure/gpt-4o"]] == [provider]
assert "gpt-4o" in unique_models
@@ -186,7 +186,7 @@ def test_create_model_mappings_dedupes_with_provider_identity_not_provider_type(
disabled_model_keys=set(),
)
providers_for_alias = provider_map["azure/gpt-4o"]
providers_for_alias = [p for _, p in provider_map["azure/gpt-4o"]]
assert provider_a in providers_for_alias
assert provider_b in providers_for_alias
assert len(providers_for_alias) == 2
@@ -226,8 +226,8 @@ def test_create_model_mappings_applies_override_only_to_matching_provider(
disabled_model_keys=set(),
)
assert provider_map["provider-b-only"] == [provider_b]
assert set(provider_map["same-id"]) == {provider_a, provider_b}
assert [p for _, p in provider_map["provider-b-only"]] == [provider_b]
assert {p for _, p in provider_map["same-id"]} == {provider_a, provider_b}
def test_create_model_mappings_disables_only_matching_provider() -> None:
@@ -251,4 +251,4 @@ def test_create_model_mappings_disables_only_matching_provider() -> None:
disabled_model_keys={("same-id", 2)},
)
assert provider_map["same-id"] == [provider_a]
assert [p for _, p in provider_map["same-id"]] == [provider_a]