.praisonai/agents/, .praisonai/commands/, and .praisonai/tools/ to extend the CLI without writing packaging code.
The user runs praisonai run --agent researcher; discovery loads custom agents, slash commands, and project-local tools from .praisonai/.
How It Works
Quick Start
Skip the boilerplate —
praisonai init scaffolds a working .praisonai/ with a starter agent and command, then read on to customise.1
Create an agent file
2
Run the agent
3
Create a command file
4
Run the command
How discovery works
Project definitions override user definitions on name collision.
Agent definitions
Files:.praisonai/agents/*.md or *.yaml
Scoping permissions
Three built-in agents (
build, plan, review) are available without any file — see Agent Presets & Modes.mode: to a definition for instant read-only or review scoping:
permission: block:
Supported mode: values
mode: subagent marks an agent as delegatable from other agents at run time (see Named Agent Delegation). It is a marker only — it does not apply any permission changes and is ignored when computing permissions. Every other mode: value still flows through the permission engine as before.
Command templates
Files:.praisonai/commands/*.md
Opt-in live shell substitution
!`cmd` is disabled by default. Enable with any one of:
PRAISONAI_ALLOW_SHELL=trueenvironment variablecommands.allow_shell: truein.praisonai/config.yaml- Per-command frontmatter
allow_shell: true
ShellSubstitutionError. !`cmd` inside $ARGUMENTS or @file contents is never executed — only markers in the original template run.
Project-local tools
Drop any.py file into .praisonai/tools/ and every praisonai run in that project auto-loads its tools — no --tools flag, no packaging, no imports in your agent code.
How discovery works
What gets loaded
Precedence & opt-out
A richer example — private helpers stay private
Scaffold with praisonai init
example.py is a commented @tool stub — uncomment or replace it in place.
Making an agent delegatable
Mark an agent withmode: subagent so a running primary agent can hand it sub-tasks by name.
praisonai run --agent lead) can call spawn_subagent(agent_name="researcher", …) and this agent runs the sub-task under its own model/tools/permissions. See Named Agent Delegation.
Agent vs command vs skill vs rule
Slash commands
Custom commands auto-register in interactive mode asCommandKind.CUSTOM. Disable with SlashCommandHandler(discover_custom=False).
Custom commands appear automatically in Telegram / Discord / autocomplete when your bot restarts, filtered by the same CommandAccessPolicy that gates execution. See Native / Autocomplete.
Inside praisonai code too
The same .praisonai/commands/*.md files work as /name inside praisonai code, the REPL, and the async TUI. A unified CommandRegistry aggregates built-ins, your custom commands, skills, MCP prompts, and pip-installed praisonai.commands packs into one namespace:
praisonai run --command mydeploy staging would — byte-for-byte parity between interactive and CLI. See Slash Commands → Unified Command Registry.
Python API
discover_project_tools() returns a list of tool callables (empty unless PRAISONAI_ALLOW_LOCAL_TOOLS=true). For metadata, CustomDefinitionsDiscovery().list_tools() returns CustomTool(name, path, callable, source) records where name is the namespaced <module>.<func>.
Best Practices
Use project files for team sharing
Use project files for team sharing
Commit
.praisonai/agents/, .praisonai/commands/, and .praisonai/tools/ to git. Every teammate and CI run picks up the same tool set on the next praisonai run — no pip install and no --tools flag.Decorate public tools, keep helpers private
Decorate public tools, keep helpers private
.praisonai/tools/_helpers.py is skipped entirely. Inside a loaded file, functions without @tool are only fallback-loaded when the file has no @tool at all — so decorating your public entry points keeps private helpers off the LLM’s tool list.Keep user-global files personal
Keep user-global files personal
Use
~/.praisonai/ for personal shortcuts that should not override team agents.Never rely on unguarded shell substitution
Never rely on unguarded shell substitution
!`cmd` requires an explicit opt-in gate (allow_shell: true, config, or PRAISONAI_ALLOW_SHELL). $(...) is always escaped — use !`cmd` only when you need live output like git diff.Start with praisonai init
Start with praisonai init
Run
praisonai init to scaffold .praisonai/agents/, .praisonai/commands/, and .praisonai/tools/ before hand-writing files.Related
Run CLI
—agent and —command flags
Agent CLI
List and inspect custom agents
Command CLI
List and preview commands
Slash Commands
Interactive custom commands
Init CLI
Scaffold .praisonai/ in one command
Tools
The @tool decorator and building custom tools
Agent Presets & Modes
Built-in presets and per-agent permission scoping
Named Agent Delegation
Delegate named sub-tasks to your agents with mode: subagent

