mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
refactor(ollama): move reasoning_effort unwrapping into a shared helper
A Final local inside the param loop tripped basedpyright's reassignment check in both configs and pushed reportGeneralTypeIssues over budget. think_from_reasoning_effort in common_utils keeps the Final outside any loop, guards on str so non-string efforts never reach the set check, and lets both configs share one code path
This commit is contained in:
parent
da7ec892af
commit
28f8e6d341
3 changed files with 24 additions and 18 deletions
|
|
@ -28,7 +28,7 @@ from litellm.types.llms.openai import (
|
|||
)
|
||||
from litellm.types.utils import ModelResponse, ModelResponseStream
|
||||
|
||||
from ..common_utils import OllamaError
|
||||
from ..common_utils import OllamaError, think_from_reasoning_effort
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj
|
||||
|
|
@ -170,13 +170,11 @@ class OllamaChatConfig(BaseConfig):
|
|||
if param == "response_format" and isinstance(value, dict) and value.get("type") == "json_schema":
|
||||
if value.get("json_schema") and value["json_schema"].get("schema"):
|
||||
optional_params["format"] = value["json_schema"]["schema"]
|
||||
if param == "reasoning_effort" and value is not None:
|
||||
effort: Final = value.get("effort") if isinstance(value, Mapping) else value
|
||||
if effort is not None:
|
||||
if model.startswith("gpt-oss"):
|
||||
optional_params["think"] = effort
|
||||
else:
|
||||
optional_params["think"] = effort in {"low", "medium", "high"}
|
||||
if (
|
||||
param == "reasoning_effort"
|
||||
and (think := think_from_reasoning_effort(model, cast(object, value))) is not None
|
||||
):
|
||||
optional_params["think"] = think
|
||||
### FUNCTION CALLING LOGIC ###
|
||||
# Ollama 0.4+ supports native tool calling - pass tools directly
|
||||
# and let Ollama handle model capability detection
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import base64
|
||||
import io
|
||||
from collections.abc import Mapping
|
||||
from typing import Any, Final
|
||||
|
||||
import httpx
|
||||
|
|
@ -8,6 +9,15 @@ from litellm import verbose_logger
|
|||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
|
||||
|
||||
def think_from_reasoning_effort(model: str, reasoning_effort: object) -> str | bool | None:
|
||||
effort: Final = reasoning_effort.get("effort") if isinstance(reasoning_effort, Mapping) else reasoning_effort
|
||||
if not isinstance(effort, str):
|
||||
return None
|
||||
if model.startswith("gpt-oss"):
|
||||
return effort
|
||||
return effort in {"low", "medium", "high"}
|
||||
|
||||
|
||||
class OllamaError(BaseLLMException):
|
||||
def __init__(self, status_code: int, message: str, headers: dict | httpx.Headers):
|
||||
super().__init__(status_code=status_code, message=message, headers=headers)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import json
|
||||
import time
|
||||
from collections.abc import AsyncIterator, Iterator, Mapping
|
||||
from typing import TYPE_CHECKING, Any, Final
|
||||
from collections.abc import AsyncIterator, Iterator
|
||||
from typing import TYPE_CHECKING, Any, Final, cast
|
||||
|
||||
from httpx._models import Headers, Response
|
||||
from pydantic import BaseModel, ConfigDict, ValidationError
|
||||
|
|
@ -33,7 +33,7 @@ from litellm.types.utils import (
|
|||
StreamingChoices,
|
||||
)
|
||||
|
||||
from ..common_utils import OllamaError, OllamaModelInfo, _convert_image
|
||||
from ..common_utils import OllamaError, OllamaModelInfo, _convert_image, think_from_reasoning_effort
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj
|
||||
|
|
@ -214,13 +214,11 @@ class OllamaConfig(BaseConfig):
|
|||
optional_params["frequency_penalty"] = value
|
||||
elif param == "stop":
|
||||
optional_params["stop"] = value
|
||||
elif param == "reasoning_effort" and value is not None:
|
||||
effort: Final = value.get("effort") if isinstance(value, Mapping) else value
|
||||
if effort is not None:
|
||||
if model.startswith("gpt-oss"):
|
||||
optional_params["think"] = effort
|
||||
else:
|
||||
optional_params["think"] = effort in {"low", "medium", "high"}
|
||||
elif (
|
||||
param == "reasoning_effort"
|
||||
and (think := think_from_reasoning_effort(model, cast(object, value))) is not None
|
||||
):
|
||||
optional_params["think"] = think
|
||||
elif param == "response_format" and isinstance(value, dict):
|
||||
if value["type"] == "json_object":
|
||||
optional_params["format"] = "json"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue