Workflows¶
A workflow is a graph of steps that runs without a person at each step. A trigger starts a run. The steps after the trigger wait, ask a decision model, send email, deploy, roll back, or give a task to an agent.
Open the section at Agents > Settings > Workflows. Each organization has its own
workflows. The imbi-workflows service runs them.
Setup has four steps:
- Prepare the platform: an operator does this one time for each install and organization.
- Build the workflow on the canvas, then click Save.
- Test it: click Test run. Nothing real happens.
- Activate it: set the switch to Active.
How the parts connect¶
| Part | What it is |
|---|---|
| Workflow | A name, a slug, an owner team, and its versions |
| Version | One saved graph and its settings. A version never changes after you save it |
| Active version | The one version that triggers start. Saving does not change it |
| Step | A node on the canvas. Its step type sets its parameters and output ports |
| Trigger | A step that starts a run: Manual run, Schedule, or Webhook |
| Connection | An edge from an output port of one step to the input of the next |
| Run | One execution of the active version, with a record for each step |
A workflow has one of three statuses:
| Status | Meaning |
|---|---|
| Draft | No version was activated yet |
| Active | Triggers start runs of the active version |
| Paused | Triggers start no runs |
See ADR 0021 for the design.
Build a workflow¶
- Open Agents > Settings > Workflows and click New workflow.
- Enter a name in the header. Imbi makes the slug from the name.
- Click Choose a trigger on the empty canvas, and select a trigger.
- Add the steps that follow. See The canvas.
- Click empty canvas to open Workflow settings. Select the Owner team. A workflow must have an owner team.
- Click Save.
Each save makes a new version. The header shows Saved ยท v<n>, or
Unsaved changes.
The canvas¶
The editor has three parts: the step palette on the left, the canvas in the middle, and the inspector on the right.
The palette shows the step types in four groups: Triggers, Logic, Actions, and Agents. Use Search steps to find a type.
- Click a step type to add it after the selected step.
- Drag a step type onto the canvas to put it at that position.
On the canvas:
- Drag from an output port to a step to connect them.
- Drop a connection on empty canvas to open a menu. Select a step type to add it and connect it in one action.
- Drag the canvas to move it. Use Ctrl + scroll (Cmd + scroll on macOS) to zoom.
- Use Zoom in, Zoom out, and Fit to view at the bottom.
- Press Delete or Backspace to remove the selected step or connection. Press Escape to clear the selection.
You cannot connect a step into a trigger, into itself, or twice on the same port.
The inspector¶
Select a step to see its inspector. It has these fields:
| Field | What it does |
|---|---|
| Title | The name on the canvas |
| Key | The name that references use. Imbi makes it from the title. Use lower case letters, digits, and _, and start with a letter. Each key must be unique |
| Run when | For a step with more than one input: Any input arrives or All inputs arrive. See Joins |
| Parameters | The form for the step type. See Step types |
| Output | What the step returned in the last test run or run |
Use Duplicate and Delete step at the top of the inspector.
Select a connection to see where it starts and ends, and to remove it.
Imbi validates the graph while you edit. A step with a warning shows Needs configuration. An error shows in red. The header counts the steps that need configuration.
Workflow settings¶
Click empty canvas to see the workflow settings.
| Field | Values | Default |
|---|---|---|
| Description | Free text | Empty |
| Owner team | A team in the organization | None. Required |
| Concurrency | Unlimited, One run at a time, One run per key | Unlimited |
| Concurrency key | One reference, for One run per key only | None |
| Max run time (minutes) | A run that runs longer stops as timed_out |
120 |
| When a run fails | Notify the owner team, Do nothing | Notify the owner team |
Only an admin or a member of the current owner team can change the owner team.
Step types¶
The table shows each step type, its group, and its output ports. A step with one output port has no port name.
| Type | Label | Group | Output ports |
|---|---|---|---|
manual |
Manual run | Triggers | One |
schedule |
Schedule | Triggers | One |
webhook |
Webhook | Triggers | One |
wait |
Wait | Logic | One |
model_decision |
Model decision | Logic | One for each branch |
email |
Send email | Actions | One |
deploy |
Deploy | Actions | Succeeded, Failed |
rollback |
Rollback | Actions | One |
agent |
Agent task | Agents | Succeeded, Failed |
Each step that is not a trigger has a default timeout and a default retry count:
| Type | Timeout | Retries |
|---|---|---|
wait |
None | 0 |
model_decision |
60 seconds | 2 |
email |
2 minutes | 0 |
deploy, rollback |
1 hour | 2 |
agent |
None. The max run time limits it | 2 |
The API also accepts timeout_seconds and retries (0 to 10) on a node to
replace the defaults. The editor has no field for them.
GET /organizations/{org}/workflow-step-types/ returns each type with its
parameter schema, output schema, and sample output.
Manual run¶
A person starts a run with the Run button.
| Parameter | What to enter | Default |
|---|---|---|
inputs |
The inputs that the person must enter. Each has a name (a key) and a type: string, number, or boolean |
None |
who |
Who can start and cancel runs: owner_team, admins, or anyone |
owner_team |
The inspector shows inputs as JSON, for example:
Every input is required. Imbi refuses an input that is not declared, and a value of the wrong type.
Output: the inputs, by name. Use {{ trigger.<name> }}.
admins means Imbi administrators. An administrator can always start and
cancel a run.
Schedule¶
imbi-scheduler starts a run on a cron schedule.
| Parameter | What to enter | Default |
|---|---|---|
cron |
A cron expression. imbi-scheduler checks it | Required |
timezone |
An IANA time zone, for example America/New_York |
UTC |
Output: fired_at, the time of the firing. Use
{{ trigger.fired_at }}.
Webhook¶
A delivery to a gateway Webhook starts a run.
| Parameter | What to enter | Default |
|---|---|---|
webhook_id |
A Webhook of the organization. It must be a literal id | Required |
filter |
A CEL expression. A delivery starts a run only when it is true | None (every delivery) |
Output: payload, the body of the delivery. Use
{{ trigger.payload.<field> }}, for example
{{ trigger.payload.repository.name }}.
Create the Webhook first at Admin > \
Wait¶
Holds the run for a fixed time.
| Parameter | What to enter |
|---|---|
duration |
A number and a unit: s, m, h, or d. Example: 10m |
Output: waited_seconds.
Model decision¶
A decision model selects one branch.
| Parameter | What to enter | Default |
|---|---|---|
model_id |
A decision model from the AI Model catalog | Required |
prompt |
The question for the model | Required |
context |
The text that the model decides on. Without it, the model gets the prompt | None |
min_confidence |
0 to 1 | 0.7 |
branches |
Two or more unique names. Each name is one output port | Required |
When the probability of the choice is less than min_confidence, the step
takes the last branch. Put the safe branch last, for example
["yes", "no"].
The model must be enabled, its provider must be enabled, its type must be
decision, its driver must be typesafe, and it must have credentials.
Otherwise the step fails with model_unavailable or
model_credentials_missing. See AI Models.
Output: choice, probability, and reasoning.
Send email¶
Sends an email to users and teams of the organization.
| Parameter | What to enter |
|---|---|
to |
One or more recipients. Each has a kind (user or team) and an id |
subject |
The subject. Templates are allowed |
body |
The body. Templates are allowed |
Enter a user by user id. Select a team from the list. Imbi sends only to active members of the organization. It never sends to an address outside Imbi.
If the send fails for one or more recipients, the step fails with
email_failed and the addresses. Imbi does not retry it, because the other
recipients already have the message.
Output: recipients, the addresses that got the message.
Deploy¶
Deploys a version of a project to an environment, then waits for the deployment to finish.
| Parameter | What to enter |
|---|---|
project_id |
A project id, or one reference such as {{ trigger.project }} |
environment |
An environment slug |
version |
A tag or a commit |
The step takes Succeeded when the deployment succeeds. It takes Failed
when the deployment fails or is cancelled, or when the step fails after its
retries.
The imbi-workflows service account does the deployment. See
Operator prerequisites for what it needs.
Output: deployment_id and status.
Rollback¶
Deploys an earlier version of a project again.
| Parameter | What to enter | Default |
|---|---|---|
project_id |
A project id, or one reference | Required |
environment |
An environment slug | Required |
target |
last_healthy, previous, or version |
last_healthy |
version |
The tag or commit. Required when target is version |
None |
last_healthy: the newest successful release that is not the release of the newest attempt.previous: the successful release before the one that serves now.
If Imbi finds no release, the step fails with
no_release_to_roll_back_to. A rollback has one output port, so a failed
rollback fails the run.
Output: deployment_id and status.
Agent task¶
Gives an agent a task and waits for its outcome. See Agent tasks.
| Parameter | What to enter | Default |
|---|---|---|
agent_id |
An agent of the organization. It must be a literal id | Required |
instruction |
What the agent must do. Templates are allowed | Required |
project_id |
The primary project of the task. It must be a literal id | None |
budget |
A limit in USD. It cannot be more than the task budget of the agent | The task budget of the agent |
The step takes Succeeded when the outcome is done_acted,
done_nothing_to_act_on, or no_reason_to_run. Every other outcome takes
Failed. The engine checks the task every 30 seconds.
The person who activated the workflow owns the task. That person must still be able to make agent tasks when the step runs.
When you cancel the run, or the run passes its max run time, Imbi cancels the task. A step timeout does not cancel the task.
You cannot delete an agent that a workflow uses. The delete returns 409
with "used in N workflow(s)".
Output: task_id, outcome, reason, and summary (the last
message of the agent). Run detail shows reason and summary only to
people with agent_task:read.
References¶
A parameter can use the output of an earlier step with {{ }}. The syntax
is the sandboxed Jinja of Prompts.
| Reference | Value |
|---|---|
{{ trigger.<name> }} |
A manual input, fired_at of a schedule, or payload of a webhook |
{{ <key>.<field> }} |
An output field of a step before this one, by its key |
Examples:
Deploy {{ trigger.service }} to production{{ decide.reasoning }}{{ trigger.payload.release.tag_name }}
Rules:
- A reference can name only a step that comes before this step on a path
from a trigger. Otherwise validation shows
unknown_reference. - When the whole value is one reference, the step gets the typed value. Otherwise the step gets text.
- A reference to a skipped step is empty.
- If a template fails when the step starts, the step fails with
invalid_params.
Some ids have more rules, so that run input cannot select a resource in a different organization:
| Parameter | Allowed |
|---|---|
webhook_id, and agent_id and project_id of an agent step |
A literal id only |
project_id of deploy and rollback, email recipient ids |
A literal id, or one plain reference such as {{ trigger.project }} |
A literal id must exist in the organization. Otherwise validation shows
resource_not_in_organization.
Joins¶
A step with more than one input has a join. Set it in Run when:
- Any input arrives (
any): the step runs one time, at the first input. It ignores the other inputs. - All inputs arrive (
all): the step runs when every input arrived or will not arrive, and at least one arrived.
A branching step (model decision, deploy, agent task) takes one port. The
steps on its other ports are skipped. A step whose inputs are all from
skipped paths is skipped too.
Validation warns when an Any input arrives step can get two inputs in one run.
Concurrency¶
| Mode | What it does |
|---|---|
| Unlimited | Runs start at once |
| One run at a time | One run of the workflow at a time. Other runs wait in queued |
| One run per key | One run at a time for each key value. Runs with other keys start at once |
Runs that wait start in the order that Imbi made them.
For One run per key, the Concurrency key must be one reference to a trigger value:
{{ trigger.service }}{{ trigger.payload.repository.name }}
More rules for One run per key:
- Each Manual run trigger must declare the input that the key uses.
- You cannot use it with a Schedule trigger.
- When a run has no value for the key, Imbi refuses it with
422 concurrency_key_missingand makes no run.
Validation¶
Imbi validates the graph while you edit, when you save, and when you activate. A save always stores the version with its issues, except when the graph is too large.
| Check | Issue code |
|---|---|
| At most 100 steps, 200 connections, and 64 KiB of graph JSON. A save is refused | too_many_nodes, too_many_edges, graph_too_large |
| At least one trigger | no_trigger |
| Each step type exists | unknown_type |
| Parameters are valid. A missing required parameter is a warning | invalid_param, missing_param (warning) |
| Keys and ids are unique | duplicate_key, duplicate_node_id, duplicate_edge |
| No connection into a trigger, and each port exists | edge_into_trigger, port_out_of_range, unknown_node |
| No cycles | cycle |
| Each step can be reached from a trigger | unreachable |
| Templates are valid, and references name earlier steps | invalid_template, unknown_reference |
| Ids are literal where required, and exist in the organization | invalid_reference, resource_not_in_organization |
| Concurrency key rules | missing_concurrency_key (warning), invalid_concurrency_key, concurrency_key_with_schedule, concurrency_key_input_missing |
| An Any input arrives step can get two inputs | any_join_overlap (warning) |
Activate a workflow¶
- Save the workflow. The switch is off while there are unsaved changes.
- Set the switch in the header to Active.
Activation makes the latest version the active version. Runs that already started keep the version that they started with.
Activation fails in these cases:
| Response | Cause | Fix |
|---|---|---|
422 validation_failed |
The version has issues. Warnings count | Fix every issue, save, and activate again |
403 missing_permissions |
You do not hold a permission that a step needs. The message lists them | Ask an admin to activate it, or to give you the permissions |
Imbi checks the permissions of your role in the workflow's organization only. The permissions that steps need:
| Step | Permission |
|---|---|
| Schedule | scheduled_task:create |
| Webhook | webhook:update |
| Deploy, Rollback | project:deployment:write |
| Agent task | agent_task:create |
Imbi records who activated the workflow. A workflow cannot do more than
that person can do. When a run starts, the engine checks the person again.
If the person is no longer an active member of the organization, or no
longer holds the permissions, the run fails with
activator_lacks_permission and the workflow pauses. A person with the
permissions must activate it again.
To pause a workflow, set the switch to Inactive. Its triggers start no runs. Runs that already started continue.
Triggers¶
Activation, pause, and delete write a trigger binding for each schedule
and webhook trigger. imbi-workflows syncs each binding when imbi-api tells
it, and every 5 minutes (IMBI_WORKFLOWS_RECONCILE_INTERVAL).
- Schedule: imbi-workflows makes the imbi-scheduler task
workflow-<binding id>. The task runs as theimbi-schedulerservice account. A pause disables the task. Do not edit this task: imbi-workflows changes it back. - Webhook: imbi-workflows adds a
gateway-actions#start_workflowrule to the Webhook. The rule stays when you pause the workflow. The gateway then gets409and records the delivery as no effect.
Only the imbi-workflows service account can add, change, or remove a
start_workflow rule. Other changes get 403 workflow_rule_forbidden. You
can still edit the other rules of the Webhook.
The workflow from GET /organizations/{org}/workflows/{slug} has a
bindings list. Each binding has a sync_state:
sync_state |
Meaning |
|---|---|
pending |
imbi-workflows did not sync it yet |
synced |
The task or the rule exists. The trigger starts runs |
failed |
The sync failed. error has the cause. The next pass tries again |
A trigger whose binding is not synced starts no runs. A bad cron
expression gives a failed binding with the error from imbi-scheduler.
A schedule firing or a webhook delivery starts at most one run, also when it is sent again.
Runs¶
Test run¶
Click Test run to walk the saved latest version. Each step returns its sample output. Nothing is sent, deployed, or written.
- Save first. The button is off while there are unsaved changes.
- A branching step takes its first port.
- Errors stop the test run with
422 validation_failed. Warnings do not.
The Test log tab of the bottom panel shows each step, its port, and its output.
Run¶
Click Run to start a run of the active version. The workflow must be active and have a Manual run trigger. If the trigger declares inputs, enter them, then click Run workflow.
Schedule and webhook triggers start runs without a person.
Run history¶
The Runs tab of the bottom panel lists the runs of the workflow, newest first. Click a run to see each step: status, duration, branch, error, input, and output. Open runs refresh every 2 seconds.
The workflow list shows Runs 30d and Last run for each workflow.
| Run status | Meaning |
|---|---|
queued |
Waiting for the engine, or for another run with the same concurrency key |
running |
The engine works on it |
succeeded |
No step is left to run |
failed |
A step failed and no connection handles the failure |
cancelled |
A person cancelled it |
timed_out |
It ran longer than the max run time |
The engine keeps the run log in Postgres until ClickHouse has every event of
a closed run. Then run detail reads from ClickHouse. If ClickHouse is not
available, run detail of an old run returns 503, and Runs 30d and
Last run are empty.
Cancel a run¶
Open the run and click Cancel run. The engine stops the run before its
next step. Steps that did not finish become cancelled. Imbi cancels the
task of an agent step. Imbi does not stop a deployment that already
started.
To cancel, you need workflow:run and the same who as the trigger that
started the run. A schedule or webhook run allows the owner team.
Runs that need attention¶
Admins see Runs that need attention on the workflow list:
- Failed: a run that failed or timed out in the last 7 days.
- Stuck: no engine has picked it up: an open run that no engine works on.
The list comes from GET /organizations/{org}/workflow-runs/attention.
Failures, timeouts, and retries¶
- Retries. An error (a timeout, a
5xx, a connection error, a model error) uses the retries of the step. The first retry waits 5 seconds. Each retry after that waits two times longer. - No retry. A
4xxfrom imbi-api, a403, and a failure that the step reports (a failed deployment, a failed agent outcome) are not retried. - Failed port. After the retries, a failed step takes its
Failedport when its type has one and a connection starts there. - Run fails. Otherwise the run fails at once. Steps that did not start
become
cancelled. Then the failure policy runs. - Failure policy. Notify the owner team sends an email to the members of the owner team. Do nothing sends nothing.
- Step timeout. A step that runs longer than its timeout fails with
timeout, and its retries apply. - Max run time. The engine counts it from when Imbi made the run. A run
that passes it closes as
timed_out.
Deploy, rollback, and email send the idempotency key
<run_id>:<node_key> to imbi-api. After a crash, imbi-api returns the first
result, so the step does not deploy or send two times. If the first call
did not finish, imbi-api returns 409 outcome_unknown, and the step fails
without a retry.
Permissions¶
| Permission | Allows |
|---|---|
workflow:read |
View workflows, their versions, and their runs |
workflow:create |
Create workflows |
workflow:write |
Edit, activate, and pause workflows |
workflow:delete |
Delete workflows |
workflow:run |
Start manual and test runs, and cancel runs |
The default roles get these permissions:
| Role | Permissions |
|---|---|
admin |
All |
developer |
workflow:read, workflow:create, workflow:write, workflow:run |
default, readonly |
workflow:read |
The editor has no delete button. To delete a workflow, call
DELETE /organizations/{org}/workflows/{slug}. Imbi refuses it with 409
while a run is queued or running.
Operator prerequisites¶
Do these steps one time for each install.
- Run
imbi-api setup-permissions. This adds theworkflow:*permissions,workflow:runto theimbi-schedulerandimbi-gatewayroles, andscheduled_task:*to theimbi-workflowsrole. - Run
imbi-api setup-clickhouse. This makes theworkflow_runsandworkflow_run_eventstables. - Restart iggy-connect after the first deploy, so that it reads the two new streams.
- Run imbi-workflows. It runs in Helm
service.mode: all, or as its own release withservice.mode: workflows(port 8006). - Give imbi-workflows its service account credential. See Helm values.
Each organization that uses workflows needs three service accounts as
members: imbi-workflows, imbi-scheduler (for schedule triggers), and
imbi-gateway (for webhook triggers). Each account has the role of the
same name in the organization.
imbi-api setup does this for the organization that it creates. For each
other organization, run this command:
Run imbi-api setup-permissions first, because the command assigns the
seeded roles by name. When only one organization exists, you can omit
--organization. The command does not change an account or a credential
that already exists.
You can also add the accounts in the Admin UI:
- Open Admin > Global Admin > Service Accounts.
- Open
imbi-workflows. Under Organization Memberships, click Add to Organization. - Select the organization and the
imbi-workflowsrole. - Do steps 2 and 3 again for
imbi-schedulerwith theimbi-schedulerrole, and forimbi-gatewaywith theimbi-gatewayrole.
For deploy and rollback steps, the imbi-workflows account also needs the
bounds of ADR 0017:
- Grant
integration:act-as-serviceto theimbi-workflowsrole at Admin > Global Admin > Roles. Imbi does not grant it by default. - Select Allow Autonomous Deployments on each target environment at
Admin > \
Admin > Environments .
The imbi-workflows account also needs organization membership for agent
steps.
Helm values¶
| Value | Purpose |
|---|---|
workflows.serviceAccount.clientId |
Client id of the imbi-workflows service account |
workflows.serviceAccount.clientSecret |
Client secret of that account |
workflows.schedulerUrl |
imbi-scheduler's task API with its route prefix, for example http://imbi-scheduler.<namespace>.svc.cluster.local:8005/api. Set it when imbi-workflows runs as its own release. Empty works in all mode only |
imbi-api setup seeds the account to match the client id and secret. Set
both or neither. With neither, setup makes a pair and prints it one time.
With existingSecret, the chart reads the workflows-sa-client-id and
workflows-sa-client-secret keys. In service.mode: workflows, the pod
does not start without them.
A release with service.mode: workflows also needs
service.internalApiUrl and service.publicApiUrl, as for the scheduler.
See Kubernetes.
Engine settings¶
| Variable | Purpose | Default |
|---|---|---|
IMBI_WORKFLOWS_WORKERS |
Runs that one process works on at the same time | 10 |
IMBI_WORKFLOWS_POLL_INTERVAL |
Most seconds between polls for runs | 10 |
IMBI_WORKFLOWS_LEASE_SECONDS |
How long a claim of a run lasts. More than 30 | 300 |
IMBI_WORKFLOWS_DEPLOY_POLL_SECONDS |
Seconds between deployment checks | 15 |
IMBI_WORKFLOWS_AGENT_POLL_SECONDS |
Seconds between agent task checks | 30 |
IMBI_WORKFLOWS_SCHEDULER_URL |
imbi-scheduler's task API. Helm sets it from workflows.schedulerUrl |
http://localhost:8005/api |
IMBI_WORKFLOWS_RECONCILE_INTERVAL |
Seconds between trigger binding syncs | 300 |
See also Agents, Agent tasks, and Agent runners.