mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-29 06:33:28 +00:00
Merge b9d54d15bc into 8d6b8dab3d
This commit is contained in:
commit
c77b76bdf6
2 changed files with 81 additions and 0 deletions
|
|
@ -2384,6 +2384,17 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
if len(tools) > 1:
|
||||
optional_params["tools"] = tools
|
||||
|
||||
## Deployment max output (proxy model_info) beats get_config(), which only sees the provider-stripped
|
||||
## model name and so falls back to 4096 for custom deployments; a request or class default still wins
|
||||
if "max_tokens" not in optional_params and litellm.AnthropicConfig.max_tokens is None:
|
||||
match litellm_params:
|
||||
case {"model_info": {"max_output_tokens": int(deployment_max_tokens)}} if (
|
||||
deployment_max_tokens > 0 and not isinstance(deployment_max_tokens, bool)
|
||||
):
|
||||
optional_params["max_tokens"] = deployment_max_tokens # rebind-ok: out-param store
|
||||
case object():
|
||||
pass # no deployment limit: get_config() below fills the default
|
||||
|
||||
## Load Config
|
||||
config: Final = litellm.AnthropicConfig.get_config(model=model)
|
||||
for k, v in config.items():
|
||||
|
|
|
|||
|
|
@ -2768,6 +2768,76 @@ def test_transform_request_respects_user_max_tokens():
|
|||
assert result["max_tokens"] == 1000
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("optional_params", "litellm_params", "expected"),
|
||||
[
|
||||
# custom deployment: the configured output limit replaces the 4096 fallback
|
||||
({}, {"model_info": {"max_output_tokens": 131072}}, 131072),
|
||||
# an explicit request value still wins over the deployment limit
|
||||
({"max_tokens": 1000}, {"model_info": {"max_output_tokens": 131072}}, 1000),
|
||||
# no deployment limit: unknown models keep the 4096 fallback
|
||||
({}, {}, 4096),
|
||||
({}, {"model_info": {"max_output_tokens": None}}, 4096),
|
||||
],
|
||||
)
|
||||
def test_transform_request_default_max_tokens_from_deployment(
|
||||
optional_params: dict[str, object], litellm_params: dict[str, object], expected: int
|
||||
) -> None:
|
||||
result = AnthropicConfig().transform_request(
|
||||
model="glm-5.3-flash",
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
headers={},
|
||||
)
|
||||
|
||||
assert result["max_tokens"] == expected, f"model_info={litellm_params!r} request={optional_params!r}"
|
||||
|
||||
|
||||
async def test_router_sends_deployment_max_output_tokens_when_request_omits_max_tokens(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
respx_mock: respx.MockRouter,
|
||||
) -> None:
|
||||
"""A proxy deployment `anthropic/<custom>` with model_info.max_output_tokens must not go upstream capped at 4096."""
|
||||
monkeypatch.setenv("DISABLE_AIOHTTP_TRANSPORT", "True")
|
||||
sent: Final[list[dict]] = []
|
||||
|
||||
def respond(request: httpx.Request) -> httpx.Response:
|
||||
sent.append(json.loads(request.content))
|
||||
return httpx.Response(
|
||||
200,
|
||||
json={
|
||||
"id": "msg_1",
|
||||
"type": "message",
|
||||
"role": "assistant",
|
||||
"model": "glm-5.3-flash",
|
||||
"content": [{"type": "text", "text": "OK"}],
|
||||
"stop_reason": "end_turn",
|
||||
"usage": {"input_tokens": 3, "output_tokens": 1},
|
||||
},
|
||||
)
|
||||
|
||||
respx_mock.post("https://anthropic-compatible.test/v1/messages").mock(side_effect=respond)
|
||||
router: Final = litellm.Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "claude-glm-5.3-flash",
|
||||
"litellm_params": {
|
||||
"model": "anthropic/glm-5.3-flash",
|
||||
"api_base": "https://anthropic-compatible.test",
|
||||
"api_key": "test-key",
|
||||
},
|
||||
"model_info": {"max_output_tokens": 131072},
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
await router.acompletion(model="claude-glm-5.3-flash", messages=[{"role": "user", "content": "hi"}])
|
||||
await router.acompletion(model="claude-glm-5.3-flash", messages=[{"role": "user", "content": "hi"}], max_tokens=512)
|
||||
|
||||
assert [body["max_tokens"] for body in sent] == [131072, 512], "first call omits max_tokens, second sends 512"
|
||||
|
||||
|
||||
def test_calculate_usage_completion_tokens_details_always_populated():
|
||||
"""
|
||||
Test that completion_tokens_details is always populated in Usage object,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue