Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.praison.ai/llms.txt

Use this file to discover all available pages before exploring further.

Registry dependency injection enables custom plugin registries for multi-tenant isolation, testing, and per-run overrides.

Quick Start

1

Default Registry (Simple)

Use the process-default registry for normal applications:
from praisonai.agents_generator import AgentsGenerator

# adapter_registry=None → uses get_default_registry()
generator = AgentsGenerator("agents.yaml", "crewai", config_list=[...])
2

Custom Registry (Isolation)

Inject a custom registry for tenant isolation or testing:
from praisonai.framework_adapters.registry import FrameworkAdapterRegistry
from praisonai.agents_generator import AgentsGenerator

tenant_registry = FrameworkAdapterRegistry()  # fresh, isolated
tenant_registry.register("crewai", CustomCrewAIAdapter)

generator = AgentsGenerator(
    agent_file="agents.yaml",
    framework="crewai",
    config_list=[...],
    adapter_registry=tenant_registry,  # <-- new in #1639
)

How It Works

The registry pattern supports multiple configuration levels across all four registries:
RegistryModuleDefault FactoryBackward-compat
Framework adapterspraisonai.framework_adapters.registryget_default_registry()FrameworkAdapterRegistry() directly constructible
External CLI integrationspraisonai.integrations.registryget_default_registry()get_registry() still exported
Bot platformspraisonai.bots._registryget_default_bot_registry()register_platform(), list_platforms(), etc.
Generic base (advanced)praisonai._registryn/aPluginRegistry[T] for plugin authors

Configuration Examples

Inject Registry into AgentsGenerator

from praisonai.framework_adapters.registry import FrameworkAdapterRegistry
from praisonai.agents_generator import AgentsGenerator

tenant_registry = FrameworkAdapterRegistry()
tenant_registry.register("crewai", CustomCrewAIAdapter)

generator = AgentsGenerator(
    agent_file="agents.yaml",
    framework="crewai",
    config_list=[...],
    adapter_registry=tenant_registry,
)

Inject Registry into AutoGenerator

from praisonai.framework_adapters.registry import FrameworkAdapterRegistry
from praisonai.auto import AutoGenerator

reg = FrameworkAdapterRegistry()
auto = AutoGenerator(
    topic="...",
    agent_file="test.yaml",
    framework="crewai",
    config_list=[...],
    adapter_registry=reg,
)

Build Custom Plugin Registry

Advanced: create a custom plugin registry on top of PluginRegistry[T]:
from praisonai._registry import PluginRegistry

def _my_loader():
    from my_pkg.adapter import MyAdapter
    return MyAdapter

reg = PluginRegistry(
    entry_point_group="my_app.adapters",
    builtins={"my_adapter": _my_loader},
)
reg.register("custom", SomeOtherAdapter)
print(reg.list_names())

When to Use Registry DI

Use the default registry for normal CLI / single-tenant apps — that’s still the simplest path. Reach for a custom registry only when you need: (a) per-tenant adapter overrides, (b) test isolation between parallel test cases, or (c) sandboxed runs that must not leak custom registrations into the rest of the process.

Multi-tenant Applications

Each tenant gets isolated adapter overrides:
def create_tenant_generator(tenant_id: str):
    # Each tenant gets their own registry
    registry = FrameworkAdapterRegistry()
    
    # Tenant-specific adapter configuration
    if tenant_id == "enterprise":
        registry.register("crewai", EnterpriseCrewAIAdapter)
    else:
        registry.register("crewai", StandardCrewAIAdapter)
    
    return AgentsGenerator(
        agent_file=f"tenants/{tenant_id}/agents.yaml",
        framework="crewai",
        config_list=[...],
        adapter_registry=registry
    )

Test Isolation

Parallel tests don’t interfere with each other:
def test_custom_adapter():
    test_registry = FrameworkAdapterRegistry()
    test_registry.register("crewai", MockCrewAIAdapter)
    
    generator = AgentsGenerator(
        agent_file="test_agents.yaml", 
        framework="crewai",
        config_list=[...],
        adapter_registry=test_registry
    )
    # Test runs in isolation

Sandboxed Runs

Experimental adapters don’t leak into other processes:
def experiment_with_adapter():
    experiment_registry = FrameworkAdapterRegistry()
    experiment_registry.register("experimental", ExperimentalAdapter)
    
    # This won't affect other parts of the application
    return AgentsGenerator(
        adapter_registry=experiment_registry,
        framework="experimental",
        # ...
    )

Best Practices

Library code should accept registries as parameters rather than directly accessing defaults:
# ✅ Good - accepts registry parameter
def process_with_framework(framework: str, registry: FrameworkAdapterRegistry):
    adapter = registry.create(framework)
    return adapter.run(...)

# ❌ Bad - hardcoded to default
def process_with_framework(framework: str):
    from praisonai.framework_adapters.registry import get_default_registry
    registry = get_default_registry()
    adapter = registry.create(framework)
    return adapter.run(...)
Don’t share a custom registry across threads without understanding what you’ve registered:
# ✅ Safe - each thread gets its own registry
def worker_thread():
    thread_registry = FrameworkAdapterRegistry()
    thread_registry.register("crewai", ThreadSpecificAdapter)
    # ...

# ⚠️ Careful - shared registry needs thread-safe adapters
shared_registry = FrameworkAdapterRegistry()
def worker_thread():
    # Registry operations are thread-safe, but adapter classes may not be
    adapter = shared_registry.create("crewai")
Built-in plugins are loaded lazily; failures importing a single plugin do not break others:
registry = FrameworkAdapterRegistry()
registry.register("broken", BrokenAdapter)
registry.register("working", WorkingAdapter)

# This will work even if BrokenAdapter fails to load
working = registry.create("working")

Framework Adapter Plugins

Learn about extending PraisonAI with custom execution frameworks

Bot Platform Plugins

Add custom messaging platforms via entry points