mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-09 08:08:32 +00:00
Some checks are pending
Notify Downstream / notify-downstream (push) Waiting to run
* feat: add OpenAI agent adapter implementation - Introduced OpenAIAgentAdapter class to facilitate interaction with OpenAI Assistants. - Implemented methods for task execution, tool configuration, and response processing. - Added support for converting CrewAI tools to OpenAI format and handling delegation tools. * created an adapter for the delegate and ask_question tools * delegate and ask_questions work and it delegates to crewai agents* * refactor: introduce OpenAIAgentToolAdapter for tool management - Created OpenAIAgentToolAdapter class to encapsulate tool configuration and conversion for OpenAI Assistant. - Removed tool configuration logic from OpenAIAgentAdapter and integrated it into the new adapter. - Enhanced the tool conversion process to ensure compatibility with OpenAI's requirements. * feat: implement BaseAgentAdapter for agent integration - Introduced BaseAgentAdapter as an abstract base class for agent adapters in CrewAI. - Defined common interface and methods for configuring tools and structured output. - Updated OpenAIAgentAdapter to inherit from BaseAgentAdapter, enhancing its structure and functionality. * feat: add LangGraph agent and tool adapter for CrewAI integration - Introduced LangGraphAgentAdapter to facilitate interaction with LangGraph agents. - Implemented methods for task execution, context handling, and tool configuration. - Created LangGraphToolAdapter to convert CrewAI tools into LangGraph-compatible format. - Enhanced error handling and logging for task execution and streaming processes. * feat: enhance LangGraphToolAdapter and improve conversion instructions - Added type hints for better clarity and type checking in LangGraphToolAdapter. - Updated conversion instructions to ensure compatibility with optional LLM checks. * feat: integrate structured output handling in LangGraph and OpenAI agents - Added LangGraphConverterAdapter for managing structured output in LangGraph agents. - Enhanced LangGraphAgentAdapter to utilize the new converter for system prompt and task execution. - Updated LangGraphToolAdapter to use StructuredTool for better compatibility. - Introduced OpenAIConverterAdapter for structured output management in OpenAI agents. - Improved task execution flow in OpenAIAgentAdapter to incorporate structured output configuration and post-processing. * 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. * feat: enhance OpenAIAgentAdapter with configurable agent properties - Refactored OpenAIAgentAdapter to accept agent configuration as an argument. - Introduced a method to build a system prompt for the OpenAI agent, improving task execution context. - Updated initialization to utilize role, goal, and backstory from kwargs, enhancing flexibility in agent setup. - Improved tool handling and integration within the adapter. * feat: enhance agent adapters with structured output support - Introduced BaseConverterAdapter as an abstract class for structured output handling. - Implemented LangGraphConverterAdapter and OpenAIConverterAdapter to manage structured output in their respective agents. - Updated BaseAgentAdapter to accept an agent configuration dictionary during initialization. - Enhanced LangGraphAgentAdapter to utilize the new converter and improved tool handling. - Added methods for configuring structured output and enhancing system prompts in converter adapters. * refactor: remove _parse_tools method from OpenAIAgentAdapter and BaseAgent - Eliminated the _parse_tools method from OpenAIAgentAdapter and its abstract declaration in BaseAgent. - Cleaned up related test code in MockAgent to reflect the removal of the method. * also removed _parse_tools here as not used * feat: add dynamic import handling for LangGraph dependencies - Implemented conditional imports for LangGraph components to handle ImportError gracefully. - Updated LangGraphAgentAdapter initialization to check for LangGraph availability and raise an informative error if dependencies are missing. - Enhanced the agent adapter's robustness by ensuring it only initializes components when the required libraries are present. * fix: improve error handling for agent adapters - Updated LangGraphAgentAdapter to raise an ImportError with a clear message if LangGraph dependencies are not installed. - Refactored OpenAIAgentAdapter to include a similar check for OpenAI dependencies, ensuring robust initialization and user guidance for missing libraries. - Enhanced overall error handling in agent adapters to prevent runtime issues when dependencies are unavailable. * refactor: enhance tool handling in agent adapters - Updated BaseToolAdapter to initialize original and converted tools in the constructor. - Renamed method `all_tools` to `tools` for clarity in BaseToolAdapter. - Added `sanitize_tool_name` method to ensure tool names are API compatible. - Modified LangGraphAgentAdapter to utilize the updated tool handling and ensure proper tool configuration. - Refactored LangGraphToolAdapter to streamline tool conversion and ensure consistent naming conventions. * feat: emit AgentExecutionCompletedEvent in agent adapters - Added emission of AgentExecutionCompletedEvent in both LangGraphAgentAdapter and OpenAIAgentAdapter to signal task completion. - Enhanced event handling to include agent, task, and output details for better tracking of execution results. * docs: Enhance BaseConverterAdapter documentation - Added a detailed docstring to the BaseConverterAdapter class, outlining its purpose and the expected functionality for all converter adapters. - Updated the post_process_result method's docstring to specify the expected format of the result as a string. * docs: Add comprehensive guide for bringing custom agents into CrewAI - Introduced a new documentation file detailing the process of integrating custom agents using the BaseAgentAdapter, BaseToolAdapter, and BaseConverter. - Included step-by-step instructions for creating custom adapters, configuring tools, and handling structured output. - Provided examples for implementing adapters for various frameworks, enhancing the usability of CrewAI for developers. * feat: Introduce adapted_agent flag in BaseAgent and update BaseAgentAdapter initialization - Added an `adapted_agent` boolean field to the BaseAgent class to indicate if the agent is adapted. - Updated the BaseAgentAdapter's constructor to pass `adapted_agent=True` to the superclass, ensuring proper initialization of the new field. * feat: Enhance LangGraphAgentAdapter to support optional agent configuration - Updated LangGraphAgentAdapter to conditionally apply agent configuration when creating the agent graph, allowing for more flexible initialization. - Modified LangGraphToolAdapter to ensure only instances of BaseTool are converted, improving tool compatibility and handling. * feat: Introduce OpenAIConverterAdapter for structured output handling - Added OpenAIConverterAdapter to manage structured output conversion for OpenAI agents, enhancing their ability to process and format results. - Updated OpenAIAgentAdapter to utilize the new converter for configuring structured output and post-processing results. - Removed the deprecated get_output_converter method from OpenAIAgentAdapter. - Added unit tests for BaseAgentAdapter and BaseToolAdapter to ensure proper functionality and integration of new features. * feat: Enhance tool adapters to support asynchronous execution - Updated LangGraphToolAdapter and OpenAIAgentToolAdapter to handle asynchronous tool execution by checking if the output is awaitable. - Introduced `inspect` import to facilitate the awaitability check. - Refactored tool wrapper functions to ensure proper handling of both synchronous and asynchronous tool results. * fix: Correct method definition syntax and enhance tool adapter implementation - Updated the method definition for `configure_structured_output` to include the `def` keyword for clarity. - Added an asynchronous tool wrapper to ensure tools can operate in both synchronous and asynchronous contexts. - Modified the constructor of the custom converter adapter to directly assign the agent adapter, improving clarity and functionality. * linted * refactor: Improve tool processing logic in BaseAgent - Added a check to return an empty list if no tools are provided. - Simplified the tool attribute validation by using a list of required attributes. - Removed commented-out abstract method definition for clarity. * refactor: Simplify tool handling in agent adapters - Changed default value of `tools` parameter in LangGraphAgentAdapter to None for better handling of empty tool lists. - Updated tool initialization in both LangGraphAgentAdapter and OpenAIAgentAdapter to directly pass the `tools` parameter, removing unnecessary list handling. - Cleaned up commented-out code in OpenAIConverterAdapter to improve readability. * refactor: Remove unused stream_task method from LangGraphAgentAdapter - Deleted the `stream_task` method from LangGraphAgentAdapter to streamline the code and eliminate unnecessary complexity. - This change enhances maintainability by focusing on essential functionalities within the agent adapter.
179 lines
6.2 KiB
Python
179 lines
6.2 KiB
Python
from typing import Any, List, Optional
|
|
|
|
from pydantic import Field, PrivateAttr
|
|
|
|
from crewai.agents.agent_adapters.base_agent_adapter import BaseAgentAdapter
|
|
from crewai.agents.agent_adapters.openai_agents.structured_output_converter import (
|
|
OpenAIConverterAdapter,
|
|
)
|
|
from crewai.agents.agent_builder.base_agent import BaseAgent
|
|
from crewai.tools import BaseTool
|
|
from crewai.tools.agent_tools.agent_tools import AgentTools
|
|
from crewai.utilities import Logger
|
|
from crewai.utilities.events import crewai_event_bus
|
|
from crewai.utilities.events.agent_events import (
|
|
AgentExecutionCompletedEvent,
|
|
AgentExecutionErrorEvent,
|
|
AgentExecutionStartedEvent,
|
|
)
|
|
|
|
try:
|
|
from agents import Agent as OpenAIAgent # type: ignore
|
|
from agents import Runner, enable_verbose_stdout_logging # type: ignore
|
|
|
|
from .openai_agent_tool_adapter import OpenAIAgentToolAdapter
|
|
|
|
OPENAI_AVAILABLE = True
|
|
except ImportError:
|
|
OPENAI_AVAILABLE = False
|
|
|
|
|
|
class OpenAIAgentAdapter(BaseAgentAdapter):
|
|
"""Adapter for OpenAI Assistants"""
|
|
|
|
model_config = {"arbitrary_types_allowed": True}
|
|
|
|
_openai_agent: "OpenAIAgent" = PrivateAttr()
|
|
_logger: Logger = PrivateAttr(default_factory=lambda: Logger())
|
|
_active_thread: Optional[str] = PrivateAttr(default=None)
|
|
function_calling_llm: Any = Field(default=None)
|
|
step_callback: Any = Field(default=None)
|
|
_tool_adapter: "OpenAIAgentToolAdapter" = PrivateAttr()
|
|
_converter_adapter: OpenAIConverterAdapter = PrivateAttr()
|
|
|
|
def __init__(
|
|
self,
|
|
model: str = "gpt-4o-mini",
|
|
tools: Optional[List[BaseTool]] = None,
|
|
agent_config: Optional[dict] = None,
|
|
**kwargs,
|
|
):
|
|
if not OPENAI_AVAILABLE:
|
|
raise ImportError(
|
|
"OpenAI Agent Dependencies are not installed. Please install it using `uv add openai-agents`"
|
|
)
|
|
else:
|
|
role = kwargs.pop("role", None)
|
|
goal = kwargs.pop("goal", None)
|
|
backstory = kwargs.pop("backstory", None)
|
|
super().__init__(
|
|
role=role,
|
|
goal=goal,
|
|
backstory=backstory,
|
|
tools=tools,
|
|
agent_config=agent_config,
|
|
**kwargs,
|
|
)
|
|
self._tool_adapter = OpenAIAgentToolAdapter(tools=tools)
|
|
self.llm = model
|
|
self._converter_adapter = OpenAIConverterAdapter(self)
|
|
|
|
def _build_system_prompt(self) -> str:
|
|
"""Build a system prompt for the OpenAI agent."""
|
|
base_prompt = f"""
|
|
You are {self.role}.
|
|
|
|
Your goal is: {self.goal}
|
|
|
|
Your backstory: {self.backstory}
|
|
|
|
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(
|
|
self,
|
|
task: Any,
|
|
context: Optional[str] = None,
|
|
tools: Optional[List[BaseTool]] = None,
|
|
) -> str:
|
|
"""Execute a task using the OpenAI Assistant"""
|
|
self._converter_adapter.configure_structured_output(task)
|
|
self.create_agent_executor(tools)
|
|
|
|
if self.verbose:
|
|
enable_verbose_stdout_logging()
|
|
|
|
try:
|
|
task_prompt = task.prompt()
|
|
if context:
|
|
task_prompt = self.i18n.slice("task_with_context").format(
|
|
task=task_prompt, context=context
|
|
)
|
|
crewai_event_bus.emit(
|
|
self,
|
|
event=AgentExecutionStartedEvent(
|
|
agent=self,
|
|
tools=self.tools,
|
|
task_prompt=task_prompt,
|
|
task=task,
|
|
),
|
|
)
|
|
result = self.agent_executor.run_sync(self._openai_agent, task_prompt)
|
|
final_answer = self.handle_execution_result(result)
|
|
crewai_event_bus.emit(
|
|
self,
|
|
event=AgentExecutionCompletedEvent(
|
|
agent=self, task=task, output=final_answer
|
|
),
|
|
)
|
|
return final_answer
|
|
|
|
except Exception as e:
|
|
self._logger.log("error", f"Error executing OpenAI task: {str(e)}")
|
|
crewai_event_bus.emit(
|
|
self,
|
|
event=AgentExecutionErrorEvent(
|
|
agent=self,
|
|
task=task,
|
|
error=str(e),
|
|
),
|
|
)
|
|
raise
|
|
|
|
def create_agent_executor(self, tools: Optional[List[BaseTool]] = None) -> None:
|
|
"""
|
|
Configure the OpenAI agent for execution.
|
|
While OpenAI handles execution differently through Runner,
|
|
we can use this method to set up tools and configurations.
|
|
"""
|
|
all_tools = list(self.tools or []) + list(tools or [])
|
|
|
|
instructions = self._build_system_prompt()
|
|
self._openai_agent = OpenAIAgent(
|
|
name=self.role,
|
|
instructions=instructions,
|
|
model=self.llm,
|
|
**self._agent_config or {},
|
|
)
|
|
|
|
if all_tools:
|
|
self.configure_tools(all_tools)
|
|
|
|
self.agent_executor = Runner
|
|
|
|
def configure_tools(self, tools: Optional[List[BaseTool]] = None) -> None:
|
|
"""Configure tools for the OpenAI Assistant"""
|
|
if tools:
|
|
self._tool_adapter.configure_tools(tools)
|
|
if self._tool_adapter.converted_tools:
|
|
self._openai_agent.tools = self._tool_adapter.converted_tools
|
|
|
|
def handle_execution_result(self, result: Any) -> str:
|
|
"""Process OpenAI Assistant execution result converting any structured output to a string"""
|
|
return self._converter_adapter.post_process_result(result.final_output)
|
|
|
|
def get_delegation_tools(self, agents: List[BaseAgent]) -> List[BaseTool]:
|
|
"""Implement delegation tools support"""
|
|
agent_tools = AgentTools(agents=agents)
|
|
tools = agent_tools.tools()
|
|
return tools
|
|
|
|
def configure_structured_output(self, task) -> None:
|
|
"""Configure the structured output for the specific agent implementation.
|
|
|
|
Args:
|
|
structured_output: The structured output to be configured
|
|
"""
|
|
self._converter_adapter.configure_structured_output(task)
|