refactor: strategy status

pull/12560/head
AkaraChen 1 year ago
parent 390107f97e
commit 06f0c3c886

@ -17,15 +17,27 @@ import type { ToolWithProvider } from '../../../types'
import { CollectionType } from '@/app/components/tools/types' import { CollectionType } from '@/app/components/tools/types'
import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon' import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon'
import type { StrategyStatus } from '../../agent/use-config' import type { StrategyStatus } from '../../agent/use-config'
import { useStrategyInfo } from '../../agent/use-config'
const NotInstallWarn = (props: {
strategyStatus: StrategyStatus
}) => {
// strategyStatus can be 'plugin-not-found-and-not-in-marketplace' | 'strategy-not-found'
const { strategyStatus } = props
const ExternalNotInstallWarn = () => {
const { t } = useTranslation() const { t } = useTranslation()
return <Tooltip return <Tooltip
popupContent={<div className='space-y-1 text-xs'> popupContent={<div className='space-y-1 text-xs'>
<h3 className='text-text-primary font-semibold'>{t('workflow.nodes.agent.pluginNotInstalled')}</h3> <h3 className='text-text-primary font-semibold'>
<p className='text-text-secondary tracking-tight'>{t('workflow.nodes.agent.pluginNotInstalledDesc')}</p> {t('workflow.nodes.agent.pluginNotInstalled')}
</h3>
<p className='text-text-secondary tracking-tight'>
{t('workflow.nodes.agent.pluginNotInstalledDesc')}
</p>
<p> <p>
<Link href={'/plugins'} className='text-text-accent tracking-tight'>{t('workflow.nodes.agent.linkToPlugin')}</Link> <Link href={'/plugins'} className='text-text-accent tracking-tight'>
{t('workflow.nodes.agent.linkToPlugin')}
</Link>
</p> </p>
</div>} </div>}
needsDelay needsDelay
@ -68,11 +80,10 @@ function formatStrategy(input: StrategyPluginDetail[], getIcon: (i: string) => s
export type AgentStrategySelectorProps = { export type AgentStrategySelectorProps = {
value?: Strategy, value?: Strategy,
onChange: (value?: Strategy) => void, onChange: (value?: Strategy) => void,
strategyStatus?: StrategyStatus
} }
export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) => { export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) => {
const { value, onChange, strategyStatus } = props const { value, onChange } = props
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [viewType, setViewType] = useState<ViewType>(ViewType.flat) const [viewType, setViewType] = useState<ViewType>(ViewType.flat)
const [query, setQuery] = useState('') const [query, setQuery] = useState('')
@ -83,14 +94,23 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
if (!list) return [] if (!list) return []
return list.filter(tool => tool.name.toLowerCase().includes(query.toLowerCase())) return list.filter(tool => tool.name.toLowerCase().includes(query.toLowerCase()))
}, [query, list]) }, [query, list])
const showError = (['plugin-not-found', 'strategy-not-found'] as Array<undefined | StrategyStatus>).includes(strategyStatus) const { strategyStatus } = useStrategyInfo(
value?.agent_strategy_provider_name,
value?.agent_strategy_name,
)
const showError = ['strategy-not-found', 'plugin-not-found-and-not-in-marketplace']
.includes(strategyStatus)
const icon = list?.find( const icon = list?.find(
coll => coll.tools?.find(tool => tool.name === value?.agent_strategy_name), coll => coll.tools?.find(tool => tool.name === value?.agent_strategy_name),
)?.icon as string | undefined )?.icon as string | undefined
const { t } = useTranslation() const { t } = useTranslation()
return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'> return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'>
<PortalToFollowElemTrigger className='w-full'> <PortalToFollowElemTrigger className='w-full'>
<div className='h-8 p-1 gap-0.5 flex items-center rounded-lg bg-components-input-bg-normal w-full hover:bg-state-base-hover-alt select-none' onClick={() => setOpen(o => !o)}> <div
className='h-8 p-1 gap-0.5 flex items-center rounded-lg bg-components-input-bg-normal w-full hover:bg-state-base-hover-alt select-none'
onClick={() => setOpen(o => !o)}
>
{/* eslint-disable-next-line @next/next/no-img-element */} {/* eslint-disable-next-line @next/next/no-img-element */}
{icon && <div className='flex items-center justify-center w-6 h-6'><img {icon && <div className='flex items-center justify-center w-6 h-6'><img
src={icon} src={icon}
@ -105,8 +125,16 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
{value?.agent_strategy_label || t('workflow.nodes.agent.strategy.selectTip')} {value?.agent_strategy_label || t('workflow.nodes.agent.strategy.selectTip')}
</p> </p>
{value && <div className='ml-auto flex items-center gap-1'> {value && <div className='ml-auto flex items-center gap-1'>
{strategyStatus === 'plugin-not-found' && <InstallPluginButton onClick={e => e.stopPropagation()} size={'small'} uniqueIdentifier={value.plugin_unique_identifier} />} {strategyStatus === 'plugin-not-found' && <InstallPluginButton
{showError ? <ExternalNotInstallWarn /> : <RiArrowDownSLine className='size-4 text-text-tertiary' />} onClick={e => e.stopPropagation()}
size={'small'}
uniqueIdentifier={value.plugin_unique_identifier}
/>}
{showError
? <NotInstallWarn
strategyStatus={strategyStatus}
/>
: <RiArrowDownSLine className='size-4 text-text-tertiary' />}
</div>} </div>}
</div> </div>
</PortalToFollowElemTrigger> </PortalToFollowElemTrigger>

@ -19,7 +19,6 @@ import { useWorkflowStore } from '../../../store'
import { useRenderI18nObject } from '@/hooks/use-i18n' import { useRenderI18nObject } from '@/hooks/use-i18n'
import type { NodeOutPutVar } from '../../../types' import type { NodeOutPutVar } from '../../../types'
import type { Node } from 'reactflow' import type { Node } from 'reactflow'
import type { StrategyStatus } from '../../agent/use-config'
export type Strategy = { export type Strategy = {
agent_strategy_provider_name: string agent_strategy_provider_name: string
@ -37,7 +36,6 @@ export type AgentStrategyProps = {
onFormValueChange: (value: ToolVarInputs) => void onFormValueChange: (value: ToolVarInputs) => void
nodeOutputVars?: NodeOutPutVar[], nodeOutputVars?: NodeOutPutVar[],
availableNodes?: Node[], availableNodes?: Node[],
strategyStatus: StrategyStatus
} }
type CustomSchema<Type, Field = {}> = Omit<CredentialFormSchema, 'type'> & { type: Type } & Field type CustomSchema<Type, Field = {}> = Omit<CredentialFormSchema, 'type'> & { type: Type } & Field
@ -56,7 +54,7 @@ type StringSchema = CustomSchema<'string', {
type CustomField = ToolSelectorSchema | MultipleToolSelectorSchema | StringSchema type CustomField = ToolSelectorSchema | MultipleToolSelectorSchema | StringSchema
export const AgentStrategy = memo((props: AgentStrategyProps) => { export const AgentStrategy = memo((props: AgentStrategyProps) => {
const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange, nodeOutputVars, availableNodes, strategyStatus } = props const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange, nodeOutputVars, availableNodes } = props
const { t } = useTranslation() const { t } = useTranslation()
const defaultModel = useDefaultModel(ModelTypeEnum.textGeneration) const defaultModel = useDefaultModel(ModelTypeEnum.textGeneration)
const renderI18nObject = useRenderI18nObject() const renderI18nObject = useRenderI18nObject()
@ -178,7 +176,7 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
} }
} }
return <div className='space-y-2'> return <div className='space-y-2'>
<AgentStrategySelector value={strategy} onChange={onStrategyChange} strategyStatus={strategyStatus} /> <AgentStrategySelector value={strategy} onChange={onStrategyChange} />
{ {
strategy strategy
? <div> ? <div>

@ -90,16 +90,20 @@ const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
? <SettingItem ? <SettingItem
label={t('workflow.nodes.agent.strategy.shortLabel')} label={t('workflow.nodes.agent.strategy.shortLabel')}
status={ status={
['plugin-not-found', 'strategy-not-found'].includes(currentStrategyStatus) ['plugin-not-found', 'strategy-not-found', 'plugin-not-found-and-not-in-marketplace'].includes(currentStrategyStatus)
? 'error' ? 'error'
: undefined : undefined
} }
tooltip={t(`workflow.nodes.agent.${currentStrategyStatus === 'plugin-not-found' ? 'strategyNotInstallTooltip' : 'strategyNotFoundInPlugin'}`, { tooltip={
strategy: inputs.agent_strategy_label, ['plugin-not-found', 'strategy-not-found', 'plugin-not-found-and-not-in-marketplace'].includes(currentStrategyStatus)
plugin: pluginDetail?.declaration.label ? t('workflow.nodes.agent.strategyNotInstallTooltip', {
? renderI18nObject(pluginDetail?.declaration.label) plugin: pluginDetail?.declaration.label
: undefined, ? renderI18nObject(pluginDetail?.declaration.label)
})} : undefined,
strategy: inputs.agent_strategy_label,
})
: undefined
}
> >
{inputs.agent_strategy_label} {inputs.agent_strategy_label}
</SettingItem> </SettingItem>

@ -30,7 +30,6 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
inputs, inputs,
setInputs, setInputs,
currentStrategy, currentStrategy,
currentStrategyStatus,
formData, formData,
onFormChange, onFormChange,
@ -96,7 +95,6 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
onFormValueChange={onFormChange} onFormValueChange={onFormChange}
nodeOutputVars={availableVars} nodeOutputVars={availableVars}
availableNodes={availableNodesWithParent} availableNodes={availableNodesWithParent}
strategyStatus={currentStrategyStatus}
/> />
</Field> </Field>
<div> <div>

@ -15,25 +15,21 @@ import useAvailableVarList from '../_base/hooks/use-available-var-list'
export type StrategyStatus = 'loading' | 'plugin-not-found' | 'plugin-not-found-and-not-in-marketplace' | 'strategy-not-found' | 'success' export type StrategyStatus = 'loading' | 'plugin-not-found' | 'plugin-not-found-and-not-in-marketplace' | 'strategy-not-found' | 'success'
const useConfig = (id: string, payload: AgentNodeType) => { export const useStrategyInfo = (
const { nodesReadOnly: readOnly } = useNodesReadOnly() strategyProviderName?: string,
const { inputs, setInputs } = useNodeCrud<AgentNodeType>(id, payload) strategyName?: string,
// variables ) => {
const { handleVarListChange, handleAddVariable } = useVarList<AgentNodeType>({
inputs,
setInputs,
})
const strategyProvider = useStrategyProviderDetail( const strategyProvider = useStrategyProviderDetail(
inputs.agent_strategy_provider_name || '', strategyProviderName || '',
{ retry: false }, { retry: false },
) )
const currentStrategy = strategyProvider.data?.declaration.strategies.find( const strategy = strategyProvider.data?.declaration.strategies.find(
str => str.identity.name === inputs.agent_strategy_name, str => str.identity.name === strategyName,
) )
const marketplace = useFetchPluginsInMarketPlaceByIds([inputs.agent_strategy_provider_name!], { const marketplace = useFetchPluginsInMarketPlaceByIds([strategyProviderName!], {
retry: false, retry: false,
}) })
const currentStrategyStatus: StrategyStatus = useMemo(() => { const strategyStatus: StrategyStatus = useMemo(() => {
if (strategyProvider.isLoading || marketplace.isLoading) return 'loading' if (strategyProvider.isLoading || marketplace.isLoading) return 'loading'
if (strategyProvider.isError) { if (strategyProvider.isError) {
if (marketplace.data && marketplace.data.data.plugins.length === 0) if (marketplace.data && marketplace.data.data.plugins.length === 0)
@ -41,9 +37,32 @@ const useConfig = (id: string, payload: AgentNodeType) => {
return 'plugin-not-found' return 'plugin-not-found'
} }
if (!currentStrategy) return 'strategy-not-found' if (!strategy) return 'strategy-not-found'
return 'success' return 'success'
}, [currentStrategy, marketplace, strategyProvider.isError, strategyProvider.isLoading]) }, [strategy, marketplace, strategyProvider.isError, strategyProvider.isLoading])
return {
strategyProvider,
strategy,
strategyStatus,
}
}
const useConfig = (id: string, payload: AgentNodeType) => {
const { nodesReadOnly: readOnly } = useNodesReadOnly()
const { inputs, setInputs } = useNodeCrud<AgentNodeType>(id, payload)
// variables
const { handleVarListChange, handleAddVariable } = useVarList<AgentNodeType>({
inputs,
setInputs,
})
const {
strategyStatus: currentStrategyStatus,
strategy: currentStrategy,
strategyProvider,
} = useStrategyInfo(
inputs.agent_strategy_provider_name,
inputs.agent_strategy_name,
)
console.log('currentStrategyStatus', currentStrategyStatus) console.log('currentStrategyStatus', currentStrategyStatus)
const pluginId = inputs.agent_strategy_provider_name?.split('/').splice(0, 2).join('/') const pluginId = inputs.agent_strategy_provider_name?.split('/').splice(0, 2).join('/')
const pluginDetail = useCheckInstalled({ const pluginDetail = useCheckInstalled({

@ -734,6 +734,7 @@ const translation = {
toolNotAuthorizedTooltip: '{{tool}} Not Authorized', toolNotAuthorizedTooltip: '{{tool}} Not Authorized',
strategyNotInstallTooltip: '{{strategy}} is not installed', strategyNotInstallTooltip: '{{strategy}} is not installed',
strategyNotFoundInPlugin: '{{strategy}} is not found in {{plugin}}', strategyNotFoundInPlugin: '{{strategy}} is not found in {{plugin}}',
strategyNotInstallAndNotInMarketplace: '{{strategy}} is not installed and not found in Marketplace',
modelSelectorTooltips: { modelSelectorTooltips: {
deprecated: 'This model is deprecated', deprecated: 'This model is deprecated',
}, },

@ -733,6 +733,7 @@ const translation = {
toolNotInstallTooltip: '{{tool}} 未安装', toolNotInstallTooltip: '{{tool}} 未安装',
toolNotAuthorizedTooltip: '{{tool}} 未授权', toolNotAuthorizedTooltip: '{{tool}} 未授权',
strategyNotInstallTooltip: '{{strategy}} 未安装', strategyNotInstallTooltip: '{{strategy}} 未安装',
strategyNotInstallAndNotInMarketplace: '{{strategy}} 未安装且未在市场中找到',
strategyNotFoundInPlugin: '在 {{plugin}} 中未找到 {{strategy}}', strategyNotFoundInPlugin: '在 {{plugin}} 中未找到 {{strategy}}',
modelSelectorTooltips: { modelSelectorTooltips: {
deprecated: '此模型已弃用', deprecated: '此模型已弃用',

Loading…
Cancel
Save