This commit is contained in:
Quinn Xu 2026-10-20 04:46:20 +00:00 • committed by GitHub
commit 895dbcf9d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 86 additions and 2 deletions

View file

@ -40,6 +40,37 @@ def split_mantle_region_prefix(model: str) -> tuple[str | None, str]:
return None, model
# Cross-Region / geo inference-profile prefixes on Bedrock model IDs
# (us.openai.gpt-6.1-sol, eu.anthropic..., global....). Distinct from the
# AWS-region path prefix handled by split_mantle_region_prefix (us-east-1/...).
# Keep aligned with litellm.utils._BEDROCK_REGION_PREFIXES; cannot import that
# here without a circular import through utils -> this module.
_MANTLE_GEO_PROFILE_PREFIXES: Final = (
"us.",
"eu.",
"apac.",
"jp.",
"au.",
"us-gov.",
"global.",
"ap-northeast-1.",
)
def mantle_cost_map_model_id(model: str) -> str:
"""Bare model id for ``bedrock_mantle/<id>`` cost-map lookups.
Strips an optional AWS-region path prefix and a geo inference-profile
prefix so ``us.openai.gpt-6.1-sol`` resolves to the
``openai.gpt-6.1-sol`` row. The model id sent to AWS is unchanged.
"""
bare: Final = split_mantle_region_prefix(model)[1]
for prefix in _MANTLE_GEO_PROFILE_PREFIXES:
if bare.startswith(prefix):
return bare[len(prefix) :]
return bare
def resolve_mantle_region(params: Mapping[str, object]) -> str:
region: Final = params.get("aws_region_name")
if isinstance(region, str) and region:
@ -149,7 +180,7 @@ def mantle_supports_responses(model: str | None, model_cost: dict) -> bool:
gpt-oss substring), so a substring gate would be wrong. A model absent from
model_cost simply has no signal and returns False (chat-completions emulation).
"""
entry: Final = model_cost.get(f"bedrock_mantle/{split_mantle_region_prefix(model)[1]}", {}) if model else {}
entry: Final = model_cost.get(f"bedrock_mantle/{mantle_cost_map_model_id(model)}", {}) if model else {}
if "/v1/responses" in (entry.get("supported_endpoints") or []):
return True
return entry.get("mode") == "responses"
@ -166,5 +197,5 @@ def mantle_base_segment(model: str | None, model_cost: dict) -> str:
the base for the model's whole OpenAI-compatible surface, so both the chat and
responses configs derive from it -- there is no separate model-name rule.
"""
entry: Final = model_cost.get(f"bedrock_mantle/{split_mantle_region_prefix(model)[1]}", {}) if model else {}
entry: Final = model_cost.get(f"bedrock_mantle/{mantle_cost_map_model_id(model)}", {}) if model else {}
return "openai/v1" if entry.get("use_openai_responses_path") is True else "v1"

View file

@ -1352,6 +1352,22 @@ class TestMantleBaseSegment:
),
("openai.gpt-oss-120b", {}, "v1"),
(None, {}, "v1"),
# Geo inference-profile prefixes must resolve to the bare cost-map row
(
"us.openai.gpt-5.5",
{"bedrock_mantle/openai.gpt-5.5": {"use_openai_responses_path": True}},
"openai/v1",
),
(
"eu.openai.gpt-oss-120b",
{"bedrock_mantle/openai.gpt-oss-120b": {}},
"v1",
),
(
"us-east-1/us.openai.gpt-5.5",
{"bedrock_mantle/openai.gpt-5.5": {"use_openai_responses_path": True}},
"openai/v1",
),
],
)
def test_base_segment(self, model, model_cost, expected):
@ -1365,6 +1381,43 @@ class TestMantleSupportsResponses:
model-name match: per-model, so gpt-oss-120b is supported but the safeguard
variant is not despite the shared substring."""
@pytest.mark.parametrize(
"model",
[
"openai.gpt-6.1-sol",
"us.openai.gpt-6.1-sol",
"eu.openai.gpt-6.1-sol",
"global.openai.gpt-6.1-sol",
"us-east-1/us.openai.gpt-6.1-sol",
],
)
def test_geo_inference_profile_resolves_cost_map_row(self, model):
from litellm.llms.bedrock_mantle.common_utils import (
mantle_base_segment,
mantle_cost_map_model_id,
mantle_supports_responses,
)
model_cost = {
"bedrock_mantle/openai.gpt-6.1-sol": {
"mode": "responses",
"supported_endpoints": ["/v1/chat/completions", "/v1/responses"],
"use_openai_responses_path": True,
}
}
assert mantle_cost_map_model_id(model) == "openai.gpt-6.1-sol"
assert mantle_supports_responses(model, model_cost) is True
assert mantle_base_segment(model, model_cost) == "openai/v1"
def test_unknown_geo_prefixed_model_stays_unsupported(self):
from litellm.llms.bedrock_mantle.common_utils import (
mantle_base_segment,
mantle_supports_responses,
)
assert mantle_supports_responses("us.openai.unknown-model", {}) is False
assert mantle_base_segment("us.openai.unknown-model", {}) == "v1"
class TestBedrockMantlePerModelResponsesURL:
"""End-to-end: the registry-selected config must build the correct wire URL