mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-26 01:12:21 +00:00
fix(proxy): compare model_info echo against the deployment's cost-map lookup
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
b9df34aa11
commit
de86d2fdbe
2 changed files with 82 additions and 12 deletions
|
|
@ -138,7 +138,6 @@ from litellm.types.router import (
|
|||
updateLiteLLMParams,
|
||||
)
|
||||
from litellm.types.utils import (
|
||||
COST_MAP_LOOKUP_KEY,
|
||||
echoed_cost_map_fields,
|
||||
echoed_cost_map_pricing_fields,
|
||||
without_server_derived_pricing,
|
||||
|
|
@ -876,12 +875,11 @@ def _ptu_priced_deployment(model_params: Deployment) -> Deployment:
|
|||
)
|
||||
|
||||
|
||||
def _cost_map_entry(model_info: Mapping[str, object]) -> Mapping[str, object]:
|
||||
key: Final = model_info.get(COST_MAP_LOOKUP_KEY)
|
||||
if not isinstance(key, str):
|
||||
return MappingProxyType({})
|
||||
def _cost_map_entry(db_model: Deployment, incoming_model_info: Mapping[str, object]) -> Mapping[str, object]:
|
||||
base_model: Final = incoming_model_info.get("base_model")
|
||||
lookup: Final = base_model if isinstance(base_model, str) else db_model.litellm_params.model
|
||||
try:
|
||||
return MappingProxyType(dict(litellm.get_model_info(model=key)))
|
||||
return MappingProxyType(dict(litellm.get_model_info(model=lookup)))
|
||||
except Exception:
|
||||
return MappingProxyType({})
|
||||
|
||||
|
|
@ -909,7 +907,9 @@ def update_db_model(db_model: Deployment, updated_patch: updateDeployment) -> Pr
|
|||
# update model info
|
||||
if updated_patch.model_info:
|
||||
incoming_model_info: Final = updated_patch.model_info.model_dump(exclude_none=True)
|
||||
echoed_fields: Final = echoed_cost_map_fields(incoming_model_info, _cost_map_entry(incoming_model_info))
|
||||
echoed_fields: Final = echoed_cost_map_fields(
|
||||
incoming_model_info, _cost_map_entry(db_model, incoming_model_info)
|
||||
)
|
||||
merged_model_info.update(
|
||||
MappingProxyType(
|
||||
dict(
|
||||
|
|
|
|||
|
|
@ -3961,7 +3961,7 @@ class TestModelInfoCostMapEchoFilter:
|
|||
from litellm.proxy.management_endpoints.model_management_endpoints import update_db_model
|
||||
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
||||
|
||||
entry = litellm.get_model_info("gpt-5.6")
|
||||
entry = litellm.get_model_info("openai/gpt-5.6")
|
||||
echo = {**entry, "id": "dep-echo-0", "db_model": True, "access_groups": ["prod"]}
|
||||
db_model = Deployment(
|
||||
model_name="gpt-5.6",
|
||||
|
|
@ -3987,7 +3987,7 @@ class TestModelInfoCostMapEchoFilter:
|
|||
from litellm.proxy.management_endpoints.model_management_endpoints import update_db_model
|
||||
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
||||
|
||||
entry = litellm.get_model_info("gpt-5.6")
|
||||
entry = litellm.get_model_info("openai/gpt-5.6")
|
||||
echo = {
|
||||
**entry,
|
||||
"id": "dep-echo-1",
|
||||
|
|
@ -4020,7 +4020,7 @@ class TestModelInfoCostMapEchoFilter:
|
|||
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
||||
from litellm.types.utils import echoed_cost_map_fields
|
||||
|
||||
entry = litellm.get_model_info("gpt-5.6")
|
||||
entry = litellm.get_model_info("openai/gpt-5.6")
|
||||
assert echoed_cost_map_fields({"max_input_tokens": entry["max_input_tokens"]}, entry) == ()
|
||||
db_model = Deployment(
|
||||
model_name="gpt-5.6",
|
||||
|
|
@ -4049,7 +4049,7 @@ class TestModelInfoCostMapEchoFilter:
|
|||
from litellm.proxy.management_endpoints.model_management_endpoints import update_db_model
|
||||
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
||||
|
||||
entry = litellm.get_model_info("gpt-5.6")
|
||||
entry = litellm.get_model_info("openai/gpt-5.6")
|
||||
db_model = Deployment(
|
||||
model_name="gpt-5.6",
|
||||
litellm_params=LiteLLM_Params(model="openai/gpt-5.6"),
|
||||
|
|
@ -4072,7 +4072,7 @@ class TestModelInfoCostMapEchoFilter:
|
|||
from litellm.proxy.management_endpoints.model_management_endpoints import update_db_model
|
||||
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
||||
|
||||
entry = litellm.get_model_info("gpt-5.6")
|
||||
entry = litellm.get_model_info("openai/gpt-5.6")
|
||||
db_model = Deployment(
|
||||
model_name="gpt-5.6",
|
||||
litellm_params=LiteLLM_Params(model="openai/gpt-5.6"),
|
||||
|
|
@ -4090,6 +4090,76 @@ class TestModelInfoCostMapEchoFilter:
|
|||
assert info["mode"] == "chat"
|
||||
assert info["access_groups"] == ["staging"]
|
||||
|
||||
def test_echo_is_compared_against_the_deployments_lookup_not_the_key(self):
|
||||
import litellm
|
||||
|
||||
from litellm.proxy.management_endpoints.model_management_endpoints import update_db_model
|
||||
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
||||
|
||||
lookup_pairs: Final = (
|
||||
("openai/gpt-5.6", "gpt-5.6"),
|
||||
("openai/gpt-4.1-mini", "gpt-4.1-mini"),
|
||||
)
|
||||
lookup_data: Final = tuple(
|
||||
(deployment_model, deployment_entry, differing_fields)
|
||||
for deployment_model, key_model in lookup_pairs
|
||||
for deployment_entry in (litellm.get_model_info(deployment_model),)
|
||||
for key_entry in (litellm.get_model_info(key_model),)
|
||||
for differing_fields in (
|
||||
frozenset(
|
||||
k for k in deployment_entry if k in key_entry and deployment_entry[k] != key_entry[k]
|
||||
),
|
||||
)
|
||||
if differing_fields
|
||||
)
|
||||
if not lookup_data:
|
||||
pytest.skip("No deployment/key cost-map lookup differences are available")
|
||||
|
||||
deployment_model, entry, differing_fields = lookup_data[0]
|
||||
assert differing_fields
|
||||
db_model = Deployment(
|
||||
model_name=deployment_model,
|
||||
litellm_params=LiteLLM_Params(model=deployment_model),
|
||||
model_info=ModelInfo(id="dep-echo-5"),
|
||||
)
|
||||
echo = {**entry, "id": "dep-echo-5", "db_model": True, "access_groups": ["prod"]}
|
||||
|
||||
result = update_db_model(
|
||||
db_model=db_model,
|
||||
updated_patch=updateDeployment(model_info=ModelInfo(**echo)),
|
||||
)
|
||||
|
||||
info = json.loads(result["model_info"])
|
||||
assert not frozenset(info).intersection(frozenset(entry) - frozenset(("mode",)))
|
||||
|
||||
def test_base_model_wins_over_litellm_params_model_for_the_lookup(self):
|
||||
import litellm
|
||||
|
||||
from litellm.proxy.management_endpoints.model_management_endpoints import update_db_model
|
||||
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
||||
|
||||
entry = litellm.get_model_info("azure/gpt-5.6")
|
||||
db_model = Deployment(
|
||||
model_name="azure/my-deploy",
|
||||
litellm_params=LiteLLM_Params(model="azure/my-deploy"),
|
||||
model_info=ModelInfo(id="dep-echo-6", base_model="azure/gpt-5.6"),
|
||||
)
|
||||
echo = {
|
||||
**entry,
|
||||
"id": "dep-echo-6",
|
||||
"base_model": "azure/gpt-5.6",
|
||||
"db_model": True,
|
||||
}
|
||||
|
||||
result = update_db_model(
|
||||
db_model=db_model,
|
||||
updated_patch=updateDeployment(model_info=ModelInfo(**echo)),
|
||||
)
|
||||
|
||||
info = json.loads(result["model_info"])
|
||||
assert not frozenset(info).intersection(frozenset(entry) - frozenset(("mode",)))
|
||||
assert info["base_model"] == "azure/gpt-5.6"
|
||||
|
||||
|
||||
class TestUpdateDBModelClearCacheControlInjectionPoints:
|
||||
def test_explicit_null_removes_stored_injection_points(self):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue