From ba76312248fd43caf23192ee8b671c95efb2e096 Mon Sep 17 00:00:00 2001 From: Stream Date: Wed, 27 Aug 2025 16:12:40 +0800 Subject: [PATCH 1/8] feat: adapt to plugin_daemon endpoint --- api/controllers/console/workspace/plugin.py | 22 ++++++++++++++++++ api/core/plugin/entities/plugin_daemon.py | 4 ++++ api/core/plugin/impl/plugin.py | 25 +++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/api/controllers/console/workspace/plugin.py b/api/controllers/console/workspace/plugin.py index fd5421fa64..572723ff65 100644 --- a/api/controllers/console/workspace/plugin.py +++ b/api/controllers/console/workspace/plugin.py @@ -643,8 +643,30 @@ class PluginAutoUpgradeExcludePluginApi(Resource): return jsonable_encoder({"success": PluginAutoUpgradeService.exclude_plugin(tenant_id, args["plugin_id"])}) +class PluginReadmeApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self): + tenant_id = current_user.current_tenant_id + parser = reqparse.RequestParser() + parser.add_argument("plugin_unique_identifier", type=str, required=True, location="args") + parser.add_argument("language", type=str, required=False, location="args") + args = parser.parse_args() + return jsonable_encoder( + { + "readme": PluginService.fetch_plugin_readme( + tenant_id, + args["plugin_unique_identifier"], + args.get("language", "en-US") + ) + } + ) + + api.add_resource(PluginDebuggingKeyApi, "/workspaces/current/plugin/debugging-key") api.add_resource(PluginListApi, "/workspaces/current/plugin/list") +api.add_resource(PluginReadmeApi, "/workspaces/current/plugin/readme") api.add_resource(PluginListLatestVersionsApi, "/workspaces/current/plugin/list/latest-versions") api.add_resource(PluginListInstallationsFromIdsApi, "/workspaces/current/plugin/list/installations/ids") api.add_resource(PluginIconApi, "/workspaces/current/plugin/icon") diff --git a/api/core/plugin/entities/plugin_daemon.py b/api/core/plugin/entities/plugin_daemon.py index f1d6860bb4..ecbdd7ab17 100644 --- a/api/core/plugin/entities/plugin_daemon.py +++ b/api/core/plugin/entities/plugin_daemon.py @@ -196,3 +196,7 @@ class PluginListResponse(BaseModel): class PluginDynamicSelectOptionsResponse(BaseModel): options: Sequence[PluginParameterOption] = Field(description="The options of the dynamic select.") + +class PluginReadmeResponse(BaseModel): + content: str = Field(description="The readme of the plugin.") + language: str = Field(description="The language of the readme.") diff --git a/api/core/plugin/impl/plugin.py b/api/core/plugin/impl/plugin.py index 04ac8c9649..ab0b1c15ab 100644 --- a/api/core/plugin/impl/plugin.py +++ b/api/core/plugin/impl/plugin.py @@ -1,5 +1,7 @@ from collections.abc import Sequence +from requests import HTTPError + from core.plugin.entities.bundle import PluginBundleDependency from core.plugin.entities.plugin import ( GenericProviderID, @@ -14,11 +16,34 @@ from core.plugin.entities.plugin_daemon import ( PluginInstallTask, PluginInstallTaskStartResponse, PluginListResponse, + PluginReadmeResponse, ) from core.plugin.impl.base import BasePluginClient class PluginInstaller(BasePluginClient): + def fetch_plugin_readme(self, tenant_id: str, plugin_unique_identifier: str, language: str) -> str: + """ + Fetch plugin readme + """ + try: + response = self._request_with_plugin_daemon_response( + "GET", + f"plugin/{tenant_id}/management/fetch/readme", + PluginReadmeResponse, + params={ + "tenant_id":tenant_id, + "plugin_unique_identifier": plugin_unique_identifier, + "language": language + } + ) + return response.content + except HTTPError as e: + message = e.args[0] + if "404" in message: + return "" + raise e + def fetch_plugin_by_identifier( self, tenant_id: str, From 94ecbd44e46d128d6687951010c387bc3aceed52 Mon Sep 17 00:00:00 2001 From: Stream Date: Wed, 27 Aug 2025 20:03:59 +0800 Subject: [PATCH 2/8] feat: add API endpoint to extract plugin assets --- api/controllers/console/workspace/plugin.py | 17 +++++++++++++++++ api/core/plugin/impl/asset.py | 6 ++++++ api/services/plugin/plugin_service.py | 13 +++++++++++++ 3 files changed, 36 insertions(+) diff --git a/api/controllers/console/workspace/plugin.py b/api/controllers/console/workspace/plugin.py index 572723ff65..27adf7662b 100644 --- a/api/controllers/console/workspace/plugin.py +++ b/api/controllers/console/workspace/plugin.py @@ -107,6 +107,22 @@ class PluginIconApi(Resource): icon_cache_max_age = dify_config.TOOL_ICON_CACHE_MAX_AGE return send_file(io.BytesIO(icon_bytes), mimetype=mimetype, max_age=icon_cache_max_age) +class PluginAssetApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self): + req = reqparse.RequestParser() + req.add_argument("plugin_unique_identifier", type=str, required=True, location="args") + req.add_argument("file_name", type=str, required=True, location="args") + args = req.parse_args() + + tenant_id = current_user.current_tenant_id + try: + binary = PluginService.extract_asset(tenant_id, args["plugin_unique_identifier"], args["file_name"]) + return send_file(io.BytesIO(binary), mimetype="application/octet-stream") + except PluginDaemonClientSideError as e: + raise ValueError(e) class PluginUploadFromPkgApi(Resource): @setup_required @@ -670,6 +686,7 @@ api.add_resource(PluginReadmeApi, "/workspaces/current/plugin/readme") api.add_resource(PluginListLatestVersionsApi, "/workspaces/current/plugin/list/latest-versions") api.add_resource(PluginListInstallationsFromIdsApi, "/workspaces/current/plugin/list/installations/ids") api.add_resource(PluginIconApi, "/workspaces/current/plugin/icon") +api.add_resource(PluginAssetApi, "/workspaces/current/plugin/asset") api.add_resource(PluginUploadFromPkgApi, "/workspaces/current/plugin/upload/pkg") api.add_resource(PluginUploadFromGithubApi, "/workspaces/current/plugin/upload/github") api.add_resource(PluginUploadFromBundleApi, "/workspaces/current/plugin/upload/bundle") diff --git a/api/core/plugin/impl/asset.py b/api/core/plugin/impl/asset.py index b9bfe2d2cf..0c6a744bb5 100644 --- a/api/core/plugin/impl/asset.py +++ b/api/core/plugin/impl/asset.py @@ -10,3 +10,9 @@ class PluginAssetManager(BasePluginClient): if response.status_code != 200: raise ValueError(f"can not found asset {id}") return response.content + + def extract_asset(self, tenant_id: str, plugin_unique_identifier: str, filename: str) -> bytes: + response = self._request(method="GET", path=f"plugin/{tenant_id}/asset/{plugin_unique_identifier}") + if response.status_code != 200: + raise ValueError(f"can not found asset {plugin_unique_identifier}, {str(response.status_code)}") + return response.content diff --git a/api/services/plugin/plugin_service.py b/api/services/plugin/plugin_service.py index 9005f0669b..4c0da761d7 100644 --- a/api/services/plugin/plugin_service.py +++ b/api/services/plugin/plugin_service.py @@ -186,6 +186,11 @@ class PluginService: mime_type, _ = guess_type(asset_file) return manager.fetch_asset(tenant_id, asset_file), mime_type or "application/octet-stream" + @staticmethod + def extract_asset(tenant_id: str, plugin_unique_identifier: str, file_name: str) -> bytes: + manager = PluginAssetManager() + return manager.extract_asset(tenant_id, plugin_unique_identifier, file_name) + @staticmethod def check_plugin_unique_identifier(tenant_id: str, plugin_unique_identifier: str) -> bool: """ @@ -492,3 +497,11 @@ class PluginService: """ manager = PluginInstaller() return manager.check_tools_existence(tenant_id, provider_ids) + + @staticmethod + def fetch_plugin_readme(tenant_id: str, plugin_unique_identifier: str, language: str) -> str: + """ + Fetch plugin readme + """ + manager = PluginInstaller() + return manager.fetch_plugin_readme(tenant_id, plugin_unique_identifier, language) From 13af48800b87789a7213071e4cdbdf79cbcc4e71 Mon Sep 17 00:00:00 2001 From: Stream Date: Thu, 23 Oct 2025 12:13:21 +0800 Subject: [PATCH 3/8] fix: merge --- api/controllers/console/workspace/plugin.py | 41 +++------------------ 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/api/controllers/console/workspace/plugin.py b/api/controllers/console/workspace/plugin.py index 9d7c75e361..2f38832b05 100644 --- a/api/controllers/console/workspace/plugin.py +++ b/api/controllers/console/workspace/plugin.py @@ -113,6 +113,7 @@ class PluginIconApi(Resource): icon_cache_max_age = dify_config.TOOL_ICON_CACHE_MAX_AGE return send_file(io.BytesIO(icon_bytes), mimetype=mimetype, max_age=icon_cache_max_age) + class PluginAssetApi(Resource): @setup_required @login_required @@ -123,13 +124,14 @@ class PluginAssetApi(Resource): req.add_argument("file_name", type=str, required=True, location="args") args = req.parse_args() - tenant_id = current_user.current_tenant_id + current_user, tenant_id = current_account_with_tenant() try: binary = PluginService.extract_asset(tenant_id, args["plugin_unique_identifier"], args["file_name"]) return send_file(io.BytesIO(binary), mimetype="application/octet-stream") except PluginDaemonClientSideError as e: raise ValueError(e) + @console_ns.route("/workspaces/current/plugin/upload/pkg") class PluginUploadFromPkgApi(Resource): @setup_required @@ -706,12 +708,13 @@ class PluginAutoUpgradeExcludePluginApi(Resource): return jsonable_encoder({"success": PluginAutoUpgradeService.exclude_plugin(tenant_id, args["plugin_id"])}) +@console_ns.route("/workspaces/current/plugin/readme") class PluginReadmeApi(Resource): @setup_required @login_required @account_initialization_required def get(self): - tenant_id = current_user.current_tenant_id + current_user, tenant_id = current_account_with_tenant() parser = reqparse.RequestParser() parser.add_argument("plugin_unique_identifier", type=str, required=True, location="args") parser.add_argument("language", type=str, required=False, location="args") @@ -725,37 +728,3 @@ class PluginReadmeApi(Resource): ) } ) - - -api.add_resource(PluginDebuggingKeyApi, "/workspaces/current/plugin/debugging-key") -api.add_resource(PluginListApi, "/workspaces/current/plugin/list") -api.add_resource(PluginReadmeApi, "/workspaces/current/plugin/readme") -api.add_resource(PluginListLatestVersionsApi, "/workspaces/current/plugin/list/latest-versions") -api.add_resource(PluginListInstallationsFromIdsApi, "/workspaces/current/plugin/list/installations/ids") -api.add_resource(PluginIconApi, "/workspaces/current/plugin/icon") -api.add_resource(PluginAssetApi, "/workspaces/current/plugin/asset") -api.add_resource(PluginUploadFromPkgApi, "/workspaces/current/plugin/upload/pkg") -api.add_resource(PluginUploadFromGithubApi, "/workspaces/current/plugin/upload/github") -api.add_resource(PluginUploadFromBundleApi, "/workspaces/current/plugin/upload/bundle") -api.add_resource(PluginInstallFromPkgApi, "/workspaces/current/plugin/install/pkg") -api.add_resource(PluginInstallFromGithubApi, "/workspaces/current/plugin/install/github") -api.add_resource(PluginUpgradeFromMarketplaceApi, "/workspaces/current/plugin/upgrade/marketplace") -api.add_resource(PluginUpgradeFromGithubApi, "/workspaces/current/plugin/upgrade/github") -api.add_resource(PluginInstallFromMarketplaceApi, "/workspaces/current/plugin/install/marketplace") -api.add_resource(PluginFetchManifestApi, "/workspaces/current/plugin/fetch-manifest") -api.add_resource(PluginFetchInstallTasksApi, "/workspaces/current/plugin/tasks") -api.add_resource(PluginFetchInstallTaskApi, "/workspaces/current/plugin/tasks/") -api.add_resource(PluginDeleteInstallTaskApi, "/workspaces/current/plugin/tasks//delete") -api.add_resource(PluginDeleteAllInstallTaskItemsApi, "/workspaces/current/plugin/tasks/delete_all") -api.add_resource(PluginDeleteInstallTaskItemApi, "/workspaces/current/plugin/tasks//delete/") -api.add_resource(PluginUninstallApi, "/workspaces/current/plugin/uninstall") -api.add_resource(PluginFetchMarketplacePkgApi, "/workspaces/current/plugin/marketplace/pkg") - -api.add_resource(PluginChangePermissionApi, "/workspaces/current/plugin/permission/change") -api.add_resource(PluginFetchPermissionApi, "/workspaces/current/plugin/permission/fetch") - -api.add_resource(PluginFetchDynamicSelectOptionsApi, "/workspaces/current/plugin/parameters/dynamic-options") - -api.add_resource(PluginFetchPreferencesApi, "/workspaces/current/plugin/preferences/fetch") -api.add_resource(PluginChangePreferencesApi, "/workspaces/current/plugin/preferences/change") -api.add_resource(PluginAutoUpgradeExcludePluginApi, "/workspaces/current/plugin/preferences/autoupgrade/exclude") From a77aab96f53cb36253fea28ee89dbda14005e557 Mon Sep 17 00:00:00 2001 From: lyzno1 Date: Thu, 23 Oct 2025 12:17:27 +0800 Subject: [PATCH 4/8] fix: align all workflow trigger docs link --- web/app/components/app/overview/app-card.tsx | 2 +- web/app/components/app/overview/trigger-card.tsx | 11 +++++------ .../components/workflow-onboarding-modal/index.tsx | 2 +- .../workflow/nodes/trigger-plugin/default.ts | 1 + .../workflow/nodes/trigger-schedule/default.ts | 1 + .../workflow/nodes/trigger-webhook/default.ts | 1 + 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/web/app/components/app/overview/app-card.tsx b/web/app/components/app/overview/app-card.tsx index a2d71436c1..43293ab53b 100644 --- a/web/app/components/app/overview/app-card.tsx +++ b/web/app/components/app/overview/app-card.tsx @@ -221,7 +221,7 @@ function AppCard({
window.open(docLink('/guides/workflow/node/start'), '_blank')} + onClick={() => window.open(docLink('/guides/workflow/node/user-input'), '_blank')} > {t('appOverview.overview.appInfo.enableTooltip.learnMore')}
diff --git a/web/app/components/app/overview/trigger-card.tsx b/web/app/components/app/overview/trigger-card.tsx index 856f17c595..8946bdc0a5 100644 --- a/web/app/components/app/overview/trigger-card.tsx +++ b/web/app/components/app/overview/trigger-card.tsx @@ -18,6 +18,7 @@ import { canFindTool } from '@/utils' import { useTriggerStatusStore } from '@/app/components/workflow/store/trigger-status' import BlockIcon from '@/app/components/workflow/block-icon' import { BlockEnum } from '@/app/components/workflow/types' +import { useDocLink } from '@/context/i18n' export type ITriggerCardProps = { appInfo: AppDetailResponse & Partial @@ -83,6 +84,7 @@ const getTriggerIcon = (trigger: AppTrigger, triggerPlugins: any[]) => { function TriggerCard({ appInfo, onToggleResult }: ITriggerCardProps) { const { t } = useTranslation() + const docLink = useDocLink() const appId = appInfo.id const { isCurrentWorkspaceEditor } = useAppContext() const { data: triggersResponse, isLoading } = useAppTriggers(appId) @@ -136,10 +138,6 @@ function TriggerCard({ appInfo, onToggleResult }: ITriggerCardProps) { } } - const handleLearnMoreClick = () => { - console.log('Learn about Triggers clicked') - } - if (isLoading) { return (
@@ -209,8 +207,9 @@ function TriggerCard({ appInfo, onToggleResult }: ITriggerCardProps) {
{t('appOverview.overview.triggerInfo.triggerStatusDescription')}{' '} {t('appOverview.overview.triggerInfo.learnAboutTriggers')} diff --git a/web/app/components/workflow-app/components/workflow-onboarding-modal/index.tsx b/web/app/components/workflow-app/components/workflow-onboarding-modal/index.tsx index 7e8c76d67a..747a232ca7 100644 --- a/web/app/components/workflow-app/components/workflow-onboarding-modal/index.tsx +++ b/web/app/components/workflow-app/components/workflow-onboarding-modal/index.tsx @@ -63,7 +63,7 @@ const WorkflowOnboardingModal: FC = ({
{t('workflow.onboarding.description')}{' '} , schemaTypeDefinitions?: Sc const metaData = genNodeMetaData({ sort: 1, type: BlockEnum.TriggerPlugin, + helpLinkUri: 'plugin-trigger', isStart: true, }) diff --git a/web/app/components/workflow/nodes/trigger-schedule/default.ts b/web/app/components/workflow/nodes/trigger-schedule/default.ts index e47518cc25..69f93c33f4 100644 --- a/web/app/components/workflow/nodes/trigger-schedule/default.ts +++ b/web/app/components/workflow/nodes/trigger-schedule/default.ts @@ -107,6 +107,7 @@ const validateVisualConfig = (payload: ScheduleTriggerNodeType, t: any): string const metaData = genNodeMetaData({ sort: 2, type: BlockEnum.TriggerSchedule, + helpLinkUri: 'schedule-trigger', isStart: true, }) diff --git a/web/app/components/workflow/nodes/trigger-webhook/default.ts b/web/app/components/workflow/nodes/trigger-webhook/default.ts index 176b365b03..5071a79913 100644 --- a/web/app/components/workflow/nodes/trigger-webhook/default.ts +++ b/web/app/components/workflow/nodes/trigger-webhook/default.ts @@ -8,6 +8,7 @@ import { createWebhookRawVariable } from './utils/raw-variable' const metaData = genNodeMetaData({ sort: 3, type: BlockEnum.TriggerWebhook, + helpLinkUri: 'webhook-trigger', isStart: true, }) From 7ada2385b3509e1a56705f12bc935f3fb0aab96d Mon Sep 17 00:00:00 2001 From: lyzno1 Date: Thu, 23 Oct 2025 12:27:42 +0800 Subject: [PATCH 5/8] feat: add toggle behavior for featured tools --- .../solid/arrows/arrow-up-double-line.svg | 3 +++ .../solid/arrows/ArrowUpDoubleLine.json | 26 +++++++++++++++++++ .../vender/solid/arrows/ArrowUpDoubleLine.tsx | 20 ++++++++++++++ .../icons/src/vender/solid/arrows/index.ts | 1 + .../block-selector/featured-tools.tsx | 23 +++++++++++----- web/i18n/en-US/workflow.ts | 1 + web/i18n/zh-Hans/workflow.ts | 1 + 7 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 web/app/components/base/icons/assets/vender/solid/arrows/arrow-up-double-line.svg create mode 100644 web/app/components/base/icons/src/vender/solid/arrows/ArrowUpDoubleLine.json create mode 100644 web/app/components/base/icons/src/vender/solid/arrows/ArrowUpDoubleLine.tsx diff --git a/web/app/components/base/icons/assets/vender/solid/arrows/arrow-up-double-line.svg b/web/app/components/base/icons/assets/vender/solid/arrows/arrow-up-double-line.svg new file mode 100644 index 0000000000..1f0b9858e1 --- /dev/null +++ b/web/app/components/base/icons/assets/vender/solid/arrows/arrow-up-double-line.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/app/components/base/icons/src/vender/solid/arrows/ArrowUpDoubleLine.json b/web/app/components/base/icons/src/vender/solid/arrows/ArrowUpDoubleLine.json new file mode 100644 index 0000000000..b76fc3e80c --- /dev/null +++ b/web/app/components/base/icons/src/vender/solid/arrows/ArrowUpDoubleLine.json @@ -0,0 +1,26 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "16", + "height": "16", + "viewBox": "0 0 16 16", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M8 3.22388L3.86194 7.36193L4.80475 8.30473L8 5.10949L11.1953 8.30473L12.1381 7.36193L8 3.22388ZM8 6.99046L3.86194 11.1285L4.80475 12.0713L8 8.87606L11.1953 12.0713L12.1381 11.1285L8 6.99046Z", + "fill": "currentColor" + }, + "children": [] + } + ] + }, + "name": "ArrowUpDoubleLine" +} diff --git a/web/app/components/base/icons/src/vender/solid/arrows/ArrowUpDoubleLine.tsx b/web/app/components/base/icons/src/vender/solid/arrows/ArrowUpDoubleLine.tsx new file mode 100644 index 0000000000..06ba38ec70 --- /dev/null +++ b/web/app/components/base/icons/src/vender/solid/arrows/ArrowUpDoubleLine.tsx @@ -0,0 +1,20 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './ArrowUpDoubleLine.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconData } from '@/app/components/base/icons/IconBase' + +const Icon = ( + { + ref, + ...props + }: React.SVGProps & { + ref?: React.RefObject>; + }, +) => + +Icon.displayName = 'ArrowUpDoubleLine' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/solid/arrows/index.ts b/web/app/components/base/icons/src/vender/solid/arrows/index.ts index 44522622dc..58ce9aa8ac 100644 --- a/web/app/components/base/icons/src/vender/solid/arrows/index.ts +++ b/web/app/components/base/icons/src/vender/solid/arrows/index.ts @@ -1,4 +1,5 @@ export { default as ArrowDownDoubleLine } from './ArrowDownDoubleLine' export { default as ArrowDownRoundFill } from './ArrowDownRoundFill' +export { default as ArrowUpDoubleLine } from './ArrowUpDoubleLine' export { default as ChevronDown } from './ChevronDown' export { default as HighPriority } from './HighPriority' diff --git a/web/app/components/workflow/block-selector/featured-tools.tsx b/web/app/components/workflow/block-selector/featured-tools.tsx index a4d4655988..fe5c561362 100644 --- a/web/app/components/workflow/block-selector/featured-tools.tsx +++ b/web/app/components/workflow/block-selector/featured-tools.tsx @@ -16,7 +16,7 @@ import { ViewType } from './view-type-select' import Tools from './tools' import { formatNumber } from '@/utils/format' import Action from '@/app/components/workflow/block-selector/market-place-plugin/action' -import { ArrowDownDoubleLine, ArrowDownRoundFill } from '@/app/components/base/icons/src/vender/solid/arrows' +import { ArrowDownDoubleLine, ArrowDownRoundFill, ArrowUpDoubleLine } from '@/app/components/base/icons/src/vender/solid/arrows' import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace' const MAX_RECOMMENDED_COUNT = 15 @@ -119,7 +119,9 @@ const FeaturedTools = ({ const totalVisible = visibleInstalledProviders.length + visibleUninstalledPlugins.length const maxAvailable = Math.min(MAX_RECOMMENDED_COUNT, installedProviders.length + uninstalledPlugins.length) - const showMore = totalVisible < maxAvailable + const hasMoreToShow = totalVisible < maxAvailable + const canToggleVisibility = maxAvailable > INITIAL_VISIBLE_COUNT + const isExpanded = canToggleVisibility && !hasMoreToShow const showEmptyState = !isLoading && totalVisible === 0 return ( @@ -183,19 +185,28 @@ const FeaturedTools = ({ )} - {!isLoading && totalVisible > 0 && showMore && ( + {!isLoading && totalVisible > 0 && canToggleVisibility && (
{ - setVisibleCount(count => Math.min(count + INITIAL_VISIBLE_COUNT, maxAvailable)) + setVisibleCount((count) => { + if (count >= maxAvailable) + return INITIAL_VISIBLE_COUNT + + return Math.min(count + INITIAL_VISIBLE_COUNT, maxAvailable) + }) }} >
- + {isExpanded ? ( + + ) : ( + + )}
- {t('workflow.tabs.showMoreFeatured')} + {t(isExpanded ? 'workflow.tabs.showLessFeatured' : 'workflow.tabs.showMoreFeatured')}
)} diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index 150b9a8902..61d1d010f0 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -279,6 +279,7 @@ const translation = { 'searchDataSource': 'Search Data Source', 'featuredTools': 'Featured', 'showMoreFeatured': 'Show more', + 'showLessFeatured': 'Show less', 'installed': 'Installed', 'pluginByAuthor': 'By {{author}}', 'usePlugin': 'Select tool', diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index 51ae3b8050..759b628144 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -265,6 +265,7 @@ const translation = { 'start': '开始', 'featuredTools': '精选推荐', 'showMoreFeatured': '查看更多', + 'showLessFeatured': '收起', 'installed': '已安装', 'pluginByAuthor': '来自 {{author}}', 'usePlugin': '选择工具', From 37e75f77916909a5450542071ada0741c771d2f9 Mon Sep 17 00:00:00 2001 From: lyzno1 Date: Thu, 23 Oct 2025 13:08:59 +0800 Subject: [PATCH 6/8] Ensure workflow tools tab always shows marketplace footer --- web/app/components/workflow/block-selector/all-tools.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index e18433714a..97e18c43c3 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -229,7 +229,7 @@ const AllTools = ({
)} - {(hasToolsListContent || hasPluginContent) && ( + {(hasToolsListContent || enable_marketplace) && ( <>
{t('tools.allTools')} @@ -249,7 +249,7 @@ const AllTools = ({ isShowRAGRecommendations={isShowRAGRecommendations} /> )} - {hasPluginContent && ( + {enable_marketplace && ( } From 6df786248cef524bbbf9bb1650708a3004e9dd11 Mon Sep 17 00:00:00 2001 From: hjlarry Date: Thu, 23 Oct 2025 13:35:45 +0800 Subject: [PATCH 7/8] fix: draft run webhook node the _raw var not display on the panel --- api/controllers/console/app/workflow.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/api/controllers/console/app/workflow.py b/api/controllers/console/app/workflow.py index f07fd32a27..a3b75555cd 100644 --- a/api/controllers/console/app/workflow.py +++ b/api/controllers/console/app/workflow.py @@ -1056,15 +1056,23 @@ class DraftWorkflowTriggerNodeApi(Resource): raise e if not event: return jsonable_encoder({"status": "waiting", "retry_in": LISTENING_RETRY_IN}) + + workflow_args = dict(event.workflow_args or {}) + raw_files = workflow_args.get("files") + files = _parse_file(draft_workflow, raw_files if isinstance(raw_files, list) else None) + if node_type == NodeType.TRIGGER_WEBHOOK: + user_inputs = workflow_args.get("inputs") or {} + else: + user_inputs = workflow_args try: node_execution = workflow_service.run_draft_workflow_node( app_model=app_model, draft_workflow=draft_workflow, node_id=node_id, - user_inputs=event.workflow_args, + user_inputs=user_inputs, account=current_user, query="", - files=[], + files=files, ) return jsonable_encoder(node_execution) except Exception as e: From ecd1d44d23163fff82740492b58ccc0d78fffbfc Mon Sep 17 00:00:00 2001 From: hjlarry Date: Thu, 23 Oct 2025 15:05:39 +0800 Subject: [PATCH 8/8] chore: update trigger dsl version to 0.5.0 --- api/services/app_dsl_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/services/app_dsl_service.py b/api/services/app_dsl_service.py index 9c3cc48961..15fefd6116 100644 --- a/api/services/app_dsl_service.py +++ b/api/services/app_dsl_service.py @@ -44,7 +44,7 @@ IMPORT_INFO_REDIS_KEY_PREFIX = "app_import_info:" CHECK_DEPENDENCIES_REDIS_KEY_PREFIX = "app_check_dependencies:" IMPORT_INFO_REDIS_EXPIRY = 10 * 60 # 10 minutes DSL_MAX_SIZE = 10 * 1024 * 1024 # 10MB -CURRENT_DSL_VERSION = "0.4.0" +CURRENT_DSL_VERSION = "0.5.0" class ImportMode(StrEnum):