diff --git a/litellm/llms/databricks/chat/transformation.py b/litellm/llms/databricks/chat/transformation.py index 60081c38073..e68f24a6c38 100644 --- a/litellm/llms/databricks/chat/transformation.py +++ b/litellm/llms/databricks/chat/transformation.py @@ -668,7 +668,7 @@ class DatabricksConfig(DatabricksBase, OpenAILikeChatConfig, AnthropicConfig): def resolve_reasoning_and_content( message: DatabricksMessage, block_reasoning_content: str | None ) -> tuple[str | None, str | None]: - content_str: Final = DatabricksConfig.extract_content_str(message["content"]) + content_str: Final = DatabricksConfig.extract_content_str(message.get("content")) if block_reasoning_content is not None: return block_reasoning_content, content_str return extract_reasoning_content({**message, "content": content_str}) diff --git a/tests/unit/llms/databricks/chat/test_databricks_chat_transformation.py b/tests/unit/llms/databricks/chat/test_databricks_chat_transformation.py index 19234767b19..875192a734c 100644 --- a/tests/unit/llms/databricks/chat/test_databricks_chat_transformation.py +++ b/tests/unit/llms/databricks/chat/test_databricks_chat_transformation.py @@ -8,7 +8,7 @@ import httpx import pytest import respx from openai.lib.streaming.chat import ChatCompletionStreamState -from openai.types.chat import ChatCompletionChunk +from openai.types.chat import ChatCompletion, ChatCompletionChunk from pydantic import TypeAdapter from fastapi.testclient import TestClient from pydantic import BaseModel, ConfigDict @@ -2429,6 +2429,45 @@ def test_transform_response_carries_served_service_tier(served_tier: str | None) assert result.to_dict().get("service_tier") == served_tier +def test_transform_response_keeps_a_tool_only_message_without_content() -> None: + tool_call: Final = { + "id": "call_weather", + "type": "function", + "function": {"name": "get_weather", "arguments": '{"city": "Paris"}'}, + } + raw_response: Final = httpx.Response( + 200, + json={ + "id": "chatcmpl-1", + "object": "chat.completion", + "created": 0, + "model": "dbrx", + "choices": [ + {"index": 0, "message": {"role": "assistant", "tool_calls": [tool_call]}, "finish_reason": "tool_calls"} + ], + "usage": {"prompt_tokens": 5, "completion_tokens": 3, "total_tokens": 8}, + }, + ) + + result: Final = DatabricksConfig().transform_response( + model="databricks/dbrx", + raw_response=raw_response, + model_response=litellm.ModelResponse(), + logging_obj=MagicMock(), + request_data={}, + messages=[{"role": "user", "content": "weather in Paris?"}], + optional_params={}, + litellm_params={}, + encoding=None, + ) + + completion: Final = ChatCompletion.model_validate(result.model_dump()) + assert completion.choices[0].finish_reason == "tool_calls" + assert completion.choices[0].message.model_dump(exclude_none=True) == {"role": "assistant", "tool_calls": [tool_call]} + assert completion.usage is not None + assert (completion.usage.prompt_tokens, completion.usage.completion_tokens, completion.usage.total_tokens) == (5, 3, 8) + + _DATABRICKS_TOOLS_WITH_OPENAI_TOOL_SEARCH: Final = [ {"type": "tool_search", "execution": "server"}, {