feat(webui): surface discovery health state in the Providers tab

Add healthState and openUntil to AdminProviderView, and a formatUntil
helper alongside the existing formatAgo/formatTimestamp pair, rendering
a future ISO timestamp as "in Ns".

ProvidersView.vue shows a Badge next to a provider's other status
indicators, destructive for open and secondary for half-open, using the
existing shadcn-vue Badge component rather than a hand-rolled
indicator. A closed provider, the healthy common case, renders no badge
at all, matching the existing convention for the per-model rate badge.
The expanded accordion content adds a matching detail row.

This was the brief's stated motivation for the admin surfacing work: a
broken provider looked identical to a working one in the dashboard.
That gap was previously closed at the API layer only; this closes it in
the UI clients actually see.

Regenerates admin_assets_gen.go from the rebuilt webui via make
admin-ui, per this repository's own convention of committing the
generated asset alongside its source change.
This commit is contained in:
2026-08-22 22:57:19 +01:00
parent e82dabb1dc
commit 8a3f9e7d00
4 changed files with 88 additions and 7 deletions
+19
View File
@@ -64,6 +64,25 @@ export interface AdminProviderView {
* zero lastRefresh.
*/
discoveryEnabled: boolean
/**
* healthState is the provider's DISCOVERY circuit breaker state
* (admin.go: adminProviderView.HealthState — feat/provider-health):
* 'closed' (normal), 'open' (backing off after repeated discovery
* failures — openUntil below is when it next probes), or 'half-open'
* (a probe is in flight, deciding whether to close again). Reflects
* the discovery endpoint ONLY, not request-path health — a provider
* whose model listing 401s while its actual completion endpoint works
* fine still reads 'open' here. A provider with discovery disabled, or
* one that has never failed a refresh, always reads 'closed'.
*/
healthState: 'closed' | 'open' | 'half-open'
/**
* openUntil is when this provider's breaker will next attempt a
* half-open probe (admin.go: adminProviderView.OpenUntil). The unset
* zero-time sentinel (formatAgo/formatTimestamp's ZERO_TIME) when
* healthState is not 'open'.
*/
openUntil: string
/**
* attemptsDay/failuresDay/attemptsMinute/failuresMinute are this
* provider's current-window upstream-attempt counters (admin.go: