diff --git a/core/http/routes/ui.go b/core/http/routes/ui.go index c12f40f65059..707158235ab2 100644 --- a/core/http/routes/ui.go +++ b/core/http/routes/ui.go @@ -237,4 +237,37 @@ func RegisterUIRoutes(app *fiber.App, // Render index return c.Render("views/text2image", summary) }) + + app.Get("/tts/:model", auth, func(c *fiber.Ctx) error { + backendConfigs := cl.GetAllBackendConfigs() + + summary := fiber.Map{ + "Title": "LocalAI - Generate images with " + c.Params("model"), + "ModelsConfig": backendConfigs, + "Model": c.Params("model"), + "Version": internal.PrintableVersion(), + } + + // Render index + return c.Render("views/tts", summary) + }) + + app.Get("/tts/", auth, func(c *fiber.Ctx) error { + + backendConfigs := cl.GetAllBackendConfigs() + + if len(backendConfigs) == 0 { + return c.SendString("No models available") + } + + summary := fiber.Map{ + "Title": "LocalAI - Generate audio with " + backendConfigs[0].Name, + "ModelsConfig": backendConfigs, + "Model": backendConfigs[0].Name, + "Version": internal.PrintableVersion(), + } + + // Render index + return c.Render("views/tts", summary) + }) } diff --git a/core/http/static/tts.js b/core/http/static/tts.js new file mode 100644 index 000000000000..79e5034aac4c --- /dev/null +++ b/core/http/static/tts.js @@ -0,0 +1,110 @@ +function downloadFile(urlToSend) { + var req = new XMLHttpRequest(); + req.open("GET", urlToSend, true); + req.responseType = "blob"; + req.onload = function (event) { + var blob = req.response; + var fileName = req.getResponseHeader("fileName") //if you have the fileName header available + var link=document.createElement('a'); + link.href=window.URL.createObjectURL(blob); + link.download=fileName; + link.click(); + }; + + req.send(); +} + + +/* + +https://github.com/david-haerer/chatapi + +MIT License + +Copyright (c) 2023 David Härer +Copyright (c) 2024 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 +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ +function submitKey(event) { + event.preventDefault(); + localStorage.setItem("key", document.getElementById("apiKey").value); + document.getElementById("apiKey").blur(); + } + + +function genAudio(event) { + event.preventDefault(); + const input = document.getElementById("input").value; + const key = localStorage.getItem("key"); + + tts(key, input); + +} + +async function tts(key, input) { + document.getElementById("loader").style.display = "block"; + document.getElementById("input").value = ""; + document.getElementById("input").disabled = true; + + const model = document.getElementById("tts-model").value; + const response = await fetch("/tts", { + method: "POST", + headers: { + Authorization: `Bearer ${key}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + model: model, + input: input, + }), + }); + if (!response.ok) { + const jsonData = await response.json(); // Now safely parse JSON + var div = document.getElementById('result'); + div.innerHTML = '
Error: ' +jsonData.error.message + '
'; + return; + } + + var div = document.getElementById('result'); // Get the div by its ID + var link=document.createElement('a'); + link.className = "m-2 float-right inline-block rounded bg-primary px-6 pb-2.5 mb-3 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-primary-3 transition duration-150 ease-in-out hover:bg-primary-accent-300 hover:shadow-primary-2 focus:bg-primary-accent-300 focus:shadow-primary-2 focus:outline-none focus:ring-0 active:bg-primary-600 active:shadow-primary-2 dark:shadow-black/30 dark:hover:shadow-dark-strong dark:focus:shadow-dark-strong dark:active:shadow-dark-strong"; + link.innerHTML = " Download result"; + const blob = await response.blob(); + link.href=window.URL.createObjectURL(blob); + + div.innerHTML = ''; // Clear the existing content of the div + div.appendChild(link); // Add the new img element to the div + console.log(link) + document.getElementById("loader").style.display = "none"; + document.getElementById("input").disabled = false; + document.getElementById("input").focus(); +} + +document.getElementById("key").addEventListener("submit", submitKey); +document.getElementById("input").focus(); +document.getElementById("tts").addEventListener("submit", genAudio); +document.getElementById("loader").style.display = "none"; + +const storeKey = localStorage.getItem("key"); +if (storeKey) { + document.getElementById("apiKey").value = storeKey; +} + diff --git a/core/http/views/chat.html b/core/http/views/chat.html index bd35364fd3b1..909a56991c32 100644 --- a/core/http/views/chat.html +++ b/core/http/views/chat.html @@ -44,7 +44,9 @@