praisonai.integrations — a static export map serves built-ins, and the praisonai.integrations entry-point group adds third-party names.
Rewritten for PraisonAI PR #4651. The old
IntegrationRegistry class, get_integrations_registry(), INTEGRATIONS_REGISTRY, and .get_by_attr() were removed. The public surface is now a static name -> "module:attr" map plus an entry-point lookup, both inside praisonai/integrations/__init__.py. Importing every built-in name and every plugin name works exactly as before — only the internal registry machinery changed. See Migration.Choose Your Registration Path
Pick a path based on how the integration ships.Quick Start
1
Use a built-in integration
2
Distribute as a pip plugin
acme) is the name users import; the right-hand side is the dotted path to the class. Names that collide with a built-in are ignored — built-ins always win.How It Works
__getattr__onpraisonai.integrationsfirst checks the static_STATIC_EXPORTSmap (name -> "module:attr"), lazily importing the owning module on first access.- If the name isn’t a built-in, it’s looked up in the
praisonai.integrationsentry-point group andep.load()-ed. - Unknown names raise
AttributeError(native Python behaviour). - Dunder / underscore-prefixed submodule names (e.g.
from praisonai.integrations import base) fall through to normal import machinery.
Precedence
Built-ins always win because they are served by_STATIC_EXPORTS before the entry-point lookup runs. A plugin may only add names, never replace a shipped one.
Available built-in names
Every key below imports directly:from praisonai.integrations import <name>.
CLI Tools
BaseCLIIntegration— base class for CLI toolsCLIExecutionError— CLI execution error classget_available_integrations— list available integrationsClaudeCodeIntegration— Claude Code CLIGeminiCLIIntegration— Gemini CLICodexCLIIntegration— Codex CLICursorCLIIntegration— Cursor CLI
Managed Agents
ManagedAgent(aliasManagedAgentIntegration) — managed agent interfaceAnthropicManagedAgent— Anthropic managed agentManagedConfig(aliasManagedBackendConfig) — 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
ExternalAgentRegistry— external agent registry (typed source of truth for--external-agent)get_registry— get the external-agent registryregister_integration— register a new integrationcreate_integration— create an integration instance
list_external_agents and external_agent_catalog cover the separate praisonai.external_agents entry-point group (short-name --external-agent choices and UI toggles), not the praisonai.integrations group documented here. See Single source of truth.Typed backend registries
The two typed registries are unchanged by #4651 and remain the sources of truth for their surfaces:
Use these when you need typed enumeration of backends rather than plain module importability.
Migration from the old registry
The internal registry surfaces removed in PR #4651 no longer exist. Update any code that touched them: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 BUILTIN_INTEGRATIONS (short-alias → loader) used by ExternalAgentRegistry. Register a new built-in there and add the class to _STATIC_EXPORTS in praisonai/integrations/__init__.py to make it importable.
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. That group is distinct from praisonai.integrations (module importability) documented here.Build your own namespace
Usecreate_lazy_getattr(registry) from praisonai._registry to give your own package the same lazy-loading + entry-point dispatch behaviour:
PluginRegistry.has(name) -> bool (added in #4651) is a cheap, load-free membership check you can use before triggering a lazy import.
Best Practices
Import from the package root, not submodules
Import from the package root, not submodules
Use the public surface so you get built-in-vs-plugin resolution:
Never reuse a built-in name
Never reuse a built-in name
Built-ins are served by
_STATIC_EXPORTS before the entry-point lookup runs, so a plugin sharing a built-in name is never reached. Pick a name unique to your package.Prefer typed registries for enumeration
Prefer typed registries for enumeration
When you need to list backends (not just import one), use
ExternalAgentRegistry / ManagedBackendRegistry — they own the --external-agent and run_on= surfaces.Upgrade for entry-point discovery
Upgrade for entry-point discovery
Plugin discovery needs PR #4154 or later. On older releases, only built-ins resolve.
Related
Model Provider Plugins
Same static-map + entry-point + built-ins-win pattern for model → provider
Framework Adapter Plugins
Plugin system for multi-agent frameworks

