Files
wehub-resource-sync e768098d0e
tools_continuous_delivery / Private PyPI non-main branch release (push) Has been skipped
tools_continuous_delivery / Private PyPI main branch release (push) Failing after 2m42s
Publish Promptflow Doc / Build (push) Has been cancelled
Publish Promptflow Doc / Deploy (push) Has been cancelled
Flake8 Lint / flake8 (push) Has been cancelled
Spell check CI / Spell_Check (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:39:52 +08:00

119 lines
3.7 KiB
Python

"""Visualize Phase 2 workflows in agent-framework-devui.
Loads one or more module-level ``workflow`` objects from this folder and
launches the DevUI web app so you can inspect the executor graph and run
the workflow interactively.
Examples:
# Visualize all phase-2-rebuild samples (default)
python visualize_workflow.py
# Visualize a single sample
python visualize_workflow.py --file 03_conditional_flow.py
# Visualize multiple specific samples
python visualize_workflow.py --file 01_linear_flow.py --file 04_parallel_flow.py
# Custom port, don't auto-open browser
python visualize_workflow.py --port 9000 --no-open
Prerequisites:
pip install agent-framework-devui --pre
"""
from __future__ import annotations
import argparse
import os
import sys
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
GUIDE_ROOT = SCRIPT_DIR.parent
if str(GUIDE_ROOT) not in sys.path:
sys.path.insert(0, str(GUIDE_ROOT))
from workflow_loader import load_workflow # noqa: E402
# Default sample set — every numbered workflow file in this folder.
DEFAULT_SAMPLES = sorted(
p.name for p in SCRIPT_DIR.glob("[0-9][0-9]_*.py")
)
def _load_one(file_name: str):
"""Load a single workflow file by re-using ``workflow_loader.load_workflow``.
``load_workflow()`` reads the ``MAF_WORKFLOW_FILE`` env var, so we set it
per file and restore the previous value afterwards.
"""
workflow_path = SCRIPT_DIR / file_name
if not workflow_path.exists():
raise FileNotFoundError(f"Workflow file not found: {workflow_path}")
previous = os.environ.get("MAF_WORKFLOW_FILE")
os.environ["MAF_WORKFLOW_FILE"] = str(workflow_path)
try:
return load_workflow()
finally:
if previous is None:
os.environ.pop("MAF_WORKFLOW_FILE", None)
else:
os.environ["MAF_WORKFLOW_FILE"] = previous
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__.split("\n", 1)[0])
parser.add_argument(
"--file",
action="append",
default=None,
help=(
"Workflow file under phase-2-rebuild/ to load. May be passed "
"multiple times. Defaults to all numbered samples."
),
)
parser.add_argument("--port", type=int, default=8080, help="Server port (default: 8080).")
parser.add_argument("--host", default="127.0.0.1", help="Server host (default: 127.0.0.1).")
parser.add_argument(
"--no-open",
action="store_true",
help="Do not auto-open the browser when the server starts.",
)
args = parser.parse_args()
try:
from agent_framework.devui import serve
except ImportError:
try:
from agent_framework_devui import serve # type: ignore[no-redef]
except ImportError as exc:
raise SystemExit(
"agent-framework-devui is not installed.\n"
"Install it with: pip install agent-framework-devui --pre"
) from exc
files = args.file or DEFAULT_SAMPLES
workflows = []
for file_name in files:
print(f"Loading {file_name} ...")
workflow = _load_one(file_name)
workflows.append(workflow)
name = getattr(workflow, "name", workflow.__class__.__name__)
print(f" -> {name}")
print(f"\nLaunching DevUI on http://{args.host}:{args.port} with {len(workflows)} workflow(s)")
print("Pick a workflow from the entity dropdown to inspect its graph and run it.\n")
serve(
entities=workflows,
port=args.port,
host=args.host,
auto_open=not args.no_open,
)
if __name__ == "__main__":
main()