Skip to content

AbstractFlow — Architecture (Current)

Updated: 2026-02-09
Scope: describes implemented behavior in this repository (no roadmap claims).

AbstractFlow is a workflow authoring + orchestration layer in the AbstractFramework ecosystem, built on: - AbstractRuntime: durable runs, waits, subworkflows, stores (RunStore/LedgerStore/ArtifactStore) - AbstractCore (via runtime integration): LLM + tool effects - AbstractAgent (optional): Agent node subworkflows (ReAct) - AbstractMemory (optional): memory/KG nodes

See also: ../README.md, getting-started.md, api.md, faq.md, visualflow.md, web-editor.md, cli.md.

Repository layout (what ships where)

abstractflow/                  # Published Python package
  __init__.py                  # Public API exports
  core/flow.py                 # Flow IR re-export (from AbstractRuntime)
  runner.py                    # FlowRunner (runtime-backed)
  compiler.py                  # Compiler shim (delegates to AbstractRuntime)
  visual/                      # VisualFlow models + portable execution wiring
  adapters/                    # Adapter re-exports (delegates to AbstractRuntime)
  cli.py                       # `abstractflow` CLI
  workflow_bundle.py           # Bundle helpers (delegates to AbstractRuntime)
docs/                          # Human docs (this folder)
web/                           # Reference visual editor app
  backend/                     # Legacy/dev FastAPI host + Gateway proxy
  frontend/                    # React editor + Gateway-first run UI
  flows/                       # Default flow storage when running backend from `web/`
  runtime/                     # Default runtime persistence in a source checkout (installed: ~/.abstractflow/runtime)
tests/                         # Test suite

High-level data and execution flow

flowchart LR
  subgraph Authoring
    FE[web/frontend<br/>React editor] -->|/api/gateway/*| GW[AbstractGateway<br/>VisualFlows + bundles]
    GW -->|persists| GWDATA[(Gateway data dirs)]
  end

  subgraph Execution
    HOST[Host process<br/>(Gateway / CLI / 3rd party)] -->|validate| VF[VisualFlow models<br/>abstractflow/visual/models.py]
    HOST -->|create_visual_runner| WIRE[Runtime wiring<br/>abstractflow/visual/executor.py]
    WIRE --> RT[AbstractRuntime Runtime<br/>tick/resume]
    RT --> STORES[(RunStore / LedgerStore / ArtifactStore)]
    RT -->|LLM_CALL, TOOL_CALLS| AC[AbstractCore integration]
    RT -->|START_SUBWORKFLOW| REG[WorkflowRegistry]
  end

  FE -->|HTTP/SSE: start/commands/ledger| GW

Portable data model: VisualFlow JSON

The portable authoring format is VisualFlow (Pydantic models): - VisualFlow, VisualNode, VisualEdge, NodeType, PinType, …

Evidence: ../abstractflow/visual/models.py.

Key portability rule (enforced by design): the JSON must contain enough configuration to execute outside the web backend. Hosts may add storage, auth, and UI around it, but execution should remain host-independent.

Compilation and execution (portable)

VisualFlow → Flow IR

AbstractFlow delegates “VisualFlow → Flow IR” semantics to AbstractRuntime: - abstractflow.visual.executor.visual_to_flow() calls abstractruntime.visualflow_compiler.visual_to_flow(...).

Evidence: ../abstractflow/visual/executor.py.

Flow IR → WorkflowSpec

AbstractFlow delegates compilation to AbstractRuntime: - abstractflow.compiler.compile_flow is re-exported from abstractruntime.visualflow_compiler.compiler.

Evidence: ../abstractflow/compiler.py.

Running (FlowRunner)

FlowRunner owns host-friendly execution convenience: - creates a default in-memory runtime when you don’t provide one - normalizes outputs to {"success": bool, "result": ...} for callers - can auto-drive nested SUBWORKFLOW waits in non-interactive contexts

Evidence: ../abstractflow/runner.py, tests in ../tests/test_runner.py.

VisualFlow execution wiring (host responsibilities)

The key host entrypoint is: - abstractflow.visual.executor.create_visual_runner(...)

It wires the runtime based on what is present in the flow tree: - registers subflows/agent workflows when needed (workflow registry) - enables artifact storage when memory nodes are present - wires AbstractCore effect handlers when LLM/tool nodes are present - optionally installs AbstractMemory KG effect handlers when memory_kg_* nodes are present

Evidence: ../abstractflow/visual/executor.py.

Session-scoped events (VisualSessionRunner)

VisualFlows that include custom events (on_event / emit_event) are executed with a session-aware runner: - VisualSessionRunner starts derived event-listener workflows as child runs in the same session. - During run(), it also ticks those child runs so EMIT_EVENT branches make progress without a separate host loop.

Evidence: ../abstractflow/visual/session_runner.py, wiring in ../abstractflow/visual/executor.py, tests in ../tests/test_visual_custom_events.py.

Web editor host (Gateway-first)

The modern editor is a thin Gateway client: - VisualFlow CRUD: GET/POST/PUT/DELETE /api/gateway/visualflows - Publish: POST /api/gateway/visualflows/{flow_id}/publish - Run input schema: GET /api/gateway/bundles/{bundle_id}/flows/{flow_id}/input_schema - Runs/commands: POST /api/gateway/runs/start, POST /api/gateway/commands - Replay/stream: GET /api/gateway/runs/{run_id}/ledger, GET /api/gateway/runs/{run_id}/ledger/stream - Artifacts: GET /api/gateway/runs/{run_id}/artifacts/...

The static @abstractframework/flow server, Vite dev proxy, and Python FastAPI host all proxy /api/gateway/* and inject the configured Gateway bearer token server-side. This is required because browser EventSource cannot send custom auth headers.

Legacy/dev FastAPI host

The reference host in web/ is now a Gateway proxy/static host by default. When ABSTRACTFLOW_ENABLE_LOCAL_RUNTIME=1 is set, it also provides compatibility routes for: - Flow CRUD (web/backend/routes/flows.py) storing ./flows/*.json relative to its working dir - Durable stores for runs/ledger/artifacts (web/backend/services/runtime_stores.py) - WebSocket execution (web/backend/routes/ws.py) with message types: - { "type": "run", "input_data": {…} } - { "type": "resume", "response": "…" } - { "type": "control", "action": "pause|resume|cancel", "run_id": "…" }

These local routes remain for development/reference compatibility only. The normal browser editor path uses /api/gateway/* and Gateway's run/ledger/artifact contracts. See web-editor.md for current run instructions.

Workflow bundles (.flow)

WorkflowBundles package a root VisualFlow JSON plus any referenced subflows into a single .flow (zip) file (manifest + flow JSON files).

  • CLI: abstractflow bundle pack|inspect|unpack (abstractflow/cli.py)
  • Implementation delegates to AbstractRuntime: abstractflow/workflow_bundle.py
  • Format/packing semantics are owned by AbstractRuntime; AbstractFlow is a thin wrapper.

Evidence: ../tests/test_workflow_bundle_pack.py, ../abstractflow/workflow_bundle.py.

What AbstractFlow owns vs delegates

Owns in this repo - VisualFlow schema (abstractflow/visual/models.py) - Host wiring helpers (abstractflow/visual/executor.py, abstractflow/visual/session_runner.py) - Public runner conveniences (abstractflow/runner.py) - Reference web editor app (web/) - CLI wrapper (abstractflow/cli.py)

Delegates to AbstractRuntime - Compilation semantics and builtins (abstractflow/compiler.py, abstractflow/visual/builtins.py) - Adapter implementations (abstractflow/adapters/*) - WorkflowBundle format and IO (abstractflow/workflow_bundle.py)