Skip to main content
The user installs a third-party package; entry points register CLI and agent backends in one registry. Third-party discovery via the praisonai.integrations entry-point group is fully supported from PraisonAI PR #4154 (2026-08-20) onwards; on earlier releases the group was silently ignored and only runtime registration (below) worked.
Built-in names always win over entry-point plugins. Since PraisonAI PR #4176, this guard lives in the base PluginRegistry — not per-registry — so IntegrationRegistry and every other registry on this site enforce it automatically. The registry skips any entry point whose name (case-insensitive) matches a shipped built-in, keeps the built-in, and logs a DEBUG line. Runtime register(...) is the only way to deliberately override a built-in. See Plugin Precedence for the full rule across every registry.
Integration Registry enables third-party developers to add custom CLI tools, managed agents, and agent backends to PraisonAI through a centralized plugin system.

Choose Your Registration Path

Pick a registration path based on how the integration ships.

Quick Start

1

Use a built-in integration

2

Register at runtime

3

Distribute as a pip plugin

The left-hand side (acme) is the name users import; the right-hand side is the dotted path to the class. Names collide case-insensitively with built-ins, and built-ins always win.
On PraisonAI releases prior to PR #4154 (merged 2026-08-20), entry-point-based plugins were discovered and then silently discarded — from praisonai.integrations import my_plugin raised AttributeError even when the plugin was correctly installed. If entry-point discovery seems to do nothing, upgrade to a release that includes PR #4154. Runtime register_lazy(...) registration always worked.

How It Works

  • Third-party plugins in the praisonai.integrations entry-point group are discovered once, lazily, the first time anything imports from praisonai.integrations.
  • Discovery only stores each plugin’s loader; no third-party code runs until you actually import that name.
  • Built-in integrations take precedence on name collisions — as of PR #4176 the base PluginRegistry skips any colliding entry point and keeps the built-in (a DEBUG line notes the collision), so you cannot silently override a built-in by shipping a plugin with the same name.
  • from praisonai.integrations import <name> raises AttributeError for unknown names (native Python behaviour); .resolve("<name>") on the registry raises ValueError.

Precedence

Registration sources resolve in a fixed order when names collide. Built-ins can never be silently shadowed by a same-named entry-point plugin. Since PR #4176 the base PluginRegistry skips the colliding entry point during discovery and keeps the built-in — runtime register(...) remains the deliberate override path.

Configuration / API

INTEGRATIONS_REGISTRY remains available as a module-level name for backward compatibility — the first access triggers construction. Use get_integrations_registry() in new code to make the lazy build explicit. Underscore-prefixed submodule names (for example from praisonai.integrations import _unified_registry) now import normally instead of triggering registry construction.

Built-in Integrations

The registry includes these built-in integrations with lazy loading:

CLI Tools

  • ClaudeCodeIntegration — Claude Code CLI integration
  • GeminiCLIIntegration — Gemini CLI tools
  • CodexCLIIntegration — Codex CLI interface
  • CursorCLIIntegration — Cursor CLI integration
  • BaseCLIIntegration — Base class for CLI tools
  • CLIExecutionError — CLI execution error class

Managed Agents

  • ManagedAgent (alias: ManagedAgentIntegration) — Managed agent interface
  • AnthropicManagedAgent — Anthropic-specific managed agent
  • ManagedConfig (alias: ManagedBackendConfig) — Managed agent configuration

Local & Sandboxed Agents

  • LocalManagedAgent — Local managed agent
  • LocalManagedConfig — Local agent configuration
  • SandboxedAgent — Sandboxed agent execution
  • SandboxedAgentConfig — Sandboxed agent configuration

Agent Backends

  • HostedAgent — Hosted agent backend
  • HostedAgentConfig — Hosted agent configuration
  • LocalAgent — Local agent backend
  • LocalAgentConfig — Local agent configuration

Registry Functions

  • get_available_integrations — List available integrations
  • ExternalAgentRegistry — External agent registry
  • get_registry — Get integration registry
  • register_integration — Register new integration
  • create_integration — Create integration instance
  • list_external_agents — Usable --external-agent short names (built-ins + plugins)
  • external_agent_catalog — Presentation metadata per external agent (cls, label, cli, install)
list_external_agents and external_agent_catalog cover the praisonai.external_agents entry-point group (short-name --external-agent choices and UI toggles), not the praisonai.integrations group documented on this page. A listed name is always a usable name — see Single source of truth.

Advanced Usage

Adding a New Built-in Backend

Built-in CLI backends (Claude Code, Gemini, Codex, Cursor) are registered from a single canonical module: praisonai/integrations/_cli_loaders.py. It exports CLASS_NAME_LOADERS (class-name → loader) used by IntegrationRegistry, and BUILTIN_INTEGRATIONS (short-alias → loader) used by ExternalAgentRegistry. Register a new built-in backend in one place and both registry surfaces pick it up.
This is the in-tree path. To ship a --external-agent short name and UI toggle out-of-tree — pip-installable, no PraisonAI code changes — publish to the praisonai.external_agents entry-point group instead. See Register a custom external agent. Note praisonai.external_agents (short-name --external-agent + UI toggles) is a different group from praisonai.integrations (module importability) documented on this page.

Build Your Own Namespace

Use create_lazy_getattr(registry) from praisonai._registry for plugin authors who want to give their own package the same lazy-loading + entry-point dispatch behaviour:

Common Patterns

Last-write-wins on the canonical name.
Both the alias and the canonical name resolve.
Construct your own IntegrationRegistry() for per-tenant registration that doesn’t leak.

Best Practices

Always use a _loader function, never import the integration at module top-level — that defeats the lazy-loading:
Names are case-insensitive; pick the canonical form (matching the class name) for the registration key:
Don’t bypass the registry to import internal integration modules directly — those paths are not part of the public API:
Built-ins always win on name collisions. Since PR #4176 this rule is enforced in the base PluginRegistry, so it holds for every registry — not just this one. If you ship a plugin under an existing built-in name, the entry point is skipped and users get the built-in (a DEBUG line notes the collision) — pick a name unique to your package. Names are compared case-insensitively, so ClaudeCodeIntegration, claudecodeintegration, and CLAUDECODEINTEGRATION are the same key. See Plugin Precedence.

Framework Adapter Plugins

Plugin system for multi-agent frameworks

Persistence Backend Plugins

Add custom storage backends