fix(ollama/chat): support images

Fixes https://github.com/BerriAI/litellm/issues/14217
This commit is contained in:
Krrish Dholakia 2025-09-12 17:49:42 -07:00
parent dd663f80ce
commit 461e181450
3 changed files with 31 additions and 6 deletions

View file

@ -913,3 +913,20 @@ def _parse_content_for_reasoning(
return reasoning_match.group(1), reasoning_match.group(2)
return None, message_text
def extract_images_from_message(message: AllMessageValues) -> List[str]:
"""
Extract images from a message
"""
images = []
message_content = message.get("content")
if isinstance(message_content, list):
for m in message_content:
image_url = m.get("image_url")
if image_url:
if isinstance(image_url, str):
images.append(image_url)
elif isinstance(image_url, dict) and "url" in image_url:
images.append(image_url["url"])
return images

View file

@ -19,6 +19,7 @@ import litellm
from litellm.litellm_core_utils.prompt_templates.common_utils import (
_extract_reasoning_content,
convert_content_list_to_str,
extract_images_from_message,
)
from litellm.llms.base_llm.base_model_iterator import BaseModelResponseIterator
from litellm.llms.base_llm.chat.transformation import BaseConfig, BaseLLMException
@ -311,6 +312,7 @@ class OllamaChatConfig(BaseConfig):
cast(dict, m)
)
content_str = convert_content_list_to_str(cast(AllMessageValues, m))
images = extract_images_from_message(cast(AllMessageValues, m))
ollama_message = OllamaChatCompletionMessage(
role=cast(str, m.get("role")),
@ -319,6 +321,8 @@ class OllamaChatConfig(BaseConfig):
ollama_message["thinking"] = reasoning_content
if content_str is not None:
ollama_message["content"] = content_str
if images is not None:
ollama_message["images"] = images
new_messages.append(ollama_message)

View file

@ -4414,7 +4414,7 @@ class Router:
return tpm_key
except Exception as e:
verbose_router_logger.exception(
verbose_router_logger.debug(
"litellm.router.Router::deployment_callback_on_success(): Exception occured - {}".format(
str(e)
)
@ -4562,8 +4562,10 @@ class Router:
parent_otel_span=parent_otel_span,
ttl=RoutingArgs.ttl.value,
)
def _get_metadata_variable_name_from_kwargs(self, kwargs: dict) -> Literal["metadata", "litellm_metadata"]:
def _get_metadata_variable_name_from_kwargs(
self, kwargs: dict
) -> Literal["metadata", "litellm_metadata"]:
"""
Helper to return what the "metadata" field should be called in the request data
@ -5672,11 +5674,11 @@ class Router:
)
if supported_openai_params is None:
supported_openai_params = []
# Get mode from database model_info if available, otherwise default to "chat"
db_model_info = model.get("model_info", {})
mode = db_model_info.get("mode", "chat")
model_info = ModelMapInfo(
key=model_group,
max_tokens=None,
@ -6802,7 +6804,9 @@ class Router:
model=model,
request_kwargs=request_kwargs,
healthy_deployments=healthy_deployments,
metadata_variable_name=self._get_metadata_variable_name_from_kwargs(request_kwargs),
metadata_variable_name=self._get_metadata_variable_name_from_kwargs(
request_kwargs
),
)
if len(healthy_deployments) == 0: