diff --git a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx index f9a2d5e003..b412b2bbcc 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx @@ -223,7 +223,7 @@ const SettingBuiltInTool: FC = ({ {isInfoActive ? infoUI : settingUI} {!readonly && !isInfoActive && ( -
+
diff --git a/web/app/components/plugins/plugin-detail-panel/agent-strategy-list.tsx b/web/app/components/plugins/plugin-detail-panel/agent-strategy-list.tsx new file mode 100644 index 0000000000..dd20403985 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/agent-strategy-list.tsx @@ -0,0 +1,52 @@ +import React, { useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import ToolItem from '@/app/components/tools/provider/tool-item' +import { + useAllToolProviders, + useBuiltinTools, +} from '@/service/use-tools' +import type { PluginDetail } from '@/app/components/plugins/types' + +type Props = { + detail: PluginDetail +} + +const AgentStrategyList = ({ + detail, +}: Props) => { + const { t } = useTranslation() + const providerBriefInfo = detail.declaration.agent_strategy.identity + const providerKey = `${detail.plugin_id}/${providerBriefInfo.name}` + const { data: collectionList = [] } = useAllToolProviders() + + const provider = useMemo(() => { + return collectionList.find(collection => collection.name === providerKey) + }, [collectionList, providerKey]) + const { data } = useBuiltinTools(providerKey) + + if (!data || !provider) + return null + + return ( +
+
+
+ {t('plugin.detailPanel.strategyNum', { num: data.length, strategy: data.length > 1 ? 'strategies' : 'strategy' })} +
+
+
+ {data.map(tool => ( + + ))} +
+
+ ) +} + +export default AgentStrategyList diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index d42304742b..4d20c0877d 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -5,6 +5,7 @@ import DetailHeader from './detail-header' import EndpointList from './endpoint-list' import ActionList from './action-list' import ModelList from './model-list' +import AgentStrategyList from './agent-strategy-list' import Drawer from '@/app/components/base/drawer' import type { PluginDetail } from '@/app/components/plugins/types' import cn from '@/utils/classnames' @@ -48,6 +49,7 @@ const PluginDetailPanel: FC = ({ />
{!!detail.declaration.tool && } + {!!detail.declaration.agent_strategy && } {!!detail.declaration.endpoint && } {!!detail.declaration.model && }
diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index a0558d1153..fd8191736a 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -69,8 +69,9 @@ export type PluginDeclaration = { verified: boolean endpoint: PluginEndpointDeclaration tool: PluginToolDeclaration - model: any // TODO + model: any tags: string[] + agent_strategy: any } export type PluginManifestInMarket = { @@ -374,3 +375,47 @@ export type VersionProps = { installedVersion?: string toInstallVersion: string } + +export type StrategyParamItem = { + name: string + label: Record + placeholder: Record + type: string + scope: string + required: boolean + default: any + options: any[] +} + +export type StrategyDetail = { + identity: { + author: string + name: string + icon: string + label: Record + provider: string + }, + parameters: StrategyParamItem[] + description: Record + output_schema: Record +} + +export type StrategyDeclaration = { + identity: { + author: string + name: string + description: Record + icon: string + label: Record + tags: string[] + }, + plugin_id: string + strategies: StrategyDetail[] +} + +export type StrategyPluginDetail = { + provider: string + plugin_unique_identifier: string + plugin_id: string + declaration: StrategyDeclaration +} diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 8690eb5ac8..dcc2a7892a 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -51,6 +51,7 @@ const translation = { remove: 'Remove', }, actionNum: '{{num}} {{action}} INCLUDED', + strategyNum: '{{num}} {{strategy}} INCLUDED', endpoints: 'Endpoints', endpointsTip: 'This plugin provides specific functionalities via endpoints, and you can configure multiple endpoint sets for current workspace.', endpointsDocLink: 'View the document', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 55d31e47a1..a45aca0264 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -51,6 +51,7 @@ const translation = { remove: '移除', }, actionNum: '包含 {{num}} 个 {{action}}', + strategyNum: '包含 {{num}} 个 {{strategy}}', endpoints: 'API 端点', endpointsTip: '此插件通过 API 端点提供特定功能,您可以为当前工作区配置多个 API 端点集。', endpointsDocLink: '查看文档', diff --git a/web/service/use-strategy.ts b/web/service/use-strategy.ts new file mode 100644 index 0000000000..6ef11e15ee --- /dev/null +++ b/web/service/use-strategy.ts @@ -0,0 +1,33 @@ +import { get } from './base' +import type { + StrategyPluginDetail, +} from '@/app/components/plugins/types' +import { useInvalid } from './use-base' +import { + useQuery, +} from '@tanstack/react-query' + +const NAME_SPACE = 'agent-strategy' + +const useStrategyListKey = [NAME_SPACE, 'strategyList'] +export const useStrategyProviders = () => { + return useQuery({ + queryKey: useStrategyListKey, + queryFn: () => get('/workspaces/current/agent-providers'), + }) +} + +export const useInvalidateStrategyProviders = () => { + return useInvalid(useStrategyListKey) +} + +export const useStrategyProviderDetail = (agentProvider: string) => { + return useQuery({ + queryKey: [NAME_SPACE, 'detail', agentProvider], + queryFn: () => get(`/workspaces/current/agent-providers/${agentProvider}`), + }) +} + +export const useInvalidateStrategyProviderDetail = (agentProvider: string) => { + return useInvalid([NAME_SPACE, 'detail', agentProvider]) +}