diff --git a/headroom/proxy/server.py b/headroom/proxy/server.py index ea9615fcc..10e5260c7 100644 --- a/headroom/proxy/server.py +++ b/headroom/proxy/server.py @@ -2685,15 +2685,29 @@ def create_app(config: ProxyConfig | None = None) -> FastAPI: *, enabled: bool, ready: bool, + optional: bool = False, **details: Any, ) -> dict[str, Any]: - status = "disabled" if not enabled else ("healthy" if ready else "unhealthy") - return { + if not enabled: + status = "disabled" + elif ready: + status = "healthy" + elif optional: + # Optional/non-gating components report "degraded" rather than + # "unhealthy" so the top-level status: "healthy" / ready: true + # payload is not contradicted by a component-level failure label. + status = "degraded" + else: + status = "unhealthy" + result: dict[str, Any] = { "enabled": enabled, "ready": (ready if enabled else True), "status": status, - **details, } + if optional: + result["optional"] = True + result.update(details) + return result def _kompress_health_routers() -> list[ContentRouter]: routers: list[ContentRouter] = [] @@ -2803,6 +2817,7 @@ def create_app(config: ProxyConfig | None = None) -> FastAPI: "kompress": _component_health( enabled=kompress_enabled, ready=proxy.warmup.kompress.status == "loaded", + optional=True, backend=proxy.warmup.kompress.info.get("backend", None), ), } diff --git a/tests/test_proxy_health.py b/tests/test_proxy_health.py index efdad4cc1..b45cb42ad 100644 --- a/tests/test_proxy_health.py +++ b/tests/test_proxy_health.py @@ -69,7 +69,8 @@ def test_readyz_excludes_kompress_from_aggregate_readiness(monkeypatch): assert payload["checks"]["kompress"] == { "enabled": True, "ready": False, - "status": "unhealthy", + "status": "degraded", + "optional": True, "backend": None, } @@ -85,6 +86,7 @@ def test_readyz_promotes_deferred_kompress_after_runtime_load(monkeypatch): "enabled": True, "ready": True, "status": "healthy", + "optional": True, "backend": "onnx", } # The promotion must also clear the startup marker, otherwise the slot @@ -110,6 +112,7 @@ def test_readyz_promotes_kompress_from_module_cache(monkeypatch, attached): "enabled": True, "ready": True, "status": "healthy", + "optional": True, "backend": "onnx", } assert proxy.warmup.kompress.handle is model @@ -141,7 +144,8 @@ def test_readyz_keeps_pending_kompress_unloaded(monkeypatch): assert payload["checks"]["kompress"] == { "enabled": True, "ready": False, - "status": "unhealthy", + "status": "degraded", + "optional": True, "backend": None, } assert compressor.calls == ["is_ready"] @@ -181,6 +185,7 @@ def test_readyz_disabled_kompress_skips_inspection(monkeypatch): "enabled": False, "ready": True, "status": "disabled", + "optional": True, "backend": None, } assert compressor.calls == [] @@ -202,6 +207,7 @@ def test_readyz_per_provider_kompress_override_reenables_health(monkeypatch): "enabled": True, "ready": True, "status": "healthy", + "optional": True, "backend": "onnx", } assert compressor.calls == ["is_ready", "ready_backend"] @@ -222,7 +228,8 @@ def test_readyz_never_calls_lazy_kompress_getters(monkeypatch): assert payload["checks"]["kompress"] == { "enabled": True, "ready": False, - "status": "unhealthy", + "status": "degraded", + "optional": True, "backend": None, } @@ -234,37 +241,73 @@ def test_readyz_never_calls_lazy_kompress_getters(monkeypatch): "null", None, False, - {"enabled": True, "ready": False, "status": "unhealthy", "backend": None}, + { + "enabled": True, + "ready": False, + "status": "degraded", + "optional": True, + "backend": None, + }, ), ( "null", _ReadyCompressor(), False, - {"enabled": True, "ready": True, "status": "healthy", "backend": "onnx"}, + { + "enabled": True, + "ready": True, + "status": "healthy", + "optional": True, + "backend": "onnx", + }, ), ( "null", _ReadyCompressor(backend="remote"), False, - {"enabled": True, "ready": True, "status": "healthy", "backend": "remote"}, + { + "enabled": True, + "ready": True, + "status": "healthy", + "optional": True, + "backend": "remote", + }, ), ( "error", _ReadyCompressor(), False, - {"enabled": True, "ready": True, "status": "healthy", "backend": "onnx"}, + { + "enabled": True, + "ready": True, + "status": "healthy", + "optional": True, + "backend": "onnx", + }, ), ( "loaded", _ReadyCompressor(), False, - {"enabled": True, "ready": True, "status": "healthy", "backend": "existing"}, + { + "enabled": True, + "ready": True, + "status": "healthy", + "optional": True, + "backend": "existing", + }, ), ( "null", _ReadyCompressor(), True, - {"enabled": False, "ready": True, "status": "disabled", "backend": None}, + { + "enabled": False, + "ready": True, + "status": "disabled", + "optional": True, + "backend": None, + }, ), ], )