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