Extensions - Capsize-Games/airunner GitHub Wiki
AI Runner Plugin System
AI Runner supports custom plugins that extend functionality through widgets, background services, or signal-based behavior.
To install a plugin, place it in the extensions
directory located in the AI Runner base path. You can find the base path location in the Settings documentation.
βββ [AI Runner Base Path]/extensions
βββ extension_folder
Writing a Custom Plugin
Each plugin must define a Plugin
class that inherits from BasePlugin
, and optionally, a custom widget class that inherits from BaseWidget
.
Here's a basic example of a plugin that adds a simple logging widget:
from PySide6.QtWidgets import QWidget, QTextEdit, QVBoxLayout, QPushButton
from airunner.widgets.base_widget import BaseWidget
from airunner.base_plugin import BasePlugin
from airunner.enums import SignalCode
class LoggerWidget(BaseWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.layout = QVBoxLayout(self)
self.text_area = QTextEdit()
self.log_button = QPushButton("Log Message")
self.layout.addWidget(self.text_area)
self.layout.addWidget(self.log_button)
self.log_button.clicked.connect(self.log_message)
def log_message(self):
message = self.text_area.toPlainText()
if message:
print(f"[LoggerPlugin] {message}")
self.emit_signal(SignalCode.LOG_EVENT, {"message": message})
class Plugin(BasePlugin):
name = "Logger"
version = "1.0.0"
airunner_version = ">=3.3.0"
def get_widget(self) -> QWidget:
return LoggerWidget()
Notes
The Plugin class must define:
name
: The plugin's display name.version
: Your plugin's version.airunner_version
: The minimum compatible version of AI Runner.get_widget()
: Optional. Returns a QWidget to display in the interface.
You can use emit_signal(SignalCode.YOUR_SIGNAL, data) from BaseWidget to communicate with other parts of the application.
Place any assets, UI files, or helpers in the same plugin folder as needed.
Advanced Plugin Features
Plugin Directory Structure
Each plugin must reside in the extensions
directory within the AI Runner base path. Example structure:
[AI Runner Base Path]/extensions
βββ my_plugin
β βββ __init__.py
β βββ plugin.py
β βββ assets/
β βββ helpers.py
Plugin Configuration
name
: Display name of the plugin.version
: Plugin version.airunner_version
: Minimum compatible version of AI Runner.get_widget()
: Optional method to return a QWidget for the interface.
Signal Communication
Plugins can emit signals to communicate with other parts of the application. Example:
self.emit_signal(SignalCode.LOG_EVENT, {"message": "Plugin initialized"})
Debugging Plugins
- Use the
--debug
flag when running AI Runner to enable verbose logging for plugins. - Check logs in the
logs/
directory for detailed error messages.
Example Plugin
Hereβs a basic example of a plugin that logs messages:
from PySide6.QtWidgets import QWidget, QTextEdit, QVBoxLayout, QPushButton
from airunner.widgets.base_widget import BaseWidget
from airunner.base_plugin import BasePlugin
from airunner.enums import SignalCode
class LoggerWidget(BaseWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.layout = QVBoxLayout(self)
self.text_area = QTextEdit()
self.log_button = QPushButton("Log Message")
self.layout.addWidget(self.text_area)
self.layout.addWidget(self.log_button)
self.log_button.clicked.connect(self.log_message)
def log_message(self):
message = self.text_area.toPlainText()
if message:
print(f"[LoggerPlugin] {message}")
self.emit_signal(SignalCode.LOG_EVENT, {"message": message})
class Plugin(BasePlugin):
name = "Logger"
version = "1.0.0"
airunner_version = ">=3.3.0"
def get_widget(self) -> QWidget:
return LoggerWidget()