• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

deepset-ai / haystack / 18595249452

17 Oct 2025 02:08PM UTC coverage: 92.22% (+0.02%) from 92.2%
18595249452

Pull #9886

github

web-flow
Merge ad30d1879 into cc4f024af
Pull Request #9886: feat: Update tools param to Optional[Union[list[Union[Tool, Toolset]], Toolset]]

13382 of 14511 relevant lines covered (92.22%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.02
haystack/tools/serde_utils.py
1
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
2
#
3
# SPDX-License-Identifier: Apache-2.0
4

5
from typing import TYPE_CHECKING, Any, Optional, Union
1✔
6

7
from haystack.core.errors import DeserializationError
1✔
8
from haystack.core.serialization import import_class_by_name
1✔
9
from haystack.tools.tool import Tool
1✔
10
from haystack.tools.toolset import Toolset
1✔
11

12
if TYPE_CHECKING:
13
    from haystack.tools import ToolsType
14

15

16
def serialize_tools_or_toolset(tools: "Optional[ToolsType]") -> Union[dict[str, Any], list[dict[str, Any]], None]:
1✔
17
    """
18
    Serialize tools or toolsets to dictionaries.
19

20
    :param tools: A Toolset, a list of Tools and/or Toolsets, or None
21
    :returns: Serialized representation preserving Tool/Toolset boundaries when provided
22
    """
23
    if tools is None:
1✔
24
        return None
1✔
25
    if isinstance(tools, Toolset):
1✔
26
        return tools.to_dict()
1✔
27
    if isinstance(tools, list):
1✔
28
        serialized: list[dict[str, Any]] = []
1✔
29
        for item in tools:
1✔
30
            if isinstance(item, (Toolset, Tool)):
1✔
31
                serialized.append(item.to_dict())
1✔
32
            else:
33
                raise TypeError("Items in the tools list must be Tool or Toolset instances.")
×
34
        return serialized
1✔
35
    raise TypeError("tools must be Toolset, list[Union[Tool, Toolset]], or None")
×
36

37

38
def deserialize_tools_or_toolset_inplace(data: dict[str, Any], key: str = "tools") -> None:
1✔
39
    """
40
    Deserialize a list of Tools and/or Toolsets, or a single Toolset in a dictionary inplace.
41

42
    :param data:
43
        The dictionary with the serialized data.
44
    :param key:
45
        The key in the dictionary where the list of Tools and/or Toolsets, or single Toolset is stored.
46
    """
47
    if key in data:
1✔
48
        serialized_tools = data[key]
1✔
49

50
        if serialized_tools is None:
1✔
51
            return
1✔
52

53
        # Check if it's a serialized Toolset (a dict with "type" and "data" keys)
54
        if isinstance(serialized_tools, dict) and all(k in serialized_tools for k in ["type", "data"]):
1✔
55
            toolset_class_name = serialized_tools.get("type")
1✔
56
            if not toolset_class_name:
1✔
57
                raise DeserializationError("The 'type' key is missing or None in the serialized toolset data")
×
58

59
            toolset_class = import_class_by_name(toolset_class_name)
1✔
60

61
            if not issubclass(toolset_class, Toolset):
1✔
62
                raise TypeError(f"Class '{toolset_class}' is not a subclass of Toolset")
1✔
63

64
            data[key] = toolset_class.from_dict(serialized_tools)
1✔
65
            return
1✔
66

67
        if not isinstance(serialized_tools, list):
1✔
68
            raise TypeError(f"The value of '{key}' is not a list or a dictionary")
1✔
69

70
        deserialized_tools: list[Union[Tool, Toolset]] = []
1✔
71
        for tool in serialized_tools:
1✔
72
            if not isinstance(tool, dict):
1✔
73
                raise TypeError(f"Serialized tool '{tool}' is not a dictionary")
1✔
74

75
            # different classes are allowed: Tool, ComponentTool, Toolset, etc.
76
            tool_class = import_class_by_name(tool["type"])
1✔
77
            if issubclass(tool_class, (Tool, Toolset)):
1✔
78
                deserialized_tools.append(tool_class.from_dict(tool))
1✔
79
            else:
80
                raise TypeError(f"Class '{tool_class}' is neither Tool nor Toolset")
1✔
81

82
        data[key] = deserialized_tools
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc