mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-14 09:03:16 +00:00
fix(bedrock): send only the effort from output_config to Converse Claude without thinking
Other output_config keys such as task_budget never reached Converse without a thinking block, and Bedrock answers 400 to them, so they stay behind there
This commit is contained in:
parent
afb8eb7dfe
commit
ce02ebfbd0
2 changed files with 35 additions and 3 deletions
|
|
@ -1222,7 +1222,9 @@ class LiteLLMAnthropicMessagesAdapter:
|
|||
|
||||
Bedrock Converse takes the tier in ``output_config`` with or without a ``thinking`` block, so
|
||||
it travels on its own instead of only alongside ``thinking``. ``format`` stays behind, since
|
||||
``_translate_output_format_to_openai`` carries it as ``response_format``.
|
||||
``_translate_output_format_to_openai`` carries it as ``response_format``. Without ``thinking``
|
||||
only ``effort`` goes, since the other keys (``task_budget``) never reached Converse there and
|
||||
it rejects them.
|
||||
"""
|
||||
if "output_config" not in anthropic_message_request or not self._is_bedrock_claude_target(new_kwargs["model"]):
|
||||
return
|
||||
|
|
@ -1231,13 +1233,16 @@ class LiteLLMAnthropicMessagesAdapter:
|
|||
if not isinstance(output_config, dict):
|
||||
return
|
||||
|
||||
effort_config: Final = {k: v for k, v in output_config.items() if k != "format"}
|
||||
has_thinking: Final = bool(anthropic_message_request.get("thinking"))
|
||||
effort_config: Final = {
|
||||
k: v for k, v in output_config.items() if k == "effort" or (has_thinking and k != "format")
|
||||
}
|
||||
if not effort_config:
|
||||
return
|
||||
model: Final = new_kwargs["model"]
|
||||
if (
|
||||
drop_params
|
||||
and not anthropic_message_request.get("thinking")
|
||||
and not has_thinking
|
||||
and is_bedrock_application_inference_profile_arn(bedrock_capability_model(model, base_model))
|
||||
):
|
||||
litellm.verbose_logger.warning(UNRESOLVED_ARN_EFFORT_WITHOUT_THINKING_WARNING, model)
|
||||
|
|
|
|||
|
|
@ -5526,6 +5526,33 @@ async def test_bedrock_converse_claude_gets_the_effort_without_a_thinking_block(
|
|||
assert "thinking" not in sent
|
||||
|
||||
|
||||
_TASK_BUDGET: Final = {"type": "tokens", "total": 20000}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("output_config", "sent_output_config"),
|
||||
[
|
||||
pytest.param({"effort": "low", "task_budget": _TASK_BUDGET}, {"effort": "low"}, id="effort_and_task_budget"),
|
||||
pytest.param({"task_budget": _TASK_BUDGET}, None, id="task_budget_only"),
|
||||
],
|
||||
)
|
||||
async def test_bedrock_converse_claude_without_a_thinking_block_gets_only_the_effort_from_output_config(
|
||||
_converse_route: respx.Route,
|
||||
output_config: Mapping[str, object],
|
||||
sent_output_config: Mapping[str, object] | None,
|
||||
) -> None:
|
||||
await litellm.anthropic.messages.acreate(
|
||||
model=f"bedrock/converse/{_CONVERSE_EFFORT_MODEL}",
|
||||
max_tokens=64,
|
||||
messages=[{"role": "user", "content": "Name the capital of France."}],
|
||||
output_config=output_config,
|
||||
drop_params=True,
|
||||
)
|
||||
|
||||
assert _sent_converse_fields(_converse_route).get("output_config") == sent_output_config
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("drop_params_source", "forwards_effort"),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue