diff --git a/docs/concepts/knowledge.mdx b/docs/concepts/knowledge.mdx index 16ac586d6..8af9b70a2 100644 --- a/docs/concepts/knowledge.mdx +++ b/docs/concepts/knowledge.mdx @@ -12,9 +12,11 @@ Knowledge in CrewAI is a powerful system that allows AI agents to access and uti Think of it as giving your agents a reference library they can consult while working. - Key benefits of using Knowledge: - Enhance agents with domain-specific - information - Support decisions with real-world data - Maintain context across - conversations - Ground responses in factual information + Key benefits of using Knowledge: + - Enhance agents with domain-specific information + - Support decisions with real-world data + - Maintain context across conversations + - Ground responses in factual information ## Supported Knowledge Sources @@ -23,10 +25,14 @@ CrewAI supports various types of knowledge sources out of the box: - - Raw strings - Text files (.txt) - PDF documents + - Raw strings + - Text files (.txt) + - PDF documents - - CSV files - Excel spreadsheets - JSON documents + - CSV files + - Excel spreadsheets + - JSON documents @@ -300,14 +306,14 @@ recent_news = SpaceNewsKnowledgeSource( - - Keep chunk sizes appropriate for your content type - Consider content - overlap for context preservation - Organize related information into - separate knowledge sources + - Keep chunk sizes appropriate for your content type + - Consider content overlap for context preservation + - Organize related information into separate knowledge sources - - Adjust chunk sizes based on content complexity - Configure appropriate - embedding models - Consider using local embedding providers for faster - processing + - Adjust chunk sizes based on content complexity + - Configure appropriate embedding models + - Consider using local embedding providers for faster processing diff --git a/docs/concepts/tools.mdx b/docs/concepts/tools.mdx index 9b9c6a32e..8abe0f4e6 100644 --- a/docs/concepts/tools.mdx +++ b/docs/concepts/tools.mdx @@ -172,6 +172,48 @@ def my_tool(question: str) -> str: return "Result from your custom tool" ``` +### Structured Tools + +The `StructuredTool` class wraps functions as tools, providing flexibility and validation while reducing boilerplate. It supports custom schemas and dynamic logic for seamless integration of complex functionalities. + +#### Example: +Using `StructuredTool.from_function`, you can wrap a function that interacts with an external API or system, providing a structured interface. This enables robust validation and consistent execution, making it easier to integrate complex functionalities into your applications as demonstrated in the following example: + +```python +from crewai.tools.structured_tool import CrewStructuredTool +from pydantic import BaseModel + +# Define the schema for the tool's input using Pydantic +class APICallInput(BaseModel): + endpoint: str + parameters: dict + +# Wrapper function to execute the API call +def tool_wrapper(*args, **kwargs): + # Here, you would typically call the API using the parameters + # For demonstration, we'll return a placeholder string + return f"Call the API at {kwargs['endpoint']} with parameters {kwargs['parameters']}" + +# Create and return the structured tool +def create_structured_tool(): + return CrewStructuredTool.from_function( + name='Wrapper API', + description="A tool to wrap API calls with structured input.", + args_schema=APICallInput, + func=tool_wrapper, + ) + +# Example usage +structured_tool = create_structured_tool() + +# Execute the tool with structured input +result = structured_tool._run(**{ + "endpoint": "https://example.com/api", + "parameters": {"key1": "value1", "key2": "value2"} +}) +print(result) # Output: Call the API at https://example.com/api with parameters {'key1': 'value1', 'key2': 'value2'} +``` + ### Custom Caching Mechanism diff --git a/src/crewai/agents/crew_agent_executor.py b/src/crewai/agents/crew_agent_executor.py index 649360e30..83ca06e41 100644 --- a/src/crewai/agents/crew_agent_executor.py +++ b/src/crewai/agents/crew_agent_executor.py @@ -143,6 +143,9 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): tool_result = self._execute_tool_and_check_finality( formatted_answer ) + if self.step_callback: + self.step_callback(tool_result) + formatted_answer.text += f"\nObservation: {tool_result.result}" formatted_answer.result = tool_result.result if tool_result.result_as_answer: diff --git a/src/crewai/project/annotations.py b/src/crewai/project/annotations.py index be4710b2b..bf0051c4d 100644 --- a/src/crewai/project/annotations.py +++ b/src/crewai/project/annotations.py @@ -66,6 +66,8 @@ def cache_handler(func): def crew(func) -> Callable[..., Crew]: + + @wraps(func) def wrapper(self, *args, **kwargs) -> Crew: instantiated_tasks = [] instantiated_agents = [] diff --git a/src/crewai/project/crew_base.py b/src/crewai/project/crew_base.py index e93452a6e..0b43882f2 100644 --- a/src/crewai/project/crew_base.py +++ b/src/crewai/project/crew_base.py @@ -213,4 +213,8 @@ def CrewBase(cls: T) -> T: callback_functions[callback]() for callback in callbacks ] + # Include base class (qual)name in the wrapper class (qual)name. + WrappedClass.__name__ = CrewBase.__name__ + "(" + cls.__name__ + ")" + WrappedClass.__qualname__ = CrewBase.__qualname__ + "(" + cls.__name__ + ")" + return cast(T, WrappedClass) diff --git a/src/crewai/project/utils.py b/src/crewai/project/utils.py index be3f757d9..2e95c755d 100644 --- a/src/crewai/project/utils.py +++ b/src/crewai/project/utils.py @@ -1,11 +1,13 @@ +from functools import wraps + def memoize(func): cache = {} + @wraps(func) def memoized_func(*args, **kwargs): key = (args, tuple(kwargs.items())) if key not in cache: cache[key] = func(*args, **kwargs) return cache[key] - memoized_func.__dict__.update(func.__dict__) return memoized_func