aboutsummaryrefslogtreecommitdiff
path: root/app/backends/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/backends/__init__.py')
-rw-r--r--app/backends/__init__.py36
1 files changed, 34 insertions, 2 deletions
diff --git a/app/backends/__init__.py b/app/backends/__init__.py
index 9e8bf31..488c36e 100644
--- a/app/backends/__init__.py
+++ b/app/backends/__init__.py
@@ -24,6 +24,7 @@ automatically.
import shlex
from dataclasses import dataclass, field
+from pathlib import Path
from typing import Callable, Dict, List, Optional
@@ -35,10 +36,24 @@ class ServerSpec:
on separate ports). ARGV is the exact command line the hub spawns (using
the managed venv's absolute binaries, so no shell activation is needed);
URL is the endpoint ``common.server_running`` probes to decide readiness.
+
+ CWD is the working directory the server is spawned in. It matters for
+ servers that discover resources relative to their process working
+ directory (audio.cpp resolves ``model_specs/<family>.json`` by walking up
+ from its cwd), so the hub starts them from their checkout root. None
+ inherits the hub's cwd (today's behavior).
+
+ IDENTITY is the ``backends.probe.IDENTITY_*`` constant the server is
+ expected to answer as once it is truly ready. When set, ``servers.start``
+ waits for the server to answer HTTP with that identity — not merely to
+ accept TCP connections — so "listening but still starting" servers are
+ caught. None keeps the plain TCP-connect readiness check.
"""
name: str
url: str
argv: List[str]
+ cwd: Optional[Path] = None
+ identity: Optional[str] = None
@dataclass
@@ -72,6 +87,12 @@ class BackendStatus:
RUNNING_MODELS names which of a multi-server backend's models answered
(qwen: "Base" and/or "CustomVoice", local and remote combined), shown in
parentheses in the hub's status table.
+
+ MODELS_MISSING says the server config references model files that are not
+ on disk (e.g. an audio.cpp server.json entry whose ``path`` was never
+ downloaded); DETAILS then names them. The backend still counts as ready
+ (the hub surfaces the warning), but a conversion would fail until the
+ models are installed.
"""
key: str
label: str
@@ -86,6 +107,7 @@ class BackendStatus:
remote: bool = False
remote_urls: Dict[str, str] = field(default_factory=dict)
remote_models: List[str] = field(default_factory=list)
+ models_missing: bool = False
@property
def ready(self) -> bool:
@@ -94,8 +116,18 @@ class BackendStatus:
def format_launch_hint(servers: List[ServerSpec]) -> str:
- """Join a backend's server argvs into a copy-pasteable launch hint."""
- return " ; ".join(shlex.join(s.argv) for s in servers)
+ """Join a backend's server argvs into a copy-pasteable launch hint.
+
+ A server with a CWD is prefixed with ``cd <cwd> &&`` so the hint works
+ pasted into a shell (the server relies on that working directory).
+ """
+ parts = []
+ for server in servers:
+ command = shlex.join(server.argv)
+ if server.cwd is not None:
+ command = f"cd {shlex.quote(str(server.cwd))} && {command}"
+ parts.append(command)
+ return " ; ".join(parts)
@dataclass