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.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
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.How It Works
- Third-party plugins in the
praisonai.integrationsentry-point group are discovered once, lazily, the first time anything imports frompraisonai.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
PluginRegistryskips any colliding entry point and keeps the built-in (aDEBUGline notes the collision), so you cannot silently override a built-in by shipping a plugin with the same name. from praisonai.integrations import <name>raisesAttributeErrorfor unknown names (native Python behaviour);.resolve("<name>")on the registry raisesValueError.
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 integrationGeminiCLIIntegration— Gemini CLI toolsCodexCLIIntegration— Codex CLI interfaceCursorCLIIntegration— Cursor CLI integrationBaseCLIIntegration— Base class for CLI toolsCLIExecutionError— CLI execution error class
Managed Agents
ManagedAgent(alias:ManagedAgentIntegration) — Managed agent interfaceAnthropicManagedAgent— Anthropic-specific managed agentManagedConfig(alias:ManagedBackendConfig) — Managed agent configuration
Local & Sandboxed Agents
LocalManagedAgent— Local managed agentLocalManagedConfig— Local agent configurationSandboxedAgent— Sandboxed agent executionSandboxedAgentConfig— Sandboxed agent configuration
Agent Backends
HostedAgent— Hosted agent backendHostedAgentConfig— Hosted agent configurationLocalAgent— Local agent backendLocalAgentConfig— Local agent configuration
Registry Functions
get_available_integrations— List available integrationsExternalAgentRegistry— External agent registryget_registry— Get integration registryregister_integration— Register new integrationcreate_integration— Create integration instancelist_external_agents— Usable--external-agentshort 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
Usecreate_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
Override a Built-in
Override a Built-in
Multiple Aliases
Multiple Aliases
Multi-tenant Isolation
Multi-tenant Isolation
IntegrationRegistry() for per-tenant registration that doesn’t leak.Best Practices
Always Use Lazy Loading
Always Use Lazy Loading
Always use a
_loader function, never import the integration at module top-level — that defeats the lazy-loading:Use Canonical Names
Use Canonical Names
Names are case-insensitive; pick the canonical form (matching the class name) for the registration key:
Avoid Internal Imports
Avoid Internal Imports
Don’t bypass the registry to import internal integration modules directly — those paths are not part of the public API:
Never Reuse a Built-in Name
Never Reuse a Built-in Name
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.Related
Framework Adapter Plugins
Plugin system for multi-agent frameworks
Persistence Backend Plugins
Add custom storage backends

