FabricFabric
Automations

Automations Configuration Guide

This guide explains how to configure automations in Fabric Agent to automate workflows based on events.

This guide explains how to configure automations in Fabric Agent to automate workflows based on events.

What Are Automations?

Automations allow you to trigger actions automatically when specific events occur in Fabric Agent. You can:

  • Send prompts to create agent sessions based on events
  • Execute prompts on a schedule using cron expressions
  • Automate workflows based on permission mode changes, flags, or session status changes

automations.json Location

Automations are configured in automations.json at the root of your workspace:

~/.fabric-agent/workspaces/{workspaceId}/automations.json

Basic Structure

{
  "version": 2,
  "automations": {
    "EventName": [
      {
        "name": "Optional display name",
        "matcher": "regex-pattern",
        "actions": [
          { "type": "prompt", "prompt": "Check for updates and report status" }
        ]
      }
    ]
  }
}

Supported Events

App Events (triggered by Fabric Agent)

EventTriggerMatch Value
LabelAddLabel added to sessionLabel ID (e.g., bug, not Bug)
LabelRemoveLabel removed from sessionLabel ID (e.g., bug, not Bug)
LabelConfigChangeLabel configuration changedAlways matches
PermissionModeChangePermission mode changedNew mode name
FlagChangeSession flagged/unflaggedtrue or false
SessionStatusChangeSession status changedNew status (e.g., done, in_progress)
SchedulerTickRuns every minuteUses cron matching

Note: TodoStateChange is a deprecated alias for SessionStatusChange. Existing configs using the old name will continue to work but will show a deprecation warning during validation.

Agent Events (passed to Claude SDK)

EventTriggerMatch Value
PreToolUseBefore a tool executesTool name
PostToolUseAfter a tool executes successfullyTool name
PostToolUseFailureAfter a tool execution failsTool name
NotificationNotification received-
UserPromptSubmitUser submits a prompt-
SessionStartSession starts-
SessionEndSession ends-
StopAgent stops-
SubagentStartSubagent spawned-
SubagentStopSubagent completes-
PreCompactBefore context compaction-
PermissionRequestPermission requested-
SetupInitial setup-

Action Types

Prompt Actions

Send a prompt to Fabric Agent (creates a new session for scheduled prompts).

{
  "type": "prompt",
  "prompt": "Run the @weather skill and summarize the forecast"
}
PropertyTypeDefaultDescription
type"prompt"RequiredAction type
promptstringRequiredPrompt text to send
llmConnectionstringWorkspace defaultLLM connection slug (configured in AI Settings)
modelstringWorkspace defaultModel ID for the created session

Features:

  • Use @mentions to reference sources or skills
  • Environment variables are expanded (e.g., $FABRIC_LABEL)

LLM Connection & Model: Optionally specify which AI provider and model to use for the created session. If omitted, the workspace default connection and model are used.

{
  "type": "prompt",
  "prompt": "Quick code review of recent changes",
  "llmConnection": "my-copilot-connection",
  "model": "gemini-3-pro-preview"
}

The llmConnection value is the slug of an LLM connection configured in AI Settings. The model value is a model ID supported by the provider. If either is invalid or not found, it gracefully falls back to the workspace default. Both can be used independently or together.

Script Actions

Run a script that lives inside the workspace. Scripts are spawned directly (never through a shell), so arguments are passed as-is and nothing is interpolated.

{
  "type": "script",
  "script": "scripts/rotate-logs.ts",
  "args": ["--keep", "7"],
  "runtime": "bun",
  "timeoutMs": 60000
}
PropertyTypeDefaultDescription
type"script"RequiredAction type
scriptstringRequiredScript path relative to the workspace root
argsstring[][]Extra arguments appended after the script path
runtime"bun" | "node" | "python3""bun"Runtime used to execute the script
timeoutMsnumber60000Per-run timeout in milliseconds, clamped to 1 second – 15 minutes
pagestring–Slug of a page this script refreshes

How scripts run:

  • The script path must stay inside the workspace. Symlinks that escape it are rejected.
  • The working directory is the workspace root.
  • The child environment contains only FABRIC_* variables: the event context (FABRIC_EVENT plus the same fields webhook actions receive), FABRIC_WORKSPACE_PATH, and any FABRIC_* variables exported in the app's environment. PATH, credentials, and the rest of the process environment are never passed through.
  • A run that exceeds timeoutMs receives SIGTERM, then SIGKILL.
  • Runs of the same matcher never overlap. If a tick fires while the previous run is still going, the tick is skipped and recorded in history.
  • When page is set, the executor also injects FABRIC_PAGE_SLUG, FABRIC_PAGE_DIR, and FABRIC_PAGE_DATA_DIR, and records the outcome on the page so the app can show refresh failures.

Exit code, stdout, and stderr are captured in the automation history. A non-zero exit is recorded as a failure.

Action types are a strict set: prompt, webhook, and script. An unknown type fails validation and the whole automations.json is rejected, matching how other invalid configs are handled.

Matcher Configuration

Display Name

Use the optional name field to give an automation a human-readable display name. If omitted, the name is automatically derived from the first action.

{
  "name": "Morning Weather Report",
  "cron": "0 8 * * *",
  "actions": [
    { "type": "prompt", "prompt": "Run the @weather skill" }
  ]
}

Regex Matching (for most events)

Use the matcher field to filter which events trigger your automations:

{
  "matcher": "^urgent$",
  "actions": [
    { "type": "prompt", "prompt": "An urgent label was added. Review the session and summarise the issue." }
  ]
}

If matcher is omitted, the automation triggers for all events of that type.

Cron Matching (for SchedulerTick)

For SchedulerTick events, use cron expressions instead of regex:

{
  "cron": "0 9 * * 1-5",
  "timezone": "America/New_York",
  "actions": [
    { "type": "prompt", "prompt": "Give me a morning briefing" }
  ]
}

Cron format: minute hour day-of-month month day-of-week

FieldValues
Minute0-59
Hour0-23
Day of month1-31
Month1-12
Day of week0-6 (0 = Sunday)

Examples:

  • */15 * * * * - Every 15 minutes
  • 0 9 * * * - Daily at 9:00 AM
  • 0 9 * * 1-5 - Weekdays at 9:00 AM
  • 30 14 1 * * - 1st of each month at 2:30 PM

Timezone: Use IANA timezone names (e.g., Europe/Budapest, America/New_York). Defaults to system timezone if not specified.

Semantic Conditions

Matchers and conditions compare fields. A semanticCondition asks a yes/no question that the decision model answers before a prompt action starts a session:

{
  "matcher": "^needs-triage$",
  "semanticCondition": {
    "question": "Is the user reporting a bug or crash, rather than asking a question?",
    "threshold": 0.6
  },
  "actions": [{ "type": "prompt", "prompt": "Triage the bug in session $FABRIC_SESSION_NAME" }]
}
PropertyTypeDescription
questionstringRequired. The yes/no question, in English (max 500 characters).
thresholdnumber"Yes" probability needed to run, 0 < threshold <= 1. Default 0.5.
  • The model sees the event (name, automation name, payload fields) and, for session events, the session's name, labels, status and its latest user and assistant messages.
  • Below the threshold the run is skipped, and the automation history records it as skipped, not failed.
  • A matcher is judged once per event: all of its prompt actions run, or all are skipped.
  • Inert without the decision model — when it is off (or the Automation conditions switch is), unavailable or fails, the automation runs as it would without the condition.
  • It applies to prompt actions only; webhook and script actions are not gated.
  • With fabric-cli automation, set semanticCondition (and conditions, telegramTopic) through --json.

Loop guard

An automation never runs for an event about a session it created itself — its own prompt matching a label rule would otherwise re-trigger it forever — and a chain of automation-created sessions triggering further automations stops at three levels deep. Such runs are recorded as skipped.

Permission Mode

The permissionMode field controls the permission level of sessions created by prompt actions.

{
  "cron": "*/10 * * * *",
  "permissionMode": "allow-all",
  "actions": [
    { "type": "prompt", "prompt": "Check system health and log the results" }
  ]
}

Permission modes:

  • safe - Session runs in Explore mode (default)
  • ask - Session prompts for approval before write operations
  • allow-all - Session auto-approves all operations

Labels for Prompt Actions

Prompt actions can specify labels that will be applied to the session they create:

{
  "cron": "0 9 * * *",
  "labels": ["Scheduled", "morning-briefing"],
  "actions": [
    { "type": "prompt", "prompt": "Give me today's priorities" }
  ]
}

This creates a session with the "Scheduled" and "morning-briefing" labels applied automatically.

Complete Examples

Daily Weather Report

{
  "version": 2,
  "automations": {
    "SchedulerTick": [
      {
        "name": "Daily Weather Report",
        "cron": "0 8 * * *",
        "timezone": "Europe/Budapest",
        "labels": ["Scheduled", "weather"],
        "actions": [
          { "type": "prompt", "prompt": "Run the @weather skill and give me today's forecast" }
        ]
      }
    ]
  }
}

Log Label Changes

{
  "version": 2,
  "automations": {
    "LabelAdd": [
      {
        "actions": [
          { "type": "prompt", "prompt": "The label $FABRIC_LABEL was added. Log this change with a timestamp." }
        ]
      }
    ],
    "LabelRemove": [
      {
        "actions": [
          { "type": "prompt", "prompt": "The label $FABRIC_LABEL was removed. Log this change with a timestamp." }
        ]
      }
    ]
  }
}

Urgent Label Notification

{
  "version": 2,
  "automations": {
    "LabelAdd": [
      {
        "matcher": "^urgent$",
        "actions": [
          { "type": "prompt", "prompt": "An urgent label was added to this session. Triage the session and summarise what needs immediate attention." }
        ]
      }
    ]
  }
}

Permission Mode Change Notification

{
  "version": 2,
  "automations": {
    "PermissionModeChange": [
      {
        "matcher": "allow-all",
        "actions": [
          { "type": "prompt", "prompt": "The permission mode was changed to allow-all. Log the change and note any security implications." }
        ]
      }
    ]
  }
}

Validation

Automations are validated when:

  1. The workspace is loaded
  2. You edit automations.json (via PreToolUse hook)
  3. You run config_validate with target automations or all

Using config_validate:

Ask Fabric Agent to validate your automations configuration:

Validate my automations configuration

Or use the config_validate tool directly with target: "automations".

Common validation errors:

  • Invalid JSON syntax
  • Unknown event names
  • Empty actions array
  • Invalid cron expression
  • Invalid timezone
  • Invalid regex pattern
  • Potentially unsafe regex patterns (nested quantifiers)

To validate manually:

# Check automations.json syntax
cat automations.json | jq .

Rate Limits

To protect against runaway automations (e.g., an automation that indirectly triggers itself in a loop), the event bus enforces per-event-type rate limits:

EventMax fires / minute
SchedulerTick60 (1/sec)
All others (LabelAdd, FlagChange, PreToolUse, etc.)10

When a limit is hit, further events of that type are silently dropped for the remainder of the 60-second window. A warning is logged. The window resets automatically.

Example: If you have a LabelAdd task that triggers a prompt which adds a label back to a session, it will fire at most 10 times before being rate-limited — preventing infinite session creation.

Troubleshooting

Automation not firing

  1. Check event name - Must be exact (e.g., LabelAdd not labeladd)
  2. Check matcher - Regex must match the event value
  3. Check cron - For SchedulerTick, verify cron expression with an online tool
  4. Check logs - Look for [automations] or [Scheduler] in the logs

Prompt not creating session

  1. Check that the prompt is not empty
  2. Verify @mentions reference valid sources/skills

Best Practices

  1. Start simple - Test with a basic prompt before building complex workflows
  2. Use labels - Tag scheduled sessions for easy filtering
  3. Be specific - Use matchers to avoid triggering on every event
  4. Test cron - Use crontab.guru to verify expressions

On this page