#!/usr/bin/env python3 """ Adolf CLI — interactive REPL for the multi-channel gateway. Usage: python3 cli.py [--url http://localhost:8000] [--session cli-alvis] """ import argparse import json import os import sys import urllib.request GATEWAY = "http://localhost:8000" def post_message(gateway: str, text: str, session_id: str) -> None: payload = json.dumps({ "text": text, "session_id": session_id, "channel": "cli", "user_id": os.getlogin(), }).encode() req = urllib.request.Request( f"{gateway}/message", data=payload, headers={"Content-Type": "application/json"}, method="POST", ) with urllib.request.urlopen(req, timeout=10) as r: if r.status != 202: print(f"[error] gateway returned {r.status}", file=sys.stderr) sys.exit(1) def wait_for_reply(gateway: str, session_id: str, timeout: int = 400) -> str: """Open SSE stream and return first data event.""" req = urllib.request.Request( f"{gateway}/reply/{session_id}", headers={"Accept": "text/event-stream"}, ) with urllib.request.urlopen(req, timeout=timeout + 5) as r: for raw_line in r: line = raw_line.decode("utf-8").rstrip("\n") if line.startswith("data:"): return line[5:].strip().replace("\\n", "\n") return "" def main(): parser = argparse.ArgumentParser(description="Adolf CLI") parser.add_argument("--url", default=GATEWAY, help="Gateway URL") parser.add_argument("--session", default=f"cli-{os.getlogin()}", help="Session ID") parser.add_argument("--timeout", type=int, default=400, help="Reply timeout (seconds)") args = parser.parse_args() print(f"Adolf CLI (session={args.session}, gateway={args.url})") print("Type your message and press Enter. Ctrl+C or Ctrl+D to exit.\n") try: while True: try: text = input("> ").strip() except EOFError: break if not text: continue post_message(args.url, text, args.session) print("...", end="", flush=True) reply = wait_for_reply(args.url, args.session, timeout=args.timeout) print(f"\r{reply}\n") except KeyboardInterrupt: print("\nbye") if __name__ == "__main__": main()