Skip to main content
The user types praisonai …; the dispatcher routes to Typer subcommands, version flags, or the legacy prompt path. PraisonAI picks one of five paths based on what you type — and adding a new subcommand means it Just Works.

Dispatch Paths

Quick Start

1

Check Version

2

Interactive Mode

3

Get Help

4

Use Subcommands

5

Free-text Prompts


How It Works


Routing Rules


Auto-Discovery

Commands registered in praisonai/cli/app.py become routable automatically through Click introspection.
Adding a new subcommand? Register it in praisonai/cli/app.py (e.g. app.add_typer(my_app, name="mycmd")) and the dispatcher picks it up automatically — praisonai mycmd ... routes to Typer with no changes to __main__.py. The command set is discovered once via click.Context.list_commands() and cached behind a thread-safe lock.
The auto-discovery cache (_get_typer_commands()) works by:
  1. Importing the Typer app and calling register_commands()
  2. Using Click’s introspection to list all registered commands
  3. Caching the result in _typer_commands_cache with thread safety
  4. Returning an empty set on failure (cache not poisoned for retry)

Common Patterns

Bare Prompt

YAML File

Subcommand with Global Flags


Unknown-command guard

The dispatcher intercepts single-word command-like tokens so a mistyped verb never becomes a paid LLM call. classify_unknown_command in praisonai/cli/legacy/dispatch/argparse_builder.py returns a hint string only when a lone token looks like a mistyped or reserved command; otherwise it returns None and the token runs as a prompt.

When it fires

The hint prints to stderr with exit code 2. Shell scripts must not swallow stderr if they need the diagnostic.
To send a single word to the model, wrap it in praisonai run "<word>" — arguments to run bypass the guard by construction.

Best Practices

The --version flag takes a fast path that prints version information without importing any praisonai.cli.* modules. This keeps the command responsive even if optional dependencies are broken or missing. The version check happens before any heavy imports or command discovery.
To add a new subcommand, simply register it in praisonai/cli/app.py using app.add_typer(). The dispatcher automatically discovers it through Click introspection with no manual updates needed to routing logic. The command becomes available immediately after registration.
Multi-word bare positionals (e.g. praisonai "build a weather agent") still fall through to legacy and run as a direct prompt. Single-word tokens go through classify_unknown_command first: a reserved verb like show or a close typo like memoyr fails fast with a hint on stderr and exits with code 2, while an unrecognised single word (e.g. hello) still runs as a prompt for backward compatibility. Use praisonai run "hello" to send a genuine single-word prompt.
Registration errors from register_commands() propagate directly to the user — the dispatcher does not swallow them. If an optional dependency is missing or a command fails to register, you see the real error instead of silent fallback behavior. This fail-loud approach aids debugging.

Registration errors fail loud. If register_commands() raises (e.g. an ImportError from a missing optional dep), the exception propagates from praisonai ... — you see the real error, not Typer’s “no command” page. This is intentional and pinned by tests.

CLI Reference

Complete command reference

CLI Commands

Basic CLI usage guide

Gateway

Multi-bot WebSocket gateway

Version

Version management