feat: surface fleet_singleton flag on /topologies/services
Adds a fleet_singletons array to ServiceCatalogResponse so per-decky add UIs can filter out services like LLMNR that run once fleet-wide (and would 422 server-side at the live add endpoint). The existing 'services: list[str]' field is unchanged for back-compat with MazeNET/useMazeApi.ts:257; the new field is additive. decnet_web/src/hooks/useServiceRegistry.ts wraps the endpoint with a module-scoped cache (registry only changes on BYOS install / plugin drop, neither of which happens mid-session) and exposes a precomputed .perDecky list so consumers don't need to re-derive the diff.
This commit is contained in:
@@ -404,6 +404,12 @@ class NotEditableResponse(BaseModel):
|
||||
|
||||
class ServiceCatalogResponse(BaseModel):
|
||||
services: list[str]
|
||||
# Subset of ``services`` that run once fleet-wide (LLMNR, etc.) and
|
||||
# therefore can't be added to a single decky. Per-decky add UIs
|
||||
# filter these out so the operator never picks an option that the
|
||||
# server would reject as 422. Empty when the registry has no
|
||||
# singletons.
|
||||
fleet_singletons: list[str] = PydanticField(default_factory=list)
|
||||
|
||||
|
||||
class ArchetypeEntry(BaseModel):
|
||||
|
||||
@@ -42,7 +42,14 @@ router = APIRouter()
|
||||
async def api_list_services(
|
||||
_viewer: dict = Depends(require_viewer),
|
||||
) -> ServiceCatalogResponse:
|
||||
return ServiceCatalogResponse(services=all_service_names())
|
||||
from decnet.services.registry import all_services
|
||||
registry = all_services()
|
||||
return ServiceCatalogResponse(
|
||||
services=all_service_names(),
|
||||
fleet_singletons=[
|
||||
name for name, svc in registry.items() if svc.fleet_singleton
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
|
||||
Reference in New Issue
Block a user