Browse Source

feat: plugin managment

Yeuoly 10 months ago
parent
commit
91fd7c3e7f

+ 27 - 0
internal/server/controllers/plugins.go

@@ -68,4 +68,31 @@ func UninstallPlugin(c *gin.Context) {
 }
 
 func ListPlugins(c *gin.Context) {
+	BindRequest(c, func(request struct {
+		TenantID string `form:"tenant_id" binding:"required"`
+		Page     int    `form:"page" binding:"required,min=1"`
+		PageSize int    `form:"page_size" binding:"required,min=1,max=256"`
+	}) {
+		c.JSON(http.StatusOK, service.ListPlugins(request.TenantID, request.Page, request.PageSize))
+	})
+}
+
+func ListModels(c *gin.Context) {
+	BindRequest(c, func(request struct {
+		TenantID string `form:"tenant_id" binding:"required"`
+		Page     int    `form:"page" binding:"required,min=1"`
+		PageSize int    `form:"page_size" binding:"required,min=1,max=256"`
+	}) {
+		c.JSON(http.StatusOK, service.ListModels(request.TenantID, request.Page, request.PageSize))
+	})
+}
+
+func ListTools(c *gin.Context) {
+	BindRequest(c, func(request struct {
+		TenantID string `form:"tenant_id" binding:"required"`
+		Page     int    `form:"page" binding:"required,min=1"`
+		PageSize int    `form:"page_size" binding:"required,min=1,max=256"`
+	}) {
+		c.JSON(http.StatusOK, service.ListTools(request.TenantID, request.Page, request.PageSize))
+	})
 }

+ 2 - 0
internal/server/http_server.go

@@ -105,4 +105,6 @@ func (app *App) pluginGroup(group *gin.RouterGroup, config *app.Config) {
 	group.POST("/install/identifier", controllers.InstallPluginFromIdentifier(config))
 	group.POST("/uninstall", controllers.UninstallPlugin)
 	group.GET("/list", controllers.ListPlugins)
+	group.GET("/models", controllers.ListModels)
+	group.GET("/tools", controllers.ListTools)
 }

+ 63 - 0
internal/service/endpoint.go

@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"context"
 	"encoding/hex"
+	"fmt"
 	"sync/atomic"
 	"time"
 
@@ -178,3 +179,65 @@ func DisableEndpoint(endpoint_id string, tenant_id string) *entities.Response {
 
 	return entities.NewSuccessResponse("success")
 }
+
+func ListEndpoints(tenant_id string, page int, page_size int) *entities.Response {
+	endpoints, err := db.GetAll[models.Endpoint](
+		db.Equal("tenant_id", tenant_id),
+		db.OrderBy("created_at", true),
+		db.Page(page, page_size),
+	)
+	if err != nil {
+		return entities.NewErrorResponse(-500, fmt.Sprintf("failed to list endpoints: %v", err))
+	}
+
+	// decrypt settings
+	for i, endpoint := range endpoints {
+		plugin_installation, err := db.GetOne[models.PluginInstallation](
+			db.Equal("plugin_id", endpoint.PluginID),
+			db.Equal("tenant_id", tenant_id),
+		)
+		if err != nil {
+			return entities.NewErrorResponse(-404, fmt.Sprintf("failed to find plugin installation: %v", err))
+		}
+
+		plugin, err := db.GetOne[models.Plugin](
+			db.Equal("plugin_unique_identifier", plugin_installation.PluginUniqueIdentifier),
+		)
+		if err != nil {
+			return entities.NewErrorResponse(-404, fmt.Sprintf("failed to find plugin: %v", err))
+		}
+
+		plugin_declaration, err := plugin.GetDeclaration()
+		if err != nil {
+			return entities.NewErrorResponse(-404, fmt.Sprintf("failed to get plugin declaration: %v", err))
+		}
+
+		if plugin_declaration.Endpoint == nil {
+			return entities.NewErrorResponse(-404, "plugin does not have an endpoint")
+		}
+
+		decrypted_settings, err := dify_invocation.InvokeEncrypt(&dify_invocation.InvokeEncryptRequest{
+			BaseInvokeDifyRequest: dify_invocation.BaseInvokeDifyRequest{
+				TenantId: tenant_id,
+				UserId:   "",
+				Type:     dify_invocation.INVOKE_TYPE_ENCRYPT,
+			},
+			InvokeEncryptSchema: dify_invocation.InvokeEncryptSchema{
+				Opt:       dify_invocation.ENCRYPT_OPT_DECRYPT,
+				Namespace: dify_invocation.ENCRYPT_NAMESPACE_ENDPOINT,
+				Identity:  endpoint.ID,
+				Data:      endpoint.GetSettings(),
+				Config:    plugin_declaration.Endpoint.Settings,
+			},
+		})
+		if err != nil {
+			return entities.NewErrorResponse(-500, fmt.Sprintf("failed to decrypt settings: %v", err))
+		}
+
+		endpoint.SetSettings(decrypted_settings)
+
+		endpoints[i] = endpoint
+	}
+
+	return entities.NewSuccessResponse(endpoints)
+}

internal/service/install.go → internal/service/install_plugin.go


+ 71 - 0
internal/service/manage_plugin.go

@@ -0,0 +1,71 @@
+package service
+
+import (
+	"time"
+
+	"github.com/langgenius/dify-plugin-daemon/internal/db"
+	"github.com/langgenius/dify-plugin-daemon/internal/types/entities"
+	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
+	"github.com/langgenius/dify-plugin-daemon/internal/types/models"
+	"github.com/langgenius/dify-plugin-daemon/internal/utils/cache"
+)
+
+func ListPlugins(tenant_id string, page int, page_size int) *entities.Response {
+	type installation struct {
+		ID             string                             `json:"id"`
+		Name           string                             `json:"name"`
+		PluginID       string                             `json:"plugin_id"`
+		InstallationID string                             `json:"installation_id"`
+		Description    *plugin_entities.PluginDeclaration `json:"description"`
+		RuntimeType    plugin_entities.PluginRuntimeType  `json:"runtime_type"`
+		Version        string                             `json:"version"`
+		CreatedAt      time.Time                          `json:"created_at"`
+		UpdatedAt      time.Time                          `json:"updated_at"`
+	}
+
+	plugin_installations, err := db.GetAll[models.PluginInstallation](
+		db.Equal("tenant_id", tenant_id),
+		db.Page(page, page_size),
+	)
+
+	if err != nil {
+		return entities.NewErrorResponse(-500, err.Error())
+	}
+
+	data := make([]installation, 0, len(plugin_installations))
+
+	for _, plugin_installation := range plugin_installations {
+		plugin, err := cache.Get[models.Plugin](plugin_installation.PluginUniqueIdentifier)
+		if err != nil {
+			return entities.NewErrorResponse(-500, err.Error())
+		}
+
+		declaration, err := plugin.GetDeclaration()
+		if err != nil {
+			return entities.NewErrorResponse(-500, err.Error())
+		}
+
+		data = append(data, installation{
+			ID:             plugin_installation.ID,
+			Name:           declaration.Name,
+			PluginID:       plugin.ID,
+			InstallationID: plugin_installation.ID,
+			Description:    declaration,
+			RuntimeType:    plugin_entities.PluginRuntimeType(plugin_installation.RuntimeType),
+			Version:        declaration.Version,
+			CreatedAt:      plugin_installation.CreatedAt,
+			UpdatedAt:      plugin_installation.UpdatedAt,
+		})
+
+	}
+
+	return entities.NewSuccessResponse(data)
+}
+
+func ListTools(tenant_id string, page int, page_size int) *entities.Response {
+	return nil
+}
+
+func ListModels(tenant_id string, page int, page_size int) *entities.Response {
+	return nil
+}

+ 0 - 62
internal/service/setup_endpoint.go

@@ -83,68 +83,6 @@ func SetupEndpoint(
 	return entities.NewSuccessResponse(nil)
 }
 
-func ListEndpoints(tenant_id string, page int, page_size int) *entities.Response {
-	endpoints, err := db.GetAll[models.Endpoint](
-		db.Equal("tenant_id", tenant_id),
-		db.OrderBy("created_at", true),
-		db.Page(page, page_size),
-	)
-	if err != nil {
-		return entities.NewErrorResponse(-500, fmt.Sprintf("failed to list endpoints: %v", err))
-	}
-
-	// decrypt settings
-	for i, endpoint := range endpoints {
-		plugin_installation, err := db.GetOne[models.PluginInstallation](
-			db.Equal("plugin_id", endpoint.PluginID),
-			db.Equal("tenant_id", tenant_id),
-		)
-		if err != nil {
-			return entities.NewErrorResponse(-404, fmt.Sprintf("failed to find plugin installation: %v", err))
-		}
-
-		plugin, err := db.GetOne[models.Plugin](
-			db.Equal("plugin_unique_identifier", plugin_installation.PluginUniqueIdentifier),
-		)
-		if err != nil {
-			return entities.NewErrorResponse(-404, fmt.Sprintf("failed to find plugin: %v", err))
-		}
-
-		plugin_declaration, err := plugin.GetDeclaration()
-		if err != nil {
-			return entities.NewErrorResponse(-404, fmt.Sprintf("failed to get plugin declaration: %v", err))
-		}
-
-		if plugin_declaration.Endpoint == nil {
-			return entities.NewErrorResponse(-404, "plugin does not have an endpoint")
-		}
-
-		decrypted_settings, err := dify_invocation.InvokeEncrypt(&dify_invocation.InvokeEncryptRequest{
-			BaseInvokeDifyRequest: dify_invocation.BaseInvokeDifyRequest{
-				TenantId: tenant_id,
-				UserId:   "",
-				Type:     dify_invocation.INVOKE_TYPE_ENCRYPT,
-			},
-			InvokeEncryptSchema: dify_invocation.InvokeEncryptSchema{
-				Opt:       dify_invocation.ENCRYPT_OPT_DECRYPT,
-				Namespace: dify_invocation.ENCRYPT_NAMESPACE_ENDPOINT,
-				Identity:  endpoint.ID,
-				Data:      endpoint.GetSettings(),
-				Config:    plugin_declaration.Endpoint.Settings,
-			},
-		})
-		if err != nil {
-			return entities.NewErrorResponse(-500, fmt.Sprintf("failed to decrypt settings: %v", err))
-		}
-
-		endpoint.SetSettings(decrypted_settings)
-
-		endpoints[i] = endpoint
-	}
-
-	return entities.NewSuccessResponse(endpoints)
-}
-
 func RemoveEndpoint(endpoint_id string, tenant_id string) *entities.Response {
 	endpoint, err := db.GetOne[models.Endpoint](
 		db.Equal("endpoint_id", endpoint_id),

+ 3 - 1
internal/types/models/curd/atomic.go

@@ -63,7 +63,8 @@ func CreatePlugin(
 		// remove exists installation
 		if err := db.DeleteByCondition(
 			models.PluginInstallation{
-				PluginID: plugin_to_be_returns.PluginID,
+				PluginID:    plugin_to_be_returns.PluginID,
+				RuntimeType: string(install_type),
 			},
 			tx,
 		); err != nil {
@@ -74,6 +75,7 @@ func CreatePlugin(
 			PluginID:               plugin_to_be_returns.PluginID,
 			PluginUniqueIdentifier: plugin_to_be_returns.PluginUniqueIdentifier,
 			TenantID:               tenant_id,
+			RuntimeType:            string(install_type),
 		}
 
 		err = db.Create(installation, tx)

+ 1 - 13
internal/types/models/installation.go

@@ -1,9 +1,5 @@
 package models
 
-import (
-	"encoding/json"
-)
-
 type PluginInstallationStatus string
 
 type PluginInstallation struct {
@@ -11,13 +7,5 @@ type PluginInstallation struct {
 	TenantID               string `json:"tenant_id" gorm:"index;type:uuid;"`
 	PluginID               string `json:"plugin_id" gorm:"index;size:127"`
 	PluginUniqueIdentifier string `json:"plugin_unique_identifier" gorm:"index;size:127"`
-	Config                 string `json:"config"`
-}
-
-func (p *PluginInstallation) ConfigMap() (map[string]any, error) {
-	var config map[string]any
-	if err := json.Unmarshal([]byte(p.Config), &config); err != nil {
-		return nil, err
-	}
-	return config, nil
+	RuntimeType            string `json:"runtime_type" gorm:"size:127"`
 }