Select a walkthrough step to explore its source.
Full source text
"""Entry point for the Astral Omnidominion Operating System demo.
This wrapper keeps the execution experience consistent with other demos by
invoking the underlying TypeScript implementation via ``npm run``. It is
intentionally lightweight: the Python layer only assembles the command,
ensures we execute from the repository root, and forwards any user-supplied
arguments verbatim.
"""
from __future__ import annotations
import os
import subprocess
import sys
from pathlib import Path
from typing import Callable, Iterable, Protocol
class _Runner(Protocol):
def __call__(self, cmd: list[str], *, check: bool, cwd: str | os.PathLike[str]) -> subprocess.CompletedProcess:
...
REPO_ROOT = Path(__file__).resolve().parents[2]
DEFAULT_ARGS = ["--network", "localhost", "--yes", "--no-compose", "--skip-deploy"]
AUTO_FLAG = "--auto"
AUTO_ENV = "ASTRAL_OS_AUTO"
def build_command(args: Iterable[str]) -> list[str]:
"""Construct the npm command that drives the demo."""
return ["npm", "run", "demo:agi-os:first-class", "--", *args]
def run(
argv: Iterable[str] | None = None,
*,
runner: _Runner | None = None,
is_interactive: Callable[[], bool] | None = None,
) -> int:
"""Execute the Astral Omnidominion demo through npm.
Args:
argv: Optional iterable of CLI arguments to forward to the demo.
runner: Optional callable used to execute the command. Defaults to
:func:`subprocess.run` and primarily exists to keep tests fast and
deterministic.
Returns:
The exit code from the underlying npm script.
"""
args = list(argv) if argv is not None else sys.argv[1:]
normalized_args, _ = _normalize_args(args, is_interactive)
cmd = build_command(normalized_args)
runner = runner or subprocess.run
result = runner(cmd, check=False, cwd=str(REPO_ROOT))
return result.returncode
def _normalize_args(
args: list[str], is_interactive: Callable[[], bool] | None
) -> tuple[list[str], bool]:
"""Apply automation defaults while respecting explicit caller intent."""
is_interactive = is_interactive or sys.stdin.isatty
requested = _auto_requested(args)
args = [arg for arg in args if arg != AUTO_FLAG]
if not args:
# Default to the automation-friendly profile even in interactive
# shells so ``python run_demo.py`` never blocks on nested prompts.
# The caller can still override the behavior by explicitly passing
# interactive flags.
return DEFAULT_ARGS, requested or not is_interactive()
if requested:
args = _merge_defaults(args)
return args, requested
def _auto_requested(args: Iterable[str]) -> bool:
env_value = os.environ.get(AUTO_ENV, "").strip().lower()
env_requested = env_value in {"1", "true", "yes", "on"}
return AUTO_FLAG in args or env_requested
def _merge_defaults(args: list[str]) -> list[str]:
"""Ensure automation defaults are present without clobbering overrides."""
def _has_flag(flag: str, values: list[str]) -> bool:
if flag == "--network":
return any(value == flag or value.startswith(f"{flag}=") for value in values)
return flag in values
merged: list[str] = []
merged.extend(args)
if not _has_flag("--network", merged):
merged.extend(["--network", "localhost"])
for flag in ["--yes", "--no-compose", "--skip-deploy"]:
if not _has_flag(flag, merged):
merged.append(flag)
return merged
def main() -> None:
raise SystemExit(run())
if __name__ == "__main__":
main()