workers: let every isolated-venv worker point at a remote service

Each `ensure_service()` already returns a base URL, so a worker can be
pointed at a service running elsewhere — another host, a container, a
rented RunPod pod — without anything downstream noticing. Only the TTS
backends had that escape hatch (parler/melo, checked at the caller);
now the check lives in the workers themselves, per-model via
`service_url` in the config plus a CODERAI_*_SERVICE_URL env var:

  vllm, ds4, kt, h3, pyannote, melotts, canary, crisperwhisper, parler

Each verifies the remote's health check before returning it, so a stale
or wrong URL fails loudly instead of surfacing as a confusing timeout
later. vLLM additionally checks that the remote actually serves the
requested model — the OCR path asks for surya-2 by name, and a generic
remote vLLM would otherwise be proxied silently.

colibri/k3 are left out: they speak a stdin/stdout mux protocol, not
HTTP, so there is no URL to redirect.
Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0182DhR1eFNPQyGmDrpHbedY
parent b456c041
......@@ -124,6 +124,19 @@ def ensure_service(model_name: str, config: dict = None,
First call may build the venv and download the model, so the timeout is
generous. Raises RuntimeError if the service never comes up."""
config = config or {}
# An explicit `service_url` points at a NeMo worker running somewhere else — another
# host, a container, a rented pod — so nothing is built, spawned or downloaded
# here and coderai just proxies to it. This function already returns a URL, so
# its callers cannot tell the difference.
_remote = ((config.get("service_url") or "") or os.environ.get("CODERAI_CANARY_SERVICE_URL") or "").strip()
if _remote:
_remote = str(_remote).rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
print(f"[canary] using the configured remote service at {_remote}", flush=True)
return _remote
with _lock:
svc = _services.get(model_name)
if svc and svc["proc"].poll() is None and _health_ok(svc["url"]):
......
......@@ -111,6 +111,19 @@ def _health_ok(url: str) -> bool:
def ensure_service(model_name: str, config: dict = None,
ready_timeout: float = 1800.0) -> str:
config = config or {}
# An explicit `service_url` points at a CrisperWhisper worker running somewhere else — another
# host, a container, a rented pod — so nothing is built, spawned or downloaded
# here and coderai just proxies to it. This function already returns a URL, so
# its callers cannot tell the difference.
_remote = ((config.get("service_url") or "") or os.environ.get("CODERAI_CRISPERWHISPER_SERVICE_URL") or "").strip()
if _remote:
_remote = str(_remote).rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
print(f"[crisperwhisper] using the configured remote service at {_remote}", flush=True)
return _remote
with _lock:
svc = _services.get(model_name)
if svc and svc["proc"].poll() is None and _health_ok(svc["url"]):
......
......@@ -352,6 +352,19 @@ def ensure_service(cfg, model_file: Optional[str] = None,
downloading ``cfg.model_variant``. ``ctx`` overrides the ds4 global context
(so the per-model n_ctx configuration wins). Returns the base URL.
"""
# An explicit `service_url` points at a ds4-server running somewhere else — another
# host, a container, a rented pod — so nothing is built, spawned or downloaded
# here and coderai just proxies to it. This function already returns a URL, so
# its callers cannot tell the difference.
_remote = (str(getattr(cfg, "service_url", "") or "") or os.environ.get("CODERAI_DS4_SERVICE_URL") or "").strip()
if _remote:
_remote = str(_remote).rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
print(f"[ds4] using the configured remote service at {_remote}", flush=True)
return _remote
resolved, svc_key = resolve_service_key(cfg, model_file)
with _lock:
svc = _services.get(svc_key)
......
......@@ -272,6 +272,21 @@ def ensure_service(model_path: str, config: dict = None,
ready_timeout: float = 1800.0) -> str:
"""Start (or reuse) the H3 service for one checkpoint; return its base URL."""
config = config or {}
# An explicit `service_url` points at a service running somewhere else —
# another host, a container, a rented RunPod pod — so nothing is spawned or
# downloaded here and coderai just proxies to it. Same contract the TTS
# backends have used for parler/melo, and the hook that makes a per-engine
# remote pod possible without changing anything downstream: this function
# already returns a URL, so its callers cannot tell the difference.
_remote = (config.get("service_url") or os.environ.get("CODERAI_H3_SERVICE_URL") or "").strip()
if _remote:
_remote = str(_remote).rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
print(f"[h3] using the configured remote service at {_remote}", flush=True)
return _remote
with _lock:
svc = _services.get(model_path)
if svc and svc["proc"].poll() is None and _health_ok(svc["url"]):
......
......@@ -124,6 +124,19 @@ def _launch_cmd(cfg, host: str, port: int, model_path: str) -> list:
def ensure_service(cfg, model_path: Optional[str] = None,
ready_timeout: float = 3600.0) -> str:
"""Launch (or reuse) the SGLang server for a ktransformers model; return its base URL."""
# An explicit `service_url` points at a SGLang server running somewhere else — another
# host, a container, a rented pod — so nothing is built, spawned or downloaded
# here and coderai just proxies to it. This function already returns a URL, so
# its callers cannot tell the difference.
_remote = (str(getattr(cfg, "service_url", "") or "") or os.environ.get("CODERAI_KT_SERVICE_URL") or "").strip()
if _remote:
_remote = str(_remote).rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
print(f"[kt] using the configured remote service at {_remote}", flush=True)
return _remote
resolved, svc_key = resolve_service_key(cfg, model_path)
with _lock:
svc = _services.get(svc_key)
......
......@@ -123,11 +123,28 @@ def _health_ok(url: str) -> bool:
return False
def ensure_service(model_name: str, ready_timeout: float = 1800.0) -> str:
def ensure_service(model_name: str, ready_timeout: float = 1800.0,
config: dict = None) -> str:
"""Start (or reuse) the worker for ``model_name`` and return its base URL.
First call bootstraps the venv and downloads the model, so the timeout is
generous. Raises RuntimeError if the service never comes up."""
# An explicit `service_url` points at a service running somewhere else —
# another host, a container, a rented RunPod pod — so nothing is spawned or
# downloaded here and coderai just proxies to it. Same contract the TTS
# backends have used for parler/melo, and the hook that makes a per-engine
# remote pod possible without changing anything downstream: this function
# already returns a URL, so its callers cannot tell the difference.
_remote = ((config or {}).get("service_url")
or os.environ.get("CODERAI_MELOTTS_SERVICE_URL") or "").strip()
if _remote:
_remote = _remote.rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
print(f"[melotts] using the configured remote service at {_remote}", flush=True)
return _remote
with _lock:
svc = _services.get(model_name)
if svc and svc["proc"].poll() is None and _health_ok(svc["url"]):
......
......@@ -124,6 +124,19 @@ def ensure_service(model_name: str, ready_timeout: float = 1800.0) -> str:
First call bootstraps the venv and downloads the model, so the timeout is
generous. Raises RuntimeError if the service never comes up."""
# An explicit service URL points at a parler worker running somewhere else —
# another host, a container, a rented pod — so nothing is built, spawned or
# downloaded here. The per-model `service_url` is handled one level up in
# tts_backends; this env var covers direct callers too.
_remote = (os.environ.get("CODERAI_PARLER_SERVICE_URL") or "").strip()
if _remote:
_remote = _remote.rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
print(f"[parler] using the configured remote service at {_remote}", flush=True)
return _remote
with _lock:
svc = _services.get(model_name)
if svc and svc["proc"].poll() is None and _health_ok(svc["url"]):
......
......@@ -151,6 +151,21 @@ def ensure_service(model_name: str = None, config: dict = None,
ready_timeout: float = 1800.0) -> str:
"""Start (or reuse) the pyannote worker and return its base URL."""
config = config or {}
# An explicit `service_url` points at a service running somewhere else —
# another host, a container, a rented RunPod pod — so nothing is spawned or
# downloaded here and coderai just proxies to it. Same contract the TTS
# backends have used for parler/melo, and the hook that makes a per-engine
# remote pod possible without changing anything downstream: this function
# already returns a URL, so its callers cannot tell the difference.
_remote = (config.get("service_url") or os.environ.get("CODERAI_PYANNOTE_SERVICE_URL") or "").strip()
if _remote:
_remote = str(_remote).rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
print(f"[pyannote] using the configured remote service at {_remote}", flush=True)
return _remote
model_name = model_name or config.get("model_path") or _default_model()
with _lock:
svc = _services.get(model_name)
......
......@@ -144,6 +144,18 @@ def _launch_cmd(py, cfg, host: str, port: int, model_path: str,
return cmd
def _remote_serves(url: str, name: str) -> bool:
"""True when a remote vLLM's /v1/models lists ``name`` (or a suffix match)."""
import requests
try:
r = requests.get(url + "/v1/models", timeout=5)
ids = [str(m.get("id", "")) for m in (r.json().get("data") or [])]
except Exception:
return False
tail = name.rstrip("/").split("/")[-1]
return any(i == name or i.rstrip("/").split("/")[-1] == tail for i in ids)
def ensure_service(cfg, model_path: Optional[str] = None,
served_name: Optional[str] = None,
ready_timeout: float = 3600.0) -> str:
......@@ -151,6 +163,27 @@ def ensure_service(cfg, model_path: Optional[str] = None,
``model_path``/``served_name`` override the config (used by the OCR subsystem to serve
surya-2 on its own vLLM instance alongside any LLM instance)."""
# An explicit `service_url` points at a vLLM running somewhere else — another
# host, a container, a rented RunPod pod (where vLLM's own image is the ready-
# made option) — so nothing is spawned or downloaded here. This function
# already returns a URL, so its callers cannot tell the difference.
_remote = (str(getattr(cfg, "service_url", "") or "")
or os.environ.get("CODERAI_VLLM_SERVICE_URL") or "").strip()
if _remote:
_remote = _remote.rstrip("/")
if not _health_ok(_remote):
raise RuntimeError(
f"configured service_url {_remote} is not answering its health check")
# A remote vLLM serves whatever it was started with. When the caller asks
# for a specific model (the OCR path does, for surya-2), make sure that
# model is actually there rather than silently proxying to the wrong one.
_want = (served_name or model_path or "").strip()
if _want and not _remote_serves(_remote, _want):
raise RuntimeError(
f"configured service_url {_remote} does not serve {_want}")
print(f"[vllm] using the configured remote service at {_remote}", flush=True)
return _remote
resolved, svc_key = resolve_service_key(cfg, model_path)
if served_name:
svc_key = f"{svc_key}|{served_name}"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment