Skip to content

vugarfamiloglu/Conduit-Workflow-Automation-Platform

Repository files navigation

Conduit — AI workflow automation

Self-hosted Zapier-style workflow editor. Build automations visually from triggers, actions, transforms, and AI steps. Next.js full-stack — the UI, the API, the execution engine, the scheduler, and the SQLite database all live in one process.

        Visual editor                         Execution engine
        (canvas + node palette)              (topo-sorted DAG runner)
                │                                     │
                ▼                                     ▼
       /api/workflows  ─────►   workflows.graph_json (nodes + edges)
                                                      │
       /api/webhooks/:token  ◄───┐                    ▼
       /api/workflows/:id/run ◄──┤    for each node in topological order:
                                 │       resolve {{ steps.X.path }} templates
       node-cron scheduler  ─────┘       run node implementation (lib/nodes/*)
                                          persist run_nodes row
                                                      │
                                                      ▼
                                              SQLite (WAL)
                                          runs, run_nodes, webhook_log

Node catalog

Triggers

  • Webhook — opens a public URL at /api/webhooks/<token>. Any POST body becomes the trigger payload.
  • Schedule — fires on a 5-field UNIX cron expression. The scheduler is a background task running inside the Next.js process.
  • Manual run — fired by hitting "Test run" in the editor.

Actions

  • HTTP Request — any method, headers, body. Returns { status, ok, headers, body }.
  • Send Message — POSTs { text } to a webhook URL (Slack-compatible out of the box).
  • Log — writes a structured line into the run trace.

Transforms

  • Template — string with {{ steps.X.path }} placeholders, rendered before the node runs.
  • Transform (JS) — body of a function: input, steps, trigger are in scope. Sandboxed via new Function(...) — local-only, do not trust user code from outside.

AI (OpenAI)

  • AI Generate — free-form prompt, returns { text }.
  • AI Summarize — concise summary with configurable max words + style.
  • AI Classify — assign to one of N declared categories with confidence.
  • AI Extract — pull structured fields out of free text per a JSON shape.

Variable resolution

Every config field that's a string runs through a template resolver before the node executes:

{{ trigger.body.email }}
{{ steps.n_extract.email }}
{{ steps["n_request"].body.items.0.title }}

Resolution is dot/bracket paths against a single scope { trigger, steps }. Undefined paths render as empty string. Non-string values are JSON-stringified.

Execution

1. topo-sort the workflow graph (cycles are rejected)
2. for each node in order:
     a. compute input = output of the node's incoming edge (trigger payload for triggers)
     b. resolve {{ ... }} templates inside the node's config against `steps`
     c. await node.run({ input, config, steps, trigger, log })
     d. persist the node's input/output/status into `run_nodes`
3. mark the run succeeded; or, on the first failure, mark remaining nodes
   "skipped" and the run "failed"

Quick start

Requires Node 18+. OpenAI key only needed if you use AI nodes.

cp .env.example .env
# Edit .env: set SESSION_SECRET to something long+random; add OPENAI_API_KEY
# if you want to run AI nodes.

npm install
npm run seed     # creates 2 demo workflows + sets passcode to "0000"
npm run dev

Open http://localhost:4848, enter passcode 0000. Two workflows are seeded:

  1. Support email triage (enabled) — POST to http://localhost:4848/api/webhooks/support-intake with { "text": "..." } → AI classifies urgency → posts to a Slack-compatible webhook (placeholder — edit the URL in the editor).
  2. Minute heartbeat (disabled by default) — every minute, render a template, write a log line. Enable it from the Workflows page to see the scheduler in action.

Try it from the workflow detail page: hit Test run with no trigger payload, watch the per-node trace appear at /runs/<id>.

Editor UX

  • Add node — the floating + button. Categorised palette: triggers, actions, transforms, AI.
  • Wire two nodes — click the cyan dot at the bottom of the source node, then click anywhere on the target node.
  • Remove an edge — click on its curved line.
  • Drag the node header to reposition. The right panel edits the selected node's config.
  • Save persists; Test run triggers the workflow manually with whatever body you typed (default {}).

Layout

app/
  (app)/                       authenticated panel
    workflows/                 list + [id]/editor
    runs/                      list + [id]/detail
    webhooks/                  active URLs + recent payloads
    settings/                  static info
  api/
    auth/                      passcode + cookie
    workflows[/[id][/run]]     CRUD + manual trigger
    runs[/[id]]                list + detail
    webhooks/[token]           PUBLIC trigger receiver
    webhook-log                admin view of recent calls
    node-catalog               schema of every node kind (for the editor)
  lock/                        unlock screen
  globals.css, layout.tsx, page.tsx
components/
  Modal.tsx, ConfirmModal.tsx, Sidebar.tsx
  editor/
    Editor.tsx                 canvas, drag, connections
    NodePalette.tsx            cmd-palette-style node picker
    NodeForm.tsx               right-rail config form (renders from FieldSpec)
lib/
  db.ts                        SQLite WAL + migrations
  auth.ts                      passcode + signed cookie
  api-helpers.ts               handle() wrapper
  client-api.ts                fetch wrapper
  engine.ts                    THE execution engine + variable resolver
  scheduler.ts                 node-cron registrar
  nodes/                       one file per category + index registry
  types.ts, format.ts
scripts/seed.ts                demo data

Notes on the design

  • One big graph_json on the workflow row. Per-node tables are normal in larger systems but for a few KB of JSON on each workflow, denormal saves a lot of join code and keeps the editor's save path one row.
  • Inline scheduler in-process. Acceptable for a single-node Next.js deployment. For HA / multi-replica you'd want a leader election so only one process schedules. The hooks are obvious (DB-backed leader lock).
  • JS sandbox is new Function(). Real sandboxing needs an isolate (VM2, isolated-vm, deno_core, etc.). Conduit is self-hosted single-user — the threat model is "you write a bug", not "untrusted user code".
  • Webhook URLs are bearer-by-obscurity. Anyone with the URL can trigger. If you need stronger auth, add an X-Conduit-Secret header check inside a Transform JS node at the start of the workflow.
  • AI nodes call OpenAI directly. No retry/timeout/cost limits yet — the hooks are obvious (per-node max tokens, per-workspace daily cap).

License

MIT.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors