# 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]]