Getting started¶
This guide covers the two primary ways to use AbstractFlow:
- Programmatic flows (Flow + FlowRunner)
- Visual flows (portable VisualFlow JSON authored by the editor in web/)
See also: README, docs index, api.md, faq.md, visualflow.md, web-editor.md, cli.md, architecture.md.
Requirements¶
- Python 3.10+ (
pyproject.toml:requires-python)
Install¶
# From PyPI
pip install abstractflow
Optional extras:
- Host profile for local Python proxy stack + compatibility routes (Flow, FlowRunner, abstractflow.visual local execution, workflow bundles, Agent nodes): pip install "abstractflow[apple]" or pip install "abstractflow[gpu]"
- Agent nodes only, without the host profile: pip install "abstractflow[agent]"
- Documentation site tools: pip install "abstractflow[docs]"
From source (repo root):
pip install -e .
Evidence: dependencies and extras are declared in ../pyproject.toml.
For thin-client gateway-first mode, abstractflow (without extras) is sufficient. Install abstractgateway[http] separately for the backend.
Enable local runtime compatibility only when needed with ABSTRACTFLOW_ENABLE_LOCAL_RUNTIME=1.
If you install a host profile (apple, gpu), the local execution stack is already included for compatibility.
Programmatic and local VisualFlow execution examples below require a host profile:
pip install "abstractflow[apple]" # or abstractflow[gpu]
Programmatic flow (FlowRunner)¶
from abstractflow import Flow, FlowRunner
flow = Flow("linear")
flow.add_node("double", lambda x: x * 2, input_key="value", output_key="doubled")
flow.add_node("add_ten", lambda x: x + 10, input_key="doubled", output_key="final")
flow.add_edge("double", "add_ten")
flow.set_entry("double")
print(FlowRunner(flow).run({"value": 5}))
# {"success": True, "result": 20}
Evidence:
- Flow / FlowNode / FlowEdge are re-exported from AbstractRuntime: ../abstractflow/core/flow.py
- FlowRunner output normalization and “waiting” shape: ../abstractflow/runner.py
- Baseline behavior: ../tests/test_runner.py
Execute a VisualFlow JSON¶
Visual flows are JSON documents matching the Pydantic models in abstractflow/visual/models.py.
Minimal example (single flow, no subflows):
import json
from abstractflow.visual import VisualFlow, execute_visual_flow
with open("my-flow.json", "r", encoding="utf-8") as f:
vf = VisualFlow.model_validate(json.load(f))
print(execute_visual_flow(vf, {"prompt": "Hello"}, flows={vf.id: vf}))
If your flow uses subflows:
- load all referenced *.json flows into the flows={flow_id: VisualFlow} mapping, or
- package them as a WorkflowBundle (.flow) and load via AbstractRuntime (see cli.md).
Convenient loader:
from pathlib import Path
import json
from abstractflow.visual import VisualFlow
def load_flows(dir_path: str) -> dict[str, VisualFlow]:
flows: dict[str, VisualFlow] = {}
for p in Path(dir_path).glob("*.json"):
vf = VisualFlow.model_validate(json.loads(p.read_text(encoding="utf-8")))
flows[vf.id] = vf
return flows
Evidence: - VisualFlow execution wiring: ../abstractflow/visual/executor.py - Subflow reachability / registry behavior: ../tests/test_visual_subflow_registry_reachability.py, ../tests/test_visual_subflow_recursion.py
Run the visual editor (local)¶
The modern editor talks to AbstractGateway. Follow: web-editor.md.
Quick start (no repo clone needed):
pip install "abstractgateway[http]" abstractflow
export ABSTRACTGATEWAY_AUTH_TOKEN=dev-token
abstractgateway --port 8080
export ABSTRACTGATEWAY_AUTH_TOKEN=dev-token
npx @abstractframework/flow --gateway-url http://127.0.0.1:8080
Tip (from source): install Flow and Gateway editably, then run npm run dev from web/frontend with ABSTRACTGATEWAY_AUTH_TOKEN set so Vite can inject Gateway auth in its proxy.
Workflow bundles (.flow)¶
To package a VisualFlow + subflows into a single file, use the CLI: - cli.md
Waiting runs (durable asks/events/schedules)¶
Some flows intentionally block waiting for external input (e.g. ask_user, wait_event, wait_until).
FlowRunner.run()returns{"waiting": True, "state": <RunState>, ...}when blocked (abstractflow/runner.py).execute_visual_flow()returns a friendly shape includingwaiting,wait_key, and optional UX fields (prompt,choices,allow_free_text) (abstractflow/visual/executor.py).- Note: waiting results are reported as
success: Falsewith anerrormessage (the run is not “failed”; it is blocked on input).
To resume a run you need a host that can call Runtime.resume(...) (the web editor does this via WebSocket; see web-editor.md).