mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-20 05:56:56 +00:00
feat(admin): rates + discovery flag in API
Extend GET /admin/api/overview's existing providers payload rather than adding a sibling endpoint: the route already returns one providers array per request on the dashboard's 5s poll, is already admin-gated and stats-excluded, and the new fields are one more batched limiter read sharing that same request — a second endpoint would duplicate all three properties for no benefit. adminProviderView gains AttemptsDay/FailuresDay/AttemptsMinute/ FailuresMinute (the provider's own current-window counters) and ModelRates (a per-model breakdown, keyed by upstream model id, via the new adminModelRateView) — Feature A. buildAdminOverview builds every provider's and every (provider, model) pair's limitScope in two passes and reads them all through limiter.providerUsage in ONE storeGetMulti call, then slices the flat result back by index. adminProviderView also gains DiscoveryEnabled, mirroring a new providerSnapshot.discoveryEnabled field (registry.go) read straight off providerState — it is set once at construction and never mutated afterward, so it needs neither providerState's mutex nor a place in its existing snapshot() method's mutable-field return shape. Feature B: this lets the webui tell "discovery is off" apart from "discovery is on but has not refreshed yet", which previously both showed the same zero lastRefresh as an identical "refreshed never".
This commit is contained in:
@@ -707,6 +707,39 @@ func TestModelRegistry_Snapshot_ModelsStaleWhileError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestModelRegistry_Snapshot_DiscoveryEnabledReflectsConfig proves
|
||||
// providerSnapshot.discoveryEnabled (Feature B, v0.22 — last-refresh label
|
||||
// honesty) mirrors each provider's own configured Discovery flag exactly,
|
||||
// read straight from providerState rather than through providerState.
|
||||
// snapshot()'s mutex-guarded fields, since it never changes after
|
||||
// construction.
|
||||
func TestModelRegistry_Snapshot_DiscoveryEnabledReflectsConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
adapters := map[string]providerAdapter{
|
||||
"on": newFakeAdapter("on"),
|
||||
"off": newFakeAdapter("off"),
|
||||
}
|
||||
cfg := &Config{Providers: map[string]*ProviderConfig{
|
||||
"on": {Discovery: true, DiscoveryInterval: "1h"},
|
||||
"off": {Models: []string{"pinned"}},
|
||||
}}
|
||||
reg, err := newModelRegistry(adapters, cfg, func(string, ...any) {})
|
||||
if err != nil {
|
||||
t.Fatalf("newModelRegistry: %v", err)
|
||||
}
|
||||
|
||||
byName := map[string]providerSnapshot{}
|
||||
for _, s := range reg.snapshot() {
|
||||
byName[s.name] = s
|
||||
}
|
||||
if !byName["on"].discoveryEnabled {
|
||||
t.Error(`provider "on" discoveryEnabled = false, want true`)
|
||||
}
|
||||
if byName["off"].discoveryEnabled {
|
||||
t.Error(`provider "off" discoveryEnabled = true, want false`)
|
||||
}
|
||||
}
|
||||
|
||||
// --- listFor: group filtering, sorting, collision presentation (ruling h) ---
|
||||
|
||||
func TestModelRegistry_ListFor_GroupFiltered(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user