diff --git a/core/gallery/gallery.go b/core/gallery/gallery.go index a3a1d909..0c540052 100644 --- a/core/gallery/gallery.go +++ b/core/gallery/gallery.go @@ -29,6 +29,8 @@ func InstallModelFromGallery(galleries []config.Gallery, name string, basePath s if err != nil { return err } + config.Description = model.Description + config.License = model.License } else if len(model.ConfigFile) > 0 { // TODO: is this worse than using the override method with a blank cfg yaml? reYamlConfig, err := yaml.Marshal(model.ConfigFile) diff --git a/core/http/routes/ui.go b/core/http/routes/ui.go index 40919a83..65d1b09c 100644 --- a/core/http/routes/ui.go +++ b/core/http/routes/ui.go @@ -404,6 +404,15 @@ func RegisterUIRoutes(app *fiber.App, return c.Redirect(utils.BaseURL(c)) } modelThatCanBeUsed := "" + galleryConfigs := map[string]*gallery.Config{} + + for _, m := range backendConfigs { + cfg, err := gallery.GetLocalModelConfiguration(ml.ModelPath, m.Name) + if err != nil { + continue + } + galleryConfigs[m.Name] = cfg + } title := "LocalAI - Chat" @@ -419,6 +428,7 @@ func RegisterUIRoutes(app *fiber.App, "Title": title, "BaseURL": utils.BaseURL(c), "ModelsWithoutConfig": modelsWithoutConfig, + "GalleryConfig": galleryConfigs, "ModelsConfig": backendConfigs, "Model": modelThatCanBeUsed, "Version": internal.PrintableVersion(), @@ -434,10 +444,21 @@ func RegisterUIRoutes(app *fiber.App, backendConfigs := cl.GetAllBackendConfigs() modelsWithoutConfig, _ := services.ListModels(cl, ml, config.NoFilterFn, services.LOOSE_ONLY) + galleryConfigs := map[string]*gallery.Config{} + + for _, m := range backendConfigs { + cfg, err := gallery.GetLocalModelConfiguration(ml.ModelPath, m.Name) + if err != nil { + continue + } + galleryConfigs[m.Name] = cfg + } + summary := fiber.Map{ "Title": "LocalAI - Chat with " + c.Params("model"), "BaseURL": utils.BaseURL(c), "ModelsConfig": backendConfigs, + "GalleryConfig": galleryConfigs, "ModelsWithoutConfig": modelsWithoutConfig, "Model": c.Params("model"), "Version": internal.PrintableVersion(), diff --git a/core/http/static/chat.js b/core/http/static/chat.js index 67e0bb60..ac1e0ba8 100644 --- a/core/http/static/chat.js +++ b/core/http/static/chat.js @@ -49,7 +49,7 @@ function submitPrompt(event) { document.getElementById("input").value = ""; const key = localStorage.getItem("key"); const systemPrompt = localStorage.getItem("system_prompt"); - + Alpine.nextTick(() => { document.getElementById('messages').scrollIntoView(false); }); promptGPT(systemPrompt, key, input); } @@ -74,7 +74,6 @@ function readInputImage() { // Make the "loader" visible document.getElementById("loader").style.display = "block"; document.getElementById("input").disabled = true; - document.getElementById('messages').scrollIntoView(false) messages = Alpine.store("chat").messages(); @@ -181,8 +180,8 @@ function readInputImage() { const chatStore = Alpine.store("chat"); chatStore.add("assistant", token); // Efficiently scroll into view without triggering multiple reflows - const messages = document.getElementById('messages'); - messages.scrollTop = messages.scrollHeight; + // const messages = document.getElementById('messages'); + // messages.scrollTop = messages.scrollHeight; }; let buffer = ""; diff --git a/core/http/views/chat.html b/core/http/views/chat.html index 71e9b8d6..59414fe4 100644 --- a/core/http/views/chat.html +++ b/core/http/views/chat.html @@ -4,7 +4,7 @@ Part of this page is based on the OpenAI Chatbot example by David Härer: https://github.com/david-haerer/chatapi MIT License Copyright (c) 2023 David Härer - Copyright (c) 2024 Ettore Di Giacinto + Copyright (c) 2024-2025 Ettore Di Giacinto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,205 +29,355 @@ SOFTWARE. {{template "views/partials/head" .}} - - -
+ {{ $allGalleryConfigs:=.GalleryConfig }} + {{ $model:=.Model}} + {{template "views/partials/navbar" .}} - -