diff --git a/nexusos_cli/cli.py b/nexusos_cli/cli.py index a5c0e93..66dadde 100644 --- a/nexusos_cli/cli.py +++ b/nexusos_cli/cli.py @@ -24,10 +24,8 @@ from . import ncp as services CONFIG_SCHEMA = { "home": "path", "api_url": "url", - "memory_url": "url", "bind_host": "text", "backend_port": "port", - "memory_port": "port", "provider": "provider", "provider_url": "url", "provider_timeout": "positive_int", @@ -39,8 +37,6 @@ CONFIG_SCHEMA = { } LEGACY_TARGETS = { - "-m": "memory", - "--memory": "memory", "-b": "backend", "--backend": "backend", "-f": "frontend", @@ -303,14 +299,13 @@ def diagnostics() -> dict: ) add( "service ports", - all(1 <= port <= 65535 for port in (settings.backend_port, settings.memory_port)), - f"backend={settings.backend_port}, memory={settings.memory_port}", + 1 <= settings.backend_port <= 65535, + f"backend={settings.backend_port}", ) for module in ("fastapi", "uvicorn", "httpx", "pydantic", "yaml"): add(f"import:{module}", _check_import(module), module) add("backend", _http_ok(settings.api_url + "/status"), settings.api_url, required=False) - add("memory service", _http_ok(settings.memory_url + "/"), settings.memory_url, required=False) provider = _provider_payload() add("provider", provider["reachable"], provider["url"], required=False) if settings.manage_ollama: @@ -362,7 +357,7 @@ def cmd_doctor(args) -> int: def service_status() -> dict: payload = {} - for key in ("backend", "memory", "frontend"): + for key in ("backend", "frontend"): svc = services.SERVICES[key] pid = services.read_pid(svc) payload[key] = { @@ -380,7 +375,7 @@ def cmd_status(args) -> int: _emit(payload, True) return 0 print("Nexus Service Status:\n") - for key in ("backend", "memory", "frontend"): + for key in ("backend", "frontend"): info = payload[key] suffix = f" (PID {info['pid']})" if info["pid"] else "" print(f" {key:<10} {'RUNNING' if info['running'] else 'STOPPED'}{suffix} {info['url']}") @@ -400,7 +395,6 @@ def cmd_monitor(args) -> int: def _target_flag(target: str | None): return { - "memory": "--memory", "backend": "--backend", "frontend": "--frontend", "ai": "--ai", @@ -485,18 +479,14 @@ def cmd_serve(args) -> int: return 2 settings.backend_port = args.port - settings.memory_port = args.memory_port settings.bind_host = host settings.api_url = f"http://127.0.0.1:{args.port}" - settings.memory_url = f"http://127.0.0.1:{args.memory_port}" os.environ["NEXUS_BACKEND_PORT"] = str(args.port) - os.environ["NEXUS_MEMORY_PORT"] = str(args.memory_port) os.environ["NEXUS_BIND_HOST"] = host for origin_host in ("localhost", "127.0.0.1"): - for port in (args.port, args.memory_port): - origin = f"http://{origin_host}:{port}" - if origin not in config.ALLOWED_ORIGINS: - config.ALLOWED_ORIGINS.append(origin) + origin = f"http://{origin_host}:{args.port}" + if origin not in config.ALLOWED_ORIGINS: + config.ALLOWED_ORIGINS.append(origin) if args.allow_lan: # Widen to the addresses this bind actually answers on - NOT "*". # ALLOWED_HOSTS drives TrustedHostMiddleware, which is the DNS-rebinding @@ -508,10 +498,9 @@ def cmd_serve(args) -> int: for name in names: if name not in config.ALLOWED_HOSTS: config.ALLOWED_HOSTS.append(name) - for port in (args.port, args.memory_port): - origin = f"http://{_origin_host(name)}:{port}" - if origin not in config.ALLOWED_ORIGINS: - config.ALLOWED_ORIGINS.append(origin) + origin = f"http://{_origin_host(name)}:{args.port}" + if origin not in config.ALLOWED_ORIGINS: + config.ALLOWED_ORIGINS.append(origin) os.environ.setdefault("NEXUS_ALLOWED_HOSTS", ",".join(config.ALLOWED_HOSTS)) os.environ.setdefault("NEXUS_ALLOWED_ORIGINS", ",".join(config.ALLOWED_ORIGINS)) print( @@ -520,35 +509,13 @@ def cmd_serve(args) -> int: " has full admin and data access." ) - memory_proc = None - memory_log = None - try: - if not args.no_memory and not _http_ok(settings.memory_url + "/"): - log_path = settings.runtime_dir / "memory.log" - log_path.parent.mkdir(parents=True, exist_ok=True) - memory_log = open(log_path, "ab") - memory_proc = subprocess.Popen( - [sys.executable, "-m", "uvicorn", "synapse.memory.service:app", - "--host", host, "--port", str(args.memory_port)], - stdout=memory_log, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL, - ) - print(f"Memory service starting on {host}:{args.memory_port} (log: {log_path})") - print(f"NexusOS serving on http://{host}:{args.port}") - import uvicorn - uvicorn.run( - "synapse.main:sio_app", host=host, port=args.port, - reload=bool(args.reload and settings.source_checkout), - log_level=args.log_level, - ) - finally: - if memory_proc is not None and memory_proc.poll() is None: - memory_proc.terminate() - try: - memory_proc.wait(timeout=5) - except subprocess.TimeoutExpired: - memory_proc.kill() - if memory_log is not None: - memory_log.close() + print(f"NexusOS serving on http://{host}:{args.port}") + import uvicorn + uvicorn.run( + "synapse.main:sio_app", host=host, port=args.port, + reload=bool(args.reload and settings.source_checkout), + log_level=args.log_level, + ) return 0 @@ -608,7 +575,7 @@ def cmd_nvidia_reqs(_args) -> int: def cmd_logs(args) -> int: - keys = ("backend", "memory", "frontend") if args.target == "all" else (args.target,) + keys = ("backend", "frontend") if args.target == "all" else (args.target,) paths = [services.SERVICES[key].log_file for key in keys] for path in paths: print(f"=== {path.name} ===") @@ -751,8 +718,7 @@ def build_parser() -> argparse.ArgumentParser: p = sub.add_parser("serve", help="run NexusOS in the foreground") p.add_argument("--host"); p.add_argument("--port", type=_port, default=settings.backend_port) - p.add_argument("--memory-port", type=_port, default=settings.memory_port) - p.add_argument("--no-memory", action="store_true"); p.add_argument("--allow-lan", action="store_true") + p.add_argument("--allow-lan", action="store_true") p.add_argument("--reload", action="store_true"); p.add_argument("--log-level", default="info") p.set_defaults(fn=cmd_serve) @@ -761,7 +727,7 @@ def build_parser() -> argparse.ArgumentParser: ("stop", cmd_stop, "stop background services"), ): p = sub.add_parser(name, help=help_text) - p.add_argument("target", nargs="?", choices=["all", "backend", "memory", "frontend", "ai"], default="all") + p.add_argument("target", nargs="?", choices=["all", "backend", "frontend", "ai"], default="all") p.set_defaults(fn=fn) sub.add_parser("restart", aliases=["refresh"], help="restart all services").set_defaults(fn=cmd_refresh) sub.add_parser("kill", help="force-stop NexusOS-owned processes").set_defaults(fn=lambda _a: services.cmd_kill() or 0) @@ -771,7 +737,7 @@ def build_parser() -> argparse.ArgumentParser: sub.add_parser("web", help="legacy desktop alias for open").set_defaults(fn=cmd_web) sub.add_parser("panel", help="launch the legacy desktop control panel").set_defaults(fn=cmd_panel) p = sub.add_parser("logs", help="read or follow service logs") - p.add_argument("target", nargs="?", choices=["all", "backend", "memory", "frontend"], default="all") + p.add_argument("target", nargs="?", choices=["all", "backend", "frontend"], default="all") p.add_argument("--lines", type=int, choices=range(1, 10001), default=50, metavar="1..10000") p.add_argument("--follow", "-f", action="store_true"); p.set_defaults(fn=cmd_logs) sub.add_parser("clean", help="remove runtime logs and stale PID files").set_defaults(fn=cmd_clean) diff --git a/nexusos_cli/monitor.py b/nexusos_cli/monitor.py index c4301e0..8697a55 100644 --- a/nexusos_cli/monitor.py +++ b/nexusos_cli/monitor.py @@ -62,7 +62,7 @@ def _provider_payload() -> dict: def _service_status() -> dict: payload = {} - for key in ("backend", "memory", "frontend"): + for key in ("backend", "frontend"): svc = services.SERVICES[key] pid = services.read_pid(svc) payload[key] = { @@ -253,7 +253,6 @@ def collect_snapshot() -> dict: services_payload = _service_status() pids = [ services_payload.get("backend", {}).get("pid"), - services_payload.get("memory", {}).get("pid"), services_payload.get("frontend", {}).get("pid"), ] api = _api_counts(settings.api_url) @@ -268,7 +267,6 @@ def collect_snapshot() -> dict: "recent_tools": _recent_tools(settings.logs_dir / "chat.log"), "paths": { "api_url": settings.api_url, - "memory_url": settings.memory_url, "runtime_dir": str(settings.runtime_dir), }, } @@ -328,7 +326,7 @@ def render_frame(snapshot: dict, *, width: int | None = None, unicode: bool | No lines.append(_row(box, "SERVICES", width)) svcs = snapshot.get("services") or {} - for key, label in (("backend", "backend"), ("memory", "memory"), ("frontend", "frontend")): + for key, label in (("backend", "backend"), ("frontend", "frontend")): info = svcs.get(key) or {} running = bool(info.get("running")) pid = info.get("pid") diff --git a/nexusos_cli/ncp.py b/nexusos_cli/ncp.py index 0a9943c..be38932 100644 --- a/nexusos_cli/ncp.py +++ b/nexusos_cli/ncp.py @@ -146,9 +146,6 @@ def _uvicorn(app: str, port: int): SERVICES = { - "memory": Service("memory", "NEXUS MEMORY SERVICE", settings.memory_port, settings.state_dir, - ["uvicorn synapse.memory"], - lambda: _uvicorn("synapse.memory.service:app", settings.memory_port)), "backend": Service("backend", "NEXUS BACKEND SERVICE", settings.backend_port, settings.state_dir, ["uvicorn synapse.main"], lambda: _uvicorn("synapse.main:sio_app", settings.backend_port)), @@ -468,7 +465,6 @@ def cmd_kill() -> None: print("Force-killing all Nexus processes...") targets = [ (settings.backend_port, "SYNAPSE"), - (settings.memory_port, "MEMORY"), (5173, "INTERFACE"), ] patterns = ["uvicorn synapse", "npm run dev", "vite --host"] diff --git a/synapse/main.py b/synapse/main.py index b405090..cf20e39 100644 --- a/synapse/main.py +++ b/synapse/main.py @@ -184,8 +184,6 @@ from .memory.store import store, MemoryItem from .playbooks.store import playbook_store, PlaybookItem from .search import needs_web_search, web_search -MEMORY_SERVICE = settings.memory_url - app = FastAPI(title="Synapse Backend", version=VERSION) # Alias for startup scripts diff --git a/synapse/nexus_config.py b/synapse/nexus_config.py index 7382adb..bb0ddcf 100644 --- a/synapse/nexus_config.py +++ b/synapse/nexus_config.py @@ -317,13 +317,9 @@ class Settings: "bind_host", "NEXUS_BIND_HOST", "127.0.0.1" )) self.backend_port: int = _int_value("backend_port", "NEXUS_BACKEND_PORT", 8000) - self.memory_port: int = _int_value("memory_port", "NEXUS_MEMORY_PORT", 8001) self.api_url: str = str(_value( "api_url", "NEXUS_API", f"http://127.0.0.1:{self.backend_port}" )).rstrip("/") - self.memory_url: str = str(_value( - "memory_url", "NEXUS_MEMORY_URL", f"http://127.0.0.1:{self.memory_port}" - )).rstrip("/") def as_dict(self) -> Dict[str, Any]: return { @@ -345,8 +341,6 @@ class Settings: "api_url": self.api_url, "bind_host": self.bind_host, "backend_port": self.backend_port, - "memory_port": self.memory_port, - "memory_url": self.memory_url, } # --- local-access allowlists (shared by the backend + memory FastAPI apps) --- @@ -369,7 +363,6 @@ _LOCAL_ORIGINS = [ for h in ("localhost", "127.0.0.1") for p in ( _int_value("backend_port", "NEXUS_BACKEND_PORT", 8000), - _int_value("memory_port", "NEXUS_MEMORY_PORT", 8001), 5173, ) ] diff --git a/tests/test_cli_packaging.py b/tests/test_cli_packaging.py index 873ea78..d3b1753 100644 --- a/tests/test_cli_packaging.py +++ b/tests/test_cli_packaging.py @@ -40,12 +40,10 @@ def test_legacy_cli_spellings_remain_compatible(): assert _normalize_legacy_argv(["start", "-b"]) == ["start", "backend"] assert _normalize_legacy_argv(["stop", "--ai"]) == ["stop", "ai"] - assert _normalize_legacy_argv(["logs", "-m", "--follow"]) == ["logs", "memory", "--follow"] assert _normalize_legacy_argv(["backup", "full"]) == ["backup", "--full"] # -f is --follow for `logs`, but --frontend for start/stop. Translating it # for logs turned `logs -f` into a one-shot tail of the frontend log. assert _normalize_legacy_argv(["logs", "-f"]) == ["logs", "-f"] - assert _normalize_legacy_argv(["logs", "-m", "-f"]) == ["logs", "memory", "-f"] assert _normalize_legacy_argv(["start", "-f"]) == ["start", "frontend"] assert _normalize_legacy_argv(["restore", "-f"]) == ["restore"] assert _normalize_legacy_argv(["help"]) == ["--help"] diff --git a/tests/test_monitor.py b/tests/test_monitor.py index 9d96f99..b9eac43 100644 --- a/tests/test_monitor.py +++ b/tests/test_monitor.py @@ -22,7 +22,6 @@ def test_render_frame_contains_sections(): "version": "0.0.0", "services": { "backend": {"running": True, "pid": 11, "url": "http://127.0.0.1:8000"}, - "memory": {"running": False, "pid": None, "url": "http://127.0.0.1:8001"}, "frontend": {"running": False, "pid": None, "url": "http://127.0.0.1:5173"}, "provider": { "provider": "ollama", @@ -55,7 +54,7 @@ def test_render_frame_contains_sections(): assert "DATA / TOOLS" in frame assert "RUN TOOLCHAINS" in frame assert "backend" in frame and "UP" in frame - assert "memory" in frame and "DOWN" in frame + assert "frontend" in frame and "DOWN" in frame assert "run_snippet" in frame assert "ready python" in frame assert "missing rust" in frame