mirror of https://github.com/langgenius/dify.git
feat: strategy install status
This commit is contained in:
parent
87ce813175
commit
f2eb095960
|
|
@ -16,6 +16,7 @@ import type { StrategyPluginDetail } from '@/app/components/plugins/types'
|
|||
import type { ToolWithProvider } from '../../../types'
|
||||
import { CollectionType } from '@/app/components/tools/types'
|
||||
import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon'
|
||||
import type { StrategyStatus } from '../../agent/use-config'
|
||||
|
||||
const ExternalNotInstallWarn = () => {
|
||||
const { t } = useTranslation()
|
||||
|
|
@ -67,10 +68,11 @@ function formatStrategy(input: StrategyPluginDetail[], getIcon: (i: string) => s
|
|||
export type AgentStrategySelectorProps = {
|
||||
value?: Strategy,
|
||||
onChange: (value?: Strategy) => void,
|
||||
strategyStatus?: StrategyStatus
|
||||
}
|
||||
|
||||
export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) => {
|
||||
const { value, onChange } = props
|
||||
const { value, onChange, strategyStatus } = props
|
||||
const [open, setOpen] = useState(false)
|
||||
const [viewType, setViewType] = useState<ViewType>(ViewType.flat)
|
||||
const [query, setQuery] = useState('')
|
||||
|
|
@ -81,8 +83,7 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
|
|||
if (!list) return []
|
||||
return list.filter(tool => tool.name.toLowerCase().includes(query.toLowerCase()))
|
||||
}, [query, list])
|
||||
// TODO: should be replaced by real data
|
||||
const isExternalInstalled = true
|
||||
const isShowError = (['plugin-not-found', 'strategy-not-found'] as Array<undefined | StrategyStatus>).includes(strategyStatus)
|
||||
const icon = list?.find(
|
||||
coll => coll.tools?.find(tool => tool.name === value?.agent_strategy_name),
|
||||
)?.icon as string | undefined
|
||||
|
|
@ -104,8 +105,8 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
|
|||
{value?.agent_strategy_label || t('workflow.nodes.agent.strategy.selectTip')}
|
||||
</p>
|
||||
{value && <div className='ml-auto flex items-center gap-1'>
|
||||
<InstallPluginButton onClick={e => e.stopPropagation()} size={'small'} />
|
||||
{isExternalInstalled ? <ExternalNotInstallWarn /> : <RiArrowDownSLine className='size-4 text-text-tertiary' />}
|
||||
{strategyStatus === 'plugin-not-found' && <InstallPluginButton onClick={e => e.stopPropagation()} size={'small'} />}
|
||||
{isShowError ? <ExternalNotInstallWarn /> : <RiArrowDownSLine className='size-4 text-text-tertiary' />}
|
||||
</div>}
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
|
|
@ -143,9 +144,6 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
|
|||
</div>
|
||||
</main>
|
||||
</div>
|
||||
{/* <div>
|
||||
aaa
|
||||
</div> */}
|
||||
</PortalToFollowElemContent>
|
||||
</PortalToFollowElem>
|
||||
})
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import { useWorkflowStore } from '../../../store'
|
|||
import { useRenderI18nObject } from '@/hooks/use-i18n'
|
||||
import type { NodeOutPutVar } from '../../../types'
|
||||
import type { Node } from 'reactflow'
|
||||
import type { StrategyStatus } from '../../agent/use-config'
|
||||
|
||||
export type Strategy = {
|
||||
agent_strategy_provider_name: string
|
||||
|
|
@ -36,6 +37,7 @@ export type AgentStrategyProps = {
|
|||
onFormValueChange: (value: ToolVarInputs) => void
|
||||
nodeOutputVars?: NodeOutPutVar[],
|
||||
availableNodes?: Node[],
|
||||
strategyStatus: StrategyStatus
|
||||
}
|
||||
|
||||
type CustomSchema<Type, Field = {}> = Omit<CredentialFormSchema, 'type'> & { type: Type } & Field
|
||||
|
|
@ -54,7 +56,7 @@ type StringSchema = CustomSchema<'string', {
|
|||
type CustomField = ToolSelectorSchema | MultipleToolSelectorSchema | StringSchema
|
||||
|
||||
export const AgentStrategy = memo((props: AgentStrategyProps) => {
|
||||
const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange, nodeOutputVars, availableNodes } = props
|
||||
const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange, nodeOutputVars, availableNodes, strategyStatus } = props
|
||||
const { t } = useTranslation()
|
||||
const defaultModel = useDefaultModel(ModelTypeEnum.textGeneration)
|
||||
const renderI18nObject = useRenderI18nObject()
|
||||
|
|
@ -176,7 +178,7 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
|
|||
}
|
||||
}
|
||||
return <div className='space-y-2'>
|
||||
<AgentStrategySelector value={strategy} onChange={onStrategyChange} />
|
||||
<AgentStrategySelector value={strategy} onChange={onStrategyChange} strategyStatus={strategyStatus} />
|
||||
{
|
||||
strategy
|
||||
? <div>
|
||||
|
|
|
|||
|
|
@ -3,14 +3,31 @@ import { RiInstallLine, RiLoader2Line } from '@remixicon/react'
|
|||
import type { ComponentProps } from 'react'
|
||||
import classNames from '@/utils/classnames'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useCheckInstalled, useInstallPackageFromMarketPlace } from '@/service/use-plugins'
|
||||
|
||||
type InstallPluginButtonProps = Omit<ComponentProps<typeof Button>, 'children'>
|
||||
type InstallPluginButtonProps = Omit<ComponentProps<typeof Button>, 'children' | 'loading'> & {
|
||||
uniqueIdentifier: string
|
||||
}
|
||||
|
||||
export const InstallPluginButton = (props: InstallPluginButtonProps) => {
|
||||
const { loading, className, ...rest } = props
|
||||
const { className, uniqueIdentifier, ...rest } = props
|
||||
const { t } = useTranslation()
|
||||
return <Button variant={'secondary'} disabled={loading} className={classNames('flex items-center', className)} {...rest}>
|
||||
{loading ? t('workflow.nodes.agent.pluginInstaller.install') : t('workflow.nodes.agent.pluginInstaller.installing')}
|
||||
{!loading ? <RiInstallLine className='size-4 ml-1' /> : <RiLoader2Line className='size-4 ml-1 animate-spin' />}
|
||||
const manifest = useCheckInstalled({
|
||||
pluginIds: [uniqueIdentifier],
|
||||
enabled: !!uniqueIdentifier,
|
||||
})
|
||||
const install = useInstallPackageFromMarketPlace({
|
||||
onSuccess() {
|
||||
manifest.refetch()
|
||||
},
|
||||
})
|
||||
const handleInstall = () => {
|
||||
install.mutate(uniqueIdentifier)
|
||||
}
|
||||
if (!manifest.data) return null
|
||||
if (manifest.data.plugins.some(plugin => plugin.id === uniqueIdentifier)) return null
|
||||
return <Button variant={'secondary'} disabled={install.isPending} {...rest} onClick={handleInstall} className={classNames('flex items-center', className)} >
|
||||
{install.isPending ? t('workflow.nodes.agent.pluginInstaller.install') : t('workflow.nodes.agent.pluginInstaller.installing')}
|
||||
{!install.isPending ? <RiInstallLine className='size-4 ml-1' /> : <RiLoader2Line className='size-4 ml-1 animate-spin' />}
|
||||
</Button>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
|||
inputs,
|
||||
setInputs,
|
||||
currentStrategy,
|
||||
currentStrategyStatus,
|
||||
formData,
|
||||
onFormChange,
|
||||
|
||||
|
|
@ -95,6 +96,7 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
|||
onFormValueChange={onFormChange}
|
||||
nodeOutputVars={availableVars}
|
||||
availableNodes={availableNodesWithParent}
|
||||
strategyStatus={currentStrategyStatus}
|
||||
/>
|
||||
</Field>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import type { Var } from '../../types'
|
|||
import { VarType as VarKindType } from '../../types'
|
||||
import useAvailableVarList from '../_base/hooks/use-available-var-list'
|
||||
|
||||
export type StrategyStatus = 'loading' | 'plugin-not-found' | 'strategy-not-found' | 'success'
|
||||
|
||||
const useConfig = (id: string, payload: AgentNodeType) => {
|
||||
const { nodesReadOnly: readOnly } = useNodesReadOnly()
|
||||
const { inputs, setInputs } = useNodeCrud<AgentNodeType>(id, payload)
|
||||
|
|
@ -27,7 +29,7 @@ const useConfig = (id: string, payload: AgentNodeType) => {
|
|||
const currentStrategy = strategyProvider.data?.declaration.strategies.find(
|
||||
str => str.identity.name === inputs.agent_strategy_name,
|
||||
)
|
||||
const currentStrategyStatus: 'loading' | 'plugin-not-found' | 'strategy-not-found' | 'success' = useMemo(() => {
|
||||
const currentStrategyStatus: StrategyStatus = useMemo(() => {
|
||||
if (strategyProvider.isLoading) return 'loading'
|
||||
if (strategyProvider.isError) return 'plugin-not-found'
|
||||
if (!currentStrategy) return 'strategy-not-found'
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import type {
|
|||
PluginsSearchParams,
|
||||
} from '@/app/components/plugins/marketplace/types'
|
||||
import { get, getMarketplace, post, postMarketplace } from './base'
|
||||
import type { MutateOptions } from '@tanstack/react-query'
|
||||
import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
|
|
@ -72,8 +73,9 @@ export const useInvalidateInstalledPluginList = () => {
|
|||
}
|
||||
}
|
||||
|
||||
export const useInstallPackageFromMarketPlace = () => {
|
||||
export const useInstallPackageFromMarketPlace = (options?: MutateOptions<InstallPackageResponse, Error, string>) => {
|
||||
return useMutation({
|
||||
...options,
|
||||
mutationFn: (uniqueIdentifier: string) => {
|
||||
return post<InstallPackageResponse>('/workspaces/current/plugin/install/marketplace', { body: { plugin_unique_identifiers: [uniqueIdentifier] } })
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue