diff --git a/web/app/components/plugins/plugin-detail-panel/tool-selector/tool-item.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/tool-item.tsx
new file mode 100644
index 0000000000..a20e0d6e6f
--- /dev/null
+++ b/web/app/components/plugins/plugin-detail-panel/tool-selector/tool-item.tsx
@@ -0,0 +1,120 @@
+'use client'
+import React, { useState } from 'react'
+import { useTranslation } from 'react-i18next'
+import {
+ RiDeleteBinLine,
+ RiEqualizer2Line,
+ RiErrorWarningFill,
+} from '@remixicon/react'
+import AppIcon from '@/app/components/base/app-icon'
+import Switch from '@/app/components/base/switch'
+import Button from '@/app/components/base/button'
+import Indicator from '@/app/components/header/indicator'
+import ActionButton from '@/app/components/base/action-button'
+import Tooltip from '@/app/components/base/tooltip'
+import { InstallPluginButton } from '@/app/components/workflow/nodes/_base/components/install-plugin-button'
+import cn from '@/utils/classnames'
+
+type Props = {
+ icon?: any
+ providerName?: string
+ toolName?: string
+ showSwitch?: boolean
+ switchValue?: boolean
+ onSwitchChange?: (value: boolean) => void
+ onDelete?: () => void
+ noAuth?: boolean
+ onAuth?: () => void
+ isError?: boolean
+ errorTip?: any
+ uninstalled?: boolean
+ isInstalling?: boolean
+ onInstall?: () => void
+ open: boolean
+}
+
+const ToolItem = ({
+ open,
+ icon,
+ providerName,
+ toolName,
+ showSwitch,
+ switchValue,
+ onSwitchChange,
+ onDelete,
+ noAuth,
+ onAuth,
+ uninstalled,
+ isInstalling,
+ onInstall,
+ isError,
+ errorTip,
+}: Props) => {
+ const { t } = useTranslation()
+ const providerNameText = providerName?.split('/').pop()
+ const isTransparent = uninstalled || isError
+ const [isDeleting, setIsDeleting] = useState(false)
+
+ return (
+
+
+ {typeof icon === 'string' &&
}
+ {typeof icon !== 'string' &&
}
+
+
+
{providerNameText}
+
{toolName}
+
+
+ {!noAuth && !isError && !uninstalled && (
+
+
+
+ )}
+
setIsDeleting(true)}
+ onMouseLeave={() => setIsDeleting(false)}
+ >
+
+
+
+ {!isError && !uninstalled && !noAuth && showSwitch && (
+
+ )}
+ {!isError && !uninstalled && noAuth && (
+
+ )}
+ {!isError && uninstalled && (
+
{
+ e.stopPropagation()
+ onInstall?.()
+ }} />
+ )}
+ {isError && (
+
+
+
+
+
+ )}
+
+ )
+}
+
+export default ToolItem
diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts
index aa835687af..d36ba4109a 100644
--- a/web/app/components/plugins/types.ts
+++ b/web/app/components/plugins/types.ts
@@ -6,7 +6,7 @@ export enum PluginType {
tool = 'tool',
model = 'model',
extension = 'extension',
- agent = 'agent-strategy',
+ agent = 'agent_strategy',
}
export enum PluginSource {
@@ -109,7 +109,7 @@ export type PluginDetail = {
}
export type Plugin = {
- type: 'plugin' | 'bundle' | 'model' | 'extension' | 'tool'
+ type: 'plugin' | 'bundle' | 'model' | 'extension' | 'tool' | 'agent_strategy'
org: string
author?: string
name: string
diff --git a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx
index 2fa582d70e..c8aa80431b 100644
--- a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx
+++ b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx
@@ -222,6 +222,7 @@ export const AgentStrategy = (props: AgentStrategyProps) => {
validating={false}
showOnVariableMap={{}}
isEditMode={true}
+ isAgentStrategy={true}
fieldLabelClassName='uppercase'
customRenderField={renderField}
override={override}
diff --git a/web/app/components/workflow/run/utils/format-log/index.ts b/web/app/components/workflow/run/utils/format-log/index.ts
index 4a974fc35a..8239f6ca33 100644
--- a/web/app/components/workflow/run/utils/format-log/index.ts
+++ b/web/app/components/workflow/run/utils/format-log/index.ts
@@ -13,7 +13,7 @@ const formatToTracingNodeList = (list: NodeTracing[], t: any) => {
const formattedAgentList = formatAgentNode(allItems)
const formattedRetryList = formatRetryNode(formattedAgentList) // retry one node
// would change the structure of the list. Iteration and parallel can include each other.
- const formattedIterationList = formatIterationNode(formattedRetryList)
+ const formattedIterationList = formatIterationNode(formattedRetryList, t)
const formattedParallelList = formatParallelNode(formattedIterationList, t)
const result = formattedParallelList
diff --git a/web/app/components/workflow/run/utils/format-log/iteration/index.ts b/web/app/components/workflow/run/utils/format-log/iteration/index.ts
index 7583f40b1a..ca3dad7fb0 100644
--- a/web/app/components/workflow/run/utils/format-log/iteration/index.ts
+++ b/web/app/components/workflow/run/utils/format-log/iteration/index.ts
@@ -1,6 +1,6 @@
import { BlockEnum } from '@/app/components/workflow/types'
import type { NodeTracing } from '@/types/workflow'
-
+import formatParallelNode from '../parallel'
function addChildrenToIterationNode(iterationNode: NodeTracing, childrenNodes: NodeTracing[]): NodeTracing {
const details: NodeTracing[][] = []
childrenNodes.forEach((item) => {
@@ -18,7 +18,7 @@ function addChildrenToIterationNode(iterationNode: NodeTracing, childrenNodes: N
}
}
-const format = (list: NodeTracing[]): NodeTracing[] => {
+const format = (list: NodeTracing[], t: any): NodeTracing[] => {
const iterationNodeIds = list
.filter(item => item.node_type === BlockEnum.Iteration)
.map(item => item.node_id)
@@ -36,7 +36,14 @@ const format = (list: NodeTracing[]): NodeTracing[] => {
item.status = 'failed'
item.error = error.error
}
- return addChildrenToIterationNode(item, childrenNodes)
+ const addedChildrenList = addChildrenToIterationNode(item, childrenNodes)
+ // handle parallel node in iteration node
+ if (addedChildrenList.details && addedChildrenList.details.length > 0) {
+ addedChildrenList.details = addedChildrenList.details.map((row) => {
+ return formatParallelNode(row, t)
+ })
+ }
+ return addedChildrenList
}
return item
diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts
index ecce13b5b2..30e13b527d 100644
--- a/web/i18n/en-US/workflow.ts
+++ b/web/i18n/en-US/workflow.ts
@@ -714,6 +714,8 @@ const translation = {
install: 'Install',
installing: 'Installing',
},
+ configureModel: 'Configure Model',
+ notAuthorized: 'Not Authorized',
model: 'model',
toolbox: 'toolbox',
strategyNotSet: 'Agentic strategy Not Set',
@@ -723,6 +725,9 @@ const translation = {
toolNotInstallTooltip: '{{tool}} is not installed',
toolNotAuthorizedTooltip: '{{tool}} Not Authorized',
strategyNotInstallTooltip: '{{strategy}} is not installed',
+ modelSelectorTooltips: {
+ deprecated: 'This model is deprecated',
+ },
},
},
tracing: {
diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts
index 0935791136..b4291c64fc 100644
--- a/web/i18n/zh-Hans/workflow.ts
+++ b/web/i18n/zh-Hans/workflow.ts
@@ -717,12 +717,17 @@ const translation = {
model: '模型',
toolbox: '工具箱',
strategyNotSet: '代理策略未设置',
+ configureModel: '配置模型',
+ notAuthorized: '未授权',
tools: '工具',
maxIterations: '最大迭代次数',
modelNotInstallTooltip: '此模型未安装',
toolNotInstallTooltip: '{{tool}} 未安装',
toolNotAuthorizedTooltip: '{{tool}} 未授权',
strategyNotInstallTooltip: '{{strategy}} 未安装',
+ modelSelectorTooltips: {
+ deprecated: '此模型已弃用',
+ },
},
},
tracing: {
diff --git a/web/service/use-strategy.ts b/web/service/use-strategy.ts
index e6f6c4b607..cbc09509b3 100644
--- a/web/service/use-strategy.ts
+++ b/web/service/use-strategy.ts
@@ -7,7 +7,7 @@ import {
useQuery,
} from '@tanstack/react-query'
-const NAME_SPACE = 'agent-strategy'
+const NAME_SPACE = 'agent_strategy'
const useStrategyListKey = [NAME_SPACE, 'strategyList']
export const useStrategyProviders = () => {