Custom Provider Registry
The Custom Provider Registry allows you to register custom LLM providers that extend PraisonAI’s capabilities beyond the built-in providers (OpenAI, Anthropic, Google via LiteLLM).Updated in PR #1624: Built-in providers (
openai, anthropic, google) plus aliases (oai, claude, gemini, google_genai) are now auto-registered and backed by LiteLLM. You add custom providers when you need a non-LiteLLM backend or a custom routing/caching/mocking layer.Verified end-to-end in PR #2171 and PR #3011:- PR #2171 wired built-in aliases (
oai,claude,gemini,google_genai) through the loader map so alias-basedcreate_llm_provider(...)calls resolve. - PR #3011 wired the wrapper’s two hot LLM paths (framework-adapter resolver + structured-completion generator) to consult the registry first, so a registered non-built-in provider is now the one that actually serves
Agent(llm="…/…")calls — not just standalonecreate_llm_provider(...).
Built-in providers
Built-in providers are automatically registered when a registry is created:What Problem Does It Solve?
- Integrate proprietary or internal LLM APIs
- Add support for new providers before LiteLLM supports them
- Create mock providers for testing
- Build custom routing or caching layers
Quick Start
1
Define provider
2
Register and use
Where a Registered Provider Takes Effect
Registering a provider isn’t just for directcreate_llm_provider(...) calls — the registry is now consulted on the hot LLM paths, so your provider is used end-to-end:
PraisonAIModel.get_model()— every framework adapter’s model resolver. Any non-built-in prefix (e.g.bedrock/) resolves through your registered provider.AutoGenerator._completion_impl— the YAML generator’s structured-completion path, before the LiteLLM → OpenAI ladder.
- Built-in prefixes (
openai/,groq/,anthropic/,google/,cohere/,ollama/,openrouter/) keep the fast, direct-SDK path — never routed through the registry. - Non-built-in prefixes are looked up in the registry and, if registered, use your provider.
- Anything else falls through to the LiteLLM → OpenAI ladder.
- Fail-closed on unknown providers is preserved.
- Registry lookup never raises on the hot path — any registry error degrades to the built-in ladder.
- For
PraisonAIModel, the OpenAI-key requirement is deferred to your registered provider (no spurious auth error when you supply your own credentials).
Structured Outputs from the YAML Generator
To be used byAutoGenerator for structured completion, a registered provider opts in by exposing an async generate_structured(...):
generate_structured(...) are skipped and the built-in ladder runs unchanged.
Thread Safety
Enhanced in PR #1597:
LLMProviderRegistry is now thread-safe with singleton access and RLock protection for all operations.register, unregister, resolve, alias lookup, and listing) are safe to call concurrently from threads. Built-in providers are registered automatically on first instantiation.
Singleton access pattern (preferred for app code):
register_llm_provider / create_llm_provider continue to work unchanged (backwards compatible).
How Provider Resolution Works
The registry resolves providers in this order:1. Explicit Provider Format: provider/model
2. Model Prefix Inference
When no provider is specified, the model name prefix determines the provider:3. Custom Provider with Explicit Name
Where registered providers take effect
Registering a provider makes it reachable from every entry point that resolves models through the wrapper — not just directcreate_llm_provider(...) calls.
Two wrapper hot paths now consult the registry before falling back to the built-in ladder.
Registering a provider under a built-in prefix (
openai/, groq/, cohere/, ollama/, anthropic/, google/, openrouter/) does not hijack the built-in path. Both hot paths gate against a shared _BUILTIN_MODEL_PREFIXES set so the built-in ladder always wins for those prefixes. Use a unique namespace (e.g. mycompany-openai/) if you need custom routing under an OpenAI-like protocol.End-to-end Bedrock example
Provider Aliases
Built-in providers support aliases for shorter, more convenient model specifications:Using Aliases
Registering Custom Providers with Aliases
When registering your own custom providers, you can specify aliases:Registering Custom Providers Safely
Unique Name Rules
Provider names must be unique. Attempting to register a duplicate name raises an error:Alias Rules
Aliases provide alternative names for a provider:Override Flag
Useoverride=True only when you intentionally want to replace an existing registration:
Avoiding Collisions
Recommended Naming Pattern
Use a namespace prefix to avoid collisions:Reserved Names
These provider names are now registered providers (not just inference defaults):openai- Auto-registered LiteLLM provideranthropic- Auto-registered LiteLLM providergoogle- Auto-registered LiteLLM provider- Their aliases:
oai,claude,gemini,google_genai
Re-registering them without
override=True will raise ValueError: Provider 'X' is already registered. Use override=True only if you’re intentionally replacing the built-in provider.Multi-Agent Guidance
Global Registry (Default)
The default global registry is shared across all code:Isolated Registry (Per Agent/Run)
For multi-agent scenarios where you need isolation:- No global state mutation
- Safe for concurrent/parallel agent runs
- Each agent can have its own provider configuration
- Testing isolation
API Reference
register_llm_provider
create_llm_provider
LLMProviderRegistry
Utility Functions
Breaking Changes
Removed APIs
LLMProviderRegistry.get_instance()→ Useget_default_llm_registry()LLMProviderRegistry._instanceand_instance_lockclass attributes removedpraisonai.profiler.default_profilermodule attribute removed
Changed Semantics
TheLLMProviderRegistry.register() and LLMProviderRegistry.resolve() methods now have PluginRegistry semantics:
Preserved Aliases
These methods continue to work for backward compatibility:has(),list(),list_all()- Module-level
register_llm_provider(...),create_llm_provider(...)
Minimal Example
Troubleshooting
Common Errors
“Provider ‘X’ is already registered”Performance Notes
- Lazy imports: The registry module only imports
typing- no heavy dependencies - Import time: ~800μs for
praisonai.llm.registry - O(1) operations:
has(),resolve(), andregister()are all O(1) - No LiteLLM coupling: The registry is completely independent of LiteLLM
Migration note
Before PR #3011,register_llm_provider("bedrock", ...) succeeded but Agent(llm="bedrock/…") raised ValueError: OPENAI_API_KEY environment variable is required for the default OpenAI service. — because the framework-adapter resolver never consulted the registry. If you worked around this by shipping OPENAI_API_KEY=not-needed or a shim adapter, you can now delete the workaround: the registered provider is used directly.
See Also
- Models Overview - Built-in provider configuration
- LLM Gateways - Pre-registered gateway providers
- Advanced Multi-Provider Patterns - Routing across providers
- LiteLLM Models - Providers supported by LiteLLM

