mirror of
https://github.com/deepset-ai/haystack.git
synced 2025-09-07 15:23:31 +00:00
fix: Adjust tool pattern to support multi-line inputs (#4801)
* Add support for multi line tool input * Fix failing agent test, additional test_tools_manager.py tests * Allow empty tool input, add more tests * More unit tests * String formatting * Small str fix
This commit is contained in:
parent
58acef77c4
commit
eb9d14faeb
@ -120,7 +120,7 @@ class ToolsManager:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
tools: Optional[List[Tool]] = None,
|
tools: Optional[List[Tool]] = None,
|
||||||
tool_pattern: str = r'Tool:\s*(\w+)\s*Tool Input:\s*("?)([^"\n]+)\2\s*',
|
tool_pattern: str = r"Tool:\s*(\w+)\s*Tool Input:\s*(?:\"([\s\S]*?)\"|((?:.|\n)*))\s*",
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
:param tools: A list of tools to add to the ToolManager. Each tool must have a unique name.
|
:param tools: A list of tools to add to the ToolManager. Each tool must have a unique name.
|
||||||
@ -198,7 +198,7 @@ class ToolsManager:
|
|||||||
tool_match = re.search(self.tool_pattern, llm_response)
|
tool_match = re.search(self.tool_pattern, llm_response)
|
||||||
if tool_match:
|
if tool_match:
|
||||||
tool_name = tool_match.group(1)
|
tool_name = tool_match.group(1)
|
||||||
tool_input = tool_match.group(3)
|
tool_input = tool_match.group(2) or tool_match.group(3)
|
||||||
return tool_name.strip('" []\n').strip(), tool_input.strip('" \n')
|
return tool_name.strip('" []\n').strip(), tool_input.strip('" \n')
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ def test_extract_tool_name_and_tool_input(tools_manager):
|
|||||||
examples = [
|
examples = [
|
||||||
"need to find out what city he was born.\nTool: Search\nTool Input: Where was Jeremy McKinnon born",
|
"need to find out what city he was born.\nTool: Search\nTool Input: Where was Jeremy McKinnon born",
|
||||||
"need to find out what city he was born.\n\nTool: Search\n\nTool Input: Where was Jeremy McKinnon born",
|
"need to find out what city he was born.\n\nTool: Search\n\nTool Input: Where was Jeremy McKinnon born",
|
||||||
"need to find out what city he was born. Tool: Search Tool Input: Where was Jeremy McKinnon born",
|
'need to find out what city he was born. Tool: Search Tool Input: "Where was Jeremy McKinnon born"',
|
||||||
]
|
]
|
||||||
for example in examples:
|
for example in examples:
|
||||||
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(example)
|
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(example)
|
||||||
@ -98,3 +98,65 @@ def test_tool_invocation():
|
|||||||
# same but for the document
|
# same but for the document
|
||||||
with unittest.mock.patch("haystack.pipelines.Pipeline.run", return_value=[Document("mocked_document")]):
|
with unittest.mock.patch("haystack.pipelines.Pipeline.run", return_value=[Document("mocked_document")]):
|
||||||
assert tool.run("input") == "mocked_document"
|
assert tool.run("input") == "mocked_document"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_extract_tool_name_and_tool_multi_line_input(tools_manager):
|
||||||
|
# new pattern being supported but with backward compatibility for the old
|
||||||
|
text = (
|
||||||
|
"We need to find out the following information:\n"
|
||||||
|
"1. What city was Jeremy McKinnon born in?\n"
|
||||||
|
"2. What's the capital of Germany?\n"
|
||||||
|
"Tool: Search\n"
|
||||||
|
"Tool Input: Where was Jeremy\n McKinnon born\n and where did he grow up?"
|
||||||
|
)
|
||||||
|
|
||||||
|
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(text)
|
||||||
|
assert tool_name == "Search" and tool_input == "Where was Jeremy\n McKinnon born\n and where did he grow up?"
|
||||||
|
|
||||||
|
# tool input is empty
|
||||||
|
text2 = (
|
||||||
|
"We need to find out the following information:\n"
|
||||||
|
"1. What city was Jeremy McKinnon born in?\n"
|
||||||
|
"2. What's the capital of Germany?\n"
|
||||||
|
"Tool: Search\n"
|
||||||
|
"Tool Input:"
|
||||||
|
)
|
||||||
|
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(text2)
|
||||||
|
assert tool_name == "Search" and tool_input == ""
|
||||||
|
|
||||||
|
# Case where the tool name and tool input are provided with extra whitespaces
|
||||||
|
text3 = " Tool: Search \n Tool Input: What is the tallest building in the world? "
|
||||||
|
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(text3)
|
||||||
|
assert tool_name.strip() == "Search" and tool_input.strip() == "What is the tallest building in the world?"
|
||||||
|
|
||||||
|
# Case where the tool name is provided but the tool input line is not provided at all
|
||||||
|
# Tool input is not optional, so this should return None for both tool name and tool input
|
||||||
|
text4 = (
|
||||||
|
"We need to find out the following information:\n"
|
||||||
|
"1. Who is the current president of the United States?\n"
|
||||||
|
"Tool: Search\n"
|
||||||
|
)
|
||||||
|
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(text4)
|
||||||
|
assert tool_name is None and tool_input is None
|
||||||
|
|
||||||
|
# Case where neither the tool name nor the tool input is provided
|
||||||
|
text5 = "We need to find out the following information:\n 1. What is the population of India?"
|
||||||
|
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(text5)
|
||||||
|
assert tool_name is None and tool_input is None
|
||||||
|
|
||||||
|
# Case where the tool name and tool input are provided with extra whitespaces and new lines
|
||||||
|
text6 = " Tool: Search \n Tool Input: \nWhat is the tallest \nbuilding in the world? "
|
||||||
|
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(text6)
|
||||||
|
assert tool_name.strip() == "Search" and tool_input.strip() == "What is the tallest \nbuilding in the world?"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_extract_tool_name_and_empty_tool_input(tools_manager):
|
||||||
|
examples = [
|
||||||
|
"need to find out what city he was born.\nTool: Search\nTool Input:",
|
||||||
|
"need to find out what city he was born.\nTool: Search\nTool Input: ",
|
||||||
|
]
|
||||||
|
for example in examples:
|
||||||
|
tool_name, tool_input = tools_manager.extract_tool_name_and_tool_input(example)
|
||||||
|
assert tool_name == "Search" and tool_input == ""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user