mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(proxy): keep the model-group alias through vector store credential merges
Since #24548, get_deployment_credentials_with_provider unconditionally injects the deployment's litellm_params.model into the returned credentials. Router-bound vector store call sites merged that dict over data, so the request left the endpoint carrying the underlying provider model instead of the alias the caller named. The router then resolved the deployment via the specific-deployment path, which skips access-group filtering, and when several model groups share one provider model the request could be served under the wrong group. Add a routing_model parameter to prepare_data_with_credentials and pass the resolved alias at the three router-bound merge sites in the vector store files endpoints. Direct-to-SDK call sites (batches, files) are unchanged and keep receiving the underlying model, preserving the #25104 fix. Fixes #36103 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
729bec69f5
commit
b62f0cc1eb
5 changed files with 58 additions and 5 deletions
|
|
@ -453,6 +453,7 @@ def prepare_data_with_credentials(
|
|||
credentials: dict,
|
||||
file_id: str | None = None,
|
||||
include_internal_credentials: bool = False,
|
||||
routing_model: str | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Update data dictionary with model credentials (in-place).
|
||||
|
|
@ -463,8 +464,17 @@ def prepare_data_with_credentials(
|
|||
file_id: Optional original file_id to set (for decoded file IDs)
|
||||
include_internal_credentials: Preserve an immutable server-side snapshot
|
||||
for code paths that must distinguish proxy config from request params.
|
||||
routing_model: Model-group alias to keep in ``data["model"]`` after the
|
||||
merge. Credentials carry the deployment's underlying
|
||||
``litellm_params.model`` (which call sites dispatching straight to
|
||||
the provider SDK need), but router-bound call sites must keep
|
||||
routing by alias: the underlying model loses the model-group
|
||||
identity (access groups, team scoping) when several aliases share
|
||||
one provider model (#36103).
|
||||
"""
|
||||
data.update(credentials)
|
||||
if routing_model is not None:
|
||||
data["model"] = routing_model
|
||||
if include_internal_credentials:
|
||||
data["_litellm_internal_model_credentials"] = MappingProxyType(dict(credentials))
|
||||
data.pop("custom_llm_provider", None)
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ def _update_request_data_with_managed_file_id(
|
|||
data=data,
|
||||
credentials=credentials,
|
||||
file_id=llm_output_file_id, # Use the actual provider file ID
|
||||
routing_model=routing_model,
|
||||
)
|
||||
verbose_logger.info(
|
||||
"Routing vector store file operation to model: %s, file_id: %s -> %s",
|
||||
|
|
@ -272,6 +273,7 @@ async def _update_request_data_with_model_routing_hint(
|
|||
prepare_data_with_credentials(
|
||||
data=data,
|
||||
credentials=credentials,
|
||||
routing_model=model_hint if isinstance(model_hint, str) else None,
|
||||
)
|
||||
return data
|
||||
|
||||
|
|
@ -293,6 +295,7 @@ async def _update_request_data_with_model_routing_hint(
|
|||
model_names_to_check.append(model_name)
|
||||
|
||||
openai_credentials = None
|
||||
openai_model_name = None
|
||||
for model_name in model_names_to_check:
|
||||
credentials = llm_router.get_deployment_credentials_with_provider(model_id=model_name, team_id=caller_team_id)
|
||||
if credentials is None:
|
||||
|
|
@ -313,9 +316,10 @@ async def _update_request_data_with_model_routing_hint(
|
|||
if openai_credentials is not None:
|
||||
return data
|
||||
openai_credentials = credentials
|
||||
openai_model_name = model_name
|
||||
|
||||
if openai_credentials is not None:
|
||||
prepare_data_with_credentials(data=data, credentials=openai_credentials)
|
||||
prepare_data_with_credentials(data=data, credentials=openai_credentials, routing_model=openai_model_name)
|
||||
elif len(model_names_to_check) == 1:
|
||||
await _authorize_model_routing_hint(
|
||||
model=model_names_to_check[0],
|
||||
|
|
|
|||
|
|
@ -88,6 +88,40 @@ class TestPrepareDataWithCredentials:
|
|||
|
||||
assert "_litellm_internal_model_credentials" not in data
|
||||
|
||||
def test_routing_model_keeps_alias_over_credentials_model(self):
|
||||
"""
|
||||
Two model groups can share one litellm_params.model; router-bound call
|
||||
sites pass routing_model so the group alias survives the merge and the
|
||||
router can still apply per-group access controls (#36103).
|
||||
"""
|
||||
data = {"model": "team-a-gpt", "vector_store_id": "vs_1"}
|
||||
credentials = {
|
||||
"api_key": "sk-shared",
|
||||
"custom_llm_provider": "openai",
|
||||
"model": "openai/gpt-4o-mini",
|
||||
}
|
||||
|
||||
prepare_data_with_credentials(
|
||||
data=data, credentials=credentials, routing_model="team-a-gpt"
|
||||
)
|
||||
|
||||
assert data["model"] == "team-a-gpt"
|
||||
assert data["api_key"] == "sk-shared"
|
||||
assert "custom_llm_provider" not in data
|
||||
|
||||
def test_credentials_model_lands_in_data_without_routing_model(self):
|
||||
"""Direct-to-SDK call sites still need the deployment model (#25104)."""
|
||||
data = {"model": "bedrock-batch-alias"}
|
||||
credentials = {
|
||||
"aws_region_name": "us-west-2",
|
||||
"model": "bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0",
|
||||
}
|
||||
|
||||
prepare_data_with_credentials(data=data, credentials=credentials)
|
||||
|
||||
assert data["model"] == "bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0"
|
||||
assert data["aws_region_name"] == "us-west-2"
|
||||
|
||||
|
||||
class TestRoundTrip:
|
||||
"""Tests for encode -> decode round-trip integrity."""
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@ async def test_vector_store_file_list_resolves_credentials_from_model_query_para
|
|||
|
||||
assert result["api_key"] == "sk-team-openai"
|
||||
assert result["api_base"] == "https://api.openai.com/v1"
|
||||
assert result["model"] == "openai/gpt-4o-mini"
|
||||
# routing stays on the model-group alias, not the deployment's provider model (#36103)
|
||||
assert result["model"] == "team-openai"
|
||||
assert "custom_llm_provider" not in result
|
||||
llm_router.get_deployment_credentials_with_provider.assert_called_once_with(
|
||||
model_id="team-openai"
|
||||
|
|
@ -207,7 +208,8 @@ async def test_vector_store_file_list_resolves_single_openai_team_deployment():
|
|||
|
||||
assert result["api_key"] == "sk-team-openai"
|
||||
assert result["api_base"] == "https://api.openai.com/v1"
|
||||
assert result["model"] == "openai/gpt-4o-mini"
|
||||
# routing stays on the model-group alias, not the deployment's provider model (#36103)
|
||||
assert result["model"] == "team-openai"
|
||||
assert "custom_llm_provider" not in result
|
||||
llm_router.get_deployment_credentials_with_provider.assert_called_once_with(
|
||||
model_id="team-openai", team_id=None
|
||||
|
|
@ -245,7 +247,8 @@ async def test_vector_store_file_list_wildcard_model_hint_falls_back_to_team_dep
|
|||
|
||||
assert result["api_key"] == "sk-team-openai"
|
||||
assert result["api_base"] == "https://api.openai.com/v1"
|
||||
assert result["model"] == "openai/gpt-4o-mini"
|
||||
# routing stays on the matched team alias, not the deployment's provider model (#36103)
|
||||
assert result["model"] == "team-openai"
|
||||
assert "custom_llm_provider" not in result
|
||||
assert llm_router.get_deployment_credentials_with_provider.call_count == 3
|
||||
|
||||
|
|
|
|||
|
|
@ -169,7 +169,9 @@ async def test_vector_store_file_list_resolves_managed_vector_store_before_team_
|
|||
assert response == {"ok": True}
|
||||
assert captured_data["vector_store_id"] == "vs_provider_native"
|
||||
assert captured_data["api_key"] == "sk-managed-deployment"
|
||||
assert captured_data["model"] == "openai/managed-deployment"
|
||||
# the alias survives the credential merge so router dispatch keeps the
|
||||
# model-group identity (#36103)
|
||||
assert captured_data["model"] == "managed-deployment"
|
||||
llm_router.get_deployment_credentials_with_provider.assert_called_once_with(
|
||||
model_id="managed-deployment"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue