mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
Merge 3376a8464d into ef8eb98724
This commit is contained in:
commit
774deff547
2 changed files with 64 additions and 10 deletions
|
|
@ -72,6 +72,15 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
(LiteLLM stores provider-specific response fields there).
|
||||
2. Otherwise inject a single space — the minimum value the API accepts.
|
||||
"""
|
||||
missing_reasoning_content: Final = any(
|
||||
msg.get("role") == "assistant"
|
||||
and not msg.get("reasoning_content")
|
||||
and not (
|
||||
isinstance(provider_fields := msg.get("provider_specific_fields"), dict)
|
||||
and provider_fields.get("reasoning_content")
|
||||
)
|
||||
for msg in messages
|
||||
)
|
||||
result: Final[list[AllMessageValues]] = []
|
||||
for msg in messages:
|
||||
if msg.get("role") == "assistant" and not msg.get("reasoning_content"):
|
||||
|
|
@ -84,20 +93,21 @@ class DeepSeekChatConfig(OpenAIGPTConfig):
|
|||
cleaned.pop("reasoning_content", None)
|
||||
patched["provider_specific_fields"] = cleaned
|
||||
else:
|
||||
litellm.verbose_logger.warning(
|
||||
"DeepSeek thinking mode: assistant message is missing "
|
||||
"`reasoning_content` and none was saved in "
|
||||
"`provider_specific_fields`. A single-space placeholder "
|
||||
"is being injected to satisfy API validation, but the "
|
||||
"model will receive a blank reasoning chain for this turn, "
|
||||
"which may silently degrade multi-turn response quality. "
|
||||
"Preserve `reasoning_content` from the original assistant "
|
||||
"response when building multi-turn conversation history."
|
||||
)
|
||||
patched["reasoning_content"] = " "
|
||||
result.append(cast(AllMessageValues, patched))
|
||||
else:
|
||||
result.append(msg)
|
||||
if missing_reasoning_content:
|
||||
litellm.verbose_logger.warning(
|
||||
"DeepSeek thinking mode: assistant message is missing "
|
||||
"`reasoning_content` and none was saved in "
|
||||
"`provider_specific_fields`. A single-space placeholder "
|
||||
"is being injected to satisfy API validation, but the "
|
||||
"model will receive a blank reasoning chain for this turn, "
|
||||
"which may silently degrade multi-turn response quality. "
|
||||
"Preserve `reasoning_content` from the original assistant "
|
||||
"response when building multi-turn conversation history."
|
||||
)
|
||||
return result
|
||||
|
||||
@overload
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
from copy import deepcopy
|
||||
from unittest.mock import patch
|
||||
|
||||
from litellm.llms.deepseek.chat.transformation import DeepSeekChatConfig
|
||||
|
||||
|
||||
|
|
@ -103,6 +106,47 @@ async def test_async_transform_request_strips_unsupported_tools_from_body():
|
|||
assert body["tools"][0]["function"]["name"] == "shell"
|
||||
|
||||
|
||||
def test_transform_request_warns_once_per_replayed_history_and_preserves_history():
|
||||
messages = [
|
||||
{"role": "user", "content": "Use both tools."},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"tool_calls": [{"id": "first"}],
|
||||
"reasoning_content": "",
|
||||
},
|
||||
{"role": "tool", "tool_call_id": "first", "content": "first result"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"tool_calls": [{"id": "second"}],
|
||||
"reasoning_content": "",
|
||||
},
|
||||
{"role": "tool", "tool_call_id": "second", "content": "second result"},
|
||||
{"role": "user", "content": "Continue."},
|
||||
]
|
||||
original_messages = deepcopy(messages)
|
||||
config = DeepSeekChatConfig()
|
||||
|
||||
warning_path = "litellm.llms.deepseek.chat.transformation.litellm.verbose_logger.warning"
|
||||
with patch(warning_path) as warning:
|
||||
results = [
|
||||
config.transform_request(
|
||||
model="deepseek-reasoner",
|
||||
messages=messages,
|
||||
optional_params={"thinking": {"type": "enabled"}},
|
||||
litellm_params={},
|
||||
headers={},
|
||||
)
|
||||
for _ in range(2)
|
||||
]
|
||||
|
||||
assert warning.call_count == 2
|
||||
for result in results:
|
||||
assert [result["messages"][index]["reasoning_content"] for index in (1, 3)] == [" ", " "]
|
||||
assert messages == original_messages
|
||||
|
||||
|
||||
def test_thinking_mode_active_bool_thinking_returns_false_without_crashing():
|
||||
config = DeepSeekChatConfig()
|
||||
assert config._thinking_mode_active(model="deepseek-reasoner", optional_params={"thinking": True}) is False
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue