You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dependencies_analysis.py 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. from configs import dify_config
  2. from core.helper import marketplace
  3. from core.plugin.entities.plugin import ModelProviderID, PluginDependency, PluginInstallationSource, ToolProviderID
  4. from core.plugin.impl.plugin import PluginInstaller
  5. class DependenciesAnalysisService:
  6. @classmethod
  7. def analyze_tool_dependency(cls, tool_id: str) -> str:
  8. """
  9. Analyze the dependency of a tool.
  10. Convert the tool id to the plugin_id
  11. """
  12. try:
  13. return ToolProviderID(tool_id).plugin_id
  14. except Exception as e:
  15. raise e
  16. @classmethod
  17. def analyze_model_provider_dependency(cls, model_provider_id: str) -> str:
  18. """
  19. Analyze the dependency of a model provider.
  20. Convert the model provider id to the plugin_id
  21. """
  22. try:
  23. return ModelProviderID(model_provider_id).plugin_id
  24. except Exception as e:
  25. raise e
  26. @classmethod
  27. def get_leaked_dependencies(cls, tenant_id: str, dependencies: list[PluginDependency]) -> list[PluginDependency]:
  28. """
  29. Check dependencies, returns the leaked dependencies in current workspace
  30. """
  31. required_plugin_unique_identifiers = []
  32. for dependency in dependencies:
  33. required_plugin_unique_identifiers.append(dependency.value.plugin_unique_identifier)
  34. manager = PluginInstaller()
  35. # get leaked dependencies
  36. missing_plugins = manager.fetch_missing_dependencies(tenant_id, required_plugin_unique_identifiers)
  37. missing_plugin_unique_identifiers = {plugin.plugin_unique_identifier: plugin for plugin in missing_plugins}
  38. leaked_dependencies = []
  39. for dependency in dependencies:
  40. unique_identifier = dependency.value.plugin_unique_identifier
  41. if unique_identifier in missing_plugin_unique_identifiers:
  42. leaked_dependencies.append(
  43. PluginDependency(
  44. type=dependency.type,
  45. value=dependency.value,
  46. current_identifier=missing_plugin_unique_identifiers[unique_identifier].current_identifier,
  47. )
  48. )
  49. return leaked_dependencies
  50. @classmethod
  51. def generate_dependencies(cls, tenant_id: str, dependencies: list[str]) -> list[PluginDependency]:
  52. """
  53. Generate dependencies through the list of plugin ids
  54. """
  55. dependencies = list(set(dependencies))
  56. manager = PluginInstaller()
  57. plugins = manager.fetch_plugin_installation_by_ids(tenant_id, dependencies)
  58. result = []
  59. for plugin in plugins:
  60. if plugin.source == PluginInstallationSource.Github:
  61. result.append(
  62. PluginDependency(
  63. type=PluginDependency.Type.Github,
  64. value=PluginDependency.Github(
  65. repo=plugin.meta["repo"],
  66. version=plugin.meta["version"],
  67. package=plugin.meta["package"],
  68. github_plugin_unique_identifier=plugin.plugin_unique_identifier,
  69. ),
  70. )
  71. )
  72. elif plugin.source == PluginInstallationSource.Marketplace:
  73. result.append(
  74. PluginDependency(
  75. type=PluginDependency.Type.Marketplace,
  76. value=PluginDependency.Marketplace(
  77. marketplace_plugin_unique_identifier=plugin.plugin_unique_identifier
  78. ),
  79. )
  80. )
  81. elif plugin.source == PluginInstallationSource.Package:
  82. result.append(
  83. PluginDependency(
  84. type=PluginDependency.Type.Package,
  85. value=PluginDependency.Package(plugin_unique_identifier=plugin.plugin_unique_identifier),
  86. )
  87. )
  88. elif plugin.source == PluginInstallationSource.Remote:
  89. raise ValueError(
  90. f"You used a remote plugin: {plugin.plugin_unique_identifier} in the app, please remove it first"
  91. " if you want to export the DSL."
  92. )
  93. else:
  94. raise ValueError(f"Unknown plugin source: {plugin.source}")
  95. return result
  96. @classmethod
  97. def generate_latest_dependencies(cls, dependencies: list[str]) -> list[PluginDependency]:
  98. """
  99. Generate the latest version of dependencies
  100. """
  101. dependencies = list(set(dependencies))
  102. if not dify_config.MARKETPLACE_ENABLED:
  103. return []
  104. deps = marketplace.batch_fetch_plugin_manifests(dependencies)
  105. return [
  106. PluginDependency(
  107. type=PluginDependency.Type.Marketplace,
  108. value=PluginDependency.Marketplace(marketplace_plugin_unique_identifier=dep.latest_package_identifier),
  109. )
  110. for dep in deps
  111. ]