add model install in model configuration for the agent node

This commit is contained in:
Yi
2024-12-30 17:55:46 +08:00
parent afb3548e45
commit 9b6f580365
8 changed files with 60 additions and 22 deletions

View File

@@ -3,7 +3,7 @@ import { RiInstallLine, RiLoader2Line } from '@remixicon/react'
type InstallButtonProps = {
loading: boolean
onInstall: () => void
onInstall: (e: React.MouseEvent) => void
t: any
}

View File

@@ -1,5 +1,5 @@
import type { FC } from 'react'
import { useEffect, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import type {
CustomConfigurationModelFixedFields,
@@ -9,6 +9,7 @@ import type {
import {
ConfigurationMethodEnum,
CustomConfigurationStatusEnum,
ModelTypeEnum,
} from '../declarations'
import { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from '../provider-added-card'
import type { PluginInfoFromMarketPlace } from '@/app/components/plugins/types'
@@ -54,13 +55,19 @@ const AgentModelTrigger: FC<AgentModelTriggerProps> = ({
const updateModelProviders = useUpdateModelProviders()
const updateModelList = useUpdateModelList()
const { eventEmitter } = useEventEmitterContextContext()
const modelProvider = modelProviders.find(item => item.provider === providerName)
const needsConfiguration = modelProvider?.custom_configuration.status === CustomConfigurationStatusEnum.noConfigure && !(
modelProvider.system_configuration.enabled === true
&& modelProvider.system_configuration.quota_configurations.find(
item => item.quota_type === modelProvider.system_configuration.current_quota_type,
const { modelProvider, needsConfiguration } = useMemo(() => {
const modelProvider = modelProviders.find(item => item.provider === providerName)
const needsConfiguration = modelProvider?.custom_configuration.status === CustomConfigurationStatusEnum.noConfigure && !(
modelProvider.system_configuration.enabled === true
&& modelProvider.system_configuration.quota_configurations.find(
item => item.quota_type === modelProvider.system_configuration.current_quota_type,
)
)
)
return {
modelProvider,
needsConfiguration,
}
}, [modelProviders, providerName])
const [pluginInfo, setPluginInfo] = useState<PluginInfoFromMarketPlace | null>(null)
const [isPluginChecked, setIsPluginChecked] = useState(false)
const [loading, setLoading] = useState(false)
@@ -124,6 +131,24 @@ const AgentModelTrigger: FC<AgentModelTriggerProps> = ({
})
}
const handleInstall = async (pluginInfo: PluginInfoFromMarketPlace) => {
setLoading(true)
try {
const { all_installed } = await installPackageFromMarketPlace(pluginInfo.latest_package_identifier)
if (all_installed) {
setInstalled(true)
updateModelProviders()
updateModelList(ModelTypeEnum.textGeneration)
}
}
catch (error) {
console.error('Installation failed:', error)
}
finally {
setLoading(false)
}
}
return (
<div
className={cn(
@@ -158,15 +183,18 @@ const AgentModelTrigger: FC<AgentModelTriggerProps> = ({
{!installed && !modelProvider && pluginInfo && (
<InstallButton
loading={loading}
onInstall={async () => {
setLoading(true)
const { all_installed } = await installPackageFromMarketPlace(pluginInfo.latest_package_identifier)
if (all_installed)
setInstalled(true)
onInstall={(e) => {
e.stopPropagation()
handleInstall(pluginInfo)
}}
t={t}
/>
)}
{modelProvider && !disabled && (
<div className="flex pr-1 items-center">
<RiEqualizer2Line className="w-4 h-4 text-text-tertiary group-hover:text-text-secondary" />
</div>
)}
</>
) : (
<>

View File

@@ -1,4 +1,5 @@
import Tooltip from '@/app/components/base/tooltip'
import Link from 'next/link'
import { RiErrorWarningFill } from '@remixicon/react'
type StatusIndicatorsProps = {
@@ -28,7 +29,16 @@ const StatusIndicators = ({ needsConfiguration, modelProvider, disabled, pluginI
<div className='min-w-[200px] text-text-secondary body-xs-regular'>
{t('workflow.nodes.agent.modelNotInMarketplace.desc')}
</div>
<div className='text-text-accent body-xs-regular'>{t('workflow.nodes.agent.modelNotInMarketplace.manageInPlugins')}</div>
<div className='text-text-accent body-xs-regular cursor-pointer z-[100]'>
<Link
href={'/plugins'}
onClick={(e) => {
e.stopPropagation()
}}
>
{t('workflow.nodes.agent.linkToPlugin')}
</Link>
</div>
</div>
}
asChild={false}

View File

@@ -22,14 +22,14 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
return (
<div
className={cn('group flex items-center px-2 h-8 rounded-lg bg-components-input-bg-disabled cursor-pointer', className)}
className={cn('group flex items-center p-1 gap-0.5 rounded-lg bg-components-input-bg-disabled cursor-pointer', className)}
>
<ModelIcon
className='shrink-0 mr-1.5'
provider={currentProvider}
modelName={modelName}
/>
<div className='mr-1 text-[13px] font-medium text-text-secondary truncate'>
<div className='mr-1 system-sm-regular text-components-input-text-filled truncate'>
{modelName}
</div>
<div className='shrink-0 flex items-center justify-center w-4 h-4'>

View File

@@ -14,7 +14,7 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
return (
<div
className={cn(
'flex items-center px-2 h-8 rounded-lg bg-components-input-bg-normal hover:bg-components-input-bg-hover cursor-pointer', open && 'bg-components-input-bg-hover',
'flex items-center p-1 gap-0.5 rounded-lg bg-components-input-bg-normal hover:bg-components-input-bg-hover cursor-pointer', open && 'bg-components-input-bg-hover',
className,
)}
>

View File

@@ -89,15 +89,15 @@ export const AgentStrategySelector = (props: AgentStrategySelectorProps) => {
const { t } = useTranslation()
return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'>
<PortalToFollowElemTrigger className='w-full'>
<div className='py-2 pl-3 pr-2 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='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 */}
{icon && <img
{icon && <div className='flex items-center justify-center w-6 h-6'><img
src={icon}
width={20}
height={20}
className='rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default-dodge'
alt='icon'
/>}
/></div>}
<p
className={classNames(value ? 'text-components-input-text-filled' : 'text-components-input-text-placeholder', 'text-xs px-1')}
>

View File

@@ -716,7 +716,7 @@ const translation = {
},
modelNotInMarketplace: {
title: 'Model not installed',
desc: 'This model is not installed from the marketplace. Please go to Plugins to reinstall.',
desc: 'This model is installed from Local or GitHub repository. Please use after installation.',
manageInPlugins: 'Manage in Plugins',
},
configureModel: 'Configure Model',

View File

@@ -716,7 +716,7 @@ const translation = {
},
modelNotInMarketplace: {
title: '模型未安装',
desc: '此模型未从市场安装。请转到插件重新安装。',
desc: '此模型安装自本地或 GitHub 仓库。请安装后使用。',
manageInPlugins: '在插件中管理',
},
model: '模型',