AI Workflow Automation Platform
AWAP is a Python-first platform for creating, versioning, validating, executing, and monitoring AI workflows.
It currently provides:
- a FastAPI backend
- a browser-based workflow editor served by the same FastAPI app
- workflow graph authoring with nodes and edges
- workflow versioning with
draftandpublishedstates - execution planning and validation
- background workflow execution with durable run tracking
- provider abstractions for LLMs, tools, credentials, and observability
- SQLite-backed persistence
The frontend and backend are served together. There is no separate frontend build step right now.
- create workflows as directed graphs of nodes and edges
- use built-in node types such as
manual_trigger,schedule_trigger,llm_prompt,decision,http_request, andnotification - edit workflows in the browser
- save new versions instead of overwriting historical workflow definitions
- workflows have a stable logical
id - each saved definition has a numeric
version - versions can be
draftorpublished - publishing one version automatically resets the other versions of that workflow to
draft
- validate node configuration requirements
- validate references between nodes and edges
- reject cyclic workflow graphs
- generate execution plans in topological order
- start workflow runs through the API or the web editor
- execute runs in background worker threads
- track run state:
queued,running,succeeded,failed - track step state per node
- inspect run events for observability
- LLM providers are abstracted behind a provider registry
- tool execution is abstracted behind tool providers
- observability sinks are abstracted behind observability providers
- credentials are stored separately from workflow definitions and resolved at execution time
The current implementation includes built-in providers so the platform is functional without external vendor setup:
echo_llmlocal placeholder LLM provider used byllm_prompthttp_toolperforms real HTTP requests forhttp_requestnotification_toolsimulates delivery fornotificationrepository_observerstores run events in the databaselogger_observerwrites run events to the application logger
- Python 3.11+
uvfor environment and dependency management- FastAPI for the HTTP server
- SQLAlchemy for persistence
- SQLite as the default database
- pytest for tests
- Ruff for linting
- plain HTML/CSS/JavaScript for the frontend editor
src/awap/
api/ FastAPI app and routes
ui/ Browser editor assets
catalog.py Built-in workflow node catalog
database.py Database engine and schema bootstrap
domain.py Pydantic models and workflow domain types
main.py Local development entrypoint
providers.py Provider abstractions and built-in provider adapters
repository.py Persistence layer
runtime.py Workflow execution runtime
service.py Application services
tests/
test_api.py
test_domain.py
test_frontend.py
test_providers.py
test_runs.py
- Python 3.11 or newer
uvinstalled on the machine
If uv is not installed yet:
pip install uvuv sync --group devThis creates .venv and installs all runtime and development dependencies.
You can start the FastAPI app with either command:
uv run awap-devor:
uv run python -m uvicorn awap.api.app:create_app --factory --reloadThe app starts on:
- backend + frontend:
http://127.0.0.1:8000/ - API docs:
http://127.0.0.1:8000/docs
Open this in your browser:
http://127.0.0.1:8000/
You can:
- create a workflow
- add nodes and edges
- save the workflow
- create new versions
- publish a version
- validate the selected version
- generate the execution plan
- start a run
- inspect runs and run events
There is only one server to start.
The backend API and the frontend editor are both served by the FastAPI application, so this is enough:
uv run awap-devThen use:
http://127.0.0.1:8000/for the editorhttp://127.0.0.1:8000/docsfor Swagger/OpenAPI
There is no separate Node/Vite/React dev server in the current architecture.
By default, the application uses:
sqlite:///./awap.db
Override it with:
$env:AWAP_DATABASE_URL = "sqlite:///./custom-awap.db"
uv run awap-devOn Linux/macOS:
export AWAP_DATABASE_URL="sqlite:///./custom-awap.db"
uv run awap-dev- the schema is created automatically at startup
- there is no migration system yet
- if you make incompatible schema changes later, existing local databases may need manual handling
A workflow is a graph with:
nodesedgesnamedescriptionidversionstate
POST /workflowscreates version1asdraftPOST /workflows/{workflow_id}/versionscreates a new draft versionPOST /workflows/{workflow_id}/versions/{version}/publishpublishes one version- reads, planning, and validation accept an optional
versionquery parameter
If no version is supplied during execution, the system prefers:
- the published version
- otherwise the latest version
When a run starts:
- the platform resolves the workflow version to execute
- it validates the workflow
- it builds an execution plan
- it creates a durable run record
- it executes steps in a background thread
- it updates step state and run state in the database
- it stores structured run events for observability
Credentials are stored independently from workflows.
Workflows reference credentials through node config such as:
{
"provider": "echo_llm",
"credential_id": "credential-uuid"
}The secret payload is not returned by the public credential listing endpoints.
The browser editor includes:
- workflow list
- version list
- node type palette
- provider list
- credential list
- workflow metadata editor
- node editor with JSON config
- edge editor
- flow preview
- validation output
- execution plan view
- run launcher
- run history
- run event viewer
Important current behavior:
- saving an edited existing workflow creates a new version rather than mutating the saved version in place
- node configuration is currently edited as JSON
- graph editing is form-based, not drag-and-drop
GET /GET /healthGET /docs
GET /workflowsPOST /workflowsGET /workflows/{workflow_id}GET /workflows/{workflow_id}/versionsPOST /workflows/{workflow_id}/versionsPOST /workflows/{workflow_id}/versions/{version}/publishPOST /workflows/{workflow_id}/validatePOST /workflows/{workflow_id}/plan
GET /workflows/{workflow_id}/runsPOST /workflows/{workflow_id}/runsGET /runs/{run_id}GET /runs/{run_id}/events
GET /providersGET /credentialsPOST /credentialsGET /credentials/{credential_id}
- start the app with
uv run awap-dev - open
http://127.0.0.1:8000/ - create or load a workflow
- add nodes and edges
- save it
- validate it
- generate the plan
- run it
- inspect the run and run events
uv run pytestuv run ruff checkuv sync --group devuv run awap-devuv run python -m uvicorn awap.api.app:create_app --factory --reloaduv run pytestuv run ruff checkThe test suite currently covers:
- domain validation rules
- API behavior
- workflow versioning and publish flow
- workflow runs and job tracking
- provider and credential behavior
- frontend serving
Run everything with:
uv run pytest- no authentication or authorization yet
- no multi-tenant isolation
- no schema migration framework yet
- frontend graph editing is form-based rather than canvas-based
echo_llmis a placeholder provider, not a real vendor integration- no queue system beyond in-process background workers
- Add authentication, authorization, and multi-tenant boundaries.
- Add schema migrations for safe persistence upgrades.
- Add real provider plugins for external LLM vendors and operational tools.
- Improve the editor with drag-and-drop graph layout and branching visualization.
This repository includes a LICENSE file.