mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
Refactor DeepSeek V4 reasoning helper imports
This commit is contained in:
parent
a3dbffa8e7
commit
5dd872eb12
5 changed files with 52 additions and 39 deletions
|
|
@ -56,7 +56,7 @@ from litellm.types.utils import (
|
|||
from litellm.utils import convert_to_model_response_object
|
||||
|
||||
from ..common_utils import OpenAIError
|
||||
from ..common_utils import patch_deepseek_v4_reasoning_messages
|
||||
from ..deepseek_reasoning_utils import patch_deepseek_v4_reasoning_messages
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj
|
||||
|
|
|
|||
|
|
@ -258,43 +258,6 @@ class BaseOpenAILLM:
|
|||
class OpenAICredentials(NamedTuple):
|
||||
api_base: str
|
||||
api_key: Optional[str]
|
||||
|
||||
|
||||
def requires_deepseek_v4_reasoning_content(model: Optional[str]) -> bool:
|
||||
"""Return True when the model requires DeepSeek V4 thinking history."""
|
||||
if not model:
|
||||
return False
|
||||
|
||||
normalized_model = model.lower()
|
||||
if normalized_model.startswith("responses/"):
|
||||
normalized_model = normalized_model.split("responses/", 1)[1]
|
||||
|
||||
return "deepseek-v4" in normalized_model
|
||||
|
||||
|
||||
def patch_deepseek_v4_reasoning_messages(
|
||||
model: Optional[str], messages: List[Any]
|
||||
) -> List[Any]:
|
||||
"""
|
||||
Ensure assistant tool-call messages include reasoning_content for DeepSeek V4.
|
||||
|
||||
DeepSeek V4 rejects multi-turn requests when prior assistant tool-call messages
|
||||
omit the reasoning_content field, even if the value is empty.
|
||||
"""
|
||||
if not requires_deepseek_v4_reasoning_content(model):
|
||||
return messages
|
||||
|
||||
for message in messages:
|
||||
if not isinstance(message, dict):
|
||||
continue
|
||||
if message.get("role") != "assistant":
|
||||
continue
|
||||
if not (message.get("tool_calls") or message.get("tool_call_id")):
|
||||
continue
|
||||
if message.get("reasoning_content") is None:
|
||||
message["reasoning_content"] = ""
|
||||
|
||||
return messages
|
||||
organization: Optional[str]
|
||||
|
||||
|
||||
|
|
|
|||
38
litellm/llms/openai/deepseek_reasoning_utils.py
Normal file
38
litellm/llms/openai/deepseek_reasoning_utils.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
from typing import Any, List, Optional
|
||||
|
||||
|
||||
def requires_deepseek_v4_reasoning_content(model: Optional[str]) -> bool:
|
||||
"""Return True when the model requires DeepSeek V4 thinking history."""
|
||||
if not model:
|
||||
return False
|
||||
|
||||
normalized_model = model.lower()
|
||||
if normalized_model.startswith("responses/"):
|
||||
normalized_model = normalized_model.split("responses/", 1)[1]
|
||||
|
||||
return "deepseek-v4" in normalized_model
|
||||
|
||||
|
||||
def patch_deepseek_v4_reasoning_messages(
|
||||
model: Optional[str], messages: List[Any]
|
||||
) -> List[Any]:
|
||||
"""
|
||||
Ensure assistant tool-call messages include reasoning_content for DeepSeek V4.
|
||||
|
||||
DeepSeek V4 rejects multi-turn requests when prior assistant tool-call messages
|
||||
omit the reasoning_content field, even if the value is empty.
|
||||
"""
|
||||
if not requires_deepseek_v4_reasoning_content(model):
|
||||
return messages
|
||||
|
||||
for message in messages:
|
||||
if not isinstance(message, dict):
|
||||
continue
|
||||
if message.get("role") != "assistant":
|
||||
continue
|
||||
if not (message.get("tool_calls") or message.get("tool_call_id")):
|
||||
continue
|
||||
if message.get("reasoning_content") is None:
|
||||
message["reasoning_content"] = ""
|
||||
|
||||
return messages
|
||||
|
|
@ -58,9 +58,9 @@ from .chat.o_series_transformation import OpenAIOSeriesConfig
|
|||
from .common_utils import (
|
||||
BaseOpenAILLM,
|
||||
OpenAIError,
|
||||
patch_deepseek_v4_reasoning_messages,
|
||||
drop_params_from_unprocessable_entity_error,
|
||||
)
|
||||
from .deepseek_reasoning_utils import patch_deepseek_v4_reasoning_messages
|
||||
|
||||
openaiOSeriesConfig = OpenAIOSeriesConfig()
|
||||
openAIGPT5Config = OpenAIGPT5Config()
|
||||
|
|
|
|||
|
|
@ -241,3 +241,15 @@ def test_deepseek_reasoner_transform_request_does_not_inject_reasoning_content()
|
|||
)
|
||||
|
||||
assert "reasoning_content" not in request["messages"][1]
|
||||
|
||||
|
||||
def test_get_openai_credentials_preserves_organization_field():
|
||||
from litellm.llms.openai.common_utils import get_openai_credentials
|
||||
|
||||
credentials = get_openai_credentials(
|
||||
api_base="https://example.com/v1",
|
||||
api_key="test-key",
|
||||
organization="test-org",
|
||||
)
|
||||
|
||||
assert credentials.organization == "test-org"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue