2023-01-29 02:26:24 +00:00
|
|
|
"""Test tool utils."""
|
2023-05-05 03:31:16 +00:00
|
|
|
from typing import Any, Type
|
2023-04-27 22:36:11 +00:00
|
|
|
from unittest.mock import MagicMock
|
2023-04-18 04:35:29 +00:00
|
|
|
|
2023-01-29 02:26:24 +00:00
|
|
|
import pytest
|
|
|
|
|
2023-04-27 22:36:11 +00:00
|
|
|
from langchain.agents.agent import Agent
|
|
|
|
from langchain.agents.chat.base import ChatAgent
|
|
|
|
from langchain.agents.conversational.base import ConversationalAgent
|
|
|
|
from langchain.agents.conversational_chat.base import ConversationalChatAgent
|
|
|
|
from langchain.agents.mrkl.base import ZeroShotAgent
|
|
|
|
from langchain.agents.react.base import ReActDocstoreAgent, ReActTextWorldAgent
|
|
|
|
from langchain.agents.self_ask_with_search.base import SelfAskWithSearchAgent
|
2023-01-29 02:26:24 +00:00
|
|
|
from langchain.agents.tools import Tool, tool
|
2023-04-27 22:36:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"agent_cls",
|
|
|
|
[
|
|
|
|
ZeroShotAgent,
|
2023-05-02 01:44:24 +00:00
|
|
|
ChatAgent,
|
2023-04-27 22:36:11 +00:00
|
|
|
ConversationalChatAgent,
|
|
|
|
ConversationalAgent,
|
|
|
|
ReActDocstoreAgent,
|
|
|
|
ReActTextWorldAgent,
|
|
|
|
SelfAskWithSearchAgent,
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_single_input_agent_raises_error_on_structured_tool(
|
|
|
|
agent_cls: Type[Agent],
|
|
|
|
) -> None:
|
|
|
|
"""Test that older agents raise errors on older tools."""
|
|
|
|
|
|
|
|
@tool
|
|
|
|
def the_tool(foo: str, bar: str) -> str:
|
|
|
|
"""Return the concat of foo and bar."""
|
|
|
|
return foo + bar
|
|
|
|
|
|
|
|
with pytest.raises(
|
|
|
|
ValueError,
|
|
|
|
match=f"{agent_cls.__name__} does not support" # type: ignore
|
|
|
|
f" multi-input tool {the_tool.name}.",
|
|
|
|
):
|
|
|
|
agent_cls.from_llm_and_tools(MagicMock(), [the_tool]) # type: ignore
|
2023-04-28 16:38:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_tool_no_args_specified_assumes_str() -> None:
|
|
|
|
"""Older tools could assume *args and **kwargs were passed in."""
|
|
|
|
|
|
|
|
def ambiguous_function(*args: Any, **kwargs: Any) -> str:
|
|
|
|
"""An ambiguously defined function."""
|
|
|
|
return args[0]
|
|
|
|
|
|
|
|
some_tool = Tool(
|
|
|
|
name="chain_run",
|
|
|
|
description="Run the chain",
|
|
|
|
func=ambiguous_function,
|
|
|
|
)
|
|
|
|
expected_args = {"tool_input": {"type": "string"}}
|
|
|
|
assert some_tool.args == expected_args
|
|
|
|
assert some_tool.run("foobar") == "foobar"
|
|
|
|
assert some_tool.run({"tool_input": "foobar"}) == "foobar"
|
|
|
|
with pytest.raises(ValueError, match="Too many arguments to single-input tool"):
|
|
|
|
some_tool.run({"tool_input": "foobar", "other_input": "bar"})
|