diff --git a/litellm/llms/ollama/chat/transformation.py b/litellm/llms/ollama/chat/transformation.py index fb2acc94122..cdc0ad00786 100644 --- a/litellm/llms/ollama/chat/transformation.py +++ b/litellm/llms/ollama/chat/transformation.py @@ -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 diff --git a/litellm/llms/ollama/common_utils.py b/litellm/llms/ollama/common_utils.py index 9f46cbc5cd5..96f28b1ed53 100644 --- a/litellm/llms/ollama/common_utils.py +++ b/litellm/llms/ollama/common_utils.py @@ -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) diff --git a/litellm/llms/ollama/completion/transformation.py b/litellm/llms/ollama/completion/transformation.py index 7d2bb726f5a..b0cb2d4ed27 100644 --- a/litellm/llms/ollama/completion/transformation.py +++ b/litellm/llms/ollama/completion/transformation.py @@ -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"