init.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package init
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "time"
  7. tea "github.com/charmbracelet/bubbletea"
  8. "github.com/langgenius/dify-plugin-daemon/internal/types/entities/constants"
  9. "github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
  10. "github.com/langgenius/dify-plugin-daemon/internal/utils/log"
  11. )
  12. func InitPlugin() {
  13. m := initialize()
  14. p := tea.NewProgram(m)
  15. if result, err := p.Run(); err != nil {
  16. fmt.Println("Error running program:", err)
  17. } else {
  18. if m, ok := result.(model); ok {
  19. if m.completed {
  20. m.createPlugin()
  21. }
  22. } else {
  23. log.Error("Error running program:", err)
  24. return
  25. }
  26. }
  27. }
  28. type subMenuKey string
  29. const (
  30. SUB_MENU_KEY_PROFILE subMenuKey = "profile"
  31. SUB_MENU_KEY_LANGUAGE subMenuKey = "language"
  32. SUB_MENU_KEY_PERMISSION subMenuKey = "permission"
  33. )
  34. type model struct {
  35. subMenus map[subMenuKey]subMenu
  36. subMenuSeq []subMenuKey
  37. currentSubMenu subMenuKey
  38. completed bool
  39. }
  40. func initialize() model {
  41. m := model{}
  42. m.subMenus = map[subMenuKey]subMenu{
  43. SUB_MENU_KEY_PROFILE: newProfile(),
  44. SUB_MENU_KEY_LANGUAGE: newLanguage(),
  45. SUB_MENU_KEY_PERMISSION: newPermission(),
  46. }
  47. m.currentSubMenu = SUB_MENU_KEY_PROFILE
  48. m.subMenuSeq = []subMenuKey{
  49. SUB_MENU_KEY_PROFILE,
  50. SUB_MENU_KEY_LANGUAGE,
  51. SUB_MENU_KEY_PERMISSION,
  52. }
  53. return m
  54. }
  55. func (m model) Init() tea.Cmd {
  56. return nil
  57. }
  58. func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
  59. currentSubMenu, event, cmd := m.subMenus[m.currentSubMenu].Update(msg)
  60. m.subMenus[m.currentSubMenu] = currentSubMenu
  61. switch event {
  62. case SUB_MENU_EVENT_NEXT:
  63. if m.currentSubMenu != m.subMenuSeq[len(m.subMenuSeq)-1] {
  64. // move the current sub menu to the next one
  65. for i, key := range m.subMenuSeq {
  66. if key == m.currentSubMenu {
  67. m.currentSubMenu = m.subMenuSeq[i+1]
  68. break
  69. }
  70. }
  71. } else {
  72. m.completed = true
  73. return m, tea.Quit
  74. }
  75. case SUB_MENU_EVENT_PREV:
  76. if m.currentSubMenu != m.subMenuSeq[0] {
  77. // move the current sub menu to the previous one
  78. for i, key := range m.subMenuSeq {
  79. if key == m.currentSubMenu {
  80. m.currentSubMenu = m.subMenuSeq[i-1]
  81. break
  82. }
  83. }
  84. }
  85. }
  86. return m, cmd
  87. }
  88. func (m model) View() string {
  89. return m.subMenus[m.currentSubMenu].View()
  90. }
  91. func (m model) createPlugin() {
  92. permission := m.subMenus[SUB_MENU_KEY_PERMISSION].(permission).Permission()
  93. manifest := &plugin_entities.PluginDeclaration{
  94. Version: "0.0.1",
  95. Type: plugin_entities.PluginType,
  96. Author: m.subMenus[SUB_MENU_KEY_PROFILE].(profile).Author(),
  97. Name: m.subMenus[SUB_MENU_KEY_PROFILE].(profile).Name(),
  98. CreatedAt: time.Now(),
  99. Resource: plugin_entities.PluginResourceRequirement{
  100. Memory: 1024 * 1024 * 256, // 256MB
  101. Permission: &permission,
  102. },
  103. Label: plugin_entities.I18nObject{
  104. EnUS: m.subMenus[SUB_MENU_KEY_PROFILE].(profile).Name(),
  105. },
  106. }
  107. manifest.Meta = plugin_entities.PluginMeta{
  108. Version: "0.0.1",
  109. Arch: []constants.Arch{
  110. constants.AMD64,
  111. constants.ARM64,
  112. },
  113. Runner: plugin_entities.PluginRunner{},
  114. }
  115. switch m.subMenus[SUB_MENU_KEY_LANGUAGE].(language).Language() {
  116. case constants.Python:
  117. manifest.Meta.Runner.Entrypoint = "main"
  118. manifest.Meta.Runner.Language = constants.Python
  119. manifest.Meta.Runner.Version = "3.10"
  120. default:
  121. log.Error("unsupported language: %s", m.subMenus[SUB_MENU_KEY_LANGUAGE].(language).Language())
  122. return
  123. }
  124. success := false
  125. clear := func() {
  126. if !success {
  127. os.RemoveAll(manifest.Name)
  128. }
  129. }
  130. defer clear()
  131. manifest_file := marshalYamlBytes(manifest)
  132. // create the plugin directory
  133. cwd, err := os.Getwd()
  134. if err != nil {
  135. log.Error("failed to get current working directory: %s", err)
  136. return
  137. }
  138. plugin_dir := filepath.Join(cwd, manifest.Name)
  139. if err := os.MkdirAll(plugin_dir, 0o755); err != nil {
  140. log.Error("failed to create plugin directory: %s", err)
  141. return
  142. }
  143. manifest_file_path := filepath.Join(plugin_dir, "manifest.yaml")
  144. if err := os.WriteFile(manifest_file_path, manifest_file, 0o644); err != nil {
  145. log.Error("failed to write manifest file: %s", err)
  146. return
  147. }
  148. err = createPythonEnvironment(plugin_dir, manifest.Meta.Runner.Entrypoint)
  149. if err != nil {
  150. log.Error("failed to create python environment: %s", err)
  151. return
  152. }
  153. success = true
  154. log.Info("plugin %s created successfully", manifest.Name)
  155. }