AbdulElahGwaith's picture
Upload folder using huggingface_hub
0f07ba7 verified
package localai
import (
"fmt"
"io"
"net/http"
"os"
"github.com/labstack/echo/v4"
"github.com/mudler/LocalAI/core/config"
httpUtils "github.com/mudler/LocalAI/core/http/middleware"
"github.com/mudler/LocalAI/internal"
"github.com/mudler/LocalAI/pkg/utils"
"gopkg.in/yaml.v3"
)
// GetEditModelPage renders the edit model page with current configuration
func GetEditModelPage(cl *config.ModelConfigLoader, appConfig *config.ApplicationConfig) echo.HandlerFunc {
return func(c echo.Context) error {
modelName := c.Param("name")
if modelName == "" {
response := ModelResponse{
Success: false,
Error: "Model name is required",
}
return c.JSON(http.StatusBadRequest, response)
}
modelConfig, exists := cl.GetModelConfig(modelName)
if !exists {
response := ModelResponse{
Success: false,
Error: "Model configuration not found",
}
return c.JSON(http.StatusNotFound, response)
}
modelConfigFile := modelConfig.GetModelConfigFile()
if modelConfigFile == "" {
response := ModelResponse{
Success: false,
Error: "Model configuration file not found",
}
return c.JSON(http.StatusNotFound, response)
}
configData, err := os.ReadFile(modelConfigFile)
if err != nil {
response := ModelResponse{
Success: false,
Error: "Failed to read configuration file: " + err.Error(),
}
return c.JSON(http.StatusInternalServerError, response)
}
// Render the edit page with the current configuration
templateData := struct {
Title string
ModelName string
Config *config.ModelConfig
ConfigJSON string
ConfigYAML string
BaseURL string
Version string
}{
Title: "LocalAI - Edit Model " + modelName,
ModelName: modelName,
Config: &modelConfig,
ConfigYAML: string(configData),
BaseURL: httpUtils.BaseURL(c),
Version: internal.PrintableVersion(),
}
return c.Render(http.StatusOK, "views/model-editor", templateData)
}
}
// EditModelEndpoint handles updating existing model configurations
func EditModelEndpoint(cl *config.ModelConfigLoader, appConfig *config.ApplicationConfig) echo.HandlerFunc {
return func(c echo.Context) error {
modelName := c.Param("name")
if modelName == "" {
response := ModelResponse{
Success: false,
Error: "Model name is required",
}
return c.JSON(http.StatusBadRequest, response)
}
modelConfig, exists := cl.GetModelConfig(modelName)
if !exists {
response := ModelResponse{
Success: false,
Error: "Existing model configuration not found",
}
return c.JSON(http.StatusNotFound, response)
}
// Get the raw body
body, err := io.ReadAll(c.Request().Body)
if err != nil {
response := ModelResponse{
Success: false,
Error: "Failed to read request body: " + err.Error(),
}
return c.JSON(http.StatusBadRequest, response)
}
if len(body) == 0 {
response := ModelResponse{
Success: false,
Error: "Request body is empty",
}
return c.JSON(http.StatusBadRequest, response)
}
// Check content to see if it's a valid model config
var req config.ModelConfig
// Parse YAML
if err := yaml.Unmarshal(body, &req); err != nil {
response := ModelResponse{
Success: false,
Error: "Failed to parse YAML: " + err.Error(),
}
return c.JSON(http.StatusBadRequest, response)
}
// Validate required fields
if req.Name == "" {
response := ModelResponse{
Success: false,
Error: "Name is required",
}
return c.JSON(http.StatusBadRequest, response)
}
// Validate the configuration
if valid, _ := req.Validate(); !valid {
response := ModelResponse{
Success: false,
Error: "Validation failed",
Details: []string{"Configuration validation failed. Please check your YAML syntax and required fields."},
}
return c.JSON(http.StatusBadRequest, response)
}
// Load the existing configuration
configPath := modelConfig.GetModelConfigFile()
if err := utils.VerifyPath(configPath, appConfig.SystemState.Model.ModelsPath); err != nil {
response := ModelResponse{
Success: false,
Error: "Model configuration not trusted: " + err.Error(),
}
return c.JSON(http.StatusNotFound, response)
}
// Write new content to file
if err := os.WriteFile(configPath, body, 0644); err != nil {
response := ModelResponse{
Success: false,
Error: "Failed to write configuration file: " + err.Error(),
}
return c.JSON(http.StatusInternalServerError, response)
}
// Reload configurations
if err := cl.LoadModelConfigsFromPath(appConfig.SystemState.Model.ModelsPath, appConfig.ToConfigLoaderOptions()...); err != nil {
response := ModelResponse{
Success: false,
Error: "Failed to reload configurations: " + err.Error(),
}
return c.JSON(http.StatusInternalServerError, response)
}
// Preload the model
if err := cl.Preload(appConfig.SystemState.Model.ModelsPath); err != nil {
response := ModelResponse{
Success: false,
Error: "Failed to preload model: " + err.Error(),
}
return c.JSON(http.StatusInternalServerError, response)
}
// Return success response
response := ModelResponse{
Success: true,
Message: fmt.Sprintf("Model '%s' updated successfully", modelName),
Filename: configPath,
Config: req,
}
return c.JSON(200, response)
}
}
// ReloadModelsEndpoint handles reloading model configurations from disk
func ReloadModelsEndpoint(cl *config.ModelConfigLoader, appConfig *config.ApplicationConfig) echo.HandlerFunc {
return func(c echo.Context) error {
// Reload configurations
if err := cl.LoadModelConfigsFromPath(appConfig.SystemState.Model.ModelsPath, appConfig.ToConfigLoaderOptions()...); err != nil {
response := ModelResponse{
Success: false,
Error: "Failed to reload configurations: " + err.Error(),
}
return c.JSON(http.StatusInternalServerError, response)
}
// Preload the models
if err := cl.Preload(appConfig.SystemState.Model.ModelsPath); err != nil {
response := ModelResponse{
Success: false,
Error: "Failed to preload models: " + err.Error(),
}
return c.JSON(http.StatusInternalServerError, response)
}
// Return success response
response := ModelResponse{
Success: true,
Message: "Model configurations reloaded successfully",
}
return c.JSON(http.StatusOK, response)
}
}