plugin.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. init_pkg "github.com/langgenius/dify-plugin-daemon/cmd/commandline/init"
  7. "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_packager/decoder"
  8. "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_packager/packager"
  9. "github.com/langgenius/dify-plugin-daemon/internal/utils/log"
  10. "github.com/spf13/cobra"
  11. )
  12. var (
  13. pluginInitCommand = &cobra.Command{
  14. Use: "init",
  15. Short: "Init",
  16. Long: "Init",
  17. Run: func(c *cobra.Command, args []string) {
  18. init_pkg.InitPlugin()
  19. },
  20. }
  21. pluginPackageCommand = &cobra.Command{
  22. Use: "package plugin_path [-o output_path]",
  23. Short: "Package",
  24. Long: "Package plugins",
  25. Run: func(cmd *cobra.Command, args []string) {
  26. if len(args) < 1 {
  27. fmt.Println("Error: plugin_path is required")
  28. return
  29. }
  30. input_path := args[0]
  31. // using filename of input_path as output_path if not specified
  32. output_path := ""
  33. if cmd.Flag("output_path") != nil {
  34. output_path = cmd.Flag("output_path").Value.String()
  35. } else {
  36. output_path = filepath.Base(input_path) + ".difypkg"
  37. }
  38. decoder, err := decoder.NewFSPluginDecoder(input_path)
  39. if err != nil {
  40. log.Error("failed to create plugin decoder , plugin path: %s, error: %v", input_path, err)
  41. return
  42. }
  43. packager := packager.NewPackager(decoder)
  44. zip_file, err := packager.Pack()
  45. if err != nil {
  46. log.Error("failed to package plugin %v", err)
  47. return
  48. }
  49. err = os.WriteFile(output_path, zip_file, 0644)
  50. if err != nil {
  51. log.Error("failed to write package file %v", err)
  52. return
  53. }
  54. log.Info("plugin packaged successfully, output path: %s", output_path)
  55. },
  56. }
  57. pluginChecksumCommand = &cobra.Command{
  58. Use: "checksum plugin_path",
  59. Short: "Checksum",
  60. Long: "Calculate the checksum of the plugin, you need specify the plugin path or .difypkg file path",
  61. Run: func(cmd *cobra.Command, args []string) {
  62. if len(args) < 1 {
  63. fmt.Println("Error: plugin_path is required")
  64. return
  65. }
  66. plugin_path := args[0]
  67. var plugin_decoder decoder.PluginDecoder
  68. if stat, err := os.Stat(plugin_path); err == nil {
  69. if stat.IsDir() {
  70. plugin_decoder, err = decoder.NewFSPluginDecoder(plugin_path)
  71. if err != nil {
  72. log.Error("failed to create plugin decoder, plugin path: %s, error: %v", plugin_path, err)
  73. return
  74. }
  75. } else {
  76. bytes, err := os.ReadFile(plugin_path)
  77. if err != nil {
  78. log.Error("failed to read plugin file, plugin path: %s, error: %v", plugin_path, err)
  79. return
  80. }
  81. plugin_decoder, err = decoder.NewZipPluginDecoder(bytes)
  82. if err != nil {
  83. log.Error("failed to create plugin decoder, plugin path: %s, error: %v", plugin_path, err)
  84. return
  85. }
  86. }
  87. } else {
  88. log.Error("failed to get plugin file info, plugin path: %s, error: %v", plugin_path, err)
  89. return
  90. }
  91. checksum, err := plugin_decoder.Checksum()
  92. if err != nil {
  93. log.Error("failed to calculate checksum, plugin path: %s, error: %v", plugin_path, err)
  94. return
  95. }
  96. log.Info("plugin checksum: %s", checksum)
  97. },
  98. }
  99. pluginPermissionCommand = &cobra.Command{
  100. Use: "permission",
  101. Short: "Permission",
  102. Long: `Permission, available values:
  103. tools - allow plugin to call tools
  104. models - allow plugin to call models
  105. models.llm - allow plugin to call llm
  106. models.text_embedding - allow plugin to call text_embedding model
  107. models.rerank - allow plugin to call rerank model
  108. models.tts - allow plugin to call tts
  109. models.speech2text - allow plugin to call speech2text
  110. models.moderation - allow plugin to call moderation
  111. apps - allow plugin to call apps
  112. storage - allow plugin to use storage
  113. endpoint - allow plugin to register endpoint`,
  114. }
  115. pluginPermissionAddCommand = &cobra.Command{
  116. Use: "add permission",
  117. Short: "",
  118. Long: "Add permission to plugin, you can find the available permission by running `dify plugin permission`",
  119. }
  120. pluginPermissionDropCommand = &cobra.Command{
  121. Use: "drop permission",
  122. Short: "",
  123. Long: "Drop permission from plugin, you can find the available permission by running `dify plugin permission`",
  124. }
  125. // NOTE: tester is deprecated, maybe, in several months, we will support this again
  126. // pluginTestCommand = &cobra.Command{
  127. // Use: "test [-i inputs] [-t timeout] package_path invoke_type invoke_action",
  128. // Short: "",
  129. // Long: "Test runs the given plugin package locally, and you can specify the inputs using json format, if not specified, will use default inputs\n" +
  130. // "type: invoke type, available values: \n" +
  131. // "[\n" +
  132. // " tool, model, endpoint\n" +
  133. // "]\n" +
  134. // "action: invoke action, available values: \n" +
  135. // "[\n" +
  136. // " invoke_tool, validate_tool_credentials, \n" +
  137. // " invoke_endpoint\n" +
  138. // " invoke_llm, invoke_text_embedding, invoke_rerank, invoke_tts, invoke_speech2text, invoke_moderation, \n" +
  139. // " validate_provider_credentials, validate_model_credentials, get_tts_model_voices, \n" +
  140. // " get_text_embedding_num_tokens, get_ai_model_schemas, get_llm_num_tokens\n" +
  141. // "]\n",
  142. // Run: func(cmd *cobra.Command, args []string) {
  143. // if len(args) < 3 {
  144. // log.Error("invalid args, please specify package_path, invoke_type, invoke_action")
  145. // return
  146. // }
  147. // // get package path
  148. // package_path_str := args[0]
  149. // // get invoke type
  150. // invoke_type_str := args[1]
  151. // // get invoke action
  152. // invoke_action_str := args[2]
  153. // // get inputs if specified
  154. // inputs := map[string]any{}
  155. // if cmd.Flag("inputs") != nil {
  156. // inputs_str := cmd.Flag("inputs").Value.String()
  157. // err := json.Unmarshal([]byte(inputs_str), &inputs)
  158. // if err != nil {
  159. // log.Error("failed to unmarshal inputs, inputs: %s, error: %v", inputs_str, err)
  160. // return
  161. // }
  162. // }
  163. // // parse flag
  164. // timeout := ""
  165. // if cmd.Flag("timeout") != nil {
  166. // timeout = cmd.Flag("timeout").Value.String()
  167. // }
  168. // // get invoke_type and invoke_action
  169. // invoke_type := access_types.PluginAccessType(invoke_type_str)
  170. // if !invoke_type.IsValid() {
  171. // log.Error("invalid invoke type: %s", invoke_type_str)
  172. // return
  173. // }
  174. // invoke_action := access_types.PluginAccessAction(invoke_action_str)
  175. // if !invoke_action.IsValid() {
  176. // log.Error("invalid invoke action: %s", invoke_action_str)
  177. // return
  178. // }
  179. // // init routine pool
  180. // routine.InitPool(1024)
  181. // // clean working directory when test finished
  182. // defer os.RemoveAll("./working")
  183. // // init testing config
  184. // config := &app.Config{
  185. // PluginWorkingPath: "./working/cwd",
  186. // PluginStoragePath: "./working/storage",
  187. // PluginMediaCachePath: "./working/media_cache",
  188. // ProcessCachingPath: "./working/subprocesses",
  189. // Platform: app.PLATFORM_LOCAL,
  190. // }
  191. // config.SetDefault()
  192. // // init oss
  193. // oss := local.NewLocalStorage("./storage")
  194. // // init plugin manager
  195. // plugin_manager := plugin_manager.InitGlobalManager(oss, config)
  196. // response, err := plugin_manager.TestPlugin(package_path_str, inputs, invoke_type, invoke_action, timeout)
  197. // if err != nil {
  198. // log.Error("failed to test plugin, package_path: %s, error: %v", package_path_str, err)
  199. // return
  200. // }
  201. // for response.Next() {
  202. // item, err := response.Read()
  203. // if err != nil {
  204. // log.Error("failed to read response item, error: %v", err)
  205. // return
  206. // }
  207. // log.Info("%v", parser.MarshalJson(item))
  208. // }
  209. // },
  210. // }
  211. )
  212. func init() {
  213. pluginCommand.AddCommand(pluginInitCommand)
  214. pluginCommand.AddCommand(pluginPackageCommand)
  215. pluginCommand.AddCommand(pluginChecksumCommand)
  216. pluginCommand.AddCommand(pluginPermissionCommand)
  217. // pluginCommand.AddCommand(pluginTestCommand)
  218. // pluginTestCommand.Flags().StringP("inputs", "i", "", "inputs")
  219. // pluginTestCommand.Flags().StringP("timeout", "t", "", "timeout")
  220. pluginPermissionCommand.AddCommand(pluginPermissionAddCommand)
  221. pluginPermissionCommand.AddCommand(pluginPermissionDropCommand)
  222. }