From 791c3ace72cb1e21337da74d20432fa174a844f5 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Thu, 5 Sep 2024 20:44:30 +0200 Subject: [PATCH] feat: add endpoint to list system informations (#3449) * feat: add endpoint to list system informations For now, it lists the available backends, but can be expanded later on to include more system informations (such as GPU devices detected, RAM, threads configured, and so on so forth). Signed-off-by: Ettore Di Giacinto * show also external backends Signed-off-by: Ettore Di Giacinto * add test Signed-off-by: Ettore Di Giacinto --------- Signed-off-by: Ettore Di Giacinto --- core/http/app_test.go | 11 ++++++++++ core/http/endpoints/localai/system.go | 29 +++++++++++++++++++++++++++ core/http/routes/localai.go | 2 ++ core/schema/localai.go | 4 ++++ pkg/model/initializers.go | 4 ++++ 5 files changed, 50 insertions(+) create mode 100644 core/http/endpoints/localai/system.go diff --git a/core/http/app_test.go b/core/http/app_test.go index a837e20c..86fe7fdd 100644 --- a/core/http/app_test.go +++ b/core/http/app_test.go @@ -772,6 +772,17 @@ var _ = Describe("API test", func() { Expect(err.Error()).To(ContainSubstring("error, status code: 500, message: could not load model - all backends returned error:")) }) + It("shows the external backend", func() { + // do an http request to the /system endpoint + resp, err := http.Get("http://127.0.0.1:9090/system") + Expect(err).ToNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(200)) + dat, err := io.ReadAll(resp.Body) + Expect(err).ToNot(HaveOccurred()) + Expect(string(dat)).To(ContainSubstring("huggingface")) + Expect(string(dat)).To(ContainSubstring("llama-cpp")) + }) + It("transcribes audio", func() { if runtime.GOOS != "linux" { Skip("test supported only on linux") diff --git a/core/http/endpoints/localai/system.go b/core/http/endpoints/localai/system.go new file mode 100644 index 00000000..11704933 --- /dev/null +++ b/core/http/endpoints/localai/system.go @@ -0,0 +1,29 @@ +package localai + +import ( + "github.com/gofiber/fiber/v2" + "github.com/mudler/LocalAI/core/config" + "github.com/mudler/LocalAI/core/schema" + "github.com/mudler/LocalAI/pkg/model" +) + +// SystemInformations returns the system informations +// @Summary Show the LocalAI instance information +// @Success 200 {object} schema.SystemInformationResponse "Response" +// @Router /system [get] +func SystemInformations(ml *model.ModelLoader, appConfig *config.ApplicationConfig) func(*fiber.Ctx) error { + return func(c *fiber.Ctx) error { + availableBackends, err := ml.ListAvailableBackends(appConfig.AssetsDestination) + if err != nil { + return err + } + for b := range appConfig.ExternalGRPCBackends { + availableBackends = append(availableBackends, b) + } + return c.JSON( + schema.SystemInformationResponse{ + Backends: availableBackends, + }, + ) + } +} diff --git a/core/http/routes/localai.go b/core/http/routes/localai.go index 105991e8..f85fa807 100644 --- a/core/http/routes/localai.go +++ b/core/http/routes/localai.go @@ -70,4 +70,6 @@ func RegisterLocalAIRoutes(app *fiber.App, }{Version: internal.PrintableVersion()}) }) + app.Get("/system", auth, localai.SystemInformations(ml, appConfig)) + } diff --git a/core/schema/localai.go b/core/schema/localai.go index 1b75e384..9070c2be 100644 --- a/core/schema/localai.go +++ b/core/schema/localai.go @@ -70,3 +70,7 @@ type P2PNodesResponse struct { Nodes []p2p.NodeData `json:"nodes" yaml:"nodes"` FederatedNodes []p2p.NodeData `json:"federated_nodes" yaml:"federated_nodes"` } + +type SystemInformationResponse struct { + Backends []string `json:"backends"` +} diff --git a/pkg/model/initializers.go b/pkg/model/initializers.go index de0662e6..3d2255cc 100644 --- a/pkg/model/initializers.go +++ b/pkg/model/initializers.go @@ -393,6 +393,10 @@ func (ml *ModelLoader) grpcModel(backend string, o *Options) func(string, string } } +func (ml *ModelLoader) ListAvailableBackends(assetdir string) ([]string, error) { + return backendsInAssetDir(assetdir) +} + func (ml *ModelLoader) BackendLoader(opts ...Option) (client grpc.Backend, err error) { o := NewOptions(opts...)