# LionAGI Action System API Reference
## Overview
The Action System implements core functionality for function execution and tool management in LionAGI.
## Type Definitions
```python
# Core type definitions for tool handling
FUNCTOOL = Tool | Callable[..., Any]
FINDABLE_TOOL = FUNCTOOL | str
INPUTTABLE_TOOL = dict[str, Any] | bool | FINDABLE_TOOL
TOOL_TYPE = FINDABLE_TOOL | list[FINDABLE_TOOL] | INPUTTABLE_TOOL
```
> [!note] Type Usage
> These types provide flexibility in how tools can be referenced and passed to the system while maintaining type safety.
## Core Components
### EventStatus
```python
class EventStatus(str, Enum):
"""Status states for tracking action execution."""
PENDING = "pending"
PROCESSING = "processing"
COMPLETED = "completed"
FAILED = "failed"
```
### ObservableAction
```python
class ObservableAction(Element):
"""Base class for actions with execution tracking."""
status: EventStatus = EventStatus.PENDING
execution_time: float | None = None
execution_response: Any = None
execution_error: str | None = None
_timed_config: TimedFuncCallConfig | None = PrivateAttr(None)
_content_fields: list = PrivateAttr(["execution_response"])
```
**Methods:**
#### `__init__`
```python
def __init__(
self,
timed_config: dict | TimedFuncCallConfig | None,
**kwargs: Any
) -> None
```
Initialize an observable action.
> [!warning] Configuration Handling
> If timed_config is None, uses default config from Settings.
> If dict, converts to TimedFuncCallConfig.
#### `to_log`
```python
def to_log(self) -> Log
```
Convert action state to log entry.
### Tool
```python
class Tool(Element):
"""Callable tool with processing pipeline."""
function: Callable[..., Any] = Field(...)
schema_: dict[str, Any] | None = Field(default=None)
pre_processor: Callable[[Any], Any] | None = Field(default=None)
post_processor: Callable[[Any], Any] | None = Field(default=None)
parser: Callable[[Any], Any] | None = Field(default=None)
```
**Methods:**
#### `__init__`
```python
def __init__(self, **data: Any) -> None
```
Initialize tool with auto schema generation.
#### `function_name`
```python
@property
def function_name(self) -> str
```
Get function name from schema.
> [!important] Schema Generation
> Schema is automatically generated from function signature if not provided.
### ActionManager
```python
class ActionManager:
"""Central registry for tools."""
def __init__(
self,
registry: dict[str, Tool] | None = None,
logger = None
) -> None:
```
**Methods:**
#### `register_tool`
```python
def register_tool(
self,
tool: FUNCTOOL,
update: bool = False,
) -> None
```
Register a single tool.
> [!warning] Registration Constraints
> - Tool names must be unique unless update=True
> - Tools must be callable or Tool instances
> - Functions must have names
#### `register_tools`
```python
def register_tools(
self,
tools: list[FUNCTOOL] | FUNCTOOL,
update: bool = False,
) -> None
```
Register multiple tools.
#### `match_tool`
```python
@singledispatchmethod
def match_tool(self, func_call: Any) -> FunctionCalling
```
Match function call to registered tool.
#### `invoke`
```python
async def invoke(self, func_call: dict | str | ActionRequest) -> Any
```
Execute a registered tool.
### FunctionCalling
```python
class FunctionCalling(ObservableAction):
"""Handles function execution pipeline."""
func_tool: Tool | None = Field(default=None)
arguments: dict[str, Any] | None = None
function: str | None = None
```
**Methods:**
#### `__init__`
```python
def __init__(
self,
func_tool: Tool,
arguments: dict[str, Any],
timed_config: dict | TimedFuncCallConfig = None,
**kwargs: Any,
) -> None
```
Initialize function call.
#### `invoke`
```python
async def invoke(self) -> Any
```
Execute function with full pipeline.
## Usage Examples
### Tool Registration
```python
from lionagi.core.action import ActionManager, Tool, func_to_tool
# Method 1: Using func_to_tool
async def process_data(data: dict) -> dict:
"""Process input data.
Args:
data: Input dictionary
Returns:
dict: Processed result
"""
return processed
# Create tool from function
tool = func_to_tool(process_data)[0]
# Method 2: Direct Tool creation
processor = Tool(
function=process_data,
pre_processor=None,
post_processor=None,
parser=None
)
# Register with manager
manager = ActionManager()
manager.register_tool(tool) # or manager.register_tool(processor)
```
> [!note] Tool Creation Options
> - Use `func_to_tool` for simple function wrapping
> - Use direct `Tool` creation when you need preprocessing/postprocessing
### Function Execution
```python
# Direct invocation
result = await manager.invoke({
"function": "process_data",
"arguments": {"data": input_data}
})
# Using ActionRequest
request = ActionRequest(
function="process_data",
arguments={"data": input_data}
)
result = await manager.invoke(request)
```
## Error Handling
### Common Errors
1. **Registration Errors**
- ValueError: Duplicate tool name
- TypeError: Invalid tool type
- ValueError: Missing function name
2. **Execution Errors**
- ValueError: Unknown function
- TypeError: Invalid arguments
- RuntimeError: Execution failure
### Error Handling Pattern
```python
try:
result = await manager.invoke(func_call)
except ValueError as e:
# Handle registration/validation errors
logger.error(f"Invalid function call: {e}")
except Exception as e:
# Handle execution errors
logger.error(f"Execution failed: {e}")
```
> [!tip] Error Recovery
> - Use status tracking for error detection
> - Log execution errors with context
> - Clean up resources on failure
> - Consider retry strategies for recoverable errors
## See Also
- [[Action System Guide]]