Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Workflows (visual automation canvas, in development)

An in-development n8n/Zapier-style automation builder: a workflow is a trigger plus a graph of steps, edited on a canvas beside the projects sidebar, with a step picker, a settings drawer, live validation, Build with AI that turns a sentence into a graph, a split view that watches an agent build it, retries and on-failure paths, and a wait-for-me approval step.

What it is

Workflows is an in-development n8n/Zapier-style automation builder inside Omniscio. A workflow is a trigger plus a directed acyclic graph (DAG) of steps: deterministic actions (HTTP request, send email, send a message, run a recipe), a branching if/else node, and AI steps. When the trigger fires — a manual "Run" click, a cron schedule, or an incoming message matching a filter — Omniscio walks the graph in order and runs each node, passing data forward between steps via {{ NodeName.path }} template references. Every workflow starts off and cannot run until a human turns it on — nothing executes silently. (The "lands in the inbox for approval" flow this page used to describe is NOT built: turning a workflow on is done from the canvas bar, and no inbox card is raised.)

This page covers the visual canvas editor and Build with AI surfaces — the sidebar row that docks a graph-editing panel beside the projects sidebar, the same way Flowcharts and Decks do. The underlying execution engine (trigger types, node registry, the DAG executor, the approval gate) is documented in workflow-engine-contract.md — read that first for anything touching how a workflow actually runs.

Where to find it

Workflows ships hidden. Turn it on under Settings → Lab → Workflows, then open the Workflows row in the sidebar to dock the graph-editing panel beside the projects sidebar. The saved-workflows list itself lives in the Pane-2 rail — the sub-sidebar beside Omniscio's main nav — in its Workflows tab, beside the Sessions tab (AI build sessions) and the Runs tab (run history).

How it behaves

How it is gated

Workflows is an in-development feature registered as 'workflows' in src/shared/unreleased-features.ts (settingKey: 'workflowsEnabled'). It is visible when any one of the following is true:

  • The feature is marked 'shipped' in the registry (releases to everyone).
  • Omniscio is launched with the feature's reveal env var set.
  • The user flips the Settings → Lab → Workflows toggle on.

No code reads settings.workflowsEnabled directly to decide sidebar visibility — the gate goes through isUnreleasedFeatureVisibleInRenderer('workflows', …) in project-visibility.ts (UNRELEASED_PROJECT_GATES).

Using the canvas (build → configure → validate → turn on)

The Phase-2 canvas editor is built. Reveal via Settings → Lab → Workflows, then open the Workflows sidebar row.

The saved-workflows list lives in the Pane-2 rail (the sub-sidebar beside Omniscio's main nav), not inside the panel. That placement is load-bearing rather than cosmetic: the panel yields to the session chat while a build is open, so a rail rendered inside it would vanish exactly when the user needs a way back to their workflows. The rail carries three tabs — Workflows (the saved list), Sessions (AI build sessions), and Runs (run history; selecting a run shows its detail in the panel) — plus the split-view toggle. The node palette and the React Flow canvas stay in the panel:

  1. Create — "New workflow" makes an empty workflow and opens it.
  2. Build — press "Add step" (or double-click empty canvas) to open the step picker: a search-first palette browsed app-first — your Favorites and Recent steps first, then one group per app (Jira, Notion, Slack…), each owning its own triggers and actions. Type to filter — it matches names, apps and synonyms, so "api" finds HTTP request — arrow-key through the results and press Enter to drop the step into the middle of your view. A side pane previews what the highlighted step does and what it hands to later steps, and a Trigger badge marks the steps that can start a workflow. On a brand-new workflow the picker shows triggers only, under a "Choose how this workflow starts" title, since a workflow always begins with its trigger. You can still add a step from the left rail, which browses the same app groups (a single-step app is a chip, a multi-step app expands) and is the place to drag a step onto the canvas by hand. A ⭐ on the rail pins an app or a step to the top of both, and your pins and recents are remembered across restarts. A workflow needs one trigger, then actions / an if-branch / AI steps. Drag between node handles to connect them; a branch node has separate true/false output handles (labeled Yes / No on the canvas so the two paths are distinguishable). "Tidy up" auto-lays-out the graph (elk, lazily loaded). Move/delete freely; every edit is undo/redo-able and autosaves.
  3. Configure — click a step to open the right-hand settings drawer. Each node type ships a form descriptor (its form on the NodeDefinition, surfaced over WORKFLOW_NODE_TYPES), so the drawer renders the right fields (text / number / select / toggle / value-ref) bound straight to the node's config. In a value-ref field, "+ Insert a value from an earlier step" lists the outputs of upstream steps only (topo-bounded) and splices a {{ Step.field }} token into the field.
  4. Validate — a banner above the canvas shows the live graph-validation issue count (via the shared validateWorkflowGraph); a workflow with no trigger, a cycle, an unknown type, or a forward reference is flagged.
  5. Turn it on — the bottom bar is the workflow's on/off switch: it reads Off with a Turn on button, or On with Turn off. Turning it on flushes the pending autosave and makes the workflow live, so it reacts to its trigger. "Turn on" is disabled while the graph is invalid; turning off is always allowed — a live workflow whose graph later broke must still be stoppable. The wording is on/off but the underlying gate is unchanged (approvalStatus); there is no separate approver, because the person building the workflow is the only one who could approve it.

Not yet in the canvas (documented as gaps in the engine contract): a run-history/observability viewer, the inbound webhook trigger (Phase 4), and chip-rendering of {{ }} tokens (they show as literal text today).

Build with AI (describe → graph)

Instead of hand-placing every node, "Build with AI" turns a plain-English description into a whole workflow graph:

  1. From the Workflows list, click Build with AI and describe what you want in a sentence or two ("every morning at 9, check my unread Gmail and send me a summary in Slack").
  2. Omniscio creates an empty workflow, then spawns a normal Omniscio AI session (you keep your usual model picker) with your description pre-filled as the draft message — it is never auto-sent, so you can edit it first.
  3. Behind the scenes the session is briefed with a hidden build primer that points it at the /workflow CLI (the same REST surface the CLI-server contract documents) and the live node catalogue via GET /workflow/node-types — which returns each node's form descriptor (fields, options, outputs), so the agent always builds against the real registry, never a hard-coded node list. The agent builds the graph and then stops — it does not run the workflow (running is a separate, human-approved, billable step).
  4. The build session lands in the rail's Sessions tab, so you can watch it work or ask follow-up questions.
  5. On desktop the canvas opens beside that chat and fills in live as the agent writes — see the next section. You no longer wait for the agent to finish and then go looking for the result.
  6. When it's done the canvas is yours again; review the graph like any hand-built workflow and click Turn on when you're happy.

If the spawn itself fails, Omniscio deletes the orphan empty workflow it created in step 2 rather than leaving a dead entry in your list.

Watching a build live (the split view)

While an AI build chat is open on desktop, the workflow canvas renders side-by-side with the chat instead of the chat replacing it, so the graph is visibly assembled as the agent works. Four behaviours make that readable, and each exists to answer a question the user would otherwise have to guess at:

  • The canvas is watch-only while the agent owns it — no drag, connect, select, delete, palette drop, or "Tidy up". Pan and zoom deliberately stay on: the point is to inspect the graph being built, not stare at a frozen picture. The lock is derived from live session status on every render and never latched, so a crashed, errored, stalled, paused or vanished build session hands the canvas back by itself. A session parked on account capacity (waiting) keeps the lock — it resumes on its own, and it resumes writing.
  • Nodes the agent just touched are briefly tinted (~1s, then it fades), so the eye is pointed at the change rather than hunting a re-laid-out canvas for it. Position is deliberately excluded from the "did this change?" comparison: the live arrangement is never persisted, so every push re-lays the whole graph out and a position-aware diff would strobe the entire canvas every time.
  • The viewport follows the growing graph until the user pans or zooms, and then never takes it back. Closing the split is the reset.
  • A status strip says who owns the canvas — "Agent is building…", or "Build complete — the canvas is editable again." The strip and the canvas read the same lock value, so the strip can never promise the canvas is editable while it is still read-only.

Why edits are suppressed rather than merged. While the lock is held the store refuses both to queue and to flush a save for that workflow, so a stale local graph can never overwrite the nodes the agent just wrote over the CLI. There is one honest cost: the lock engages on a rising edge that can straddle the 500 ms autosave debounce, so an edit made in the instant before a build starts is discarded by design rather than persisted. In the steady state the user is not editing; across that edge a real edit can exist and is dropped, with the strip flipping to "Agent is building…" as the only signal.

Mobile keeps the chat-replaces-canvas behaviour (too narrow to split), and the desktop split can be collapsed from the rail's toggle — the agent keeps building either way.

Where a live workflow shows up

Turning a workflow on makes it live, but the places that reflect that are spread across three surfaces — worth knowing, because only one of them is inside Workflows:

  • The saved-workflows list marks each live row with a small dot (reading the same approvalStatus the canvas bar and the engine gate use), so the list can be scanned without opening each workflow.
  • The Cron panel, for a trigger.schedule workflow: syncWorkflowSchedule creates a backing cron job named Workflow: <name>, and the cron sidebar does not filter by type — so it appears alongside recipes and scripts. ⚠ Nothing currently stops that job being disabled or deleted there, which would silently stop the workflow firing while its own bar still reads On. Two switches for one thing; reconciling them is an open design question.
  • The Runs tab in the rail, once it has actually fired — each run with its per-step breakdown.
  • The inbox, only if the graph ends in a node that puts something there (action.create_alert). A workflow without one runs and produces nothing the user would notice.

When a workflow stops part-way and waits

A workflow does not have to finish in one go. A step can stop the whole workflow part-way through and wait — for you to answer something, for a moment in time, or for something to happen elsewhere. While it waits, the run shows as Paused in the Runs tab, with the step it is sitting on.

Three things are worth knowing about a waiting run:

  • It survives closing the app. A waiting run is written down, not held in memory. Quit Omniscio, restart your Mac, come back tomorrow — the run is still there, still waiting, still knows everything the earlier steps produced.
  • Carrying on does not repeat what already ran. When the workflow picks up again, every step that already finished is reused as-is rather than run a second time. An email that was already sent is not sent again; a message that was already posted is not posted again. Only the step that was waiting, and the steps after it, actually do anything.
  • It never waits forever in silence. A waiting step can carry a time limit. If nothing answers before the limit runs out and the step has a Timeout path drawn, the workflow carries on down that path; if it has none, the run is marked failed, saying it was waiting on a step that wasn't answered in time — including when the limit ran out while the app was closed, which is noticed the next time you open Omniscio. A step with no time limit waits indefinitely, but it always shows as Paused rather than looking finished.

Asking a person to approve (the "wait for me" step)

The first step that actually pauses a run is Wait for me — it stops the workflow and asks a person to approve or reject before it carries on. Add it like any other step; it sits on the canvas with a short question, an optional bit of detail, and up to a handful of yes/no or short-answer questions to collect along with the decision.

  • It reaches you in the inbox. When a run hits the step, a card appears in the inbox with your question and an Approve and a Reject button. Answering it there — or on a paired phone, the card is the same — unblocks the run. On the canvas the step glows amber-orange while it waits, the app's "waiting" colour.
  • Three ways out, three paths. The step has three outgoing paths you can wire to different next steps: Approved, Rejected, and Timeout. Rejecting is a real answer, not an error — the workflow simply takes the Rejected path (or just stops, if you drew nothing there). Timeout is taken only if you set a time limit and nobody answers in time.
  • Its answer is usable later. Any short-answer questions you asked are readable by the steps that follow, the same way one step reads another's output.
  • You cannot answer it on the workflow's behalf from a script. The approval is a person's decision, so it is answered only from the inbox card (yours or your phone's), never from the command-line control server — an automation answering its own approval would defeat the point of asking.
  • Turning the workflow off or editing it cancels a pending answer. If you turn the workflow off, or change its steps (which sends it back for approval), a run that was waiting on it will not carry on when answered — it re-checks that the workflow is still on and approved before spending anything, exactly as starting or re-running it does.

When a step fails (retry, and an "on failure" path)

A step that fails no longer has to take the whole workflow down with it. There are two things you can do about it, and they combine.

Retry — try the same step again. Open a step's settings and turn on Retry this step if it fails. You choose how many attempts (up to 10) and how long to wait between them — either the same wait each time, or a wait that doubles (1s, 2s, 4s…), which is the polite way to treat a service that is briefly busy. A step with retry turned off behaves exactly as it always has: one attempt.

Two deliberate limits:

  • A waiting step is never retried. Pausing is not failing, so a step that stops to wait for you is left alone.
  • A step whose settings don't make sense is never retried either. That is a mistake in how the step is set up, not bad luck, so trying it four more times would only waste time.

If a step can send something (an email, a Slack message) or create something (an issue, a page), the settings panel warns you: the first attempt may already have gone through before it reported failure, so retrying could send it twice. Whether that is acceptable is your call — which is why it is off by default.

An "on failure" path — carry on down a different route. Every step except the trigger now has a second output on its right-hand side, marked in red. Drag a connection from there to another step, and that is where the workflow goes if this step fails. The run carries on down that path and can still finish successfully. The step that failed is still recorded as failed, so the Runs tab tells you the truth about what happened — and the step you connect can read the error text with {{ StepName.message }}, which is what makes "post the failure to Slack" or "create a ticket describing what broke" possible.

If a step has no "on failure" connection, nothing changes: it fails, the run is marked failed, and the steps after it are skipped.

Retry happens first. A step set to 3 attempts uses all three; only if all three fail does the "on failure" path open. So the two work together — retry for a blip, the failure path for when something is genuinely broken.

Two things retry deliberately will not do. An AI step cannot be retried at all — a failed attempt still costs real money that the run has no way to account for, so repeating it would quietly spend more than the run reports. The Retry control simply is not offered on those steps. And an HTTP step comes with no suggested setting: a request that times out may already have reached the other end, so whether repeating it is safe depends on what it does — which is a judgement only you can make. If you do turn it on for anything other than a plain read, the panel says so.

Not built yet: the canvas does not yet show a live "retrying 2 of 3" label while it happens — the run history records the outcome either way.

Re-running a past run from a step

When a run went wrong at step 4, you usually don't want to start the whole thing over — steps 1 to 3 already did their work, and repeating them could send the same message twice. Open the run in the Runs tab and each step has a Replay from here button.

What it does:

  • It starts a NEW run. The original stays exactly as it was, so you never lose the record of what actually happened. The new run remembers which run it re-ran.
  • It repeats that step and only what depends on it. Steps that don't depend on the one you picked are reused as-is, not repeated — so a message that already went out doesn't go out again just because it happened to sit on a different branch.
  • It costs money, because the steps it re-runs really run again. It asks you to confirm first, and it is a desktop-only action — you cannot trigger it from your phone.
  • It uses the workflow as it was when that run started, not as the canvas looks today.

It refuses in three cases, with a reason: the step isn't part of that run, an earlier step is still waiting for an answer (answer it first), or the workflow has since been turned off or un-approved — re-running is not a way around the approval gate.

Trigger types

A workflow starts with exactly one trigger node. The engine supports six:

  • Manual (trigger.manual) — fires when a user clicks Run (UI or CLI).
  • Schedule (trigger.schedule) — fires on a cron schedule.
  • Message (trigger.message) — fires when an incoming message (channel, Gmail, Pushbullet) matches a channel-scope and optional keyword filter.
  • Jira issue (trigger.jira_issue) — polls every 2 minutes, fires when an issue is created, transitions status, or is updated. Requires Jira credentials.
  • Arij issue (trigger.arij_issue) — real-time WebSocket subscription, fires on issue changes, board changes, comments, or agent-state events.
  • KMS note (trigger.kms_note) — fires when a note in your KMS vault is created or updated and matches a tag and/or folder filter. Push-driven (no polling) — the KMS file watcher emits the event. Only fires on the transition from not-matching to matching (a note saved repeatedly while it already matches does not re-fire). A 5-minute cooldown per note prevents rapid flap re-fires.

Create alert (action.create_alert) is a general-purpose action node that creates an inbox item with a title, content, and optional dedup key — useful as the "notify me" step at the end of a KMS or any other trigger chain.

HTTP request auth (action.http) — the HTTP node can send saved authentication: in the step's Authentication field, pick an existing credential or add one inline (a bearer token, an API key sent as a custom header, or basic username/password). The secret is stored encrypted in the shared automation-credential vault; the workflow only references it by id, and the auth header is applied at run time inside the engine port — so an author never pastes a token into the graph, and every decrypt is audit-logged. This is the first step of connector convergence: the Workflows canvas reusing the same credential store + auth logic the v2 Automations engine already has, rather than a parallel one. (Custom request headers are carried by the node but not yet UI-editable — a documented fast-follow.)

Message + page connectors — three credential-backed action nodes ride the same seam: Send Slack message (action.slack_send_message), Create Notion page (action.notion_create_page), Send Telegram message (action.telegram_send_message), and Send Discord message (action.discord_send_message, via an incoming webhook). Each has an account field that picks (or inline-adds) the saved Slack bot token / Notion integration token / Telegram bot token; the token is resolved + applied inside the engine port at run time (never in the graph), and every decrypt is audit-logged. The inline add-credential form reuses the shared credentials editor, so it renders the right inputs for any kind. (The v2 Automations actions for these providers still keep their own copy of the send logic — migrating them onto the shared helpers is a documented follow-up.)

What an AI step is allowed to do (permissions)

An AI step (ai.agent_step) — and a Run a recipe step — starts a real Claude session, and that session asks you before it does anything your permission level says needs asking. A workflow runs on its own, so the session it starts inherits your global level (Settings → Workflow → Agent Permissions), with one deliberate exception:

  • A run started by an incoming message or email — a Message trigger, or an email that matched an email trigger — runs its AI steps at the Guarded floor instead of your global level, and shows them in your sidebar rather than hiding them. Someone else's text must never end up handled as if you had asked for it, so on those runs the sensitive-file net over ~/.ssh, ~/.aws, ~/.npmrc, ~/.bashrc and your GPG key rings stays on, and each command or config write asks for your approval first — even if you normally run at Full trust.
  • Every other trigger — Manual, Schedule, Jira issue, Arij issue, KMS note — is something you wired up yourself, so its steps keep running exactly as they always have: at your level, and out of the way.

When an email-triggered workflow's AI step needs a command, that run's session waits for you in the sidebar under Needs You; approving it lets the step carry on.

Status

The Workflow Engine (trigger types, node registry, DAG executor, approval gate, IPC + CLI) shipped dark behind workflowsEnabled. The Canvas editor (Phase 2 — build / configure / validate / request-approval, above) and AI-build (Phase 3 — describe → graph, above) are both built on top of it, also gated dark. Pausing and carrying on (above) is built and tested, but no step uses it yet — the first one ships with the "wait for me" approval step. The integration/webhook expansion (Phase 4) is not built. Reveal via Settings → Lab → Workflows.

For agents

How it is mounted

Workflows is an amc-builtin virtual project (__workflow__, defined in src/shared/virtual-project-ids.ts) registered once in src/shared/integrations/workflow.ts and assembled into INTEGRATION_REGISTRY by npm run integrations:reindex — mirroring how Flowcharts (__flowchart__) is wired.

Like Flowcharts, the Workflows panel now hosts AI build sessions: __workflow__ is spawnable and resolver-mapped (resolveProjectWorkDir() maps it to <userData>/workflow-agent, and it is in SPAWNABLE_VIRTUAL_PROJECT_SENTINELS). It is still deliberately not in SESSION_HOSTING_VIRTUAL_PROJECT_PATHS — that set drives things like Ctrl+T "jump to a hosting project's sessions"; Workflows owns its own session-reveal path (the panel's Sessions tab, via useWorkflowsSessionHost) instead. A workflow's own AI step nodes still run inside the engine's executor (see the engine contract), not as a user-facing chat session — only the build flow below spawns a real chat session.

Key files

What Where
Virtual project id src/shared/virtual-project-ids.ts (WORKFLOW_PROJECT_ID)
Integration manifest src/shared/integrations/workflow.ts
Gating registry src/shared/unreleased-features.ts (workflows)
Canvas editor (renderer) src/renderer/src/features/workflows/ (WorkflowEditor, WorkflowCanvas, NodePalette, WorkflowListSidebar, NodeSettingsDrawer, InsertValueButton, ValidationBanner, ApprovalBar, workflows-store.ts)
Node form descriptors each src/main/services/workflow-engine/nodes/*-node.ts (form) + shared types in src/shared/workflows/types.ts
Build with AI (renderer) src/renderer/src/features/workflows/ (BuildWithAiModal.tsx, useWorkflowsAiBuild.ts, workflows-spawn-prompt.ts, WorkflowSidebarTabs.tsx, workflows-session-host.ts)
Live build split view src/renderer/src/features/workflows/ (WorkflowBuildPane.tsx, WorkflowBuildStatusStrip.tsx, workflows-build-lock.ts, useWorkflowsBuildLock.ts, workflow-graph-diff.ts, workflows-build-session.ts) + features/dashboard/workflows-split.ts
Engine + data model + canvas + AI-build invariants see workflow-engine-contract.md

Related

Workflows is the graph-building sibling of the older automation surfaces: Use recipes covers single-path multi-step runs, and Agent trigger recipes covers recipes an agent can fire. The credential store the HTTP, Slack, Notion, Telegram and Discord steps reuse is documented on Automation credentials. To have an agent walk you through building one, see Workflow Coach.

Last verified 2026-09-30