feat: Galleries UI (#2104)

* WIP: add models to webui

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Register routes

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix: don't cache models

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* small fixups

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix: fixup multiple installs (strings.Clone)

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
Ettore Di Giacinto 2024-04-23 09:22:58 +02:00 committed by GitHub
parent bd507678be
commit 0d8bf91699
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 431 additions and 23 deletions

View file

@ -5,6 +5,8 @@ import "hash"
type progressWriter struct {
fileName string
total int64
fileNo int
totalFiles int
written int64
downloadStatus func(string, string, string, float64)
hash hash.Hash
@ -16,6 +18,17 @@ func (pw *progressWriter) Write(p []byte) (n int, err error) {
if pw.total > 0 {
percentage := float64(pw.written) / float64(pw.total) * 100
if pw.totalFiles > 1 {
// This is a multi-file download
// so we need to adjust the percentage
// to reflect the progress of the whole download
// This is the file pw.fileNo of pw.totalFiles files. We assume that
// the files before successfully downloaded.
percentage = percentage / float64(pw.totalFiles)
if pw.fileNo > 1 {
percentage += float64(pw.fileNo-1) * 100 / float64(pw.totalFiles)
}
}
//log.Debug().Msgf("Downloading %s: %s/%s (%.2f%%)", pw.fileName, formatBytes(pw.written), formatBytes(pw.total), percentage)
pw.downloadStatus(pw.fileName, formatBytes(pw.written), formatBytes(pw.total), percentage)
} else {

View file

@ -136,7 +136,7 @@ func removePartialFile(tmpFilePath string) error {
return nil
}
func DownloadFile(url string, filePath, sha string, downloadStatus func(string, string, string, float64)) error {
func DownloadFile(url string, filePath, sha string, fileN, total int, downloadStatus func(string, string, string, float64)) error {
url = ConvertURL(url)
// Check if the file already exists
_, err := os.Stat(filePath)
@ -209,6 +209,8 @@ func DownloadFile(url string, filePath, sha string, downloadStatus func(string,
fileName: tmpFilePath,
total: resp.ContentLength,
hash: sha256.New(),
fileNo: fileN,
totalFiles: total,
downloadStatus: downloadStatus,
}
_, err = io.Copy(io.MultiWriter(outFile, progress), resp.Body)

View file

@ -102,7 +102,7 @@ func InstallModel(basePath, nameOverride string, config *Config, configOverrides
}
// Download files and verify their SHA
for _, file := range config.Files {
for i, file := range config.Files {
log.Debug().Msgf("Checking %q exists and matches SHA", file.Filename)
if err := utils.VerifyPath(file.Filename, basePath); err != nil {
@ -111,7 +111,7 @@ func InstallModel(basePath, nameOverride string, config *Config, configOverrides
// Create file path
filePath := filepath.Join(basePath, file.Filename)
if err := downloader.DownloadFile(file.URI, filePath, file.SHA256, downloadStatus); err != nil {
if err := downloader.DownloadFile(file.URI, filePath, file.SHA256, i, len(config.Files), downloadStatus); err != nil {
return err
}
}

View file

@ -1,11 +1,12 @@
package gallery
type GalleryOp struct {
Req GalleryModel
Id string
Galleries []Gallery
GalleryName string
ConfigURL string
Req GalleryModel
Galleries []Gallery
}
type GalleryOpStatus struct {

View file

@ -54,7 +54,7 @@ func PreloadModelsConfigurations(modelLibraryURL string, modelPath string, model
// check if file exists
if _, err := os.Stat(filepath.Join(modelPath, md5Name)); errors.Is(err, os.ErrNotExist) {
modelDefinitionFilePath := filepath.Join(modelPath, md5Name) + ".yaml"
err := downloader.DownloadFile(url, modelDefinitionFilePath, "", func(fileName, current, total string, percent float64) {
err := downloader.DownloadFile(url, modelDefinitionFilePath, "", 0, 0, func(fileName, current, total string, percent float64) {
utils.DisplayDownloadFunction(fileName, current, total, percent)
})
if err != nil {