Skip to main content
Every PraisonAI registry follows one rule: a built-in name always wins over an entry-point plugin — whichever entry-point group the plugin publishes under, canonical or a deprecated legacy spelling. Publishing a pip package with an entry point named openai, docker, or aws has no effect — the built-in resolves. Runtime register(...) is the only deliberate override path.
The plugin author does not accidentally hijack a built-in through a pyproject.toml; overriding a built-in is always a deliberate, in-process decision.

Quick Start

1

Pick a name that does not collide

Names are matched case-insensitively against the built-ins of the registry you target. openai, OpenAI, and OPENAI are the same key — pick something novel.
2

Override a built-in deliberately (runtime only)

The one supported way to replace a built-in is an in-process register(...) call:
3

Confirm what resolved

Turn on DEBUG logging to see the collision line noting that a shipped built-in kept its name.

How It Works

Since PraisonAI PR #4176 the guard lives in the base PluginRegistry, so every registry that subclasses it inherits the behaviour. It is enforced once, not re-asserted per registry. Some registries also honour deprecated (legacy) entry-point group spellings for backward compatibility. Legacy discovery runs first (so the canonical spelling wins on a clash), and since PraisonAI PR #4185 it applies the same built-in check — you cannot resurrect the old shadowing behaviour by falling back to a deprecated group. Standalone installs of praisonai-sandbox and praisonai-deploy carry a vendored fallback copy of PluginRegistry that runs when praisonai-code isn’t importable (pip install praisonai-sandbox on its own). Since PraisonAI PR #4184 both vendored copies enforce the same built-in check — an entry point whose name (case-insensitive) matches a built-in is skipped on that path too, so the guarantee holds in every install shape. Prior to PR #4184 a standalone praisonai-sandbox install still let a pip plugin replace docker, and praisonai-deploy let one replace aws. The same rule runs on the vendored fallback path used by standalone praisonai-sandbox / praisonai-deploy installs:
The log level is DEBUG, not WARNING. Packages that legitimately re-declare their own built-ins as entry points (for external discoverability) do not spam users’ console output.

Every Registry Is Guarded

The two groups that matter most decide where user code executes: praisonai.sandbox and praisonai.managed_backends. A pip-installed package cannot silently take over docker — whether via the canonical base class (PR #4176), the legacy group spelling (PR #4185), or the vendored fallback copy that runs when praisonai-sandbox / praisonai-deploy is installed standalone (PR #4184).
Since PR #4800, the local routes ollama, ollama_chat, lm_studio, vllm, hosted_vllm are guarded built-ins under praisonai.llm_providers. A pip package publishing an entry point named ollama (or any of the five) is now silently skipped (DEBUG log) instead of taking over — matching the existing behaviour for openai. Plugin authors must use runtime register(..., override=True) to replace any of these.
Accessor names differ per registry — read the source (or the per-registry page below) before wiring a runtime override. Several registries expose get_default_registry() from their own module.
Registries that honour a deprecated/legacy group spelling enforce the guard on that path too. Today the only one is EndpointProviderRegistry (canonical praisonai.endpoint_providers, legacy praisonai.endpoints.providers, built-in mcp). A pip package publishing mcp under the deprecated group can no longer replace the built-in mcp endpoint provider.
Standalone installs of praisonai-sandbox and praisonai-deploy use a vendored fallback copy of PluginRegistry (they don’t import praisonai-code). Since PR #4184 those fallback copies enforce the same built-in check — a pip package publishing docker (sandbox) or aws (deploy) on its own can no longer replace the built-in on those slim installs. Runtime register(...) on the standalone package’s registry remains the only supported override.

Compatibility

Compatibility. If your plugin previously relied on shadowing a built-in name via a pyproject.toml entry point (for example, replacing openai in praisonai.llm_providers), that no longer works after PR #4176. Move the override to explicit runtime registration:
Additive plugins (novel names) are unchanged. Switching to a deprecated/legacy group spelling is not a workaround — since PR #4185 the guard applies there too. A previously‑silent shadow via a standalone praisonai-sandbox (docker) or praisonai-deploy (aws) install — the last remaining path — is closed by PR #4184. Runtime register(...) on the standalone package’s registry remains the supported override.

Best Practices

Prefix or vendor-qualify a plugin name (acme-openai, corp.pay_invoice) so it never collides with a built-in on any surface, present or future.
A runtime register(...) call is in-process and explicit — exactly what you want when overriding a built-in is intentional (a tenant-specific provider, a test double). It cannot happen by accident through packaging.
OpenAI, openai, and OPENAI are one key. When you audit a registry’s built-ins before naming a plugin, lowercase both sides.
A skipped collision writes a DEBUG line, not a warning. Run with LOGLEVEL=DEBUG to confirm which built-in kept its name.

Integration Registry

praisonai.integrations entry points and built-in precedence

External CLI Integrations

claude, gemini, codex, cursor are protected names

Tool Source Registry

Built-in tool sources win over entry-point sources

Tool Discovery Order

Where the plugin layer sits, and why built-ins outrank it

Compute Provider Plugins

Sandbox / managed-backend names decide where code runs

Custom LLM Provider

Override openai / anthropic / google at runtime

Plugins

Write, load, and ship plugins as pip packages

Pure Mode

Skip entry-point discovery for a single run