Automate Anything, Powered by Your Imagination.
Automation AI (internally, HIA — Human-Intelligence to Automation) is a "thought-to-action" no-code workflow automation platform: describe what you want to automate in plain English, watch it turn into a runnable workflow graph, and execute it — manually, on a schedule, or from an external webhook.
The project pairs a full product specification (see docs/) with an honestly-scoped working
implementation: a Python workflow engine, a REST API, and a dependency-free web UI that together cover
the core mechanics — graph execution, branching, loops, parallel branches, human-in-the-loop approval, a
heuristic NL-to-workflow generator, and both webhook and cron triggers — so the idea has real, runnable
code behind a meaningful slice of it. See Status & scope for exactly what is and isn't
implemented.
Not to be confused with bharat3645/DAG-Pipeline: that repo is a visual pipeline builder focused on validating a graph is a cycle-free DAG (Kahn's algorithm). Automation AI is about running workflows — triggers (schedule/webhook), NL-to-workflow generation, and an execution engine whose graphs are allowed to loop (with cycle protection), not just validated as DAGs.
- Overview
- Features
- Tech stack
- Architecture
- Getting started
- Usage
- Configuration
- Testing
- Docker
- Project structure
- Status & scope
- License
Type an automation request like:
"when a lead fills out the form, send an email, notify sales, assign a follow-up, and update CRM if closed."
and Automation AI parses it into a workflow graph (trigger → notifications → task assignment → condition → integration → termination), lets you save it, and runs it end-to-end — logging every node it executes, pausing for human approval where the workflow calls for it, and exposing the whole thing over a clean REST API and a zero-build web UI.
Once a workflow is saved, it isn't limited to manual runs: it automatically gets its own webhook URL for external systems to call, and can be attached to a cron schedule to run itself unattended — no extra service, no cron daemon, no separate worker process required.
- Thought-to-Automation Builder — a deterministic, fully-offline clause parser
(
backend/app/nlp.py) turns a plain-English description into a workflow graph. IfOPENAI_API_KEYis set, AI/Decision nodes additionally try a real LLM call first and fall back to the heuristic on any error. - Graph execution engine (
backend/app/engine.py) — branching conditions evaluated with a restrictedast-based expression evaluator (noeval()on untrusted input, seebackend/app/safe_eval.py), bounded loops, concurrent parallel/fan-out branches with join, sub-workflow invocation, and error routing. - Human-in-the-loop — a workflow can pause at a task-assignment node and wait for approval/rejection via the API before continuing.
- Cron-based scheduled triggers (
backend/app/scheduler.py) — attach a standard 5-field cron expression to any saved workflow and it runs itself on that cadence, evaluated in UTC regardless of host timezone. Built on APScheduler'sAsyncIOSchedulerrunning on FastAPI's own event loop; schedules persist to disk and re-register automatically on restart. - Webhook triggers — every saved workflow gets its own
POST /api/hooks/{workflow_id}/{webhook_token}URL. Post any JSON body to it from a real form handler, GitHub, Stripe,curl, or anything else, and it runs the workflow with that body as input — no other API call needed. The token is rotatable viaPOST /api/workflows/{id}/webhook/rotateif it ever leaks. - ~24 working node types spanning trigger, condition, decision, loop, parallel/join, human-in-the-loop,
AI, integration/HTTP, notification, timer, sub-workflow, data validation/processing, state management,
file handling, audit logging, and a demo real-time query — see
docs/Workflow_Nodes_74_List.mdfor the full 74-node target scope and each one's implementation status. - Full execution visibility — inspect the ordered log of every node a run executed, its output, and the final workflow context/variables.
- Zero-build web UI (
frontend/) — plain HTML/CSS/JS served directly by the backend, including an "Automatic triggers" panel for managing a workflow's webhook URL and schedules. - Dockerized — a non-root, health-checked container image with a persistent volume for saved data (see Docker).
- CI on every push/PR — the full test suite runs on Python 3.10, 3.11, and 3.12, plus a job that
builds the Docker image and asserts the container actually becomes healthy
(
.github/workflows/ci.yml). - Optional API-key authentication (
backend/app/auth.py) — setHIA_API_KEYand every/api/*route starts requiring a matchingX-API-Keyheader, enforced by a single middleware. Off by default (zero-config local/CI use keeps working);GET /api/healthand the per-workflow webhook URL are always left public since they authenticate themselves differently (a healthcheck can't know a secret, and a webhook already carries its own token). - Webhook rate limiting (
backend/app/ratelimit.py) — each workflow's webhook trigger is capped (default: 30 requests / 60s, configurable viaHIA_WEBHOOK_RATE_LIMIT/HIA_WEBHOOK_RATE_WINDOW,0disables it) so a leaked or guessed webhook URL can't be used to spam a workflow's real side effects (emails, integrations...) or hammer the server. - Node config validation at save/import time —
POST /api/workflowsand/api/workflows/importnow check each node'sconfigagainst its type (e.g. an Integration node needs aurlormock_response, a State Management node needs akey), rejecting bad workflows with one clear422up front instead of a confusing failure — or, previously, an unhandled exception — partway through a run. - Unbounded-cycle protection — the engine caps total nodes visited in a single run
(
engine.MAX_CHAIN_STEPS) so a graph that cycles through ordinary edges (e.g. two Condition nodes pointing at each other, with no Loop node involved) fails the run with a clear error instead of spinning the server's event loop forever.
| Layer | Technology |
|---|---|
| Backend API | FastAPI + Pydantic (Python 3.10–3.12) |
| ASGI server | Uvicorn |
| Scheduler | APScheduler (AsyncIOScheduler, UTC) |
| HTTP client | httpx (Integration node, optional OpenAI passthrough) |
| Frontend | Static HTML / CSS / vanilla JavaScript — no framework, no build step |
| Testing | pytest + pytest-asyncio (54 tests) |
| Containerization | Docker, single-stage python:3.12-slim image, docker-compose.yml |
| CI | GitHub Actions (matrix test + Docker build/health smoke test) |
frontend/ (static HTML/CSS/JS, no build step)
│ fetch()
▼
backend/app/main.py FastAPI routes: workflows, runs, generate, tasks, webhooks, schedules
backend/app/engine.py WorkflowEngine: graph traversal, branching, parallel fan-out/join,
human-task pause/resume, error routing, unbounded-cycle guard
backend/app/nodes.py ~24 node type handlers + per-node-type config validation
(see docs/Workflow_Nodes_74_List.md)
backend/app/scheduler.py Cron-based recurring triggers (APScheduler, UTC), persisted + restart-safe
backend/app/nlp.py Thought-to-Automation Builder (NL → workflow JSON)
backend/app/ai_helpers.py AI/Decision node helpers (heuristic, optional OpenAI passthrough)
backend/app/safe_eval.py Restricted expression evaluator for Condition/Loop/State nodes
backend/app/templating.py "{{ expr }}" string templating for messages/bodies
backend/app/auth.py Optional X-API-Key auth for the management API (off unless HIA_API_KEY is set)
backend/app/ratelimit.py Per-workflow rate limit on the webhook trigger endpoint
backend/app/storage.py In-memory + JSON-file-backed store (workflows, schedules, runs, tasks,
a demo "leads" collection for the Real-Time Query node)
External triggers into the engine — POST /api/workflows/{id}/run (manual/API), POST /api/hooks/{id}/{webhook_token} (webhook, any external system), and cron schedules registered via
POST /api/workflows/{id}/schedules (scheduler.py fires WorkflowEngine.start_run() automatically) —
all converge on the same WorkflowEngine.start_run() call, so there's one execution path regardless of
what kicked the run off.
Workflows are JSON graphs of {id, type, name, config} nodes and {source, target, when} edges. when
is the branch label an edge is taken for (e.g. "true"/"false" from a Condition node, "approved"/
"rejected" from a Human-in-the-Loop node, "error" for the failure path); an edge with no when is the
default/unconditional path.
- Python 3.10–3.12
- (Optional) Docker, if you'd rather not set up a local Python environment
git clone https://github.com/bharat3645/Automation-AI.git
cd Automation-AIcd backend
python -m venv .venv
. .venv/Scripts/activate # Windows PowerShell: .venv\Scripts\Activate.ps1 ; macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt
cp ../.env.example ../.env # optional — everything works with defaults / no API key
uvicorn app.main:app --reloadThen open:
- http://127.0.0.1:8000/ for the web UI
- http://127.0.0.1:8000/docs for the interactive OpenAPI/Swagger explorer
docker compose up --buildNo local Python setup required — see Docker for details.
-
Describe an automation in plain English, in the UI or via the API:
curl -X POST http://127.0.0.1:8000/api/generate \ -H "Content-Type: application/json" \ -d '{"description": "when a lead fills out the form, send an email, notify sales, assign a follow-up, and update CRM if closed."}'
This returns a workflow graph (trigger → notification → notification → task assignment → condition → integration → termination).
-
Save and run the generated (or a hand-authored) workflow:
curl -X POST http://127.0.0.1:8000/api/workflows -H "Content-Type: application/json" -d @workflow.json curl -X POST http://127.0.0.1:8000/api/workflows/{workflow_id}/run -H "Content-Type: application/json" -d '{"input": {}}'
-
Inspect the run — full execution log (which node ran, in what order, with what output) and the final workflow context/variables:
curl http://127.0.0.1:8000/api/runs/{run_id} -
Trigger it from outside the app, two ways (also surfaced in the UI's "Automatic triggers" panel as soon as a workflow is saved):
-
Webhook —
POSTany JSON body straight to the workflow's URL and it runs immediately:curl -X POST http://127.0.0.1:8000/api/hooks/{workflow_id}/{webhook_token} \ -H "Content-Type: application/json" -d '{"lead_name": "Ada Lovelace"}'Rotate the token at any time with
POST /api/workflows/{id}/webhook/rotate. -
Schedule (cron) — run itself on a recurring cadence, no client needed:
curl -X POST http://127.0.0.1:8000/api/workflows/{workflow_id}/schedules \ -H "Content-Type: application/json" \ -d '{"cron": "*/15 * * * *", "input": {}}'Cron expressions are standard 5-field (
minute hour day month day_of_week), evaluated in UTC. Manage schedules withGET/PATCH/DELETE /api/workflows/{id}/schedulesorGET /api/schedules. Schedules persist across restarts and re-register automatically on boot.
-
-
Try the bundled example fixture:
backend/sample_workflows/lead_automation.json— the spec's own lead-automation example, hand-built as a demo/test workflow (import it viaPOST /api/workflows/import).
Copy .env.example to .env and fill in what you need — everything is optional and the
engine runs fully offline with sensible defaults:
| Variable | Purpose | Default |
|---|---|---|
OPENAI_API_KEY |
If set, AI/Decision nodes and the workflow-name generator try a real OpenAI chat completion first, falling back to the built-in heuristic on any error. | unset (heuristic only) |
OPENAI_MODEL |
Model to use when OPENAI_API_KEY is set. |
gpt-4o-mini |
OPENAI_BASE_URL |
OpenAI-compatible API base URL. | https://api.openai.com/v1 |
HOST / PORT |
Bind address for uvicorn. |
127.0.0.1 / 8000 |
HIA_DATA_DIR |
Directory where workflows.json, schedules.json, and File Handling node output are written. |
./backend/data |
HIA_API_KEY |
If set, every /api/* route (except GET /api/health and the webhook trigger) requires a matching X-API-Key header. |
unset (auth disabled) |
HIA_WEBHOOK_RATE_LIMIT |
Max requests allowed per workflow's webhook trigger per window. 0 disables rate limiting. |
30 |
HIA_WEBHOOK_RATE_WINDOW |
Rate limit window, in seconds. | 60 |
cd backend
pytest73 tests across engine, API, NLP, safe-eval, storage, scheduler, auth, and rate-limiting behavior (including a schedule that actually fires and executes a workflow, and a run that would spin forever without the engine's cycle guard). CI runs the same suite on Python 3.10, 3.11, and 3.12 on every push/PR, plus a job that builds the Docker image and confirms the container reaches a healthy state.
docker compose up --buildBuilds the backend + frontend into a single image (Dockerfile), runs it as a non-root
user, exposes :8000, and persists backend/data/ (saved workflows, schedules, File Handling node
output) in a named volume across restarts. docker-compose.yml wires in .env automatically if present.
There's a container HEALTHCHECK against /api/health, and
CI builds the image and asserts it actually becomes healthy on every push.
Automation-AI/
├── backend/
│ ├── app/ FastAPI app, engine, node handlers, scheduler, storage, NLP, safe-eval
│ ├── tests/ pytest suite (54 tests)
│ ├── sample_workflows/ Example workflow fixtures
│ └── requirements.txt
├── frontend/ Static HTML/CSS/JS UI (no build step)
├── docs/ Product specification + node catalog (source of the original idea)
├── .github/workflows/ci.yml GitHub Actions: matrix pytest + Docker build/health check
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── LICENSE
The spec (docs/Workflow_Nodes_74_List.md) enumerates 74 target node types spanning container
orchestration, blockchain audit trails, stream processing clusters, and more. Building all of that is a
multi-year infrastructure effort, not something an honest MVP claims to have. This repo implements
~24 of the 74 — the ones that make sense as single-process, dependency-light building blocks (trigger,
condition, decision, loop, parallel/join, human-in-the-loop, AI, integration/HTTP, notification, timer,
sub-workflow, data validation/processing, state management, file handling, audit logging, a demo
real-time query). The rest are left as documented roadmap items in that file rather than stubbed out
silently.
Known v1 limitations (by design, not oversights):
- Human-in-the-loop pauses are not supported inside a parallel branch — the engine raises a clear error rather than trying (and failing) to figure out how to resume one branch of a fan-out.
- Loop nodes iterate over a list or a bounded
untilcondition with a hardmax_iterationscap; they don't support looping over an arbitrary downstream sub-graph (no cyclic graph execution). - File-watcher triggers aren't implemented (cron/webhook triggers are — see Features);
wiring in
watchdogfor filesystem-event triggers is a natural next step. - Persistence is intentionally minimal: workflow definitions and schedules are cached to
backend/data/*.json; runs and human tasks are in-memory only and reset on restart. Swapping in Postgres/Redis is future work. - The "AI"/"Decision" nodes use simple keyword-overlap heuristics unless
OPENAI_API_KEYis set, in which case they try a real chat-completion call first and fall back to the heuristic on any error. - API authentication is opt-in, not on by default — CORS is wide open and, until you set
HIA_API_KEY, there's no auth on the management API (the webhook endpoint's per-workflow token is a separate, always-on guard). Fine for a local/demo deployment; setHIA_API_KEYbefore exposing this beyond your own machine. There's also no per-user auth/RBAC — one key grants full access to every workflow. - The webhook rate limiter is per-process and per-workflow only — it resets on restart, isn't shared across multiple server instances, and doesn't distinguish by caller IP. Enough to stop obvious abuse of a single running instance; a real multi-instance deployment would want a shared store (Redis, etc.) instead.
Released under the MIT License © 2026 Bharat Singh Parihar.