|
23 | 23 | from .metrics import MetricsStore, calc_cost |
24 | 24 | from .providers import ProviderBackend, ProviderError |
25 | 25 | from .router import Router, RoutingDecision |
26 | | -from .updates import UpdateChecker |
| 26 | +from .updates import UpdateChecker, apply_auto_update_guardrails |
27 | 27 |
|
28 | 28 | logger = logging.getLogger("foundrygate") |
29 | 29 |
|
@@ -248,6 +248,17 @@ def _build_capability_coverage() -> dict[str, dict[str, Any]]: |
248 | 248 | return dict(sorted(coverage.items())) |
249 | 249 |
|
250 | 250 |
|
| 251 | +def _health_summary() -> dict[str, int]: |
| 252 | + """Return a compact provider-health summary for operator guardrails.""" |
| 253 | + providers_healthy = sum(1 for provider in _providers.values() if provider.health.healthy) |
| 254 | + providers_unhealthy = sum(1 for provider in _providers.values() if not provider.health.healthy) |
| 255 | + return { |
| 256 | + "providers_total": len(_providers), |
| 257 | + "providers_healthy": providers_healthy, |
| 258 | + "providers_unhealthy": providers_unhealthy, |
| 259 | + } |
| 260 | + |
| 261 | + |
251 | 262 | def _estimate_request_dimensions(body: dict[str, Any]) -> dict[str, int | str]: |
252 | 263 | """Return lightweight request-dimension estimates for debugging and routing preview.""" |
253 | 264 | messages = body.get("messages", []) |
@@ -675,13 +686,7 @@ async def health(): |
675 | 686 | } |
676 | 687 | return { |
677 | 688 | "status": "ok", |
678 | | - "summary": { |
679 | | - "providers_total": len(providers), |
680 | | - "providers_healthy": sum(1 for provider in providers.values() if provider["healthy"]), |
681 | | - "providers_unhealthy": sum( |
682 | | - 1 for provider in providers.values() if not provider["healthy"] |
683 | | - ), |
684 | | - }, |
| 689 | + "summary": _health_summary(), |
685 | 690 | "coverage": _build_capability_coverage(), |
686 | 691 | "providers": providers, |
687 | 692 | } |
@@ -821,6 +826,11 @@ async def update_status(request: Request, force: bool = False): |
821 | 826 | """Return cached or fresh release update metadata.""" |
822 | 827 | headers = _collect_routing_headers(request) |
823 | 828 | status = await _update_checker.get_status(force=force) |
| 829 | + status.auto_update = apply_auto_update_guardrails( |
| 830 | + status.auto_update or {}, |
| 831 | + providers_healthy=_health_summary()["providers_healthy"], |
| 832 | + providers_unhealthy=_health_summary()["providers_unhealthy"], |
| 833 | + ) |
824 | 834 | operator_action, client_tag = _collect_operator_context(headers) |
825 | 835 | auto_update = status.auto_update or {} |
826 | 836 | _metrics.log_operator_event( |
|
0 commit comments