Automation & Workflows
Automation turns a trigger into an agent run. Aura Workshop gives you five ways to fire an agent without sitting in the chat box — cron-style schedules, chat listeners that watch messaging platforms, inbound webhooks, slash commands, and self-paced autonomous agents. Each trigger can run a local task, forward to a remote deployed agent, or kick off a workflow — the visual, DAG-based engine for multi-step pipelines with branching, retries, and human approvals.
background_deploy + target_agent_id — see
Deployment & Security.
Schedules
A schedule runs a task automatically on a recurring cadence. Create one under Settings → Automation → Schedules; each row shows the title, a preview of the prompt, its type, the next run time, and an enabled toggle.
Cadence & duration
Two independent settings control how often a schedule fires and how long it keeps firing:
| Field | Values | Effect |
|---|---|---|
| Schedule type | once · hourly · daily · weekly · cron | The cadence. weekly takes a set of days; cron takes a full cron expression for advanced timing. |
| Duration type | once · repeat_until · forever | When to stop: run a single time, repeat until an end date, or repeat indefinitely until disabled. |
What a schedule carries
Besides the prompt, a scheduled task can pin a specific model and role, an optional project path for context, and a schedule window. To run the task on a remote deployment instead of locally, set background_deploy = 1 and a target_agent_id.
background_deploy = 1. Two competing daemon containers can
never fire the same schedule twice: the runner does an atomic compare-and-swap on the
next-run time before claiming a job. Per-run output is written to
schedule_run_logs.
Chat listeners
A listener is a long-running subprocess that watches a chat platform and forwards inbound messages to the agent. Aura ships bridges for 31 platforms. Each runs its own Node bridge in a dedicated environment with the platform SDK pre-installed and speaks a small NDJSON protocol on its stdio; every inbound message flows through the manager, which applies rules, rate limits, slash interception, and finally an agent run — logging each step. Full per-platform setup and auth flows live in the Integrations guide.
Supported platforms (31)
| Category | Platforms |
|---|---|
| Team chat | Slack, Discord, Microsoft Teams, Google Chat, Feishu / Lark, Zulip, Rocket.Chat, Mattermost, Nextcloud Talk, Synology Chat |
| Messaging | Telegram, WhatsApp, Signal, iMessage (macOS), Facebook Messenger, WeChat, Zalo, LINE |
| Email (IMAP/SMTP), Gmail (API) | |
| Social | Twitter / X, Mastodon, Bluesky, Reddit, Twitch, Nostr |
| IRC / XMPP / Matrix | IRC, XMPP / Jabber, Matrix |
| Built-in web | WebChat, Chatbot widget |
Fetch the live list (with per-platform auth fields and QR requirements) via GET /api/listeners/platforms.
Auth
Credentials live in the listener's auth_config (encrypted at rest), in one of three shapes:
- Direct token — a bot token, API key, or app password you paste into the form. Stored encrypted; survives restarts.
- Composio-managed bot — only a
composio_connection_idis persisted. The live token is fetched at start time and injected in memory only, so revoking the connection immediately invalidates the listener. - Email OAuth — IMAP/Gmail listeners can use an OAuth connection instead of an app password; refresh happens in the background.
When a Composio-connected listener starts, it can auto-mount that toolkit's MCP server so the message-handling agent gets the bot's own tool surface (act as the bot). The mount is gated on a per-toolkit and a per-listener switch, both default-on, and is non-fatal if it fails.
Rules & rate limits
Before any agent run, an incoming message is filtered by the listener's rules and rate limits. A message that is dropped is never silently lost — it is written to the event log with status = "filtered".
| Rule | Effect |
|---|---|
respond_to_all | Skip sender/channel allowlists (blocklists and keyword/mention checks still apply). |
sender_allowlist / sender_blocklist | Restrict or bar specific senders. Add the bot's own id to the blocklist to stop reply loops. |
channel_allowlist / channel_blocklist | Restrict or bar specific channels. |
keyword_triggers | If non-empty, the message must contain one of the keywords. |
require_mention | The message must @-mention the bot. |
pairing_mode | Require approval for new senders. |
Each listener also carries rate_limit_per_minute and rate_limit_per_hour fixed-window counters; over the limit, the message is dropped and logged as filtered with error_message = "Rate limited".
Conversation context & behaviour
When a listener's context_window > 0, the runner replays recent event-log rows
scoped to the sender as prior turns, so each client keeps an isolated thread. For the
durable full-task path, an IM binding maps
(listener, channel, thread) → task so a Slack thread or Discord channel stays
attached to one task across many messages.
Agent capability depends on the listener and platform:
| Condition | Behaviour |
|---|---|
agent_interaction = true | Full tools, multi-turn, no turn cap — behaves like the chat box. |
| WebChat / Chatbot, tools enabled (default) | Full agent, no turn cap. |
| WebChat / Chatbot, tools disabled | Single turn, no tools. |
| Any other messaging platform | Single turn, no tools, plain-text-only replies (kept snappy). |
Creating & running a listener
- Create the row (Settings → Automation → Listeners, or
POST /api/listeners) with platform,auth_config, rules, agent prompt, rate limits,context_window, and optional model / schedule window /target_agent_id. - Start it. The manager provisions the platform's environment if needed, spawns the bridge, and sends its configuration.
- QR-based platforms (e.g. WhatsApp) emit an auth-QR event — scan it to link, and the listener transitions to running.
An optional schedule window (start/end time and days) restricts when a listener is active. In daemon deployments, listeners with background_deploy = 1 auto-start shortly after boot.
Webhooks
A webhook lets an external service trigger an agent over HTTP. The inbound webhook server listens on port 18790 — separate from the 18800 API server. Each webhook has a unique URL path and an optional secret; the request body is fed to the agent as input, and the agent's answer is returned in the HTTP 200 response body.
Create / edit form
- Name — a descriptive label; the endpoint URL is generated for you.
- Agent prompt — a template describing what to do when the webhook fires. Reference the incoming request body with
{{payload}}. - Secret — an optional shared secret, verified constant-time via an
x-webhook-secretorAuthorizationheader. - Model / Role / Project path — pin the model, assign a role, and set a working directory for the triggered task.
- Target agent — with
background_deploy = 1+ atarget_agent_id, the request is forwarded to a remote deployed agent.
The detail view shows the endpoint URL with a copy button, a table of recent invocations (method, headers, body, response, status), and a ready-to-run cURL example. Every call is persisted to webhook_logs.
Slash commands
A leading /cmd args in an inbound message is intercepted as a slash command
before it reaches the agent. Built-ins are handled directly; anything else is looked up in the
custom-command table. Slash commands work from listeners and from the
Dashboard / Multi-Agent composers (type / for a typeahead).
Built-in commands
| Command | What it does |
|---|---|
/help | List available commands. |
/status | Show agent and system status. |
/stop | Stop the current running task. |
/tasks | List recent tasks. |
/skills | List available skills. |
/roles | List available roles. |
/role <name> | Switch agent role (/role reset to clear). |
/run <skill> [args] | Execute a skill. |
/workflow <name> | Trigger a workflow. |
/schedule | List and manage schedules. |
Custom commands
Custom rows define a name, description, a handler_type of agent_task | workflow | skill | builtin, the platforms it applies to, and access control. An empty allowed_senders allowlist permits everyone; otherwise the sender must be listed.
POST /api/slash-commands
{
"name": "deploy",
"handler_type": "workflow",
"handler_config": { "workflow": "deploy-workflow-id" },
"platforms": ["slack"],
"access_control": { "allowed_senders": ["@alice"] }
}
Workflows
For multi-step automation with branching, approvals, and retries, use the visual Workflow editor — a canvas where you drag typed nodes, wire them into a directed acyclic graph, and run. Each node reads the outputs of its predecessors through a shared workflow context, and the engine detects independent branches and runs them in parallel.
Node types
The workflow engine ships the following node types, grouped by how they execute:
| Node | Mode | Behaviour |
|---|---|---|
| agent-task | instant | Run an agent with predecessor context and full tools. Detects clarifying questions and pauses for input. |
| human-in-the-loop | async | Create an approval request and wait for resolve or timeout. |
| validate | instant | JSON-schema or LLM-based validation; routes pass / fail. |
| webhook | instant | HTTP request (GET/POST/PUT/PATCH/DELETE) with interpolated context. |
| conditional | instant | Evaluate an expression (==, !=, >, contains, is_empty, exists); routes true / false. |
| script | instant | Run a bash / python / node / go subprocess with a timeout and working directory. |
| transform | instant | Reshape data with a JavaScript or Python expression over the workflow context. |
| delay | instant | Sleep for a set duration (capped at 30 minutes). |
| fan-out | instant | Extract an array and fan parallel sub-workflows, one per item. |
| merge | instant | Combine predecessor outputs; performs a file-level workspace merge on conflict. |
| team | instant | Run a multi-agent team as a single nested step. |
| acp_delegate | instant | Pin the step to a specific ACP peer. |
| acp_route | instant | Auto-route the step via a pool policy (best-fit / round-robin / lowest-load). |
| acp_fanout | instant | Run the step in parallel across all enabled ACP peers. |
| acp_debate | instant | Structured multi-round debate/roundtable across ACP peers (moderator optional). |
Retries & routing ports
Every node can carry a retry policy: a maximum retry count and a strategy of exponential, linear, or static backoff (default 3 attempts, exponential, 5s base capped at 60s). Nodes expose routing ports — a success path and a failure path — so validate and conditional can branch execution to different downstream handlers.
Human-in-the-loop approvals
The human-in-the-loop node pauses the run and opens an approval request with a title, description, and options. The run enters a waiting state until a human approves or rejects — or the request times out — then resumes down the matching port. Use it as a gate before any irreversible or customer-facing step (for example, before a support listener actually sends a drafted reply).
Runtime guarantees
- Idempotency — each step carries a unique idempotency key, so re-runs never double-execute a completed step.
- Crash recovery — on startup the engine rehydrates running runs from the database and re-checks waiting approvals; a retry poller re-executes failed steps whose next-retry time has arrived.
- Pause / resume — a running workflow can be paused and resumed at any time.
- Live tracking — each run records overall status (running / completed / failed / waiting) plus per-node status and the accumulated data context, streamed over SSE and viewable in Settings → Workflows.