Documentation
Everything you need to get started with Kai Browser
Creating Extensions
Using AI to Build Extensions
Kai Browser's unique feature is AI-powered extension creation. Simply describe what
you want your extension to do, and the AI will generate the Python code for you.
Example: Creating a Dark Mode Extension
Instead of writing code, you would prompt the AI with:
"Create a Kai Browser extension that adds a dark mode toggle button to the toolbar.
When enabled, it should invert the colors of all websites and persist the setting
across browser sessions. Make sure images and videos display correctly."
The AI will generate a complete Python module that:
- Inherits from KaiModule
- Adds a toolbar button with dark mode icon
- Injects CSS to apply dark mode styling
- Saves your preference using the preferences API
- Reapplies dark mode on every page load
Tip: The more specific your prompt, the better the result. Include details like:
what it should do, where buttons should appear, what should be saved, and any special behavior.
Extension Structure
Extensions are Python files that inherit from KaiModule:
from PyQt6.QtGui import QAction
from kai_base import KaiModule
class MyExtension(KaiModule):
"""Your extension description"""
def __init__(self):
super().__init__()
# Initialize your variables
self.my_setting = False
def setup(self):
"""Setup toolbar buttons and connect signals"""
# Add a toolbar button
action = QAction("🔧 My Tool", self.browser_core)
action.triggered.connect(self.my_function)
self.add_toolbar_action(action)
# Connect to page load event
self.connect_signal(
self.browser_core.page_loaded,
self.on_page_loaded
)
def on_page_loaded(self, url):
"""Called when a page loads"""
print(f"Page loaded: {url}")
def my_function(self):
"""Your custom function"""
self.browser_core.show_status("Action triggered!")
def on_enabled(self):
"""Called when module is enabled"""
pass
def on_disabled(self):
"""Called when module is disabled"""
pass
Uploading to Marketplace
- Sign in to your account
- Go to Upload Extension
- Fill in the details (name, description, category)
- Upload your .py file
- Submit for review
Review Time: Extensions are typically reviewed within 24-48 hours.
API Reference
Base Module Class
All extensions must inherit from KaiModule:
from kai_base import KaiModule
class MyExtension(KaiModule):
pass
Lifecycle Methods
__init__(self)
Called when the extension is first loaded. Always call super().__init__() first.
def __init__(self):
super().__init__()
self.my_variable = "value"
setup(self)
Called to set up toolbar actions and connect signals.
def setup(self):
action = QAction("Button Text", self.browser_core)
action.triggered.connect(self.my_function)
self.add_toolbar_action(action)
on_page_loaded(self, url)
Called whenever a new page is loaded. Must connect this signal in setup().
def setup(self):
self.connect_signal(
self.browser_core.page_loaded,
self.on_page_loaded
)
def on_page_loaded(self, url):
print(f"Loaded: {url}")
on_enabled(self)
Called when the extension is enabled by the user.
def on_enabled(self):
# Restore state or reapply changes
pass
on_disabled(self)
Called when the extension is disabled by the user.
def on_disabled(self):
# Clean up or remove changes
pass
Available Browser APIs
Toolbar Actions
# Add a toolbar button
from PyQt6.QtGui import QAction
action = QAction("🔧 Tool Name", self.browser_core)
action.setCheckable(True) # Optional: make it toggleable
action.triggered.connect(self.my_function)
self.add_toolbar_action(action)
JavaScript Injection
# Inject JavaScript into current page
js_code = """
document.body.style.backgroundColor = 'red';
"""
self.browser_core.inject_javascript(js_code)
Status Messages
# Show status message to user
self.browser_core.show_status("Action completed!")
Signal Connections
# Connect to page load event
self.connect_signal(
self.browser_core.page_loaded,
self.on_page_loaded
)
Preferences (Persistent Storage)
# Save a preference
self.set_preference("setting_name", True)
# Load a preference
value = self.get_preference("setting_name", default_value)
Complete Example: Dark Mode
from PyQt6.QtGui import QAction
from kai_base import KaiModule
class DarkModeModule(KaiModule):
"""Apply dark mode styling to all websites"""
def __init__(self):
super().__init__()
self.dark_mode_enabled = False
self.dark_css = """
html {
background-color: #1a1a1a !important;
filter: invert(0.9) hue-rotate(180deg);
}
img, video {
filter: invert(1) hue-rotate(180deg);
}
"""
def setup(self):
# Add toolbar button
self.dark_action = QAction("🌙 Dark Mode", self.browser_core)
self.dark_action.setCheckable(True)
self.dark_action.triggered.connect(self.toggle_dark_mode)
self.add_toolbar_action(self.dark_action)
# Connect to page load
self.connect_signal(
self.browser_core.page_loaded,
self.on_page_loaded
)
# Load saved state
self.dark_mode_enabled = self.get_preference(
"dark_mode_active", False
)
self.dark_action.setChecked(self.dark_mode_enabled)
def toggle_dark_mode(self):
self.dark_mode_enabled = not self.dark_mode_enabled
self.set_preference("dark_mode_active", self.dark_mode_enabled)
if self.dark_mode_enabled:
self.apply_dark_mode()
else:
self.remove_dark_mode()
def apply_dark_mode(self):
js = f"""
let style = document.createElement('style');
style.id = 'dark-mode-style';
style.textContent = `{self.dark_css}`;
document.head.appendChild(style);
"""
self.browser_core.inject_javascript(js)
def remove_dark_mode(self):
js = """
let style = document.getElementById('dark-mode-style');
if (style) style.remove();
"""
self.browser_core.inject_javascript(js)
def on_page_loaded(self, url):
if self.enabled and self.dark_mode_enabled:
self.apply_dark_mode()