> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Registry Dependency Injection

> Inject custom plugin registries for multi-tenant isolation, sandboxed tests, or per-run overrides

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

agent = Agent(name="di-agent", instructions="Use dependency injection via the agent registry.")
agent.start("Resolve and inject the database service for this task.")
```

The user runs generation with a custom adapter registry so tenants or tests stay isolated.

Inject a custom adapter registry when you need tenant isolation, parallel test safety, or per-run plugin overrides.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.framework_adapters.registry import FrameworkAdapterRegistry
from praisonai.agents_generator import AgentsGenerator

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

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

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Default"
        A1[get_default_registry] --> R1[Shared Registry]
    end
    subgraph "Tenant A"
        A2[Custom Registry A] --> R2[Isolated Adapters]
    end
    subgraph "Tenant B"
        A3[Custom Registry B] --> R3[Isolated Adapters]
    end
    R1 --> G1[AgentsGenerator]
    R2 --> G2[AgentsGenerator tenant_a]
    R3 --> G3[AgentsGenerator tenant_b]

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef tool fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff

    class A1,A2,A3,G1,G2,G3 agent
    class R1,R2,R3 tool
```

## Quick Start

<Steps>
  <Step title="Simple Usage">
    Use the process-default registry for normal applications:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.agents_generator import AgentsGenerator

    # adapter_registry=None → uses get_default_registry()
    generator = AgentsGenerator("agents.yaml", "crewai", config_list=[...])
    ```
  </Step>

  <Step title="With Configuration">
    Inject a custom registry for tenant isolation or testing:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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,
    )
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant App
    participant Generator
    participant Registry
    participant Adapter

    App->>Generator: AgentsGenerator(adapter_registry=custom)
    Generator->>Registry: registry.create("crewai")
    Registry->>Adapter: CustomCrewAIAdapter()
    Adapter-->>Registry: adapter instance
    Registry-->>Generator: adapter
    Generator-->>App: generator ready
```

| Registry           | Module                                    | Docs                                                                  |
| ------------------ | ----------------------------------------- | --------------------------------------------------------------------- |
| Framework adapters | `praisonai.framework_adapters.registry`   | [Framework Adapter Plugins](/docs/features/framework-adapter-plugins) |
| Bot platforms      | `praisonai.bots._registry`                | [Bot Platform Plugins](/docs/features/bot-platform-plugins)           |
| Sandbox backends   | `praisonai.sandbox._registry`             | [Sandbox Backends](/docs/features/sandbox-backends)                   |
| Search providers   | `praisonai.cli.features._search_registry` | [Search Providers](/docs/features/search-provider-registry)           |

All plugin registries expose `Registry.default()` or `get_default_registry()` unless noted.

When a `SandboxConfig`'s `sandbox_type` is unknown to the built-in list, `SandboxManager` now resolves it through `praisonai.sandbox._registry` automatically — no manual `registry.resolve()` call is needed for typical use.

***

## Common Patterns

### Multi-tenant isolation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def create_tenant_generator(tenant_id: str):
    registry = FrameworkAdapterRegistry()
    adapter = EnterpriseCrewAIAdapter if tenant_id == "enterprise" else StandardCrewAIAdapter
    registry.register("crewai", adapter)

    return AgentsGenerator(
        agent_file=f"tenants/{tenant_id}/agents.yaml",
        framework="crewai",
        config_list=[...],
        adapter_registry=registry,
    )
```

### Test isolation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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,
    )
    # Parallel tests do not share registrations
```

### AutoGenerator with custom registry

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.auto import AutoGenerator

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

# The resolved adapter is retained after construction
print(auto._adapter.name)   # canonical dispatch object
print(auto.framework)       # authoritative name from adapter.name
```

After construction, `AutoGenerator` retains the resolved adapter as `self._adapter` (mirroring `AgentsGenerator.framework_adapter`), and `self.framework` is derived from `adapter.name` — the authoritative name, not the raw constructor argument. This is a stable observable side effect; the underscore prefix marks it private-by-convention, so treat the attribute name itself as an implementation detail.

### Injecting a tool-timeout executor

Like `adapter_registry=`, the `tool_timeout_executor=` constructor parameter lets you supply a shared thread-pool instead of letting each `AgentsGenerator` lazily create its own.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import concurrent.futures
from praisonai.agents_generator import AgentsGenerator

# One pool, many sessions
shared_pool = concurrent.futures.ThreadPoolExecutor(max_workers=16)

for cfg in tenant_configs:
    with AgentsGenerator(
        agent_file=cfg.path,
        framework=cfg.framework,
        config_list=cfg.llms,
        tool_timeout_executor=shared_pool,  # borrowed
    ) as gen:
        gen.generate_crew_and_kickoff()
```

The injected executor is treated as **borrowed** — `gen.close()` and exiting the `with` block will **not** shut it down. You stay responsible for `shared_pool.shutdown()`.

***

## Best Practices

<AccordionGroup>
  <Accordion title="Prefer DI in library code">
    Accept registries as parameters rather than calling defaults inside helpers:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Good — accepts registry parameter
    def process_with_framework(framework: str, registry: FrameworkAdapterRegistry):
        return registry.create(framework).run(...)

    # Risky — hardcoded to default
    def process_with_framework(framework: str):
        from praisonai.framework_adapters.registry import get_default_registry
        return get_default_registry().create(framework).run(...)
    ```
  </Accordion>

  <Accordion title="Give each thread its own registry">
    Registry operations are thread-safe, but adapter instances may not be. Prefer one registry per worker or test case.
  </Accordion>

  <Accordion title="Use the default registry for single-tenant CLI apps">
    Custom registries add complexity. Reach for DI only when you need tenant overrides, test isolation, or sandboxed experimental adapters.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Framework Adapter Plugins" icon="puzzle-piece" href="/docs/features/framework-adapter-plugins">
    Extend PraisonAI with custom execution frameworks
  </Card>

  <Card title="Bot Platform Plugins" icon="puzzle-piece" href="/docs/features/bot-platform-plugins">
    Add custom messaging platforms via entry points
  </Card>
</CardGroup>
