From 3b9d0de6aad200b42dc52abd5e0b749d67f938d4 Mon Sep 17 00:00:00 2001 From: team-coding-agent-1 Date: Thu, 5 Mar 2026 03:52:37 +0000 Subject: [PATCH] Fix: Filter models and backends by exact tag match - Added FilterByTag function to GalleryElements in gallery.go for exact tag matching - Updated /api/models and /api/backends endpoints in ui_api.go to accept 'tag' query parameter - When tag parameter is provided, only items with exact tag match are returned - Fixes issue #8775 where browsing by tags returned unrelated models Signed-off-by: LocalAI [bot] --- core/gallery/gallery.go | 15 +++++++++++++++ core/http/routes/ui_api.go | 14 ++++++++++++-- gallery.go.patch | 24 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 gallery.go.patch diff --git a/core/gallery/gallery.go b/core/gallery/gallery.go index 035bfcde8af5..ff8444b489d2 100644 --- a/core/gallery/gallery.go +++ b/core/gallery/gallery.go @@ -92,6 +92,21 @@ func (gm GalleryElements[T]) Search(term string) GalleryElements[T] { return filteredModels } +// FilterByTag returns only elements that have the specified tag as an exact match +func (gm GalleryElements[T]) FilterByTag(tag string) GalleryElements[T] { + var filtered GalleryElements[T] + tag = strings.ToLower(tag) + for _, m := range gm { + for _, t := range m.GetTags() { + if strings.ToLower(t) == tag { + filtered = append(filtered, m) + break + } + } + } + return filtered +} + func (gm GalleryElements[T]) SortByName(sortOrder string) GalleryElements[T] { sort.Slice(gm, func(i, j int) bool { if sortOrder == "asc" { diff --git a/core/http/routes/ui_api.go b/core/http/routes/ui_api.go index 4dc73a823757..5abc79233cac 100644 --- a/core/http/routes/ui_api.go +++ b/core/http/routes/ui_api.go @@ -221,7 +221,12 @@ func RegisterUIAPIRoutes(app *echo.Echo, cl *config.ModelConfigLoader, ml *model } sort.Strings(tags) - if term != "" { + tag := c.QueryParam("tag") + + // Filter by tag if provided (exact match) + if tag != "" { + models = gallery.GalleryElements[*gallery.GalleryModel](models).FilterByTag(tag) + } else if term != "" { models = gallery.GalleryElements[*gallery.GalleryModel](models).Search(term) } @@ -603,7 +608,12 @@ func RegisterUIAPIRoutes(app *echo.Echo, cl *config.ModelConfigLoader, ml *model } sort.Strings(tags) - if term != "" { + tag := c.QueryParam("tag") + + // Filter by tag if provided (exact match) + if tag != "" { + backends = gallery.GalleryElements[*gallery.GalleryBackend](backends).FilterByTag(tag) + } else if term != "" { backends = gallery.GalleryElements[*gallery.GalleryBackend](backends).Search(term) } diff --git a/gallery.go.patch b/gallery.go.patch new file mode 100644 index 000000000000..bdaf1a31d60f --- /dev/null +++ b/gallery.go.patch @@ -0,0 +1,24 @@ +--- a/core/gallery/gallery.go ++++ b/core/gallery/gallery.go +@@ -83,6 +83,18 @@ func (gm GalleryElements[T]) Search(term string) GalleryElements[T] { + return filteredModels + } + ++// FilterByTag returns only elements that have the specified tag as an exact match ++func (gm GalleryElements[T]) FilterByTag(tag string) GalleryElements[T] { ++ var filtered GalleryElements[T] ++ tag = strings.ToLower(tag) ++ for _, m := range gm { ++ for _, t := range m.GetTags() { ++ if strings.ToLower(t) == tag { ++ filtered = append(filtered, m) ++ break ++ } ++ } ++ } ++ return filtered ++} ++ + func (gm GalleryElements[T]) SortByName(sortOrder string) GalleryElements[T] { + sort.Slice(gm, func(i, j int) bool { + if sortOrder == "asc" {