fix(bedrock): route unmapped converse-only family model ids to converse

#42713 stopped Bedrock-native OpenAI ids that are not in the cost map yet from
falling to the invoke route. The same gap exists for the other families that
have no invoke transformation at all: minimax, nvidia, writer, zai, google and
xai. An id from one of them that is newer than the cost map hits
get_bedrock_route -> "invoke" -> get_bedrock_invoke_provider() -> None ->
BedrockError, when Converse would have served it

Add a second family regex for those six and default them to converse, the same
way the openai family is handled. _OPENAI_FAMILY_MODEL_RE is left alone because
the prompt-caching rule is openai-specific

Every shipped id of these families already resolves to a converse entry via its
base model (checked against the cost map), so this only changes behaviour for
ids that are not in the map yet

Tests: six unmapped ids route to converse, and an unmapped meta.* id still
routes to invoke since meta has an invoke handler
This commit is contained in:
Siddhant Badola 2026-09-26 01:43:22 -04:00
parent 4d7aa89fa3
commit ce65873c89
2 changed files with 40 additions and 0 deletions

View file

@ -37,6 +37,8 @@ if TYPE_CHECKING:
_ERROR_REQUEST_URL: Final = "https://docs.litellm.ai/docs"
_OPENAI_FAMILY_MODEL_RE: Final = re.compile(r"(^|[./])openai\.")
# Families with no invoke transformation; unmapped ids default to converse.
_CONVERSE_ONLY_FAMILY_MODEL_RE: Final = re.compile(r"(^|[./])(minimax|nvidia|writer|zai|google|xai)\.")
def error_response_text(response: httpx.Response) -> str:
@ -1220,6 +1222,8 @@ class BedrockModelInfo(BaseLLMModelInfo):
return "converse"
if _OPENAI_FAMILY_MODEL_RE.search(base_model):
return "converse"
if _CONVERSE_ONLY_FAMILY_MODEL_RE.search(base_model):
return "converse"
return "invoke"
@staticmethod

View file

@ -981,3 +981,39 @@ def test_unmapped_openai_family_model_routes_to_converse():
assert BedrockModelInfo.get_bedrock_route(unmapped) == "converse"
imported: Final = "bedrock/openai/arn:aws:bedrock:us-east-1:123456789012:imported-model/abc123"
assert BedrockModelInfo.get_bedrock_route(imported) == "openai"
@pytest.mark.parametrize(
"unmapped",
[
"bedrock/minimax.minimax-m99-unmapped",
"bedrock/us.nvidia.nemotron-99b-unmapped",
"bedrock/writer.palmyra-x99-unmapped",
"bedrock/zai.glm-99-unmapped",
"bedrock/google.gemma-99-unmapped",
"bedrock/global.xai.grok-99-unmapped",
],
)
def test_unmapped_converse_only_family_model_routes_to_converse(unmapped: str):
"""Same rule as the OpenAI family, for the other Bedrock-native families with no invoke handler.
minimax, nvidia, writer, zai, google and xai have no transformation under
``litellm/llms/bedrock/chat/invoke_transformations``; every id of theirs is served by Converse.
An id newer than the cost map used to fall to the invoke route, where
``get_bedrock_invoke_provider`` returns ``None`` and the request fails, instead of Converse.
"""
import litellm
assert BedrockModelInfo.get_base_model(unmapped) not in litellm.bedrock_converse_models
assert BedrockModelInfo.get_bedrock_route(unmapped) == "converse"
def test_unmapped_model_of_family_with_invoke_handler_still_routes_to_invoke():
"""The converse-only default is scoped to families without an invoke handler; ``meta`` has one."""
from typing import Final
import litellm
unmapped: Final = "bedrock/meta.llama99-unmapped-v1:0"
assert BedrockModelInfo.get_base_model(unmapped) not in litellm.bedrock_converse_models
assert BedrockModelInfo.get_bedrock_route(unmapped) == "invoke"