@@ -3,8 +3,13 @@ package api
33import (
44 "errors"
55
6+ config "github.com/go-skynet/LocalAI/api/config"
7+ "github.com/go-skynet/LocalAI/api/localai"
8+ "github.com/go-skynet/LocalAI/api/openai"
9+ "github.com/go-skynet/LocalAI/api/options"
610 "github.com/go-skynet/LocalAI/internal"
711 "github.com/go-skynet/LocalAI/pkg/assets"
12+
813 "github.com/gofiber/fiber/v2"
914 "github.com/gofiber/fiber/v2/middleware/cors"
1015 "github.com/gofiber/fiber/v2/middleware/logger"
@@ -13,18 +18,18 @@ import (
1318 "github.com/rs/zerolog/log"
1419)
1520
16- func App (opts ... AppOption ) (* fiber.App , error ) {
17- options := newOptions (opts ... )
21+ func App (opts ... options. AppOption ) (* fiber.App , error ) {
22+ options := options . NewOptions (opts ... )
1823
1924 zerolog .SetGlobalLevel (zerolog .InfoLevel )
20- if options .debug {
25+ if options .Debug {
2126 zerolog .SetGlobalLevel (zerolog .DebugLevel )
2227 }
2328
2429 // Return errors as JSON responses
2530 app := fiber .New (fiber.Config {
26- BodyLimit : options .uploadLimitMB * 1024 * 1024 , // this is the default limit of 4MB
27- DisableStartupMessage : options .disableMessage ,
31+ BodyLimit : options .UploadLimitMB * 1024 * 1024 , // this is the default limit of 4MB
32+ DisableStartupMessage : options .DisableMessage ,
2833 // Override default error handler
2934 ErrorHandler : func (ctx * fiber.Ctx , err error ) error {
3035 // Status code defaults to 500
@@ -38,43 +43,44 @@ func App(opts ...AppOption) (*fiber.App, error) {
3843
3944 // Send custom error page
4045 return ctx .Status (code ).JSON (
41- ErrorResponse {
42- Error : & APIError {Message : err .Error (), Code : code },
46+ openai. ErrorResponse {
47+ Error : & openai. APIError {Message : err .Error (), Code : code },
4348 },
4449 )
4550 },
4651 })
4752
48- if options .debug {
53+ if options .Debug {
4954 app .Use (logger .New (logger.Config {
5055 Format : "[${ip}]:${port} ${status} - ${method} ${path}\n " ,
5156 }))
5257 }
5358
54- log .Info ().Msgf ("Starting LocalAI using %d threads, with models path: %s" , options .threads , options .loader .ModelPath )
59+ log .Info ().Msgf ("Starting LocalAI using %d threads, with models path: %s" , options .Threads , options .Loader .ModelPath )
5560 log .Info ().Msgf ("LocalAI version: %s" , internal .PrintableVersion ())
5661
57- cm := NewConfigMerger ()
58- if err := cm .LoadConfigs (options .loader .ModelPath ); err != nil {
62+ cm := config . NewConfigLoader ()
63+ if err := cm .LoadConfigs (options .Loader .ModelPath ); err != nil {
5964 log .Error ().Msgf ("error loading config files: %s" , err .Error ())
6065 }
6166
62- if options .configFile != "" {
63- if err := cm .LoadConfigFile (options .configFile ); err != nil {
67+ if options .ConfigFile != "" {
68+ if err := cm .LoadConfigFile (options .ConfigFile ); err != nil {
6469 log .Error ().Msgf ("error loading config file: %s" , err .Error ())
6570 }
6671 }
6772
68- if options .debug {
73+ if options .Debug {
6974 for _ , v := range cm .ListConfigs () {
7075 cfg , _ := cm .GetConfig (v )
7176 log .Debug ().Msgf ("Model: %s (config: %+v)" , v , cfg )
7277 }
7378 }
7479
75- if options .assetsDestination != "" {
80+ if options .AssetsDestination != "" {
7681 // Extract files from the embedded FS
77- err := assets .ExtractFiles (options .backendAssets , options .assetsDestination )
82+ err := assets .ExtractFiles (options .BackendAssets , options .AssetsDestination )
83+ log .Debug ().Msgf ("Extracting backend assets files to %s" , options .AssetsDestination )
7884 if err != nil {
7985 log .Warn ().Msgf ("Failed extracting backend assets files: %s (might be required for some backends to work properly, like gpt4all)" , err )
8086 }
@@ -83,75 +89,76 @@ func App(opts ...AppOption) (*fiber.App, error) {
8389 // Default middleware config
8490 app .Use (recover .New ())
8591
86- if options .preloadJSONModels != "" {
87- if err := ApplyGalleryFromString (options .loader .ModelPath , options .preloadJSONModels , cm , options .galleries ); err != nil {
92+ if options .PreloadJSONModels != "" {
93+ if err := localai . ApplyGalleryFromString (options .Loader .ModelPath , options .PreloadJSONModels , cm , options .Galleries ); err != nil {
8894 return nil , err
8995 }
9096 }
9197
92- if options .preloadModelsFromPath != "" {
93- if err := ApplyGalleryFromFile (options .loader .ModelPath , options .preloadModelsFromPath , cm , options .galleries ); err != nil {
98+ if options .PreloadModelsFromPath != "" {
99+ if err := localai . ApplyGalleryFromFile (options .Loader .ModelPath , options .PreloadModelsFromPath , cm , options .Galleries ); err != nil {
94100 return nil , err
95101 }
96102 }
97103
98- if options .cors {
99- if options .corsAllowOrigins == "" {
100- app .Use (cors .New ())
104+ if options .CORS {
105+ var c func (ctx * fiber.Ctx ) error
106+ if options .CORSAllowOrigins == "" {
107+ c = cors .New ()
101108 } else {
102- app .Use (cors .New (cors.Config {
103- AllowOrigins : options .corsAllowOrigins ,
104- }))
109+ c = cors .New (cors.Config {AllowOrigins : options .CORSAllowOrigins })
105110 }
111+
112+ app .Use (c )
106113 }
107114
108115 // LocalAI API endpoints
109- applier := newGalleryApplier (options .loader .ModelPath )
110- applier . start (options .context , cm )
116+ galleryService := localai . NewGalleryService (options .Loader .ModelPath )
117+ galleryService . Start (options .Context , cm )
111118
112119 app .Get ("/version" , func (c * fiber.Ctx ) error {
113120 return c .JSON (struct {
114121 Version string `json:"version"`
115122 }{Version : internal .PrintableVersion ()})
116123 })
117124
118- app .Post ("/models/apply" , applyModelGallery (options .loader .ModelPath , cm , applier .C , options .galleries ))
119- app .Get ("/models/available" , listModelFromGallery (options .galleries , options .loader .ModelPath ))
120- app .Get ("/models/jobs/:uuid" , getOpStatus ( applier ))
125+ app .Post ("/models/apply" , localai . ApplyModelGalleryEndpoint (options .Loader .ModelPath , cm , galleryService .C , options .Galleries ))
126+ app .Get ("/models/available" , localai . ListModelFromGalleryEndpoint (options .Galleries , options .Loader .ModelPath ))
127+ app .Get ("/models/jobs/:uuid" , localai . GetOpStatusEndpoint ( galleryService ))
121128
122129 // openAI compatible API endpoint
123130
124131 // chat
125- app .Post ("/v1/chat/completions" , chatEndpoint (cm , options ))
126- app .Post ("/chat/completions" , chatEndpoint (cm , options ))
132+ app .Post ("/v1/chat/completions" , openai . ChatEndpoint (cm , options ))
133+ app .Post ("/chat/completions" , openai . ChatEndpoint (cm , options ))
127134
128135 // edit
129- app .Post ("/v1/edits" , editEndpoint (cm , options ))
130- app .Post ("/edits" , editEndpoint (cm , options ))
136+ app .Post ("/v1/edits" , openai . EditEndpoint (cm , options ))
137+ app .Post ("/edits" , openai . EditEndpoint (cm , options ))
131138
132139 // completion
133- app .Post ("/v1/completions" , completionEndpoint (cm , options ))
134- app .Post ("/completions" , completionEndpoint (cm , options ))
135- app .Post ("/v1/engines/:model/completions" , completionEndpoint (cm , options ))
140+ app .Post ("/v1/completions" , openai . CompletionEndpoint (cm , options ))
141+ app .Post ("/completions" , openai . CompletionEndpoint (cm , options ))
142+ app .Post ("/v1/engines/:model/completions" , openai . CompletionEndpoint (cm , options ))
136143
137144 // embeddings
138- app .Post ("/v1/embeddings" , embeddingsEndpoint (cm , options ))
139- app .Post ("/embeddings" , embeddingsEndpoint (cm , options ))
140- app .Post ("/v1/engines/:model/embeddings" , embeddingsEndpoint (cm , options ))
145+ app .Post ("/v1/embeddings" , openai . EmbeddingsEndpoint (cm , options ))
146+ app .Post ("/embeddings" , openai . EmbeddingsEndpoint (cm , options ))
147+ app .Post ("/v1/engines/:model/embeddings" , openai . EmbeddingsEndpoint (cm , options ))
141148
142149 // audio
143- app .Post ("/v1/audio/transcriptions" , transcriptEndpoint (cm , options ))
144- app .Post ("/tts" , ttsEndpoint (cm , options ))
150+ app .Post ("/v1/audio/transcriptions" , openai . TranscriptEndpoint (cm , options ))
151+ app .Post ("/tts" , localai . TTSEndpoint (cm , options ))
145152
146153 // images
147- app .Post ("/v1/images/generations" , imageEndpoint (cm , options ))
154+ app .Post ("/v1/images/generations" , openai . ImageEndpoint (cm , options ))
148155
149- if options .imageDir != "" {
150- app .Static ("/generated-images" , options .imageDir )
156+ if options .ImageDir != "" {
157+ app .Static ("/generated-images" , options .ImageDir )
151158 }
152159
153- if options .audioDir != "" {
154- app .Static ("/generated-audio" , options .audioDir )
160+ if options .AudioDir != "" {
161+ app .Static ("/generated-audio" , options .AudioDir )
155162 }
156163
157164 ok := func (c * fiber.Ctx ) error {
@@ -163,8 +170,15 @@ func App(opts ...AppOption) (*fiber.App, error) {
163170 app .Get ("/readyz" , ok )
164171
165172 // models
166- app .Get ("/v1/models" , listModels (options .loader , cm ))
167- app .Get ("/models" , listModels (options .loader , cm ))
173+ app .Get ("/v1/models" , openai .ListModelsEndpoint (options .Loader , cm ))
174+ app .Get ("/models" , openai .ListModelsEndpoint (options .Loader , cm ))
175+
176+ // turn off any process that was started by GRPC if the context is canceled
177+ go func () {
178+ <- options .Context .Done ()
179+ log .Debug ().Msgf ("Context canceled, shutting down" )
180+ options .Loader .StopGRPC ()
181+ }()
168182
169183 return app , nil
170184}
0 commit comments