diff --git a/api/core/helper/marketplace.py b/api/core/helper/marketplace.py index 89dae4808f..e212373e32 100644 --- a/api/core/helper/marketplace.py +++ b/api/core/helper/marketplace.py @@ -11,6 +11,20 @@ marketplace_api_url = URL(str(dify_config.MARKETPLACE_API_URL)) def get_plugin_pkg_url(plugin_unique_identifier: str) -> str: + # Parse org/name:version format (without checksum) + if "/" in plugin_unique_identifier and ":" in plugin_unique_identifier: + # Remove checksum if present (format: org/name:version@checksum) + if "@" in plugin_unique_identifier: + plugin_unique_identifier = plugin_unique_identifier.split("@")[0] + + # Parse org/name:version + org_and_name, version = plugin_unique_identifier.rsplit(":", 1) + org, name = org_and_name.split("/", 1) + + # Use new endpoint format + return str(marketplace_api_url / f"api/v1/plugins/{org}/{name}/{version}/download") + + # Fallback to old format with query param return str((marketplace_api_url / "api/v1/plugins/download").with_query(unique_identifier=plugin_unique_identifier)) diff --git a/api/core/plugin/entities/plugin.py b/api/core/plugin/entities/plugin.py index a07b58d9ea..b5ce6b525b 100644 --- a/api/core/plugin/entities/plugin.py +++ b/api/core/plugin/entities/plugin.py @@ -205,6 +205,9 @@ class PluginDependency(BaseModel): @property def plugin_unique_identifier(self) -> str: + # Strip checksum if present (format: org/name:version@checksum -> org/name:version) + if "@" in self.marketplace_plugin_unique_identifier: + return self.marketplace_plugin_unique_identifier.split("@")[0] return self.marketplace_plugin_unique_identifier class Package(BaseModel): diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx index 2691877a07..f30a722f2e 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx @@ -41,9 +41,11 @@ const InstallByDSLList: ForwardRefRenderFunction = ({ // DSL has id, to get plugin info to show more info const { isLoading: isFetchingMarketplaceDataById, data: infoGetById, error: infoByIdError } = useFetchPluginsInMarketPlaceByInfo(allPlugins.filter(d => d.type === 'marketplace').map((d) => { const dependecy = (d as GitHubItemAndMarketPlaceDependency).value - // split org, name, version by / and : - // and remove @ and its suffix - const [orgPart, nameAndVersionPart] = dependecy.marketplace_plugin_unique_identifier!.split('@')[0].split('/') + // Parse org/name:version format (checksum already removed by backend) + const identifier = dependecy.marketplace_plugin_unique_identifier! + // Remove checksum if still present (for backward compatibility) + const cleanIdentifier = identifier.includes('@') ? identifier.split('@')[0] : identifier + const [orgPart, nameAndVersionPart] = cleanIdentifier.split('/') const [name, version] = nameAndVersionPart.split(':') return { organization: orgPart, @@ -109,7 +111,13 @@ const InstallByDSLList: ForwardRefRenderFunction = ({ if (!isFetchingMarketplaceDataById && infoGetById?.data.list) { const sortedList = allPlugins.filter(d => d.type === 'marketplace').map((d) => { const p = d as GitHubItemAndMarketPlaceDependency - const id = p.value.marketplace_plugin_unique_identifier?.split(':')[0] + // Parse org/name from org/name:version format + let identifier = p.value.marketplace_plugin_unique_identifier || '' + // Remove checksum if present + if (identifier.includes('@')) + identifier = identifier.split('@')[0] + // Get org/name part (without version) + const id = identifier.split(':')[0] const retPluginInfo = infoGetById.data.list.find(item => item.plugin.plugin_id === id)?.plugin return { ...retPluginInfo, from: d.type } as Plugin }) diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index 2877ef15f2..df03b83036 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -286,6 +286,9 @@ export const useInstallOrUpdate = ({ if (item.type === 'marketplace') { const data = item as GitHubItemAndMarketPlaceDependency uniqueIdentifier = data.value.marketplace_plugin_unique_identifier! || plugin[i]?.plugin_id + // Strip checksum if present (for backward compatibility) + if (uniqueIdentifier.includes('@')) + uniqueIdentifier = uniqueIdentifier.split('@')[0] if (uniqueIdentifier === installedPayload?.uniqueIdentifier) { return { success: true,