Merge branch 'feat/plugins' of https://github.com/langgenius/dify into feat/plugins

This commit is contained in:
AkaraChen 2025-01-08 16:57:01 +08:00
commit d65c1218ae
14 changed files with 98 additions and 42 deletions

View File

@ -83,7 +83,7 @@ const AgentModelTrigger: FC<AgentModelTriggerProps> = ({
// pass
}
}
if (providerName && !modelProvider) {
if (providerName) {
const parts = providerName.split('/')
const org = parts[0]
const name = parts[1]
@ -101,7 +101,7 @@ const AgentModelTrigger: FC<AgentModelTriggerProps> = ({
setIsPluginChecked(true)
}
})()
}, [providerName, modelProvider, modelId, currentProvider])
}, [providerName, modelId, currentProvider])
if (modelId && !isPluginChecked)
return null

View File

@ -1,5 +1,7 @@
import Tooltip from '@/app/components/base/tooltip'
import Link from 'next/link'
import { SwitchPluginVersion } from '@/app/components/workflow/nodes/_base/components/switch-plugin-version'
import { useInstalledPluginList } from '@/service/use-plugins'
import { RiErrorWarningFill } from '@remixicon/react'
type StatusIndicatorsProps = {
@ -12,9 +14,10 @@ type StatusIndicatorsProps = {
}
const StatusIndicators = ({ needsConfiguration, modelProvider, inModelList, disabled, pluginInfo, t }: StatusIndicatorsProps) => {
const { data: pluginList } = useInstalledPluginList()
const renderTooltipContent = (title: string, description?: string, linkText?: string, linkHref?: string) => {
return (
<div className='flex w-[240px] max-w-[240px] gap-1 flex-col px-1 py-1.5'>
<div className='flex w-[240px] max-w-[240px] gap-1 flex-col px-1 py-1.5' onClick={e => e.stopPropagation()}>
<div className='text-text-primary title-xs-semi-bold'>{title}</div>
{description && (
<div className='min-w-[200px] text-text-secondary body-xs-regular'>
@ -36,25 +39,44 @@ const StatusIndicators = ({ needsConfiguration, modelProvider, inModelList, disa
</div>
)
}
// const installedPluginUniqueIdentifier = pluginList?.plugins.find(plugin => plugin.name === pluginInfo.name)?.plugin_unique_identifier
return (
<>
{/* plugin installed and model is in model list but disabled */}
{/* plugin installed from github/local and model is not in model list */}
{!needsConfiguration && modelProvider && disabled && (
<Tooltip
popupContent={inModelList ? t('workflow.nodes.agent.modelSelectorTooltips.deprecated')
: renderTooltipContent(
t('workflow.nodes.agent.modelNotSupport.title'),
t('workflow.nodes.agent.modelNotSupport.desc'),
!pluginInfo ? t('workflow.nodes.agent.linkToPlugin') : '',
!pluginInfo ? '/plugins' : '',
)
}
asChild={false}
needsDelay={!inModelList}
>
<RiErrorWarningFill className='w-4 h-4 text-text-destructive' />
</Tooltip>
<>
{inModelList ? (
<Tooltip
popupContent={t('workflow.nodes.agent.modelSelectorTooltips.deprecated')}
asChild={false}
needsDelay={false}
>
<RiErrorWarningFill className='w-4 h-4 text-text-destructive' />
</Tooltip>
) : !pluginInfo ? (
<Tooltip
popupContent={renderTooltipContent(
t('workflow.nodes.agent.modelNotSupport.title'),
t('workflow.nodes.agent.modelNotSupport.desc'),
t('workflow.nodes.agent.linkToPlugin'),
'/plugins',
)}
asChild={false}
needsDelay={true}
>
<RiErrorWarningFill className='w-4 h-4 text-text-destructive' />
</Tooltip>
) : (
<SwitchPluginVersion
tooltip={renderTooltipContent(
t('workflow.nodes.agent.modelNotSupport.title'),
t('workflow.nodes.agent.modelNotSupport.descForVersionSwitch'),
)}
uniqueIdentifier={pluginList?.plugins.find(plugin => plugin.name === pluginInfo.name)?.plugin_unique_identifier ?? ''}
/>
)}
</>
)}
{!modelProvider && !pluginInfo && (
<Tooltip

View File

@ -1,4 +1,5 @@
export const tagKeys = [
'agent',
'search',
'image',
'videos',

View File

@ -61,7 +61,7 @@ export const SwitchPluginVersion: FC<SwitchPluginVersionProps> = (props) => {
}
const { t } = useTranslation()
return <Tooltip popupContent={!isShow && !isShowUpdateModal && tooltip} triggerMethod='hover'>
<div className={cn('w-fit', className)}>
<div className={cn('w-fit flex items-center justify-center', className)} onClick={e => e.stopPropagation()}>
{isShowUpdateModal && pluginDetail && <PluginMutationModel
onCancel={hideUpdateModal}
plugin={pluginManifestToCardPluginProps({

View File

@ -27,7 +27,7 @@ const AgentLogItem = ({
const [expanded, setExpanded] = useState(false)
return (
<div className='border-[0.5px] border-components-panel-border rounded-[10px]'>
<div className='bg-background-default border-[0.5px] border-components-panel-border rounded-[10px]'>
<div
className={cn(
'flex items-center pl-1.5 pt-2 pr-3 pb-2 cursor-pointer',

View File

@ -1,4 +1,5 @@
import { RiArrowLeftLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import AgentLogNavMore from './agent-log-nav-more'
import Button from '@/app/components/base/button'
import type { AgentLogItemWithChildren } from '@/types/workflow'
@ -11,10 +12,14 @@ const AgentLogNav = ({
agentOrToolLogItemStack,
onShowAgentOrToolLog,
}: AgentLogNavProps) => {
const options = agentOrToolLogItemStack.slice(2)
const { t } = useTranslation()
const agentOrToolLogItemStackLength = agentOrToolLogItemStack.length
const first = agentOrToolLogItemStack[0]
const mid = agentOrToolLogItemStack.slice(1, -1)
const end = agentOrToolLogItemStack.at(-1)
return (
<div className='flex items-center p-1 pr-3 h-8'>
<div className='flex items-center p-1 pr-3 h-8 bg-components-panel-bg'>
<Button
className='shrink-0 px-[5px]'
size='small'
@ -24,32 +29,48 @@ const AgentLogNav = ({
}}
>
<RiArrowLeftLine className='mr-1 w-3.5 h-3.5' />
Agent
AGENT
</Button>
<div className='shrink-0 mx-0.5 system-xs-regular text-divider-deep'>/</div>
<Button
className='shrink-0 px-[5px]'
size='small'
variant='ghost-accent'
onClick={() => {}}
>
Agent strategy
</Button>
{
!!options.length && (
agentOrToolLogItemStackLength > 1
? (
<Button
className='shrink-0 px-[5px]'
size='small'
variant='ghost-accent'
onClick={() => onShowAgentOrToolLog(first)}
>
{t('workflow.nodes.agent.strategy.label')}
</Button>
)
: (
<div className='flex items-center px-[5px] system-xs-medium-uppercase text-text-tertiary'>
{t('workflow.nodes.agent.strategy.label')}
</div>
)
}
{
!!mid.length && (
<>
<div className='shrink-0 mx-0.5 system-xs-regular text-divider-deep'>/</div>
<AgentLogNavMore
options={options}
options={mid}
onShowAgentOrToolLog={onShowAgentOrToolLog}
/>
</>
)
}
<div className='shrink-0 mx-0.5 system-xs-regular text-divider-deep'>/</div>
<div className='flex items-center px-[5px] system-xs-medium-uppercase text-text-tertiary'>
Run Actions
</div>
{
!!end && agentOrToolLogItemStackLength > 2 && (
<>
<div className='shrink-0 mx-0.5 system-xs-regular text-divider-deep'>/</div>
<div className='flex items-center px-[5px] system-xs-medium-uppercase text-text-tertiary'>
{end.label}
</div>
</>
)
}
</div>
)
}

View File

@ -1,4 +1,5 @@
import { RiArrowRightLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import type {
AgentLogItemWithChildren,
NodeTracing,
@ -12,12 +13,13 @@ const AgentLogTrigger = ({
nodeInfo,
onShowAgentOrToolLog,
}: AgentLogTriggerProps) => {
const { t } = useTranslation()
const { agentLog } = nodeInfo
return (
<div className='bg-components-button-tertiary-bg rounded-[10px]'>
<div className='flex items-center px-3 pt-2 system-2xs-medium-uppercase text-text-tertiary'>
Agent strategy
{t('workflow.nodes.agent.strategy.label')}
</div>
<div className='flex items-center pl-3 pt-1 pr-2 pb-1.5'>
<div className='shrink-0 w-5 h-5'></div>
@ -28,7 +30,7 @@ const AgentLogTrigger = ({
onShowAgentOrToolLog({ id: nodeInfo.id, children: agentLog || [] } as AgentLogItemWithChildren)
}}
>
Detail
{t('runLog.detail')}
<RiArrowRightLine className='ml-0.5 w-3.5 h-3.5' />
</div>
</div>

View File

@ -1,4 +1,5 @@
import { RiAlertFill } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import AgentLogItem from './agent-log-item'
import AgentLogNav from './agent-log-nav'
import type { AgentLogItemWithChildren } from '@/types/workflow'
@ -13,17 +14,18 @@ const AgentResultPanel = ({
agentOrToolLogListMap,
onShowAgentOrToolLog,
}: AgentResultPanelProps) => {
const { t } = useTranslation()
const top = agentOrToolLogItemStack[agentOrToolLogItemStack.length - 1]
const list = agentOrToolLogListMap[top.id]
return (
<div className='overflow-y-auto'>
<div className='bg-background-section overflow-y-auto'>
<AgentLogNav
agentOrToolLogItemStack={agentOrToolLogItemStack}
onShowAgentOrToolLog={onShowAgentOrToolLog}
/>
{
<div className='p-2'>
<div className='p-2 space-y-1'>
{
list.map(item => (
<AgentLogItem
@ -37,7 +39,7 @@ const AgentResultPanel = ({
}
{
top.hasCircle && (
<div className='flex items-center rounded-xl px-3 pr-2 border border-components-panel-border bg-components-panel-bg-blur shadow-md'>
<div className='flex items-center mt-1 rounded-xl px-3 pr-2 border border-components-panel-border bg-components-panel-bg-blur shadow-md'>
<div
className='absolute inset-0 opacity-[0.4] rounded-xl'
style={{
@ -46,7 +48,7 @@ const AgentResultPanel = ({
></div>
<RiAlertFill className='mr-1.5 w-4 h-4 text-text-warning-secondary' />
<div className='system-xs-medium text-text-primary'>
There is circular invocation of tools/nodes in the current workflow.
{t('runLog.circularInvocationTip')}
</div>
</div>
)

View File

@ -2,6 +2,7 @@ const translation = {
allTags: 'All Tags',
searchTags: 'Search Tags',
tags: {
agent: 'Agent',
search: 'Search',
image: 'Image',
videos: 'Videos',

View File

@ -24,6 +24,8 @@ const translation = {
link: 'detail panel',
tipRight: ' view it.',
},
actionLogs: 'Action Logs',
circularInvocationTip: 'There is circular invocation of tools/nodes in the current workflow.',
}
export default translation

View File

@ -725,6 +725,7 @@ const translation = {
modelNotSupport: {
title: 'Unsupported Model',
desc: 'The installed plugin version does not provide this model.',
descForVersionSwitch: 'The installed plugin version does not provide this model. Click to switch version.',
},
configureModel: 'Configure Model',
notAuthorized: 'Not Authorized',

View File

@ -2,6 +2,7 @@ const translation = {
allTags: '所有标签',
searchTags: '搜索标签',
tags: {
agent: 'Agent',
search: '搜索',
image: '图片',
videos: '视频',

View File

@ -24,6 +24,8 @@ const translation = {
link: '详细信息面板',
tipRight: '查看它。',
},
actionLogs: 'Action 日志',
circularInvocationTip: '当前工作流中存在工具/节点的循环调用。',
}
export default translation

View File

@ -725,6 +725,7 @@ const translation = {
modelNotSupport: {
title: '不支持的模型',
desc: '已安装的插件版本不提供此模型。',
descForVersionSwitch: '已安装的插件版本不提供此模型。点击切换版本。',
},
model: '模型',
toolbox: '工具箱',