Skip to content

Commit c5b9f45

Browse files
authored
chore(cli): add backends CLI to manipulate and install backends (#5787)
Signed-off-by: Ettore Di Giacinto <[email protected]>
1 parent 61b64a6 commit c5b9f45

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

core/cli/backends.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package cli
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
cliContext "github.com/mudler/LocalAI/core/cli/context"
8+
"github.com/mudler/LocalAI/core/config"
9+
10+
"github.com/mudler/LocalAI/core/gallery"
11+
"github.com/mudler/LocalAI/pkg/downloader"
12+
"github.com/mudler/LocalAI/pkg/startup"
13+
"github.com/rs/zerolog/log"
14+
"github.com/schollz/progressbar/v3"
15+
)
16+
17+
type BackendsCMDFlags struct {
18+
BackendGalleries string `env:"LOCALAI_BACKEND_GALLERIES,BACKEND_GALLERIES" help:"JSON list of backend galleries" group:"backends" default:"${backends}"`
19+
BackendsPath string `env:"LOCALAI_BACKENDS_PATH,BACKENDS_PATH" type:"path" default:"${basepath}/backends" help:"Path containing backends used for inferencing" group:"storage"`
20+
}
21+
22+
type BackendsList struct {
23+
BackendsCMDFlags `embed:""`
24+
}
25+
26+
type BackendsInstallSingle struct {
27+
InstallArgs []string `arg:"" optional:"" name:"backend" help:"Backend images to install"`
28+
29+
BackendsCMDFlags `embed:""`
30+
}
31+
32+
type BackendsInstall struct {
33+
BackendArgs []string `arg:"" optional:"" name:"backends" help:"Backend configuration URLs to load"`
34+
35+
BackendsCMDFlags `embed:""`
36+
}
37+
38+
type BackendsUninstall struct {
39+
BackendArgs []string `arg:"" name:"backends" help:"Backend names to uninstall"`
40+
41+
BackendsCMDFlags `embed:""`
42+
}
43+
44+
type BackendsCMD struct {
45+
List BackendsList `cmd:"" help:"List the backends available in your galleries" default:"withargs"`
46+
Install BackendsInstall `cmd:"" help:"Install a backend from the gallery"`
47+
InstallSingle BackendsInstallSingle `cmd:"" help:"Install a single backend from the gallery"`
48+
Uninstall BackendsUninstall `cmd:"" help:"Uninstall a backend"`
49+
}
50+
51+
func (bi *BackendsInstallSingle) Run(ctx *cliContext.Context) error {
52+
for _, backend := range bi.InstallArgs {
53+
progressBar := progressbar.NewOptions(
54+
1000,
55+
progressbar.OptionSetDescription(fmt.Sprintf("downloading backend %s", backend)),
56+
progressbar.OptionShowBytes(false),
57+
progressbar.OptionClearOnFinish(),
58+
)
59+
progressCallback := func(fileName string, current string, total string, percentage float64) {
60+
v := int(percentage * 10)
61+
err := progressBar.Set(v)
62+
if err != nil {
63+
log.Error().Err(err).Str("filename", fileName).Int("value", v).Msg("error while updating progress bar")
64+
}
65+
}
66+
67+
if err := gallery.InstallBackend(bi.BackendsPath, &gallery.GalleryBackend{
68+
URI: backend,
69+
}, progressCallback); err != nil {
70+
return err
71+
}
72+
}
73+
74+
return nil
75+
}
76+
77+
func (bl *BackendsList) Run(ctx *cliContext.Context) error {
78+
var galleries []config.Gallery
79+
if err := json.Unmarshal([]byte(bl.BackendGalleries), &galleries); err != nil {
80+
log.Error().Err(err).Msg("unable to load galleries")
81+
}
82+
83+
backends, err := gallery.AvailableBackends(galleries, bl.BackendsPath)
84+
if err != nil {
85+
return err
86+
}
87+
for _, backend := range backends {
88+
if backend.Installed {
89+
fmt.Printf(" * %s@%s (installed)\n", backend.Gallery.Name, backend.Name)
90+
} else {
91+
fmt.Printf(" - %s@%s\n", backend.Gallery.Name, backend.Name)
92+
}
93+
}
94+
return nil
95+
}
96+
97+
func (bi *BackendsInstall) Run(ctx *cliContext.Context) error {
98+
var galleries []config.Gallery
99+
if err := json.Unmarshal([]byte(bi.BackendGalleries), &galleries); err != nil {
100+
log.Error().Err(err).Msg("unable to load galleries")
101+
}
102+
103+
for _, backendName := range bi.BackendArgs {
104+
105+
progressBar := progressbar.NewOptions(
106+
1000,
107+
progressbar.OptionSetDescription(fmt.Sprintf("downloading backend %s", backendName)),
108+
progressbar.OptionShowBytes(false),
109+
progressbar.OptionClearOnFinish(),
110+
)
111+
progressCallback := func(fileName string, current string, total string, percentage float64) {
112+
v := int(percentage * 10)
113+
err := progressBar.Set(v)
114+
if err != nil {
115+
log.Error().Err(err).Str("filename", fileName).Int("value", v).Msg("error while updating progress bar")
116+
}
117+
}
118+
119+
backendURI := downloader.URI(backendName)
120+
121+
if !backendURI.LooksLikeOCI() {
122+
backends, err := gallery.AvailableBackends(galleries, bi.BackendsPath)
123+
if err != nil {
124+
return err
125+
}
126+
127+
backend := gallery.FindGalleryElement(backends, backendName, bi.BackendsPath)
128+
if backend == nil {
129+
log.Error().Str("backend", backendName).Msg("backend not found")
130+
return fmt.Errorf("backend not found: %s", backendName)
131+
}
132+
133+
log.Info().Str("backend", backendName).Str("license", backend.License).Msg("installing backend")
134+
}
135+
136+
err := startup.InstallExternalBackends(galleries, bi.BackendsPath, progressCallback, backendName)
137+
if err != nil {
138+
return err
139+
}
140+
}
141+
return nil
142+
}
143+
144+
func (bu *BackendsUninstall) Run(ctx *cliContext.Context) error {
145+
for _, backendName := range bu.BackendArgs {
146+
log.Info().Str("backend", backendName).Msg("uninstalling backend")
147+
148+
err := gallery.DeleteBackendFromSystem(bu.BackendsPath, backendName)
149+
if err != nil {
150+
return err
151+
}
152+
153+
fmt.Printf("Backend %s uninstalled successfully\n", backendName)
154+
}
155+
return nil
156+
}

core/cli/cli.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ var CLI struct {
1111
Run RunCMD `cmd:"" help:"Run LocalAI, this the default command if no other command is specified. Run 'local-ai run --help' for more information" default:"withargs"`
1212
Federated FederatedCLI `cmd:"" help:"Run LocalAI in federated mode"`
1313
Models ModelsCMD `cmd:"" help:"Manage LocalAI models and definitions"`
14+
Backends BackendsCMD `cmd:"" help:"Manage LocalAI backends and definitions"`
1415
TTS TTSCMD `cmd:"" help:"Convert text to speech"`
1516
SoundGeneration SoundGenerationCMD `cmd:"" help:"Generates audio files from text or audio"`
1617
Transcript TranscriptCMD `cmd:"" help:"Convert audio to text"`

0 commit comments

Comments
 (0)