"""Noise WebSocket protocol gateway transport.""" import os import sys import subprocess import json from typing import Dict, Any, Optional, List, Tuple class NoiseGateway: """Primary fast gateway transport connecting via Noise protocol.""" def __init__(self, node: str = "muse"): self.node = node self.netvm_bin = os.path.expanduser("~/Projects/NetVM/bin") def _call_hybrid(self, func_name: str, *args, **kwargs) -> Tuple[Any, Optional[str]]: """Try calling muse_hybrid directly if available.""" try: if self.netvm_bin not in sys.path: sys.path.insert(0, self.netvm_bin) import muse_hybrid func = getattr(muse_hybrid, func_name, None) if func: return func(self.node, *args, **kwargs) except Exception as e: return None, str(e) return None, "muse_hybrid not found" def list_threads(self) -> Tuple[Optional[List[Dict[str, Any]]], Optional[str]]: res, err = self._call_hybrid("get_threads") if res is not None: return res, None # CLI fallback via muse-cli-node cli_path = os.path.join(self.netvm_bin, "muse-cli-node") if os.path.exists(cli_path): try: proc = subprocess.run([cli_path, self.node, "threads", "--json"], capture_output=True, text=True, timeout=10) if proc.returncode == 0: return json.loads(proc.stdout), None except Exception as e: return None, str(e) return None, err or "gateway unavailable" def send_message(self, message: str, thread_id: Optional[str] = None) -> Tuple[Optional[Dict[str, Any]], Optional[str]]: res, err = self._call_hybrid("send_message", message=message, thread_id=thread_id) if res is not None: return res, None cli_path = os.path.join(self.netvm_bin, "muse-cli-node") if os.path.exists(cli_path): try: cmd = [cli_path, self.node, "send", message] if thread_id: cmd += ["--thread", thread_id] proc = subprocess.run(cmd, capture_output=True, text=True, timeout=15) if proc.returncode == 0: return {"ok": True, "output": proc.stdout}, None except Exception as e: return None, str(e) return None, err or "gateway unavailable"