mirror of
https://github.com/deepset-ai/haystack.git
synced 2025-12-26 14:38:36 +00:00
fix: HuggingFaceAPIChatGenerator - make tool conversion compatible with huggingface_hub>=0.31.0 (#9354)
* fix: HuggingFaceAPIChatGenerator - make tool conversion compatible with huggingface_hub>=0.31.0 * relnote
This commit is contained in:
parent
de5c7ea3d2
commit
4b4b0f0041
@ -80,6 +80,26 @@ def _convert_hfapi_tool_calls(hfapi_tool_calls: Optional[List["ChatCompletionOut
|
||||
return tool_calls
|
||||
|
||||
|
||||
def _convert_tools_to_hfapi_tools(
|
||||
tools: Optional[Union[List[Tool], Toolset]],
|
||||
) -> Optional[List["ChatCompletionInputTool"]]:
|
||||
if not tools:
|
||||
return None
|
||||
|
||||
# huggingface_hub<0.31.0 uses "arguments", huggingface_hub>=0.31.0 uses "parameters"
|
||||
parameters_name = "arguments" if hasattr(ChatCompletionInputFunctionDefinition, "arguments") else "parameters"
|
||||
|
||||
hf_tools = []
|
||||
for tool in tools:
|
||||
hf_tools_args = {"name": tool.name, "description": tool.description, parameters_name: tool.parameters}
|
||||
|
||||
hf_tools.append(
|
||||
ChatCompletionInputTool(function=ChatCompletionInputFunctionDefinition(**hf_tools_args), type="function")
|
||||
)
|
||||
|
||||
return hf_tools
|
||||
|
||||
|
||||
@component
|
||||
class HuggingFaceAPIChatGenerator:
|
||||
"""
|
||||
@ -313,19 +333,11 @@ class HuggingFaceAPIChatGenerator:
|
||||
if streaming_callback:
|
||||
return self._run_streaming(formatted_messages, generation_kwargs, streaming_callback)
|
||||
|
||||
hf_tools = None
|
||||
if tools:
|
||||
if isinstance(tools, Toolset):
|
||||
tools = list(tools)
|
||||
hf_tools = [
|
||||
ChatCompletionInputTool(
|
||||
function=ChatCompletionInputFunctionDefinition(
|
||||
name=tool.name, description=tool.description, arguments=tool.parameters
|
||||
),
|
||||
type="function",
|
||||
)
|
||||
for tool in tools
|
||||
]
|
||||
if tools and isinstance(tools, Toolset):
|
||||
tools = list(tools)
|
||||
|
||||
hf_tools = _convert_tools_to_hfapi_tools(tools)
|
||||
|
||||
return self._run_non_streaming(formatted_messages, generation_kwargs, hf_tools)
|
||||
|
||||
@component.output_types(replies=List[ChatMessage])
|
||||
@ -373,19 +385,11 @@ class HuggingFaceAPIChatGenerator:
|
||||
if streaming_callback:
|
||||
return await self._run_streaming_async(formatted_messages, generation_kwargs, streaming_callback)
|
||||
|
||||
hf_tools = None
|
||||
if tools:
|
||||
if isinstance(tools, Toolset):
|
||||
tools = list(tools)
|
||||
hf_tools = [
|
||||
ChatCompletionInputTool(
|
||||
function=ChatCompletionInputFunctionDefinition(
|
||||
name=tool.name, description=tool.description, arguments=tool.parameters
|
||||
),
|
||||
type="function",
|
||||
)
|
||||
for tool in tools
|
||||
]
|
||||
if tools and isinstance(tools, Toolset):
|
||||
tools = list(tools)
|
||||
|
||||
hf_tools = _convert_tools_to_hfapi_tools(tools)
|
||||
|
||||
return await self._run_non_streaming_async(formatted_messages, generation_kwargs, hf_tools)
|
||||
|
||||
def _run_streaming(
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Make internal tool conversion in the HuggingFaceAPICompatibleChatGenerator compatible with huggingface_hub>=0.31.0.
|
||||
In the huggingface_hub library, `arguments` attribute of `ChatCompletionInputFunctionDefinition` has been renamed to
|
||||
`parameters`.
|
||||
Our implementation is compatible with both the legacy version and the new one.
|
||||
@ -10,6 +10,7 @@ from haystack import Pipeline
|
||||
from haystack.dataclasses import StreamingChunk
|
||||
from haystack.utils.auth import Secret
|
||||
from haystack.utils.hf import HFGenerationAPIType
|
||||
|
||||
from huggingface_hub import (
|
||||
ChatCompletionOutput,
|
||||
ChatCompletionOutputComplete,
|
||||
@ -21,9 +22,14 @@ from huggingface_hub import (
|
||||
ChatCompletionStreamOutputChoice,
|
||||
ChatCompletionStreamOutputDelta,
|
||||
)
|
||||
from huggingface_hub.utils import RepositoryNotFoundError
|
||||
from huggingface_hub.errors import RepositoryNotFoundError
|
||||
|
||||
from haystack.components.generators.chat.hugging_face_api import (
|
||||
HuggingFaceAPIChatGenerator,
|
||||
_convert_hfapi_tool_calls,
|
||||
_convert_tools_to_hfapi_tools,
|
||||
)
|
||||
|
||||
from haystack.components.generators.chat.hugging_face_api import HuggingFaceAPIChatGenerator, _convert_hfapi_tool_calls
|
||||
from haystack.tools import Tool
|
||||
from haystack.dataclasses import ChatMessage, ToolCall
|
||||
from haystack.tools.toolset import Toolset
|
||||
@ -980,3 +986,41 @@ class TestHuggingFaceAPIChatGenerator:
|
||||
},
|
||||
}
|
||||
assert data["init_parameters"]["tools"] == expected_tools_data
|
||||
|
||||
def test_convert_tools_to_hfapi_tools(self):
|
||||
assert _convert_tools_to_hfapi_tools(None) is None
|
||||
assert _convert_tools_to_hfapi_tools([]) is None
|
||||
|
||||
tool = Tool(
|
||||
name="weather",
|
||||
description="useful to determine the weather in a given location",
|
||||
parameters={"city": {"type": "string"}},
|
||||
function=get_weather,
|
||||
)
|
||||
hf_tools = _convert_tools_to_hfapi_tools([tool])
|
||||
assert len(hf_tools) == 1
|
||||
assert hf_tools[0].type == "function"
|
||||
assert hf_tools[0].function.name == "weather"
|
||||
assert hf_tools[0].function.description == "useful to determine the weather in a given location"
|
||||
assert hf_tools[0].function.parameters == {"city": {"type": "string"}}
|
||||
|
||||
def test_convert_tools_to_hfapi_tools_legacy(self):
|
||||
# this satisfies the check hasattr(ChatCompletionInputFunctionDefinition, "arguments")
|
||||
mock_class = MagicMock()
|
||||
|
||||
with patch(
|
||||
"haystack.components.generators.chat.hugging_face_api.ChatCompletionInputFunctionDefinition", mock_class
|
||||
):
|
||||
tool = Tool(
|
||||
name="weather",
|
||||
description="useful to determine the weather in a given location",
|
||||
parameters={"city": {"type": "string"}},
|
||||
function=get_weather,
|
||||
)
|
||||
_convert_tools_to_hfapi_tools([tool])
|
||||
|
||||
mock_class.assert_called_once_with(
|
||||
name="weather",
|
||||
arguments={"city": {"type": "string"}},
|
||||
description="useful to determine the weather in a given location",
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user