feat: implement BaseToolAdapter for tool integration

- Introduced BaseToolAdapter as an abstract base class for tool adapters in CrewAI.
- Updated LangGraphToolAdapter and OpenAIAgentToolAdapter to inherit from BaseToolAdapter, enhancing their structure and functionality.
- Improved tool configuration methods to support better integration with various frameworks.
- Added type hints and documentation for clarity and maintainability.
This commit is contained in:
lorenzejay
2025-04-11 09:27:28 -07:00
parent 6ae0c6f664
commit 65c90152af
5 changed files with 60 additions and 33 deletions

View File

@@ -0,0 +1,32 @@
from abc import ABC, abstractmethod
from typing import Any, List, Optional
from crewai.tools.base_tool import BaseTool
class BaseToolAdapter(ABC):
"""Base class for all tool adapters in CrewAI.
This abstract class defines the common interface that all tool adapters
must implement. It provides the structure for adapting CrewAI tools to
different frameworks and platforms.
"""
original_tools: List[BaseTool] = []
converted_tools: List[Any] = []
def __init__(self, tools: Optional[List[BaseTool]] = None):
self.tools = tools or []
@abstractmethod
def configure_tools(self, tools: List[BaseTool]) -> None:
"""Configure and convert tools for the specific implementation.
Args:
tools: List of BaseTool instances to be configured and converted
"""
pass
def all_tools(self) -> List[Any]:
"""Return all converted tools."""
return self.converted_tools

View File

@@ -37,7 +37,6 @@ class LangGraphAgentAdapter(BaseAgentAdapter):
function_calling_llm: Any = Field(default=None)
step_callback: Any = Field(default=None)
# Config parameters for LangGraph
model: str = Field(default="gpt-4o")
verbose: bool = Field(default=False)
@@ -81,7 +80,6 @@ class LangGraphAgentAdapter(BaseAgentAdapter):
tools=converted_tools,
checkpointer=self._memory,
)
print("langgraph graph", self._graph)
except ImportError as e:
self._logger.log(
@@ -94,15 +92,15 @@ class LangGraphAgentAdapter(BaseAgentAdapter):
def _build_system_prompt(self) -> str:
"""Build a system prompt for the LangGraph agent."""
base_prompt = f"""You are {self.role}.
base_prompt = f"""
You are {self.role}.
Your goal is: {self.goal}
Your goal is: {self.goal}
Your backstory: {self.backstory}
Your backstory: {self.backstory}
When working on tasks, think step-by-step and use the available tools when necessary.
"""
# Enhance with structured output instructions if configured
When working on tasks, think step-by-step and use the available tools when necessary.
"""
return self._converter_adapter.enhance_system_prompt(base_prompt)
def execute_task(
@@ -114,7 +112,6 @@ When working on tasks, think step-by-step and use the available tools when neces
"""Execute a task using the LangGraph workflow."""
self.create_agent_executor(tools)
# Configure structured output if needed
self.configure_structured_output(task)
try:

View File

@@ -1,30 +1,29 @@
from typing import Any, List, Optional
from crewai.agents.agent_adapters.base_tool_adapter import BaseToolAdapter
from crewai.tools.base_tool import BaseTool
class LangGraphToolAdapter:
"""Adapts CrewAI tools to LangGraph-compatible format"""
class LangGraphToolAdapter(BaseToolAdapter):
"""Adapts CrewAI tools to LangGraph agent tool compatible format"""
def __init__(self, tools: Optional[List[BaseTool]] = None):
self.tools = tools or []
self.converted_tools = []
self.original_tools = tools or []
def configure_tools(self, tools: List[BaseTool]) -> None:
"""Convert CrewAI tools to LangGraph tools"""
self.tools = tools
self.converted_tools = self._convert_tools(tools)
def _convert_tools(self, tools: List[BaseTool]) -> List[Any]:
"""
Convert CrewAI tools to LangGraph-compatible tools
LangGraph expects tools in langchain_core.tools format
Configure and convert CrewAI tools to LangGraph-compatible format.
LangGraph expects tools in langchain_core.tools format.
"""
from langchain_core.tools import StructuredTool
converted_tools = []
for tool in tools:
self.tools = tools
self.converted_tools = []
if self.original_tools:
all_tools = tools + self.original_tools
else:
all_tools = tools
for tool in all_tools:
# Create a wrapper function that matches LangGraph's expected format
def tool_wrapper(*args, tool=tool, **kwargs):
# Extract inputs based on the tool's schema
@@ -36,12 +35,13 @@ class LangGraphToolAdapter:
return tool.run(**kwargs)
converted_tool = StructuredTool(
name=tool.name,
name=tool.name.replace(" ", "_"),
description=tool.description,
func=tool_wrapper,
args_schema=tool.args_schema,
)
converted_tools.append(converted_tool)
self.converted_tools.append(converted_tool)
return converted_tools
def all_tools(self) -> List[Any]:
return self.converted_tools

View File

@@ -31,7 +31,6 @@ class OpenAIAgentAdapter(BaseAgentAdapter):
_active_thread: Optional[str] = PrivateAttr(default=None)
function_calling_llm: Any = Field(default=None)
step_callback: Any = Field(default=None)
converted_tools: Optional[List[Tool]] = Field(default=None)
_tool_adapter: OpenAIAgentToolAdapter = PrivateAttr()
_converter_adapter: OpenAIConverterAdapter = PrivateAttr()

View File

@@ -2,21 +2,20 @@ from typing import Any, List, Optional
from agents import FunctionTool, Tool
from crewai.agents.agent_adapters.base_tool_adapter import BaseToolAdapter
from crewai.tools import BaseTool
class OpenAIAgentToolAdapter:
class OpenAIAgentToolAdapter(BaseToolAdapter):
"""Adapter for OpenAI Assistant tools"""
converted_tools: Optional[List[Tool]] = None
def __init__(self, tools: Optional[List[BaseTool]] = None):
self.tools = tools
self.original_tools = tools or []
def configure_tools(self, tools: List[BaseTool]) -> None:
"""Configure tools for the OpenAI Assistant"""
if self.tools:
all_tools = tools + self.tools
if self.original_tools:
all_tools = tools + self.original_tools
else:
all_tools = tools
if all_tools: