Merge branch 'feat/plugins' into dev/plugin-deploy
This commit is contained in:
commit
9ab39c3feb
@ -12,6 +12,7 @@ import {
|
||||
import type { PluginInfoFromMarketPlace } from '@/app/components/plugins/types'
|
||||
import { useInvalidateInstalledPluginList } from '@/service/use-plugins'
|
||||
import ConfigurationButton from './configuration-button'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { PluginType } from '@/app/components/plugins/types'
|
||||
import {
|
||||
useModelModalHandler,
|
||||
@ -104,7 +105,7 @@ const AgentModelTrigger: FC<AgentModelTriggerProps> = ({
|
||||
}, [providerName, modelId, currentProvider])
|
||||
|
||||
if (modelId && !isPluginChecked)
|
||||
return null
|
||||
return <Loading />
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -45,20 +45,38 @@ const StatusIndicators = ({ needsConfiguration, modelProvider, inModelList, disa
|
||||
{/* 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'),
|
||||
!pluginInfo ? t('workflow.nodes.agent.modelNotSupport.desc') : t('workflow.nodes.agent.modelNotSupport.descForVersionSwitch'),
|
||||
!pluginInfo ? t('workflow.nodes.agent.linkToPlugin') : '',
|
||||
!pluginInfo ? '/plugins' : '',
|
||||
)
|
||||
}
|
||||
asChild={false}
|
||||
needsDelay={!inModelList}
|
||||
>
|
||||
{!pluginInfo ? <RiErrorWarningFill className='w-4 h-4 text-text-destructive' /> : <SwitchPluginVersion uniqueIdentifier={pluginList?.plugins.find(plugin => plugin.name === pluginInfo.name)?.plugin_unique_identifier ?? ''} />}
|
||||
</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
|
||||
|
@ -21,7 +21,7 @@ export const tagKeys = [
|
||||
export const categoryKeys = [
|
||||
'model',
|
||||
'tool',
|
||||
'agent',
|
||||
'agent-strategy',
|
||||
'extension',
|
||||
'bundle',
|
||||
]
|
||||
|
@ -42,10 +42,10 @@ export const useCategories = (translateFromOut?: TFunction) => {
|
||||
const t = translateFromOut || translation
|
||||
|
||||
const categories = categoryKeys.map((category) => {
|
||||
if (category === 'agent') {
|
||||
if (category === 'agent-strategy') {
|
||||
return {
|
||||
name: 'agent_strategy',
|
||||
label: t(`plugin.category.${category}s`),
|
||||
name: 'agent-strategy',
|
||||
label: t('plugin.category.agents'),
|
||||
}
|
||||
}
|
||||
return {
|
||||
@ -70,10 +70,10 @@ export const useSingleCategories = (translateFromOut?: TFunction) => {
|
||||
const t = translateFromOut || translation
|
||||
|
||||
const categories = categoryKeys.map((category) => {
|
||||
if (category === 'agent') {
|
||||
if (category === 'agent-strategy') {
|
||||
return {
|
||||
name: 'agent_strategy',
|
||||
label: t(`plugin.categorySingle.${category}`),
|
||||
name: 'agent-strategy',
|
||||
label: t('plugin.categorySingle.agent'),
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
@ -0,0 +1,37 @@
|
||||
import { sleep } from '@/utils'
|
||||
|
||||
// modalElem fold into plugin install task btn
|
||||
const animTime = 2000
|
||||
|
||||
function getElemCenter(elem: HTMLElement) {
|
||||
const rect = elem.getBoundingClientRect()
|
||||
return {
|
||||
x: rect.left + rect.width / 2 + window.scrollX,
|
||||
y: rect.top + rect.height / 2 + window.scrollY,
|
||||
}
|
||||
}
|
||||
|
||||
const useFoldAnimInto = (onClose: () => void) => {
|
||||
return async function foldIntoAnim(modalClassName: string) {
|
||||
const modalElem = document.querySelector(`.${modalClassName}`) as HTMLElement
|
||||
const pluginTaskTriggerElem = document.getElementById('plugin-task-trigger')
|
||||
|
||||
if (!modalElem || !pluginTaskTriggerElem) {
|
||||
onClose()
|
||||
return
|
||||
}
|
||||
|
||||
const modelCenter = getElemCenter(modalElem)
|
||||
const modalElemRect = modalElem.getBoundingClientRect()
|
||||
const pluginTaskTriggerCenter = getElemCenter(pluginTaskTriggerElem)
|
||||
const xDiff = pluginTaskTriggerCenter.x - modelCenter.x
|
||||
const yDiff = pluginTaskTriggerCenter.y - modelCenter.y
|
||||
const scale = 1 / Math.max(modalElemRect.width, modalElemRect.height)
|
||||
modalElem.style.transition = `all cubic-bezier(0.4, 0, 0.2, 1) ${animTime}ms`
|
||||
modalElem.style.transform = `translate(${xDiff}px, ${yDiff}px) scale(${scale})`
|
||||
await sleep(animTime)
|
||||
onClose()
|
||||
}
|
||||
}
|
||||
|
||||
export default useFoldAnimInto
|
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import React, { useCallback, useRef, useState } from 'react'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import type { Dependency, Plugin, PluginManifestInMarket } from '../../types'
|
||||
import { InstallStep } from '../../types'
|
||||
@ -9,6 +9,8 @@ import Installed from '../base/installed'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import useRefreshPluginList from '../hooks/use-refresh-plugin-list'
|
||||
import ReadyToInstallBundle from '../install-bundle/ready-to-install'
|
||||
import useFoldAnimInto from '../hooks/use-fold-anim-into'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
const i18nPrefix = 'plugin.installModal'
|
||||
|
||||
@ -35,6 +37,9 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({
|
||||
const [errorMsg, setErrorMsg] = useState<string | null>(null)
|
||||
const { refreshPluginList } = useRefreshPluginList()
|
||||
|
||||
const modalRef = useRef<HTMLElement>(null)
|
||||
const foldAnimInto = useFoldAnimInto(onClose)
|
||||
|
||||
const getTitle = useCallback(() => {
|
||||
if (isBundle && step === InstallStep.installed)
|
||||
return t(`${i18nPrefix}.installComplete`)
|
||||
@ -56,12 +61,14 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({
|
||||
setErrorMsg(errorMsg)
|
||||
}, [])
|
||||
|
||||
const modalClassName = 'install-modal'
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isShow={true}
|
||||
onClose={onClose}
|
||||
onClose={() => step === InstallStep.readyToInstall ? foldAnimInto(modalClassName) : onClose()}
|
||||
wrapperClassName='z-[9999]'
|
||||
className='flex min-w-[560px] p-0 flex-col items-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadows-shadow-xl'
|
||||
className={cn(modalClassName, 'flex min-w-[560px] p-0 flex-col items-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadows-shadow-xl')}
|
||||
closable
|
||||
>
|
||||
<div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'>
|
||||
|
@ -146,7 +146,7 @@ const PluginPage = ({
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
'sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1 z-10', activeTab === 'discover' && 'bg-background-body',
|
||||
'sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1 z-10 bg-components-panel-bg', activeTab === 'discover' && 'bg-background-body',
|
||||
)}
|
||||
>
|
||||
<div className='flex justify-between items-center w-full'>
|
||||
|
@ -87,6 +87,7 @@ const PluginTasks = () => {
|
||||
'relative flex items-center justify-center w-8 h-8 rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg shadow-xs hover:bg-components-button-secondary-bg-hover',
|
||||
(isInstallingWithError || isFailed) && 'border-components-button-destructive-secondary-border-hover bg-state-destructive-hover hover:bg-state-destructive-hover-alt cursor-pointer',
|
||||
)}
|
||||
id="plugin-task-trigger"
|
||||
>
|
||||
{
|
||||
(isInstalling || isInstallingWithError) && (
|
||||
|
@ -6,7 +6,7 @@ export enum PluginType {
|
||||
tool = 'tool',
|
||||
model = 'model',
|
||||
extension = 'extension',
|
||||
agent = 'agent_strategy',
|
||||
agent = 'agent-strategy',
|
||||
}
|
||||
|
||||
export enum PluginSource {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { ToolCredential, ToolParameter } from '../types'
|
||||
const toType = (type: string) => {
|
||||
export const toType = (type: string) => {
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return 'text-input'
|
||||
|
@ -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 { toType } from '@/app/components/tools/utils/to-form-schema'
|
||||
|
||||
export type Strategy = {
|
||||
agent_strategy_provider_name: string
|
||||
@ -150,7 +151,7 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
|
||||
onGenerated={handleGenerated}
|
||||
title={renderI18nObject(schema.label)}
|
||||
headerClassName='bg-transparent px-0 text-text-secondary system-sm-semibold-uppercase'
|
||||
containerClassName='bg-transparent'
|
||||
containerBackgroundClassName='bg-transparent'
|
||||
gradientBorder={false}
|
||||
isSupportPromptGenerator={!!schema.auto_generate?.type}
|
||||
titleTooltip={schema.tooltip && renderI18nObject(schema.tooltip)}
|
||||
@ -181,7 +182,18 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
|
||||
strategy
|
||||
? <div>
|
||||
<Form<CustomField>
|
||||
formSchemas={formSchema}
|
||||
formSchemas={[...formSchema, {
|
||||
name: 'max_iteration',
|
||||
type: toType('number'),
|
||||
required: true,
|
||||
label: {
|
||||
en_US: 'Max Iteration',
|
||||
zh_Hans: '最大迭代次数',
|
||||
pt_BR: 'Max Iteration',
|
||||
},
|
||||
show_on: [],
|
||||
variable: 'max-ite',
|
||||
}]}
|
||||
value={formValue}
|
||||
onChange={onFormValueChange}
|
||||
validating={false}
|
||||
|
@ -68,7 +68,7 @@ type Props = {
|
||||
onEditionTypeChange?: (editionType: EditionType) => void
|
||||
varList?: Variable[]
|
||||
handleAddVariable?: (payload: any) => void
|
||||
containerClassName?: string
|
||||
containerBackgroundClassName?: string
|
||||
gradientBorder?: boolean
|
||||
titleTooltip?: ReactNode
|
||||
inputClassName?: string
|
||||
@ -103,7 +103,7 @@ const Editor: FC<Props> = ({
|
||||
handleAddVariable,
|
||||
onGenerated,
|
||||
modelConfig,
|
||||
containerClassName,
|
||||
containerBackgroundClassName: containerClassName,
|
||||
gradientBorder = true,
|
||||
titleTooltip,
|
||||
inputClassName,
|
||||
|
@ -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 flex items-center justify-center', className)}>
|
||||
<div className={cn('w-fit flex items-center justify-center', className)} onClick={e => e.stopPropagation()}>
|
||||
{isShowUpdateModal && pluginDetail && <PluginMutationModel
|
||||
onCancel={hideUpdateModal}
|
||||
plugin={pluginManifestToCardPluginProps({
|
||||
|
@ -807,10 +807,17 @@ export const getNodeUsedVars = (node: Node): ValueSelector[] => {
|
||||
|
||||
case BlockEnum.Agent: {
|
||||
const payload = data as AgentNodeType
|
||||
const params = payload.agent_parameters || {}
|
||||
const mixVars = matchNotSystemVars(Object.keys(params)?.filter(key => params[key].type === ToolVarType.mixed).map(key => params[key].value) as string[])
|
||||
const vars = Object.keys(params).filter(key => params[key].type === ToolVarType.variable).map(key => params[key].value as string) || []
|
||||
res = [...(mixVars as ValueSelector[]), ...(vars as any)]
|
||||
const valueSelectors: ValueSelector[] = []
|
||||
if (!payload.agent_parameters)
|
||||
break
|
||||
|
||||
Object.keys(payload.agent_parameters || {}).forEach((key) => {
|
||||
const { value } = payload.agent_parameters![key]
|
||||
if (typeof value === 'string')
|
||||
valueSelectors.push(...matchNotSystemVars([value]))
|
||||
})
|
||||
res = valueSelectors
|
||||
break
|
||||
}
|
||||
}
|
||||
return res || []
|
||||
|
@ -14,6 +14,7 @@ import ResultPanel from '@/app/components/workflow/run/result-panel'
|
||||
import formatTracing from '@/app/components/workflow/run/utils/format-log'
|
||||
import { useLogs } from '@/app/components/workflow/run/hooks'
|
||||
import type { Props as FormProps } from '@/app/components/workflow/nodes/_base/components/before-run-form/form'
|
||||
import { toType } from '@/app/components/tools/utils/to-form-schema'
|
||||
|
||||
const i18nPrefix = 'workflow.nodes.agent'
|
||||
|
||||
@ -22,6 +23,7 @@ export function strategyParamToCredientialForm(param: StrategyParamItem): Creden
|
||||
...param as any,
|
||||
variable: param.name,
|
||||
show_on: [],
|
||||
type: toType(param.type),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user