decoder.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package decoder
  2. import (
  3. "errors"
  4. "fmt"
  5. "io"
  6. "io/fs"
  7. "github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
  8. "github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
  9. )
  10. // PluginDecoder is an interface for decoding and interacting with plugin files
  11. type PluginDecoder interface {
  12. // Open initializes the decoder and prepares it for use
  13. Open() error
  14. // Walk traverses the plugin files and calls the provided function for each file
  15. // The function is called with the filename and directory of each file
  16. Walk(fn func(filename string, dir string) error) error
  17. // ReadFile reads the entire contents of a file and returns it as a byte slice
  18. ReadFile(filename string) ([]byte, error)
  19. // Close releases any resources used by the decoder
  20. Close() error
  21. // Stat returns file info for the specified filename
  22. Stat(filename string) (fs.FileInfo, error)
  23. // FileReader returns an io.ReadCloser for reading the contents of a file
  24. // Remember to close the reader when done using it
  25. FileReader(filename string) (io.ReadCloser, error)
  26. // Signature returns the signature of the plugin, if available
  27. Signature() (string, error)
  28. // CreateTime returns the creation time of the plugin as a Unix timestamp
  29. CreateTime() (int64, error)
  30. // Manifest returns the manifest of the plugin
  31. Manifest() (plugin_entities.PluginDeclaration, error)
  32. }
  33. type PluginDecoderHelper struct {
  34. pluginDeclaration *plugin_entities.PluginDeclaration
  35. }
  36. func (p *PluginDecoderHelper) Manifest(decoder PluginDecoder) (plugin_entities.PluginDeclaration, error) {
  37. if p.pluginDeclaration != nil {
  38. return *p.pluginDeclaration, nil
  39. }
  40. // read the manifest file
  41. manifest, err := decoder.ReadFile("manifest.yaml")
  42. if err != nil {
  43. return plugin_entities.PluginDeclaration{}, err
  44. }
  45. dec, err := parser.UnmarshalYamlBytes[plugin_entities.PluginDeclaration](manifest)
  46. if err != nil {
  47. return plugin_entities.PluginDeclaration{}, err
  48. }
  49. // try to load plugins
  50. plugins := dec.Plugins
  51. for _, plugin := range plugins {
  52. // read yaml
  53. plugin_yaml, err := decoder.ReadFile(plugin)
  54. if err != nil {
  55. return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to read plugin file: %s", plugin))
  56. }
  57. plugin_dec, err := parser.UnmarshalYamlBytes[plugin_entities.GenericProviderDeclaration](plugin_yaml)
  58. if err != nil {
  59. return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to unmarshal plugin file: %s", plugin))
  60. }
  61. switch plugin_dec.Type {
  62. case plugin_entities.PROVIDER_TYPE_ENDPOINT:
  63. dec.Endpoint, err = parser.MapToStruct[plugin_entities.EndpointProviderDeclaration](plugin_dec.Provider)
  64. if err != nil {
  65. return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to convert endpoint to struct: %s", plugin))
  66. }
  67. case plugin_entities.PROVIDER_TYPE_TOOL:
  68. dec.Tool, err = parser.MapToStruct[plugin_entities.ToolProviderConfiguration](plugin_dec.Provider)
  69. if err != nil {
  70. return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to convert tool to struct: %s", plugin))
  71. }
  72. case plugin_entities.PROVIDER_TYPE_MODEL:
  73. dec.Model, err = parser.MapToStruct[plugin_entities.ModelProviderConfiguration](plugin_dec.Provider)
  74. if err != nil {
  75. return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to convert model to struct: %s", plugin))
  76. }
  77. default:
  78. return plugin_entities.PluginDeclaration{}, fmt.Errorf("unknown provider type: %s", plugin_dec.Type)
  79. }
  80. }
  81. if err := dec.ManifestValidate(); err != nil {
  82. return plugin_entities.PluginDeclaration{}, err
  83. }
  84. p.pluginDeclaration = &dec
  85. return dec, nil
  86. }