Orbito - Dokumentacja modułówOrbito - Dokumentacja modułów
Wprowadzenie
Pierwsze kroki
API
Komunikacja
Widoki
Wdrożenie
Społeczność
For AI agents
Wprowadzenie
Pierwsze kroki
API
Komunikacja
Widoki
Wdrożenie
Społeczność
For AI agents
  • For AI agents

    • Orbito for AI agents
    • Module anatomy
    • The build loop
    • Cheatsheet
    • Example module acme/hello
    • Company automations
    • Changelog

Company automations

An automation is a rule of one company: "when this happens, do that". You compose it from triggers and actions that the core and the installed modules provide, write it as a JSON graph and save it with omm automation. Use this page when the human asks for an automation, or when your module registers triggers or actions and you want to test them on a real graph.

Draft first, enable only with consent

omm automation create and update always save a disabled automation. Show the human the graph and what it will do, and run omm automation enable only after they agree. Enabling, deleting or changing an enabled automation acts on the company's real data; ask first.

What an automation is

  • Triggers start it: a module event (an order was created, a shipment changed status) or the built-in cron. An automation can have several triggers; any of them starts it.
  • Actions form a graph. A run starts at startActionId, executes the action and follows one of its branches to the next action. A plain action has one output, next; a condition has true and false; module actions may declare their own outputs. A branch set to null ends the run.
  • The trigger hands the actions event params, for example the order id. Every key is full: <moduleCode>:KEY, such as core/orders:ORDER_ID.
  • Each firing creates a run. Runs of one company go through one queue, one at a time: a long action delays every later run of the company.
  • Only an enabled automation reacts to events. There are no loops: a graph with a cycle is rejected and an action runs at most once per run. Repetition comes from a trigger (cron) or from an action that waits.

Graph format

The file you pass to omm automation create -f (update takes any subset of the fields):

{
    "name": "Weekday check of the vacation mode",
    "desc": "Every weekday at 8:00: mail the office while the vacation mode is on",
    "triggers": [
        { "type": "cron", "params": { "pattern": "0 8 * * 1-5" } }
    ],
    "startActionId": "check_vacation",
    "actions": {
        "check_vacation": {
            "type": "var_condtion",
            "params": { "key": "vacation_mode", "checkOperation": "equals", "valueToCheck": "on" },
            "branches": { "true": "notify", "false": "mark_checked" }
        },
        "notify": {
            "type": "send-email",
            "params": {
                "email": "office@example.com",
                "subject": "Vacation mode is still on",
                "message": "<p>{{ $_automationName }}: orders are on hold.</p>"
            },
            "branches": { "next": null }
        },
        "mark_checked": {
            "type": "set_var",
            "params": { "key": "last_check", "value": "workday" },
            "branches": { "next": null }
        }
    }
}
FieldRules
name, descname required for create; desc optional
triggersarray of { type, params }, at least one; type is the full element type
actionsobject actionId → { type, params, branches, saveResultAs? }; actionId matches ^[a-zA-Z0-9_-]+$ and is yours to choose (check_paid, set_status)
branchesoutput name → next actionId or null; names come from the element's outputs (no outputs: only next); a missing output ends the run
startActionIdthe first action; must exist
saveResultAsoptional key under which the action's result is kept for later actions ({{ $key }} in send-email); without it only the last result is available as $last

Every action must be reachable from startActionId. isEnabled is not part of the file: omm rejects a file that contains it.

Elements

omm automation elements lists what the company can use; omm automation element <type> prints the full definition: the params schema, outputs of an action, emits of a trigger and requires of an action. Never guess a type or a param name; read the definition.

Built-in elements of the core:

TypeKindParamsNotes
crontriggerpatterncron expression, 5 fields or 6 with seconds; the event carries only core:pattern
delayactionvalueseconds to wait, integer > 0; the run pauses, then continues on next
set_varactionkey, valuesets a company automation variable (shared and persistent, not per run)
var_condtionactionkey, checkOperation (equals, includes, not_equals), valueToCheckspelled exactly like this; outputs true / false
send-emailactionemail, subject, messagemessage is HTML rendered as a mustache template, see below
send-template-emailactiontemplateId, recipientEmail and/or recipientVara company message template; at least one recipient

Module elements have the type <moduleCode>:<code>, for example core/orders:order_created. They need params.__instanceId: the id of the module instance that runs them (omm instances -m <moduleCode> --json, or the allowed values in the param's options.values). It is required even when the company has a single instance.

Event keys connect triggers and actions:

  • A trigger declares in emits the keys it delivers; an action declares in requires the keys it needs. Both use full keys, core/orders:ORDER_ID.
  • Every action's requires must be emitted by every trigger of the automation; with several triggers only the common keys count. The core rejects a graph that breaks this (REQUIRES_NOT_EMITTED).
  • At run time an action whose keys are missing is skipped: the run continues on next, the step is marked as skipped and the company gets the problem AUTOMATION_ACTION_SKIPPED.

Params:

  • A param with options.values accepts only the listed ids. A param with options.module + options.method takes values from that module method (for example an order status id); fetch them with omm call <method> -m <module> --params '<options.params as JSON>' --json. The core does not check these values, so do not guess them.
  • Types: string, number (a number or numeric text, maybe with a format such as positive_integer), boolean, datetime, array (of of), template_var, and info (descriptive, give no value).
  • Variables are rendered only where the core supports them. send-email message is a mustache template: {{ $event.core/orders:ORDER_ID }}, {{ $last }}, {{ $<saveResultAs key> }}, {{ $_automationName }}; triple braces and partials are forbidden; email and subject are not rendered. A template_var param takes a variable path moduleCode:group.field without braces, such as core/orders:customer.email. Anywhere else {{ }} reaches the action as plain text.

Build loop with omm

Add --json to every command, as everywhere in omm. All commands work on the working company (omm company use, or --company <id>).

  1. See what exists. omm automation elements --json (filters: --kind trigger|action, --query <text>) and omm automation list --json; a similar existing automation is the best template (omm automation get <id> --json).
  2. Read every element you use. omm automation element <type> --json: params, required fields, outputs, emits / requires.
  3. Write the graph file. Instance ids from omm instances -m <moduleCode> --json, values of dynamic params from the module method.
  4. Save a draft. omm automation create -f graph.json --json (or -f - with the graph on stdin). It prints { "automationId", "name", "isEnabled": false }. The core validates the whole graph; an invalid one is rejected with 422 and nothing is saved, see Validation errors.
  5. Check it. omm automation get <id> --json shows the saved graph and its validation (element statuses, blocking).
  6. Show the human the graph in plain words: trigger, conditions, what each branch does, which instance it acts on.
  7. Enable only on consent. omm automation enable <id> --json. The core rejects it while an element is unavailable or an action param is invalid.
  8. Watch the runs. omm automation runs --automation <id> --json, then omm automation run <runId> --json for the steps.
  9. Fix with update. Take omm automation get <id> --json, edit it, remove isEnabled and send it back with omm automation update <id> -f file --json. Read-only fields (_id, validation, generatedName, …) are dropped by omm. triggers and actions are replaced as a whole, so always send the full graph. update never changes isEnabled, but an update of an enabled automation takes effect at once: ask first, or disable it before the change.

Other commands: omm automation disable <id>, omm automation duplicate <id> (a disabled copy, not validated) and omm automation delete <id> --yes (also removes its runs and problems; Human).

Validation errors

create and update send the graph with strict validation. A 422 arrives on stderr in --json mode as:

{"error":"Automation graph is invalid","status":422,"validation":{"errors":[{"path":"actions.wait.params.value","code":"INVALID_TYPE","message":"expected a number"}]}}

In text mode each error is a line path: message (CODE). Read path, fix that place in the file and send the whole graph again. INVALID_SHAPE is checked first; the other rules run only on a well-shaped graph, so new errors can appear after a fix.

CodeMeaning
INVALID_SHAPEa graph field has the wrong type, for example actions as an array
UNKNOWN_FIELDa field outside the format (trigger: type, params; action: type, params, branches, saveResultAs), or an unknown field of a template variable
NO_TRIGGERtriggers is empty
START_ACTION_MISSINGstartActionId does not point to an action
INVALID_ACTION_IDan actionId outside ^[a-zA-Z0-9_-]+$
UNKNOWN_BRANCHa branch name the action does not declare in outputs
BRANCH_TARGET_MISSINGa branch points to an action that does not exist
CYCLEa branch leads back to an earlier action
UNREACHABLE_ACTIONan action cannot be reached from startActionId
ELEMENT_UNKNOWNthe type does not exist in the company (made up, withdrawn, or an action used as a trigger)
ELEMENT_UNAVAILABLEthe module is not installed, all its instances are disabled, or __instanceId points to a disabled instance
UNKNOWN_PARAMa param outside the element's schema, or a value given to an info field
REQUIREDa required param is missing
INVALID_TYPEa value of the wrong type
INVALID_FORMATa number that breaks its format
INVALID_OPTIONa value outside options.values
REQUIRES_NOT_EMITTEDan action needs event keys that not every trigger emits
INVALID_VAR_PATHa template_var value is not moduleCode:group.field
UNKNOWN_MODULEthe variable's module is not installed or declares no variables
UNKNOWN_GROUPthe variable group does not exist
LIST_AS_VALUEa list field used as a single value
TEMPLATE_NOT_FOUNDthe message template does not exist
KEYS_NOT_EMITTEDthe trigger does not emit the keys the variables need
RECIPIENT_REQUIREDsend-template-email without recipientEmail and recipientVar

A rejected enable uses the lighter enabling rules (element availability, action param rules) and reports the blocking elements as triggers.0: <type> (<status>) plus invalid params.

Element statuses and audit

omm automation get <id> --json has a status for every trigger and action in validation (text mode lists only the blocking ones):

StatusMeaningBlocks?
okbuilt-in, or present in the version of an active instanceno
version-unknownthe module is active but this version has not reported its elements yet (just deployed or starting)no
missingthe module version no longer has this elementyes
instance-disabled__instanceId points to a disabled, removed or foreign instanceyes
module-not-installedno enabled instance of the module: not installed, or every instance disabledyes

An automation with any blocking element cannot be enabled. The core also audits enabled automations at start and about 30 seconds after module changes (disable, uninstall, version update): a blocking one is disabled (lastUpdateBy: core:audit) and the company gets the problem AUTOMATION_ELEMENT_MISSING listing the elements and reasons. The core never enables it again by itself: fix the graph (another instance, another element) or re-enable the instance, then ask the human to enable the automation. Events from the disabled period are not replayed.

Runs

omm automation runs lists runs, newest first (filters --automation <id>, --status <status>, --event <value> for a value of any event param such as an order id, --limit <n>, max 50). omm automation run <runId> prints the header, the event params and the steps with OFFSET, ACTION ID, CODE, BRANCH and OUTCOME.

StatusMeaning
runningan action is executing; stuck for long usually means the core restarted mid-run (it is not resumed)
donethe run reached the end of the graph; this does not mean every action did something
erroredan action threw; later actions did not run; the reason is in errorMsg (<type>: <message>)
abortedon resume the automation was disabled or deleted, or the paused action was removed from the graph
pausedwaiting until resumeAt
resumingpicked up after a pause, waiting in the company queue

Step outcomes: ok; skipped, missing: <keys> (the event lacked the action's requires); paused until <time> (a delay, or a module action that paused); retry (attempts: N), paused until <time> (the action asked to run again later: repeated attempts update this one step); error: <message>. Actions the run never reached have no step.

  • A run resumes along the current graph: a fix made while runs are paused applies to them. The action a run is paused on is not executed again after a plain pause (delay), only after a retry; if that action was removed, the run ends as aborted.
  • Finished runs are deleted about 3 days after they started; paused runs live until at least 3 days after resumeAt. No run for an older event proves nothing; read the module's logs and history instead.
  • done with no effect: compare the steps with the graph. Look for a skipped step or a condition that took a branch with no action.

Variables

Company automation variables are text values shared by all automations of the company, read by var_condtion and written by set_var. They persist between runs.

omm automation var list --json
omm automation var get vacation_mode --json
omm automation var set vacation_mode on --json

A new value applies at once to every enabled automation that reads the variable.

Ostatnio zaktualizowano:: 10/14/26, 10:48 AM
Contributors: Wiktor Koźmiński, Claude Fable 5.1
Prev
Example module acme/hello
Next
Changelog