Include praisonai package in your project
Option 0: One-liner (simplest)
praisonai.run() reuses the same framework auto-detection and LLM endpoint resolution the praisonai CLI uses, so anything that works on the command line works here.
What it does
Auto-detects the first installed framework in this order:
crewai → praisonaiagents → autogen. Pass framework="..." to override — ag2 and langgraph must be requested explicitly.Reads
OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MODEL_NAME (and the standard PraisonAI key/config files) — same as the CLI.Async variant for FastAPI / Jupyter
arun() offloads the synchronous work to a thread so it never blocks the event loop.
Optional parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
agent_file | str | required | Path to your agents.yaml. |
framework | str | None | None (auto-detect) | One of "crewai", "praisonai", "autogen", "ag2", "langgraph". ag2 and langgraph must be selected explicitly — they are not in the auto-detect chain. ag2 is registered but its adapter is an unimplemented stub; passing framework="ag2" will raise NotImplementedError until implemented. |
tools | list | None | None | Optional list of tool callables passed through to AgentsGenerator. |
agent_yaml | str | None | None | Inline YAML string; takes precedence over agent_file when both are given. |
cli_config | dict | None | None | Advanced: override the resolved CLI config (rarely needed). |
If no framework is installed,
run() raises RuntimeError listing available adapters. Install one with pip install praisonaiagents (recommended for new projects). ag2 and langgraph are not in the auto-detect chain; pass framework="ag2" or framework="langgraph" explicitly to select them. Note that ag2 is an unimplemented stub and will raise NotImplementedError when called.When to use PraisonAI(...) instead
Reach for the full PraisonAI class (Option 1 below) when you need:
- Streaming / approval-system integration
- Custom backends or the gradio UI
- The
auto="..."natural-language-to-YAML mode - Repeated runs against the same generator without re-parsing YAML
Option 1: Using RAW YAML
Option 2: Using separate agents.yaml file
Note: Please create agents.yaml file before hand. If you only need to run anagents.yaml once and want zero ceremony, see Option 0: One-liner above.
Other options
Lifecycle / cleanup
EachAgentsGenerator lazily creates a bounded thread-pool to run synchronous tools under per-call timeouts. The pool is owned by the instance, not the process — concurrent sessions in a multi-tenant runtime never share workers.
When you’re done with a generator, release the pool with .close() or use it as a context manager:
close() is idempotent — calling it twice is safe.
Injecting a shared executor (multi-tenant)
If you already manage a thread-pool (e.g. one per tenant), inject it viatool_timeout_executor=. The generator will use the pool but never shut it down — ownership stays with you.
praisonai-tool-timeout-<hexid> for easy enumeration in top / py-spy / thread dumps.
tool_timeout_executor parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
tool_timeout_executor | concurrent.futures.Executor | None | None (lazy, instance-owned) | Optional executor for per-call tool timeouts. When None, the generator lazily creates and owns a bounded ThreadPoolExecutor (default 32 workers, override with PRAISONAI_TOOL_TIMEOUT_WORKERS). When supplied, it is borrowed — the generator never shuts it down. |
Always close or use `with`
Always close or use `with`
Leaked tool-timeout pools accumulate threads named
praisonai-tool-timeout-<hexid> across instances. Use with AgentsGenerator(...) as gen: or call gen.close() to release them. Check top / py-spy if you suspect thread accumulation.Borrowed pools stay yours
Borrowed pools stay yours
Passing
tool_timeout_executor= means close() won’t shut it down. You manage the lifecycle — call your_pool.shutdown() when you’re done with it.One generator per session in multi-tenant
One generator per session in multi-tenant
Don’t share
AgentsGenerator instances across tenants. Share the executor instead — inject the same pool via tool_timeout_executor= into each per-tenant generator.Unique task names per workflow
Unique task names per workflow
With the CrewAI framework,
context=[...] lookup keys on the task name. Two roles defining the same task name now raise ValueError — pick names like <role>_<verb> for clarity.Logging in scripts
If you want PraisonAI to configure your application’s logging, callconfigure_cli_logging() once at startup:
configure_cli_logging — only namespaced praisonai.* loggers will be used.
C9 Architecture: Four-Tier Package Model (Developer Reference)
This section covers the internal four-tier package architecture introduced in C9 (PR #2633). It is relevant to contributors and maintainers, not end-users.
Sibling: praisonai-bot
As of C9 (merged 2026-07-03), bots, gateway, and channel CLI live in a new sibling PyPI packagepraisonai-bot (module praisonai_bot). The praisonai.bots, praisonai.gateway, and praisonai.daemon paths remain as alias_package shims and are the stable public API.
praisonai-bot Migration Guide
Install options, CLI reference, backward-compat guarantees, and channel extension guide
Built-in Channels
Telegram, Discord, Slack, WhatsApp, Linear, Email, AgentMail
Four-Tier Model
PraisonAI uses a strict four-tier package model with a one-way dependency rule: Invariant: Bothpraisonai-code and praisonai-bot declare no PyPI dependency on praisonai. All cross-tier access goes through _wrapper_bridge only.
C8 Architecture: Wrapper–Code Boundary (Historical Reference)
The following section documents the C8 three-tier model that preceded C9. The three-tier diagram and metrics are preserved for historical reference.
Three-Tier Model (pre-C9 / C8)
Before C9, PraisonAI used a three-tier package model: Invariant:praisonai-code/pyproject.toml declares no PyPI dependency on praisonai. All praisonai-code → praisonai wrapper access goes through praisonai_code._wrapper_bridge only.
C8 Metrics (post-C8, merged 2026-07-02)
| Metric | Pre-C8 | Post-C8 |
|---|---|---|
Wrapper import lines in praisonai-code | 225 | 0 |
Regression baseline in check_c7_imports.sh | 225 | 50 |
| Allowlisted files | 47 | 0 |
_wrapper_bridge — The Only Cross-Tier Path
praisonai_code._wrapper_bridge is the sole permitted mechanism for praisonai-code to call into praisonai. It lazy-loads the wrapper at runtime and never causes an import-time error when the wrapper is absent.
import praisonai or from praisonai import … inside praisonai-code is forbidden and enforced by scripts/check_c7_imports.sh.
_WRAPPER_RESIDENT_COMMANDS
Commands that live in the praisonai wrapper but are registered in the praisonai-code CLI router. The variable was renamed from _WRAPPER_COMMANDS in C8.1 (backward-compat alias retained).
get_command() lazy-loads these via the absolute praisonai.cli.commands.* path through the bridge.
C8.2 Repatriated Commands (moved from praisonai-code back to praisonai):
| Batch | Commands |
|---|---|
| A | langfuse, langextract, flow, n8n, replay, langfuse_client |
| B | train, managed, examples, standardise |
| C | docs, schedule, batch |
| D | rag, knowledge, realtime, profile, audit, app |
| E | serve wrapper paths (SDK subcommands remain in praisonai-code) |
C8.3 Repatriated Features
The followingcli/features/* modules moved from praisonai-code to praisonai/cli/features/:
recipe, templates, deploy, recipe_optimizer, persistence, eval, agent_scheduler, acp, registry, sandbox_cli, ollama, workflow, tui/app, interactive/async_tui, interactive/core
Also repatriated: commands/recipe, context, mcp, validate.
Protocols & Adapters (C8.5)
C8.5 introduces typed protocol contracts to enforce the tier boundary. TheSessionStoreProtocol (session persistence) already ships in praisonaiagents:
TemplateStoreProtocol and ServeHandlerProtocol are defined in the C8.5 design but their physical extraction is deferred (same milestone as the PraisonAI class split).
| Protocol | Location | Purpose |
|---|---|---|
SessionStoreProtocol | praisonaiagents.session.protocols | Session persistence backend contract (add_message, get_chat_history, …) |
TemplateStoreProtocol | deferred | Template persistence for repatriated CLI features |
ServeHandlerProtocol | deferred | Dispatch serve subcommands without direct wrapper imports |
praisonai.adapters module lazily re-exports existing adapter classes (AutoReader, ChromaVectorStore, BasicRetriever, FusionRetriever, LLMReranker, and registration helpers) to preserve backward compatibility.
C8.4 Legacy Structure
praisonai/cli/legacy/inbuilt_tools.py,framework_run.py— extraction targets for lazy loaders.praisonai-code/cli/legacy/prompt_dispatch.py— standalone-safe helpers.main.pystill contains thePraisonAIclass body; wrapper access is normalised via the bridge. The physical 7k-line split is deferred (out of scope of C8).
Developer Tooling (C8)
| Script | Purpose |
|---|---|
scripts/check_c7_imports.sh | Counts wrapper import lines in praisonai-code; enforces baseline ≤ 50 |
scripts/c8_bridge_convert.py | Converts direct from praisonai … imports to _wrapper_bridge calls |
scripts/c8_repatriate.py | Moves a command/feature implementation from praisonai-code → praisonai |
Deferred Work (C8)
The physical extraction of thePraisonAI class (~7k lines in main.py) to praisonai/cli/legacy/praison_class.py was explicitly deferred from C8. The docs/concepts/architecture.mdx page (HUMAN-ONLY) also needs a maintainer update to reflect the C8 metrics.
