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.

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

Quick Start

1

Programmatic Registration

Register a framework adapter directly in your code:
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)
2

Entry Point Plugin

Create a pip-installable plugin using pyproject.toml:
# pyproject.toml
[project]
name = "myframework-praisonai"
version = "1.0.0"

[project.entry-points."praisonai.framework_adapters"]
myframework = "myframework_praisonai.adapter:MyFrameworkAdapter"
# Use the framework after installation
pip install myframework-praisonai
praisonai --framework myframework agents.yaml

How It Works

The framework adapter registry provides a central point for managing framework implementations:
OperationDescriptionWhen Called
DiscoveryEntry points auto-loaded on first registry accessImport time
RegistrationAdapters registered by namePlugin installation
CreationAdapter instances created on demandCLI framework selection
AvailabilityFramework dependencies checkedBefore execution

Configuration

Framework Adapter Registry API

Complete API reference for FrameworkAdapterRegistry

Registry Methods

MethodParametersDescription
get_instance()NoneGet singleton registry instance
register(name, adapter_class)name: str, adapter_class: Type[FrameworkAdapter]Register new adapter
unregister(name)name: strRemove adapter by name
create(name)name: strCreate adapter instance
list_registered()NoneList all registered adapter names
is_available(name)name: strCheck if adapter is functional

Adapter Protocol

Framework adapters must implement the FrameworkAdapter protocol:
MethodRequiredDescription
nameUnique 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

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

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

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

Always implement defensive is_available() checks:
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
Don’t import heavy dependencies at module level:
# ❌ 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)
Log framework events for debugging:
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
Always clean up resources in the cleanup() method:
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()

Plugin Development

Learn about PraisonAI’s plugin system for tools and hooks

CrewAI Integration

See how built-in framework adapters are implemented