front: optimistic resident-model list on load/unload (front owns the list)

The front issues every load/unload, so it now updates its own per-engine resident
set in the registry the moment the action succeeds — the models page (whose loaded
status is front-native) reflects it immediately instead of waiting for the next
supervisor engine-state poll. The poll still reconciles the exact keys.
Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011DDv7BchtZQWsnPG6Jm49m
parent e2db1b5c
...@@ -795,7 +795,14 @@ class FrontProxy: ...@@ -795,7 +795,14 @@ class FrontProxy:
target = self.registry.primary() target = self.registry.primary()
if target is None: if target is None:
return JSONResponse({"detail": "No engine available"}, status_code=503) return JSONResponse({"detail": "No engine available"}, status_code=503)
return await self._forward_to_engine(request, target, body) resp = await self._forward_to_engine(request, target, body)
# The front issues the unload, so it updates its OWN resident-model list
# immediately (the supervisor's engine-state poll later reconciles) — the
# models page reflects it at once instead of waiting a poll cycle.
if path and 200 <= getattr(resp, "status_code", 500) < 300:
target.loaded_models = {k for k in target.loaded_models
if not self._key_matches_path(k, path)}
return resp
async def model_load(self, request: Request): async def model_load(self, request: Request):
"""Route an admin model-load to the model's pinned engine (or one that's """Route an admin model-load to the model's pinned engine (or one that's
...@@ -822,7 +829,12 @@ class FrontProxy: ...@@ -822,7 +829,12 @@ class FrontProxy:
target = self.registry.primary() target = self.registry.primary()
if target is None: if target is None:
return JSONResponse({"detail": "No engine available"}, status_code=503) return JSONResponse({"detail": "No engine available"}, status_code=503)
return await self._forward_to_engine(request, target, body) resp = await self._forward_to_engine(request, target, body)
# Front-maintained resident list: mark the model loaded on its engine as
# soon as the load succeeds (supervisor poll reconciles the exact keys).
if path and 200 <= getattr(resp, "status_code", 500) < 300:
target.loaded_models = set(target.loaded_models) | {path}
return resp
def _cooling_engines(self) -> list: def _cooling_engines(self) -> list:
"""Which engines are in thermal cooldown right now (for the Tasks banner).""" """Which engines are in thermal cooldown right now (for the Tasks banner)."""
......
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