mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
Merge b6aad4c215 into f445e466b4
This commit is contained in:
commit
4ad4e819ba
3 changed files with 73 additions and 10 deletions
|
|
@ -558,7 +558,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})
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class DatabricksTool(TypedDict):
|
|||
|
||||
class DatabricksMessage(TypedDict, total=False):
|
||||
role: Required[str]
|
||||
content: Required[AllDatabricksContentValues]
|
||||
content: ReadOnly[AllDatabricksContentValues | None]
|
||||
tool_calls: list[DatabricksTool] | None
|
||||
reasoning_content: ReadOnly[str | None]
|
||||
reasoning: ReadOnly[str | None]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import json
|
||||
from typing import Final
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
import respx
|
||||
|
||||
import litellm
|
||||
from litellm.constants import (
|
||||
|
|
@ -16,9 +16,7 @@ from litellm.llms.databricks.chat.transformation import (
|
|||
DatabricksConfig,
|
||||
_sanitize_empty_content,
|
||||
)
|
||||
from typing import Final
|
||||
import httpx
|
||||
import respx
|
||||
from litellm.types.utils import ChatCompletionMessageToolCall, ModelResponse
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
|
@ -813,6 +811,67 @@ def test_chunk_parser_surfaces_top_level_reasoning_delta(reasoning_key: str) ->
|
|||
assert parsed.choices[0].delta.content is None
|
||||
|
||||
|
||||
def test_completion_accepts_tool_call_without_content(respx_mock: respx.MockRouter) -> None:
|
||||
upstream: Final = respx_mock.post("https://example.databricks.test/serving-endpoints/chat/completions").mock(
|
||||
return_value=httpx.Response(
|
||||
status_code=200,
|
||||
json={
|
||||
"id": "chatcmpl-tool-call",
|
||||
"object": "chat.completion",
|
||||
"created": 1677652288,
|
||||
"model": "my-custom-model",
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_weather",
|
||||
"type": "function",
|
||||
"function": {"name": "get_weather", "arguments": '{"city":"Paris"}'},
|
||||
}
|
||||
],
|
||||
},
|
||||
"finish_reason": "tool_calls",
|
||||
}
|
||||
],
|
||||
"usage": {"prompt_tokens": 9, "completion_tokens": 5, "total_tokens": 14},
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
response: Final = litellm.completion(
|
||||
model="databricks/my-custom-model",
|
||||
messages=[{"role": "user", "content": "What is the weather in Paris?"}],
|
||||
tools=[
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_weather",
|
||||
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}},
|
||||
},
|
||||
}
|
||||
],
|
||||
api_base="https://example.databricks.test/serving-endpoints",
|
||||
api_key="fake-databricks-api-key",
|
||||
num_retries=0,
|
||||
)
|
||||
|
||||
assert upstream.call_count == 1
|
||||
assert isinstance(response, ModelResponse)
|
||||
assert response.choices[0].finish_reason == "tool_calls"
|
||||
message: Final = response.choices[0].message
|
||||
assert message.content is None
|
||||
assert message.tool_calls is not None
|
||||
assert len(message.tool_calls) == 1
|
||||
tool_call: Final = message.tool_calls[0]
|
||||
assert isinstance(tool_call, ChatCompletionMessageToolCall)
|
||||
assert tool_call.id == "call_weather"
|
||||
assert tool_call.function.name == "get_weather"
|
||||
assert tool_call.function.arguments == '{"city":"Paris"}'
|
||||
|
||||
|
||||
def test_completion_merges_leading_system_and_developer_messages_for_chat_template_models(
|
||||
respx_mock: respx.MockRouter,
|
||||
):
|
||||
|
|
@ -824,7 +883,9 @@ def test_completion_merges_leading_system_and_developer_messages_for_chat_templa
|
|||
"object": "chat.completion",
|
||||
"created": 1677652288,
|
||||
"model": "my-custom-model",
|
||||
"choices": [{"index": 0, "message": {"role": "assistant", "content": "Answer"}, "finish_reason": "stop"}],
|
||||
"choices": [
|
||||
{"index": 0, "message": {"role": "assistant", "content": "Answer"}, "finish_reason": "stop"}
|
||||
],
|
||||
"usage": {"prompt_tokens": 9, "completion_tokens": 1, "total_tokens": 10},
|
||||
},
|
||||
)
|
||||
|
|
@ -860,7 +921,9 @@ def test_completion_merges_system_messages_when_one_has_empty_content(respx_mock
|
|||
"object": "chat.completion",
|
||||
"created": 1677652288,
|
||||
"model": "my-custom-model",
|
||||
"choices": [{"index": 0, "message": {"role": "assistant", "content": "Answer"}, "finish_reason": "stop"}],
|
||||
"choices": [
|
||||
{"index": 0, "message": {"role": "assistant", "content": "Answer"}, "finish_reason": "stop"}
|
||||
],
|
||||
"usage": {"prompt_tokens": 9, "completion_tokens": 1, "total_tokens": 10},
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue