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
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)
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:
| 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
Framework Adapter Registry API
Complete API reference for FrameworkAdapterRegistry
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
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
Handle Missing Dependencies Gracefully
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
Avoid Import-Time Failures
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
Implement Proper Resource Cleanup
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