> ## 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.

# Framework Adapter Plugins

> Extend PraisonAI with custom framework adapters via Python entry points

Framework adapter plugins enable third-party developers to add new execution frameworks to PraisonAI without modifying core code.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Framework Plugin System"
        A[📦 Third-party Package] --> B[🔌 Entry Point]
        B --> C[📝 Registry]
        C --> D[🚀 CLI Framework Selection]
    end
    
    classDef package fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef entrypoint fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef registry fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef cli fill:#10B981,stroke:#7C90A0,color:#fff
    
    class A package
    class B entrypoint
    class C registry
    class D cli
```

## Quick Start

<Steps>
  <Step title="Programmatic Registration">
    Register a framework adapter directly in your code:

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

    class MyFrameworkAdapter(BaseFrameworkAdapter):
        name = "myframework"
        
        def is_available(self) -> bool:
            try:
                import myframework
                return True
            except ImportError:
                return False
        
        def run(self, config, llm_config, topic):
            # Framework execution logic
            return "Framework execution result"
        
        def cleanup(self) -> None:
            # Optional cleanup
            pass

    # Register the adapter
    registry = FrameworkAdapterRegistry.get_instance()
    registry.register("myframework", MyFrameworkAdapter)
    ```
  </Step>

  <Step title="Entry Point Plugin">
    Create a pip-installable plugin using `pyproject.toml`:

    ```toml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # pyproject.toml
    [project]
    name = "myframework-praisonai"
    version = "1.0.0"

    [project.entry-points."praisonai.framework_adapters"]
    myframework = "myframework_praisonai.adapter:MyFrameworkAdapter"
    ```

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Use the framework after installation
    pip install myframework-praisonai
    praisonai --framework myframework agents.yaml
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant CLI
    participant Registry
    participant Plugin
    participant Framework
    
    User->>CLI: pip install plugin
    CLI->>Registry: Discover entry points
    Registry->>Plugin: Load adapter class
    Plugin-->>Registry: Register framework
    User->>CLI: praisonai --framework myframework agents.yaml
    CLI->>Registry: get_adapter("myframework")
    Registry->>Plugin: create() instance
    Plugin->>Framework: run(config, llm_config, topic)
    Framework-->>User: Execution result
```

The framework adapter registry provides a central point for managing framework implementations:

| Operation    | Description                                       | When Called             |
| ------------ | ------------------------------------------------- | ----------------------- |
| Discovery    | Entry points auto-loaded on first registry access | Import time             |
| Registration | Adapters registered by name                       | Plugin installation     |
| Creation     | Adapter instances created on demand               | CLI framework selection |
| Availability | Framework dependencies checked                    | Before execution        |

***

## Configuration

<Card title="Framework Adapter Registry API" icon="code" href="/docs/sdk/reference/python/modules/framework_adapters.registry">
  Complete API reference for FrameworkAdapterRegistry
</Card>

### Registry Methods

| Method                          | Parameters                                           | Description                       |
| ------------------------------- | ---------------------------------------------------- | --------------------------------- |
| `get_instance()`                | None                                                 | Get singleton registry instance   |
| `register(name, adapter_class)` | `name: str`, `adapter_class: Type[FrameworkAdapter]` | Register new adapter              |
| `unregister(name)`              | `name: str`                                          | Remove adapter by name            |
| `create(name)`                  | `name: str`                                          | Create adapter instance           |
| `list_registered()`             | None                                                 | List all registered adapter names |
| `is_available(name)`            | `name: str`                                          | Check if adapter is functional    |

### Adapter Protocol

Framework adapters must implement the `FrameworkAdapter` protocol:

| Method                           | Required | Description                  |
| -------------------------------- | -------- | ---------------------------- |
| `name`                           | ✅        | Unique framework identifier  |
| `is_available()`                 | ✅        | Check framework dependencies |
| `run(config, llm_config, topic)` | ✅        | Execute framework logic      |
| `cleanup()`                      | ✅        | Clean up resources           |

***

## Common Patterns

### Override Built-in Adapter

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

class CustomCrewAIAdapter(BaseFrameworkAdapter):
    name = "crewai"
    
    def is_available(self) -> bool:
        try:
            import crewai
            return True
        except ImportError:
            return False
    
    def run(self, config, llm_config, topic):
        # Custom CrewAI execution logic
        return "Custom CrewAI result"

# Override built-in CrewAI adapter
registry = FrameworkAdapterRegistry.get_instance()
registry.register("crewai", CustomCrewAIAdapter)
```

### Subprocess Framework Wrapper

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import subprocess
from praisonai.framework_adapters.base import BaseFrameworkAdapter

class NonPythonAdapter(BaseFrameworkAdapter):
    name = "external_framework"
    
    def is_available(self) -> bool:
        try:
            subprocess.run(["external_framework", "--version"], 
                         capture_output=True, check=True)
            return True
        except (subprocess.CalledProcessError, FileNotFoundError):
            return False
    
    def run(self, config, llm_config, topic):
        # Convert config to external format
        cmd = ["external_framework", "run", "--topic", topic]
        result = subprocess.run(cmd, capture_output=True, text=True)
        return result.stdout
```

### Conditional Dependencies

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import logging
from praisonai.framework_adapters.base import BaseFrameworkAdapter

logger = logging.getLogger(__name__)

class OptionalDepsAdapter(BaseFrameworkAdapter):
    name = "advanced_framework"
    
    def is_available(self) -> bool:
        try:
            # Check multiple optional dependencies
            import advanced_framework
            import optional_plugin
            return True
        except ImportError as e:
            logger.debug(f"Framework not available: {e}")
            return False
    
    def run(self, config, llm_config, topic):
        if not self.is_available():
            raise RuntimeError("Framework dependencies not installed")
        
        import advanced_framework
        return advanced_framework.execute(config, llm_config, topic)
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Handle Missing Dependencies Gracefully">
    Always implement defensive `is_available()` checks:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    def is_available(self) -> bool:
        try:
            # Check all required dependencies
            import required_framework
            import optional_dependency
            
            # Verify minimum versions if needed
            if hasattr(required_framework, 'version'):
                version = required_framework.version
                if version < (1, 0, 0):
                    return False
            
            return True
        except ImportError:
            # Log debug info, don't raise
            logging.getLogger(__name__).debug(
                "Framework dependencies not available"
            )
            return False
    ```
  </Accordion>

  <Accordion title="Avoid Import-Time Failures">
    Don't import heavy dependencies at module level:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # ❌ Bad - imports at module level
    import heavy_framework
    from expensive.module import Component

    class BadAdapter(BaseFrameworkAdapter):
        pass

    # ✅ Good - lazy imports
    class GoodAdapter(BaseFrameworkAdapter):
        def run(self, config, llm_config, topic):
            # Import only when needed
            import heavy_framework
            from expensive.module import Component
            return heavy_framework.run(config)
    ```
  </Accordion>

  <Accordion title="Use Structured Logging">
    Log framework events for debugging:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    import logging
    from praisonai.framework_adapters.base import BaseFrameworkAdapter

    class LoggingAdapter(BaseFrameworkAdapter):
        def __init__(self):
            super().__init__()
            self.logger = logging.getLogger(__name__)
        
        def run(self, config, llm_config, topic):
            self.logger.info(f"Starting {self.name} execution for topic: {topic}")
            try:
                result = self._execute_framework(config, llm_config, topic)
                self.logger.info(f"Execution completed successfully")
                return result
            except Exception as e:
                self.logger.error(f"Framework execution failed: {e}")
                raise
    ```
  </Accordion>

  <Accordion title="Implement Proper Resource Cleanup">
    Always clean up resources in the `cleanup()` method:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    class ResourceAwareAdapter(BaseFrameworkAdapter):
        def __init__(self):
            super().__init__()
            self._connections = []
            self._temp_files = []
        
        def run(self, config, llm_config, topic):
            # Create resources during execution
            conn = self._create_connection()
            self._connections.append(conn)
            
            temp_file = self._create_temp_file()
            self._temp_files.append(temp_file)
            
            # Use resources...
            return result
        
        def cleanup(self) -> None:
            # Close connections
            for conn in self._connections:
                try:
                    conn.close()
                except Exception:
                    pass
            
            # Clean up temp files
            for temp_file in self._temp_files:
                try:
                    temp_file.unlink()
                except Exception:
                    pass
            
            self._connections.clear()
            self._temp_files.clear()
    ```
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Plugin Development" icon="plug" href="/docs/features/plugins">
    Learn about PraisonAI's plugin system for tools and hooks
  </Card>

  <Card title="CrewAI Integration" icon="users" href="/docs/framework/crewai">
    See how built-in framework adapters are implemented
  </Card>
</CardGroup>
