Automation Extension
Built-in extension ID: @chaton/automation
The automation extension lets users create rules that trigger actions when events occur in Chatons.
What It Does
An automation rule consists of:
| Field | Type | Description |
|---|---|---|
id | string | Unique rule identifier |
name | string | Human-readable rule name |
enabled | boolean | Whether the rule is active |
trigger_topic | string | Event topic that triggers this rule |
conditions_json | JSON | Optional conditions to match against the event payload |
actions_json | JSON | One or more actions to execute |
cooldown_ms | number | Minimum milliseconds between executions |
last_triggered_at | string | Timestamp of last execution |
User-Facing Features
The extension adds to the Chatons UI:
- Sidebar entry: "Automations" (icon:
Gauge, order: 10) - Main view:
automation.main-- a full-page automation management screen - Quick action:
automation.create-- opens the create-automation flow
In the automation screen, users can:
- List existing rules
- Create new rules in a modal dialog
- View recent execution history
- Delete rules (double-click)
- Switch between light and dark themes
Trigger Topics
The runtime validates triggers against a fixed allowlist. Current supported triggers:
| Topic | When Fired |
|---|---|
conversation.created | A new conversation is created |
conversation.message.received | A new message is received in a conversation |
project.created | A new project is imported |
conversation.agent.ended | The AI finishes processing a conversation turn |
extension.event | Any extension-published event occurs |
extension.{name} | A specific extension event (e.g., extension.user_created) occurs |
Rules with any other trigger topic are rejected on save.
:::info Extension events allow third-party extensions to publish custom events that can trigger automations. See the Extension Events section below for details. :::
Action Types
notify
Shows a host notification.
{
"type": "notify",
"title": "Automation Alert",
"body": "A new conversation was created."
}
If title or body are omitted, they are derived from the event topic and payload.
executeAndNotify
Runs an instruction through an ephemeral Pi session and sends the result as a notification.
{
"type": "executeAndNotify",
"title": "Summary",
"instruction": "Summarize the latest conversation message.",
"model": "openai/gpt-4o"
}
The instruction is executed in a temporary conversation that is created and cleaned up automatically. If a model key is provided, the Pi session uses that model.
enqueueEvent
Publishes an item into the extension queue system for downstream processing.
{
"type": "enqueueEvent",
"topic": "export-jobs",
"payload": { "format": "markdown" }
}
runHostCommand
Calls a host method from a narrow allowlist:
notifications.notifyopen.mainView
Any other method is rejected.
{
"type": "runHostCommand",
"method": "notifications.notify",
"params": { "title": "Alert", "body": "Something happened." }
}
setConversationTag
Currently a no-op placeholder. Accepted by the runtime but does not apply any tag mutation.
Conditions
Rules can include conditions evaluated against the event payload.
Supported Operators
| Operator | Behavior |
|---|---|
equals | Exact match: payload[field] === value |
contains | Substring match: payload[field].includes(value) (both must be strings) |
Limitations
- Conditions evaluate only top-level fields in the event payload
- Nested object paths are not supported
- Malformed or unsupported conditions fail conservatively (rule does not fire)
Example
[
{ "field": "projectId", "operator": "equals", "value": "my-project-uuid" }
]
Cooldown
Each rule has a cooldown_ms field (milliseconds).
When an event matches a rule:
- Check
last_triggered_at - If the cooldown window has not elapsed, skip the rule
- Otherwise execute the rule and update
last_triggered_at
LLM-Callable Tools
The extension exposes two tools that the AI can call during conversations:
automation.schedule_task
Create or update an automation rule from natural language.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | Rule name (derived from instruction if omitted) |
instruction | string | Yes | Natural-language task description |
trigger | string | No | Trigger topic (inferred from instruction if omitted) |
cooldown | number | No | Cooldown in ms (inferred from instruction if omitted) |
projectId | string | No | Target project ID |
modelKey | string | No | Model to use (e.g. openai/gpt-4o) |
notifyMessage | string | No | Custom notification message |
id | string | No | Existing rule ID to update |
conditions | array | No | Condition array |
enabled | boolean | No | Whether the rule is enabled |
When called by the AI, this creates a rule with a default notify action carrying the instruction text, or an executeAndNotify action if a model key is provided.
automation.list_scheduled_tasks
Returns existing rules so the AI can inspect them before creating or modifying.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum number of rules to return |
Extension APIs
Exposed via the manifest apis.exposes and handled in electron/extensions/runtime/automation.ts:
| API Name | Purpose |
|---|---|
automation.rules.list | List all automation rules |
automation.rules.save | Create or update a rule |
automation.rules.delete | Delete a rule by ID |
automation.runs.list | List execution history |
automation.schedule_task | Create/update rule (LLM-callable version) |
automation.list_scheduled_tasks | List rules (LLM-callable version) |
Persistence
Automation state is stored in the Chatons SQLite database.
automation_rules table
| Column | Type | Description |
|---|---|---|
id | TEXT PK | Rule identifier |
name | TEXT | Rule name |
enabled | INTEGER | 0 or 1 |
trigger_topic | TEXT | Event topic |
conditions_json | TEXT | JSON array of conditions |
actions_json | TEXT | JSON array of actions |
cooldown_ms | INTEGER | Cooldown in milliseconds |
last_triggered_at | TEXT | ISO timestamp of last trigger |
created_at | TEXT | ISO creation timestamp |
updated_at | TEXT | ISO update timestamp |
automation_runs table
| Column | Type | Description |
|---|---|---|
id | TEXT PK | Run identifier |
rule_id | TEXT | Associated rule ID |
event_topic | TEXT | Event that triggered this run |
event_payload_json | TEXT | Serialized event payload |
status | TEXT | success or error |
error_message | TEXT | Error message (if failed) |
created_at | TEXT | ISO timestamp |
Implementation Files
| File | Purpose |
|---|---|
electron/extensions/builtin/automation/chaton.extension.json | Extension manifest |
electron/extensions/builtin/automation/index.html | UI entry point |
electron/extensions/builtin/automation/index.js | UI logic (plain JavaScript) |
electron/extensions/builtin/automation/components.js | Shared UI components |
electron/extensions/runtime/automation.ts | Backend: rule evaluation, action execution |
electron/extensions/runtime/automation-pi-bridge.ts | Ephemeral Pi session executor for executeAndNotify |
electron/db/repos/automation.ts | Database operations for rules and runs |
The UI is self-contained plain HTML/JS (not compiled React). It uses the injected Chatons UI helpers (window.chatonExtensionComponents, window.chatonUi.createModelPicker()). It is the primary reference implementation for building native-looking extension UIs.
Translation
The automation extension owns its own labels. Chatons renders extension-provided strings as-is -- the host does not auto-translate extension labels. If you localize an extension, handle translation within the extension.
Scope and Limitations
The automation system is intentionally simple. Do not document it as a full workflow engine.
Current limitations:
- Fixed trigger allowlist (4 topics)
- Simple condition matching (top-level fields only, 2 operators)
- Narrow
runHostCommandallowlist (2 methods) setConversationTagis a no-op placeholder- Most LLM-scheduled tasks become notification-style rules unless a broader action is explicitly saved via the API
- The
executeAndNotifyaction creates ephemeral conversations that appear in the conversation list
Extension Events
Extensions can publish custom events that trigger automations, enabling powerful integration scenarios.
Publishing Events
Extensions with the events.publish capability can publish events using the automation.publish_extension_event API:
// Extension code example
const result = await window.chaton.extensionCall(
'@chaton/automation',
'automation.publish_extension_event',
{
eventName: 'user_created',
payload: {
userId: '123',
name: 'John Doe',
email: 'john@example.com'
}
}
);
if (result.ok) {
console.log('Event published successfully');
} else {
console.error('Failed to publish event:', result.error.message);
}
Event Name Format
Event names must follow these rules:
- Allowed characters:
a-z,A-Z,0-9,_,- - Maximum length: 100 characters
- Examples:
user_created,file_uploaded,data_processed - Invalid:
user created(spaces),user!created(special chars)
When published, an event named my_event creates the topic extension.my_event.
Triggering Automations
There are two ways to trigger automations from extension events:
1. Specific Event Trigger
Create a rule with trigger extension.my_event to respond only to that specific event.
Example Automation Rule:
{
"name": "Notify on user creation",
"trigger": "extension.user_created",
"actions": [
{
"type": "notify",
"title": "New User Created",
"body": "User {{userId}} was created"
}
]
}
2. Generic Extension Trigger
Create a rule with trigger extension.event to respond to any extension event, then use conditions to filter:
Example with Conditions:
{
"name": "Log important events",
"trigger": "extension.event",
"conditions": [
{"field": "priority", "operator": "equals", "value": "high"}
],
"actions": [
{
"type": "executeAndNotify",
"instruction": "Analyze this important event: {{eventType}}"
}
]
}
UI Integration
In the automation creation UI:
- Select "Evenement d'extension" from the trigger dropdown
- Enter your custom event name (e.g.,
user_created) - Configure the action to perform when the event occurs
- Save the automation rule
The event name field appears only when "Evenement d'extension" is selected and validates the format.
Use Cases
User Activity Tracking
// Extension publishes when user logs in
await publishExtensionAutomationEvent(
'@auth/extension',
'user_login',
{ userId: '123', timestamp: Date.now() }
);
// Automation sends notification to admin channel
File Processing
// Extension publishes when file processing completes
await publishExtensionAutomationEvent(
'@file/processor',
'file_processed',
{ file: 'document.pdf', status: 'completed' }
);
// Automation triggers follow-up analysis
System Monitoring
// Extension publishes health check results
await publishExtensionAutomationEvent(
'@system/monitor',
'health_check',
{ status: 'ok', cpu: 0.45, memory: 0.68 }
);
// Automation alerts on critical issues
API Reference
automation.publish_extension_event
Version: 1.0.0
Parameters:
{
eventName: string; // Name of the custom event
payload?: any; // Optional data to include
}
Returns:
{
ok: boolean;
data?: { success: true };
error?: {
code: string;
message: string;
};
}
Error Codes:
invalid_args: Event name format invalidevent_publication_failed: Failed to publish eventunauthorized: Extension not authorized to publish events
Best Practices
Event Naming:
- Use lowercase with underscores:
user_creatednotUserCreated - Be specific:
file_uploadednotevent - Include context:
payment_processednotprocessed
Payload Design:
- Keep payloads small (< 1KB recommended)
- Use simple JSON structures
- Avoid sensitive data
Automation Design:
- Use specific event triggers when possible
- Add conditions to filter events
- Set appropriate cooldowns to avoid flooding
Security
- Extensions must have
events.publishcapability - Event names are validated for allowed characters
- Standard automation cooldowns and rate limits apply