Skip to main content
Point PraisonAI at any Python module and it turns the module’s public functions into tools an agent can call. extract_functions_from_loaded_module is the single owner of the “walk a loaded module and collect its callables into a name → callable registry” rule that PraisonAI uses internally — reuse it when you already have a loaded module.

Quick Start

1

Simple — point an agent at a folder of tools

Drop a tools.py next to your recipe/workflow YAML and set the gate. PraisonAI loads its public functions automatically — no import needed.
2

Programmatic — load and register a module yourself

Load the module with the safe loader, extract its callables, then hand the values to Agent(tools=...).
3

Filter the walk

Two independent knobs narrow what the walk accepts.

How It Works

The helper walks the module’s members, applies the filter, and returns a name → callable dict for the caller to register. The helper does not load anything — the caller owns the loading step (via the safe loader). If you only have a file path and no module object, use the path-based sibling instead. Both share the same _accept rule, so the extraction behaviour is identical — the only difference is who owns the loading step.

Which entry point should I use?

Pick the entry point that matches what you already hold.
Reloading a module produces a distinct object. If your code filters by origin (inspect.getmodule(obj) is my_module), reuse the module you already loaded — pass it to extract_functions_from_loaded_module rather than re-loading it by path.

Filter Reference

Both knobs default to False and can be combined. With defaults, the walk accepts any member where inspect.isfunction(obj) or callable(obj) is true. Order follows inspect.getmembers(module) (alphabetical by name).

Common Patterns

The recipe/workflow loader picks up tools.py automatically when the gate is on, then keeps an own-module origin filter so re-exports from other modules stay out of the registry.
Internally the loader runs extract_functions_from_loaded_module(tools_module, functions_only=True, skip_private=True) and then keeps only members where inspect.getmodule(obj) is tools_module.

Best Practices

Use praisonai_code._safe_loader.load_user_module to stay inside the PRAISONAI_ALLOW_LOCAL_TOOLS gate and CWD path constraints. extract_functions_from_loaded_module deliberately does not load — the caller must.
Prevents _normalize_input and friends from leaking into the agent’s tool list.
Loading a second time by path breaks inspect.getmodule(obj) is my_module origin filters — object identity is what matters. Pass the module you already have.
Keep re-exported callables from other modules out of your registry, exactly like the recipe loader does.

Tool Resolver

The path-based sibling — loads + walks in one step

Local Tools Loading

How the PRAISONAI_ALLOW_LOCAL_TOOLS gate loads your tools.py

Tools (CLI)

Verify what got picked up with praisonai tools list

Tools

General Tools concept overview