aboutsummaryrefslogtreecommitdiff
path: root/app/backends/qwen.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-24 16:08:33 -0400
committerhistoria <historiavg@proton.me>2026-08-24 16:08:33 -0400
commit1ff9a635bd9b033b631a6b525891b7eb44e189d3 (patch)
tree6dbcd7e682d516770be4c0724db793666c93dd5f /app/backends/qwen.py
parentafd1c67d92c7f32389d5f652b9fa71530538a16f (diff)
downloadtts-audiobook-generator-1ff9a635bd9b033b631a6b525891b7eb44e189d3.tar.gz
feat: clearer split between local (managed) and remote URLs and server status
Diffstat (limited to 'app/backends/qwen.py')
-rw-r--r--app/backends/qwen.py53
1 files changed, 42 insertions, 11 deletions
diff --git a/app/backends/qwen.py b/app/backends/qwen.py
index 64f3996..160c0f1 100644
--- a/app/backends/qwen.py
+++ b/app/backends/qwen.py
@@ -27,6 +27,7 @@ from backends import (
common,
envs,
format_launch_hint,
+ probe,
servers,
)
from converter import config
@@ -216,15 +217,6 @@ def detect() -> BackendStatus:
installed = _is_installed()
custom_port = _config_port(config.QWEN_API_URL, DEFAULT_CUSTOM_PORT)
clone_port = _config_port(config.CLONE_API_URL, DEFAULT_CLONE_PORT)
- # Probe each port separately: whichever answers names the running
- # model — CustomVoice (speaker mode) or Base (voice clone); either
- # suffices for a conversion on its own.
- custom_up = common.server_running(config.QWEN_API_URL)
- clone_up = common.server_running(config.CLONE_API_URL)
- running = custom_up or clone_up
- running_models = [name for name, up in
- (("Base", clone_up), ("CustomVoice", custom_up))
- if up]
details: List[str] = []
details.append("pip: installed" if installed else
"not installed — run setup to pip install qwen-tts")
@@ -240,15 +232,54 @@ def detect() -> BackendStatus:
[demo, QWEN_BASE_MODEL, "--ip", "127.0.0.1",
"--port", str(clone_port)]),
]
+ managed = servers.manages(specs)
+ # Which local servers this tool started (pid alive) name the running
+ # models; a remotely-run demo names them via the probe instead.
+ local_models = [name for name, spec in
+ (("Base", specs[1]), ("CustomVoice", specs[0]))
+ if servers.alive(spec.name)]
+ remote_models, remote_urls = _detect_remote(managed)
+ running_models = list(dict.fromkeys(local_models + remote_models))
return BackendStatus("qwen", "qwen-tts",
installed=installed, configured=installed,
- running=running, details=details,
+ running=managed or bool(remote_urls),
+ details=details,
launch_hint=format_launch_hint(specs),
servers=specs,
- managed=servers.manages(specs),
+ managed=managed,
+ remote=bool(remote_urls),
+ remote_urls=remote_urls,
+ remote_models=remote_models,
running_models=running_models)
+def _detect_remote(managed: bool = False):
+ """Detect externally-run qwen demo servers at the remote URLs.
+
+ Returns ``([model, ...], {spec_name: url})``. Each remote URL (CustomVoice
+ and Base) is probed independently and must answer as the matching demo
+ (see probe.identify_server); a remote URL equal to the local URL for a
+ server this tool started is ignored (already reported "[local]").
+ """
+ remote_models = []
+ remote_urls = {}
+ for spec_name, url, local_url, identity in (
+ ("qwen-clone", config.CLONE_REMOTE_URL, config.CLONE_API_URL,
+ probe.IDENTITY_QWEN_CLONE),
+ ("qwen-custom", config.QWEN_REMOTE_URL, config.QWEN_API_URL,
+ probe.IDENTITY_QWEN_CUSTOM)):
+ url = (url or "").strip()
+ if not url:
+ continue
+ if managed and probe.same_endpoint(url, local_url):
+ continue
+ if probe.identify_server(url) == identity:
+ remote_urls[spec_name] = url
+ remote_models.append(
+ "Base" if spec_name == "qwen-clone" else "CustomVoice")
+ return remote_models, remote_urls
+
+
configure_actions: List[ConfigureAction] = [
ConfigureAction("Reconfigure qwen-tts (ports/speaker)", run_tui),
]