Skip to content

Commit

Permalink
Support crewai tools (#63)
Browse files Browse the repository at this point in the history
* add conversion from crewai tool to MotleyTool

* add agent_name parameter to MotleyAgentParent

* add processing of the arguments for launching the crewai tools

* fix to_crewai_tool method

* add test for crewai_tools

* Simplify the code a bit

* Update dependencies & fix config param in output handler _run

* Updates

* fix tests

---------

Co-authored-by: User <[email protected]>
Co-authored-by: whimo <[email protected]>
  • Loading branch information
3 people authored Jul 25, 2024
1 parent 48c9b9b commit 3338fde
Show file tree
Hide file tree
Showing 126 changed files with 708 additions and 681 deletions.
6 changes: 3 additions & 3 deletions motleycrew/agents/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from langchain_core.agents import AgentFinish, AgentAction
from langchain_core.callbacks import CallbackManagerForChainRun
from langchain_core.messages import AIMessage
from langchain_core.runnables import RunnableConfig
from langchain_core.tools import BaseTool, Tool

from motleycrew.agents.parent import DirectOutput
from motleycrew.tools import MotleyTool

Expand Down Expand Up @@ -109,9 +109,9 @@ def wrapper(
def _run_tool_direct_decorator(self, func: Callable):
"""Decorator of the tool's _run method, for intercepting a DirectOutput exception"""

def wrapper(*args, **kwargs):
def wrapper(*args, config: RunnableConfig, **kwargs):
try:
result = func(*args, **kwargs)
result = func(*args, **kwargs, config=config)
except DirectOutput as direct_exc:
return direct_exc
return result
Expand Down
4 changes: 2 additions & 2 deletions motleycrew/agents/parent.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from langchain_core.runnables import RunnableConfig
from langchain_core.tools import StructuredTool
from langchain_core.tools import Tool

from motleycrew.agents.abstract_parent import MotleyAgentAbstractParent
from motleycrew.agents.output_handler import MotleyOutputHandler
from motleycrew.common import MotleyAgentFactory, MotleySupportedTool
Expand Down Expand Up @@ -63,6 +62,7 @@ def __init__(
tools: Sequence[MotleySupportedTool] | None = None,
output_handler: MotleySupportedTool | None = None,
verbose: bool = False,
agent_name: str | None = None,
):
"""
Args:
Expand Down Expand Up @@ -193,7 +193,7 @@ def handle_agent_output(*args, **kwargs):

try:
iteration += 1
output = self.output_handler._run(*args, **kwargs)
output = self.output_handler._run(*args, **kwargs, config=RunnableConfig())
except exceptions_to_handle as exc:
if iteration <= max_iterations:
return f"{exc.__class__.__name__}: {str(exc)}"
Expand Down
1 change: 1 addition & 0 deletions motleycrew/common/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Defaults:
"lunary": "pip install lunary",
"aider": "pip install aider-chat",
"pglast": "pip install pglast",
"crewai_tools": "pip install 'crewai[tools]'"
}

DEFAULT_NUM_THREADS = 4
Expand Down
50 changes: 46 additions & 4 deletions motleycrew/tools/tool.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Callable
from typing import Union, Optional, Dict, Any
import functools
from typing import Callable, Union, Optional, Dict, Any

from langchain.tools import BaseTool
from langchain_core.runnables import Runnable, RunnableConfig
Expand All @@ -11,6 +11,13 @@
LlamaIndex__BaseTool = None
LlamaIndex__FunctionTool = None

try:
from crewai_tools import BaseTool as CrewAI__BaseTool
from crewai_tools import Tool as Crewai__Tool
except ImportError:
CrewAI__BaseTool = None
Crewai__Tool = None

from motleycrew.common.utils import ensure_module_is_installed
from motleycrew.common.types import MotleySupportedTool
from motleycrew.agents.abstract_parent import MotleyAgentAbstractParent
Expand Down Expand Up @@ -90,6 +97,25 @@ def from_llama_index_tool(llama_index_tool: LlamaIndex__BaseTool) -> "MotleyTool
langchain_tool = llama_index_tool.to_langchain_tool()
return MotleyTool.from_langchain_tool(langchain_tool=langchain_tool)

@staticmethod
def from_crewai_tool(crewai_tool: CrewAI__BaseTool) -> "MotleyTool":
"""Create a MotleyTool from a CrewAI tool.
Args:
crewai_tool: CrewAI tool to convert.
Returns:
MotleyTool instance.
"""
ensure_module_is_installed("crewai_tools")
langchain_tool = crewai_tool.to_langchain()

# change tool name punctuation
for old_symbol, new_symbol in [(" ", "_"), ("'", "")]:
langchain_tool.name = langchain_tool.name.replace(old_symbol, new_symbol)

return MotleyTool.from_langchain_tool(langchain_tool=langchain_tool)

@staticmethod
def from_supported_tool(tool: MotleySupportedTool) -> "MotleyTool":
"""Create a MotleyTool from any supported tool type.
Expand All @@ -98,7 +124,6 @@ def from_supported_tool(tool: MotleySupportedTool) -> "MotleyTool":
tool: Tool of any supported type.
Currently, we support tools from Langchain, LlamaIndex,
as well as motleycrew agents.
Returns:
MotleyTool instance.
"""
Expand All @@ -110,6 +135,8 @@ def from_supported_tool(tool: MotleySupportedTool) -> "MotleyTool":
return MotleyTool.from_llama_index_tool(tool)
elif isinstance(tool, MotleyAgentAbstractParent):
return tool.as_tool()
elif CrewAI__BaseTool is not None and isinstance(tool, CrewAI__BaseTool):
return MotleyTool.from_crewai_tool(tool)
else:
raise Exception(
f"Tool type `{type(tool)}` is not supported, please convert to MotleyTool first"
Expand All @@ -131,7 +158,7 @@ def to_llama_index_tool(self) -> LlamaIndex__BaseTool:
"""
ensure_module_is_installed("llama_index")
llama_index_tool = LlamaIndex__FunctionTool.from_defaults(
fn=self.tool._run,
fn=functools.partial(self.tool._run, config=RunnableConfig()),
name=self.tool.name,
description=self.tool.description,
fn_schema=self.tool.args_schema,
Expand Down Expand Up @@ -159,3 +186,18 @@ def autogen_tool_fn(input: field_type) -> str:
return self.invoke({field_name: input})

return autogen_tool_fn

def to_crewai_tool(self) -> CrewAI__BaseTool:
"""Description
Returns:
Crewai__BaseTool:
"""
ensure_module_is_installed("crewai_tools")
crewai_tool = Crewai__Tool(
name=self.tool.name,
description=self.tool.description,
func=self.tool._run,
args_schema=self.tool.args_schema,
)
return crewai_tool
Loading

0 comments on commit 3338fde

Please sign in to comment.