Skip to main content
Drop a Python file in .praisonai/tools/ and praisonai run auto-loads every public function as a tool — no --tools flag.
from praisonaiagents import Agent

agent = Agent(
    name="Greeter",
    instructions="Greet users by name.",
    tools=["greet.greet"],
)
agent.start("Greet Ada")
The tool name uses the namespaced form — <module>.<function> — so greet.py::greet becomes greet.greet.

Quick Start

1

Scaffold the convention

praisonai init writes a commented @tool stub at .praisonai/tools/example.py:
# .praisonai/tools/example.py
"""Project-local tools for this .praisonai/ project.

Every public callable in this directory is auto-discovered and made available
to the agent on `praisonai run` — no --tools flag required.
"""

# from praisonaiagents import tool
#
#
# @tool
# def greet(name: str) -> str:
#     """Return a friendly greeting for the given name."""
#     return f"Hello, {name}!"
2

Drop a plain function and run

Add a plain function at .praisonai/tools/greet.py:
# .praisonai/tools/greet.py
def greet(name: str) -> str:
    """Return a friendly greeting for the given name."""
    return f"Hello, {name}!"
Run — no --tools flag needed, just the opt-in env var:
PRAISONAI_ALLOW_LOCAL_TOOLS=true praisonai run "use the greet tool to greet Ada"
3

Promote to @tool for a rich schema

Decorate a function with @tool when you want a typed schema for the LLM:
# .praisonai/tools/math.py
from praisonaiagents import tool

@tool
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

How It Works

praisonai run walks .praisonai/tools/, loads each module behind the security gate, and hands the callables to the agent.

Discovery Rules

The rules below come straight from the SDK’s CustomDefinitionsDiscovery and _load_tools.
RuleBehaviour
Location.praisonai/tools/*.py (user-global ~/.praisonai/tools/ + project walk-up to git root)
PrecedenceLater wins on collision (user-global < project; nested closer to CWD < nested further)
Naming<module-filename>.<function-name> (e.g. greet.py::greetgreet.greet)
Public onlyCallables whose name doesn’t start with _
Module filterFiles starting with _ (e.g. _helpers.py) are skipped
Mixed file ruleIf any function in the file is @tool-decorated, only decorated functions are exported
Security gatePRAISONAI_ALLOW_LOCAL_TOOLS=true required — gate unset → empty discovery, no warning
Interaction with --toolsAdditive; explicit --tools items take precedence (dedup by callable identity)
Opt-out--no-tools on praisonai run skips discovery entirely

@tool-decorated vs Plain Callable

Both a plain function and a @tool-decorated function become tools — but if a file has any @tool, only the decorated functions win.
# .praisonai/tools/greet.py
def greet(name: str) -> str:
    """Return a friendly greeting for the given name."""
    return f"Hello, {name}!"
Exposed as greet.greet.

User-Global vs Project-Local

Two locations feed discovery, and they differ on the working-directory boundary.
User-global tools live at ~/.praisonai/tools/ and load even though they sit outside your project directory — the CWD boundary is deliberately opted out for that explicitly user-owned location (a regression fix that mirrors how an explicit --tools absolute path is trusted). Project-local tools walk up from your current directory and keep the strict CWD check, so an untrusted checkout cannot escape it.

Best Practices

Prefix helper functions with _ so they stay internal. Underscore names are never exported, and modules whose filename starts with _ are skipped entirely.
Decorate with @tool from praisonaiagents to give the LLM a typed schema. In a mixed file, only the @tool functions are exported — plain helpers are dropped.
Loading a tool module executes its code. Keep the opt-in on only in shells where you trust the .praisonai/tools/ contents.
Pass --no-tools to praisonai run to skip auto-discovery entirely when you want a run with no local tools loaded.

Local Tools Loading

Load your own tools.py or —tools file safely with the PRAISONAI_ALLOW_LOCAL_TOOLS opt-in.

Tool Discovery Order

The tier order that resolves a tool name — local files, built-ins, package, or plugin.

Add Tools

Copy tool files into ~/.praisonai/tools/ from local files or GitHub.

Tools CLI

List and manage the tools available to praisonai run.