config: make a settings save reach the engine and the front

Configuring a remote capability in the UI did nothing until a restart,
which makes the feature unusable as shipped.

The admin API is served by the SYSTEM worker, so a save updates that
process's config object. The remote gateway, the engine blocks and the
front's burst-to-RunPod path all read a DIFFERENT process's copy. The
engine's /internal/reload-config — which the front pushes on a config
change — re-read models.json only, and the front's own refresh copied a
fixed field list that included neither `runpod` nor `remotes`.

Both now carry them: the engine re-reads config.json into its live config
on reload, and the front refreshes runpod/remotes along with the rest.

Found by trying to use the feature on the running instance rather than by
reading the code, which is the only way this class of bug shows up.
Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0182DhR1eFNPQyGmDrpHbedY
parent ef60591a
...@@ -559,6 +559,26 @@ async def internal_reload_config(request: Request): ...@@ -559,6 +559,26 @@ async def internal_reload_config(request: Request):
n = sum(len(config_manager.models_data.get(c, []) or []) for c in _cats) n = sum(len(config_manager.models_data.get(c, []) or []) for c in _cats)
except Exception as e: except Exception as e:
return {"ok": False, "error": str(e)} return {"ok": False, "error": str(e)}
# Also re-read config.json. The admin API is served by the SYSTEM worker, so
# a settings save updates that process's config — not this engine's, which is
# where the remote gateway and the engine blocks are read. Without this,
# configuring a remote capability or a RunPod account silently does nothing
# until a restart.
try:
from codai.config import ConfigManager
from codai.admin.routes import config_manager as _cm
if _cm is not None and getattr(_cm, "config_dir", None):
fresh = ConfigManager(str(_cm.config_dir))
fresh.load()
for _f in ("remotes", "runpod", "ds4", "colibri", "k3", "ktransformers",
"vllm", "server", "models", "offload", "image", "jobs",
"enhance", "ocr", "thermal", "broker"):
if hasattr(fresh.config, _f):
setattr(_cm.config, _f, getattr(fresh.config, _f))
except Exception as exc:
print(f"[reload] config.json refresh failed: {exc}", flush=True)
try: try:
from codai.models.manager import multi_model_manager from codai.models.manager import multi_model_manager
assigned = data.get("assigned") assigned = data.get("assigned")
......
...@@ -1104,6 +1104,10 @@ class FrontProxy: ...@@ -1104,6 +1104,10 @@ class FrontProxy:
for f in ("server", "backend", "models", "offload", "vulkan", "image", for f in ("server", "backend", "models", "offload", "vulkan", "image",
"whisper", "archive", "thermal", "jobs", "enhance", "ds4", "colibri", "whisper", "archive", "thermal", "jobs", "enhance", "ds4", "colibri",
"k3", "ktransformers", "vllm", "k3", "ktransformers", "vllm",
# The front's burst-to-RunPod path reads config.runpod, and
# `remotes` decides capability routing: without these a
# settings save reached neither until a restart.
"runpod", "remotes",
"compaction", "broker", "system_prompt", "tools_closer_prompt", "compaction", "broker", "system_prompt", "tools_closer_prompt",
"grammar_guided", "parser", "tmp_dir"): "grammar_guided", "parser", "tmp_dir"):
if hasattr(new, f): if hasattr(new, f):
......
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