# CrewAI Integration
crewai-arcade enables you to add Arcade tools and Arcade Auth into your
CrewAI applications. Just create an `ArcadeToolManager` and add your
tools to your CrewAI Agent/Tasks.
## Initializing the ArcadeToolManager
There are two main ways to initialize your `ArcadeToolManager`
1. Default handling of tool authorization and execution:
```py
"""
When you provide a user id to the ArcadeToolManger,
it will handle the tool authorization and tool execution for you
"""
manager = ArcadeToolManager(default_user_id="me@example.com,
api_key="...")
```
2. Custom handling of tool authorization and execution
```py
"""
Provide a callback function to the `ArcadeToolManager` that handles
tool authorization and tool execution. The callback function will be
called whenever your CrewAI
application wants to call a tool.
"""
def custom_tool_executor(
manager: ArcadeToolManager, tool_name: str, **tool_input: dict[str, Any]
) -> Any:
"""Custom tool executor for the ArcadeToolManager
ArcadeToolManager's default executor handles authorization and tool
execution.
This function overrides the default executor to handle authorization and
tool execution
in a custom way.
"""
# Your custom tool auth logic goes here
# Your custom tool execution logic goes here
...
manager = ArcadeToolManager(executor=custom_tool_executor,
api_key="...")
```
## Tool Registration
1. Initialize the tools in the manager
```py
"""
Clears any existing tools in the manager and replaces them with tools
and toolkits that are provided.
"""
manager.init_tools(tools=["Google.ListEmails"], toolkits=["Slack"])
```
2. Add tools to the manager
```py
"""
Adds tools and toolkits to the manager's internal tool list.
"""
manager.add_tools(tools=["Google.ListEmails"], toolkits=["Slack"])
```
3. Retrieve tools and toolkits from the manager
```py
"""
Retrieves the provided tools and toolkits as CrewAI StructuredTools.
"""
manager.get_tools(tools=["Google.ListEmails"], toolkits=["Slack"])
```
## Auth Helpers
The `ArcadeToolManager` provides multiple helper methods for when you
need to create
a custom auth flow.
1. `authorize_tool` handles the whole authorization flow for you. This
is used internally when a custom auth flow is not needed.
2. `requires_auth(tool_name)` checks if the provided tool has
authorization requirements.
3. `authorize(tool_name, user_id)` authorizes the use of the provided
tool for the provided user ID
4. `is_authorized(tool_name, user_id)` checks if a tool is authorized
for use by the provided user ID
5. `wait_for_auth(auth_response)` waits for an authorization process to
complete before returning
## Tool Execution Helpers
1. `execute_tool` handles the whole tool execution flow for you. This is
used internally when a custom tool execution flow is not needed.
---------
Co-authored-by: lgesuellip <lgesuellipinto@uade.edu.ar>
Co-authored-by: lpetralli <123559656+lpetralli@users.noreply.github.com>
Co-authored-by: lgesuellip <102637283+lgesuellip@users.noreply.github.com>
Co-authored-by: “lgesuellip” <“lgesuellipinto@uade.edu.ar”>
56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
from typing import Any
|
|
|
|
from arcadepy.types import ToolDefinition
|
|
from pydantic import BaseModel, Field, create_model
|
|
|
|
# Mapping of Arcade value types to Python types
|
|
TYPE_MAPPING = {
|
|
"string": str,
|
|
"number": float,
|
|
"integer": int,
|
|
"boolean": bool,
|
|
"array": list,
|
|
"json": dict,
|
|
}
|
|
|
|
|
|
def get_python_type(val_type: str) -> Any:
|
|
"""Map Arcade value types to Python types.
|
|
|
|
Args:
|
|
val_type: The value type as a string.
|
|
|
|
Returns:
|
|
Corresponding Python type.
|
|
"""
|
|
_type = TYPE_MAPPING.get(val_type)
|
|
if _type is None:
|
|
raise ValueError(f"Invalid value type: {val_type}")
|
|
return _type
|
|
|
|
|
|
def tool_definition_to_pydantic_model(tool_def: ToolDefinition) -> type[BaseModel]:
|
|
"""Convert a ToolDefinition's inputs into a Pydantic BaseModel.
|
|
|
|
Args:
|
|
tool_def: The ToolDefinition object to convert.
|
|
|
|
Returns:
|
|
A Pydantic BaseModel class representing the tool's input schema.
|
|
"""
|
|
try:
|
|
fields: dict[str, Any] = {}
|
|
for param in tool_def.input.parameters or []:
|
|
param_type = get_python_type(param.value_schema.val_type)
|
|
if param_type == list and param.value_schema.inner_val_type: # noqa: E721
|
|
inner_type: type[Any] = get_python_type(param.value_schema.inner_val_type)
|
|
param_type = list[inner_type] # type: ignore[valid-type]
|
|
param_description = param.description or "No description provided."
|
|
default = ... if param.required else None
|
|
fields[param.name] = (
|
|
param_type,
|
|
Field(default=default, description=param_description),
|
|
)
|
|
return create_model(f"{tool_def.name}Args", **fields)
|
|
except ValueError as e:
|
|
raise ValueError(f"Error converting {tool_def.name} parameters into pydantic model: {e}")
|