.praisonai/tools/ and praisonai run auto-loads every public function as a tool — no --tools flag.
<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:2
Drop a plain function and run
Add a plain function at Run — no
.praisonai/tools/greet.py:--tools flag needed, just the opt-in:3
Promote to @tool for a rich schema
Decorate a function with Run it with the opt-in as a first-class flag:
@tool when you want a typed schema for the LLM: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’sCustomDefinitionsDiscovery and _load_tools.
YAML Agents (agents.yaml)
YAML-defined agents pick up @tool functions dropped into .praisonai/tools/*.py by their flat tool name — no tools: entry required.
Start with an agent that names no tools in YAML:
@tool function beside it:
weather:
Naming the tool explicitly
Passname= to @tool to control the flat name the agent resolves:
weather_lookup. If your agents.yaml lists tools explicitly, reference it by that flat name.
Additive with YAML-named tools
A YAML-named built-in and a.praisonai/tools/ @tool function resolve together on the same agent:
duckduckgo still resolves from the built-in tools, and weather_lookup is added on top from the discovered file.
How tools merge on the YAML path
ToolResolver.resolve_all_from_yaml resolves YAML-named built-ins, layers cwd tools.py / tools/ classes, then additively merges the discovered .praisonai/tools/*.py @tool functions — all gated by the same opt-in.
The same gate applies — set
PRAISONAI_ALLOW_LOCAL_TOOLS=true or pass --allow-local-tools. See Enabling on run below. The gate is checked first, so no directory walk-up runs when local tools are disabled.The cwd
tools.py / tools/ BaseTool-class extraction is unchanged and still runs first. Explicit Python-passed tools take precedence, and only the .praisonai/tools/ layer is additive.Enabling on run
Two equivalent ways to opt in for a praisonai run invocation.
- --allow-local-tools (per-invocation)
- PRAISONAI_ALLOW_LOCAL_TOOLS=true (shell scope)
Discoverable via
praisonai run --help. Scoped strictly to the single invocation.--allow-local-tools is a per-invocation grant — it sets PRAISONAI_ALLOW_LOCAL_TOOLS=true for this run only and restores the prior value in a finally. A later in-process run_main() call (embedded/notebook/test reuse) without the flag will not inherit the authorization.Discovery hint when the opt-in is unset
When.praisonai/tools/*.py (or ~/.praisonai/tools/*.py) files are present but the opt-in is unset, praisonai run prints a one-line hint on the default path (not just --verbose):
.praisonai/tools/, ~/.praisonai/tools/, or both. The hint is silent when there are no local tool files.
Enabling on run --agent
run --agent <name> auto-discovers .praisonai/tools/*.py too — the frontmatter tools: list, --tools/--toolset, and discovered tools all merge, dedup’d by callable identity.
PRAISONAI_ALLOW_LOCAL_TOOLS=true / --allow-local-tools opt-in applies — the security gate is identical to default run. Fixed in #3047.
Using from YAML agents (agents.yaml)
YAML-defined agents also pick up @tool functions from .praisonai/tools/*.py — reference them by tool name from any tools: list.
praisonai run:
@tool(name="…") if given, else the function __name__ — not the module-namespaced form (math.add) that direct praisonai run uses. The two paths differ only in the key.
Fixed in #3107.
@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.
- Plain function
- @tool-decorated
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
Keep private helpers underscore-prefixed
Keep private helpers underscore-prefixed
Prefix helper functions with
_ so they stay internal. Underscore names are never exported, and modules whose filename starts with _ are skipped entirely.Use @tool when you want a rich schema
Use @tool when you want a rich schema
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.Prefer --allow-local-tools over exporting the env var
Prefer --allow-local-tools over exporting the env var
Loading a tool module executes its code. Prefer
--allow-local-tools on the individual praisonai run invocation over exporting PRAISONAI_ALLOW_LOCAL_TOOLS=true in your shell — the CLI flag is scoped to the single run and cannot leak to a later in-process invocation. Export the env var only when many back-to-back runs need the opt-in in a trusted shell.Use --no-tools for one-off deterministic runs
Use --no-tools for one-off deterministic runs
Pass
--no-tools to praisonai run to skip auto-discovery entirely when you want a run with no local tools loaded.Related
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.
Tool Resolver
The resolver behind YAML
tools: lists — merges .praisonai/tools/ @tool functions by name.Add Tools
Copy tool files into ~/.praisonai/tools/ from local files or GitHub.
Tools CLI
List and manage the tools available to praisonai run.
Run CLI
How —agent composes frontmatter tools with —tools/—toolset and local tools.
Custom Agents, Commands & Tools
Tool composition order for praisonai run —agent.
Tool Resolver
The resolution chain used by YAML-defined agents.

