mirror of https://github.com/langgenius/dify.git
merge feat/plugins
This commit is contained in:
commit
6f97eb5713
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none">
|
||||
<path d="M10.3567 3.56405L10.2334 3.84689C10.1432 4.05396 9.8568 4.05396 9.76655 3.84689L9.6433 3.56405C9.42355 3.05973 9.02775 2.6582 8.53385 2.43854L8.154 2.26961C7.94865 2.17826 7.94865 1.8794 8.154 1.78806L8.5126 1.62857C9.0192 1.40325 9.4221 0.986865 9.63805 0.465414L9.76465 0.159767C9.8529 -0.0532556 10.1471 -0.0532556 10.2353 0.159767L10.3619 0.465414C10.5779 0.986865 10.9808 1.40325 11.4874 1.62857L11.846 1.78806C12.0514 1.8794 12.0514 2.17826 11.846 2.26961L11.4662 2.43854C10.9723 2.6582 10.5764 3.05973 10.3567 3.56405ZM4.25 3H3.25V9H4.25V3ZM2 5H1V7H2V5ZM6.5 1H5.5V11H6.5V1ZM8.75 4H7.75V9H8.75V4ZM11 5H10V7H11V5Z" fill="#676F83"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 750 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none">
|
||||
<path d="M10.5 4V10.4966C10.5 10.7751 10.2776 11 10.0033 11H1.9967C1.72248 11 1.5 10.778 1.5 10.5041V1.4959C1.5 1.22766 1.72435 1 2.00111 1H7.4984L10.5 4ZM9.5 4.5H7V2H2.5V10H9.5V4.5ZM4 3.5H5.5V4.5H4V3.5ZM4 5.5H8V6.5H4V5.5ZM4 7.5H8V8.5H4V7.5Z" fill="#676F83"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 364 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none">
|
||||
<path d="M10.2334 4.3469L10.3567 4.06406C10.5764 3.55974 10.9723 3.15821 11.4662 2.93854L11.846 2.76961C12.0514 2.67827 12.0514 2.37941 11.846 2.28806L11.4874 2.12857C10.9808 1.90326 10.5779 1.48687 10.3619 0.965415L10.2353 0.659765C10.1471 0.446745 9.8529 0.446745 9.76465 0.659765L9.63805 0.965415C9.4221 1.48687 9.0192 1.90326 8.5126 2.12857L8.154 2.28806C7.94865 2.37941 7.94865 2.67827 8.154 2.76961L8.53385 2.93854C9.02775 3.15821 9.42355 3.55974 9.6433 4.06406L9.76655 4.3469C9.8568 4.55396 10.1432 4.55396 10.2334 4.3469ZM1.4959 1.5H7V2.5H4V9.5H8V4.5H9V5.5H10H11V10.0033C11 10.2776 10.7723 10.5 10.5041 10.5H1.4959C1.22203 10.5 1 10.2775 1 10.0033V1.9967C1 1.72238 1.22766 1.5 1.4959 1.5ZM2 2.5V3.5H3V2.5H2ZM2 4.5V5.5H3V4.5H2ZM2 6.5V7.5H3V6.5H2ZM9 6.5V7.5H10V6.5H9ZM2 8.5V9.5H3V8.5H2ZM9 8.5V9.5H10V8.5H9Z" fill="#676F83"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 935 B |
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"isRootNode": true,
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"xmlns": "http://www.w3.org/2000/svg",
|
||||
"width": "12",
|
||||
"height": "12",
|
||||
"viewBox": "0 0 12 12",
|
||||
"fill": "none"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M10.3567 3.56405L10.2334 3.84689C10.1432 4.05396 9.8568 4.05396 9.76655 3.84689L9.6433 3.56405C9.42355 3.05973 9.02775 2.6582 8.53385 2.43854L8.154 2.26961C7.94865 2.17826 7.94865 1.8794 8.154 1.78806L8.5126 1.62857C9.0192 1.40325 9.4221 0.986865 9.63805 0.465414L9.76465 0.159767C9.8529 -0.0532556 10.1471 -0.0532556 10.2353 0.159767L10.3619 0.465414C10.5779 0.986865 10.9808 1.40325 11.4874 1.62857L11.846 1.78806C12.0514 1.8794 12.0514 2.17826 11.846 2.26961L11.4662 2.43854C10.9723 2.6582 10.5764 3.05973 10.3567 3.56405ZM4.25 3H3.25V9H4.25V3ZM2 5H1V7H2V5ZM6.5 1H5.5V11H6.5V1ZM8.75 4H7.75V9H8.75V4ZM11 5H10V7H11V5Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "AudioSupportIcon"
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './AudioSupportIcon.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
|
||||
props,
|
||||
ref,
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />)
|
||||
|
||||
Icon.displayName = 'AudioSupportIcon'
|
||||
|
||||
export default Icon
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"isRootNode": true,
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"xmlns": "http://www.w3.org/2000/svg",
|
||||
"width": "12",
|
||||
"height": "12",
|
||||
"viewBox": "0 0 12 12",
|
||||
"fill": "none"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M10.5 4V10.4966C10.5 10.7751 10.2776 11 10.0033 11H1.9967C1.72248 11 1.5 10.778 1.5 10.5041V1.4959C1.5 1.22766 1.72435 1 2.00111 1H7.4984L10.5 4ZM9.5 4.5H7V2H2.5V10H9.5V4.5ZM4 3.5H5.5V4.5H4V3.5ZM4 5.5H8V6.5H4V5.5ZM4 7.5H8V8.5H4V7.5Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "DocumentSupportIcon"
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './DocumentSupportIcon.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
|
||||
props,
|
||||
ref,
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />)
|
||||
|
||||
Icon.displayName = 'DocumentSupportIcon'
|
||||
|
||||
export default Icon
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"isRootNode": true,
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"xmlns": "http://www.w3.org/2000/svg",
|
||||
"width": "12",
|
||||
"height": "12",
|
||||
"viewBox": "0 0 12 12",
|
||||
"fill": "none"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M10.2334 4.3469L10.3567 4.06406C10.5764 3.55974 10.9723 3.15821 11.4662 2.93854L11.846 2.76961C12.0514 2.67827 12.0514 2.37941 11.846 2.28806L11.4874 2.12857C10.9808 1.90326 10.5779 1.48687 10.3619 0.965415L10.2353 0.659765C10.1471 0.446745 9.8529 0.446745 9.76465 0.659765L9.63805 0.965415C9.4221 1.48687 9.0192 1.90326 8.5126 2.12857L8.154 2.28806C7.94865 2.37941 7.94865 2.67827 8.154 2.76961L8.53385 2.93854C9.02775 3.15821 9.42355 3.55974 9.6433 4.06406L9.76655 4.3469C9.8568 4.55396 10.1432 4.55396 10.2334 4.3469ZM1.4959 1.5H7V2.5H4V9.5H8V4.5H9V5.5H10H11V10.0033C11 10.2776 10.7723 10.5 10.5041 10.5H1.4959C1.22203 10.5 1 10.2775 1 10.0033V1.9967C1 1.72238 1.22766 1.5 1.4959 1.5ZM2 2.5V3.5H3V2.5H2ZM2 4.5V5.5H3V4.5H2ZM2 6.5V7.5H3V6.5H2ZM9 6.5V7.5H10V6.5H9ZM2 8.5V9.5H3V8.5H2ZM9 8.5V9.5H10V8.5H9Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "VideoSupportIcon"
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './VideoSupportIcon.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
|
||||
props,
|
||||
ref,
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />)
|
||||
|
||||
Icon.displayName = 'VideoSupportIcon'
|
||||
|
||||
export default Icon
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
export { default as AudioSupportIcon } from './AudioSupportIcon'
|
||||
export { default as DocumentSupportIcon } from './DocumentSupportIcon'
|
||||
export { default as MagicBox } from './MagicBox'
|
||||
export { default as MagicEyes } from './MagicEyes'
|
||||
export { default as MagicWand } from './MagicWand'
|
||||
|
|
@ -7,3 +9,4 @@ export { default as Robot } from './Robot'
|
|||
export { default as Sliders02 } from './Sliders02'
|
||||
export { default as Speaker } from './Speaker'
|
||||
export { default as StopCircle } from './StopCircle'
|
||||
export { default as VideoSupportIcon } from './VideoSupportIcon'
|
||||
|
|
|
|||
|
|
@ -23,19 +23,19 @@ const Switch = React.forwardRef<HTMLButtonElement>(({ onChange, size = 'md', def
|
|||
sm: 'h-3 w-5',
|
||||
}
|
||||
|
||||
// const circleStyle = {
|
||||
// lg: 'h-5 w-5',
|
||||
// l: 'h-4 w-4',
|
||||
// md: 'h-3 w-3',
|
||||
// sm: 'h-2 w-2',
|
||||
// }
|
||||
const circleStyle = {
|
||||
lg: 'h-5 w-5',
|
||||
l: 'h-4 w-4',
|
||||
md: 'h-3 w-3',
|
||||
sm: 'h-2 w-2',
|
||||
}
|
||||
|
||||
// const translateLeft = {
|
||||
// lg: 'translate-x-5',
|
||||
// l: 'translate-x-4',
|
||||
// md: 'translate-x-3',
|
||||
// sm: 'translate-x-2',
|
||||
// }
|
||||
const translateLeft = {
|
||||
lg: 'translate-x-5',
|
||||
l: 'translate-x-4',
|
||||
md: 'translate-x-3',
|
||||
sm: 'translate-x-2',
|
||||
}
|
||||
return (
|
||||
<OriginalSwitch
|
||||
ref={ref}
|
||||
|
|
@ -57,11 +57,9 @@ const Switch = React.forwardRef<HTMLButtonElement>(({ onChange, size = 'md', def
|
|||
<span
|
||||
aria-hidden="true"
|
||||
className={classNames(
|
||||
wrapStyle[size],
|
||||
enabled ? 'bg-components-toggle-bg' : 'bg-components-toggle-bg-unchecked',
|
||||
'relative inline-flex flex-shrink-0 cursor-pointer rounded-[5px] border-2 border-transparent transition-colors duration-200 ease-in-out',
|
||||
disabled ? '!opacity-50 !cursor-not-allowed' : '',
|
||||
className,
|
||||
circleStyle[size],
|
||||
enabled ? translateLeft[size] : 'translate-x-0',
|
||||
'pointer-events-none inline-block transform rounded-[3px] bg-components-toggle-knob shadow ring-0 transition duration-200 ease-in-out',
|
||||
)}
|
||||
/>
|
||||
</OriginalSwitch>
|
||||
|
|
|
|||
|
|
@ -9,20 +9,6 @@ import { useWorkspacesContext } from '@/context/workspace-context'
|
|||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import PremiumBadge from '@/app/components/base/premium-badge'
|
||||
import classNames from '@/utils/classnames'
|
||||
|
||||
const itemClassName = `
|
||||
flex items-center px-3 py-2 h-10 cursor-pointer
|
||||
`
|
||||
const itemIconClassName = `
|
||||
shrink-0 mr-2 flex items-center justify-center w-6 h-6 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600
|
||||
`
|
||||
const itemNameClassName = `
|
||||
grow mr-2 text-sm text-gray-700 text-left
|
||||
`
|
||||
const itemCheckClassName = `
|
||||
shrink-0 w-4 h-4 text-primary-600
|
||||
`
|
||||
|
||||
const WorkplaceSelector = () => {
|
||||
const { t } = useTranslation()
|
||||
|
|
@ -30,7 +16,6 @@ const WorkplaceSelector = () => {
|
|||
const { notify } = useContext(ToastContext)
|
||||
const { workspaces } = useWorkspacesContext()
|
||||
const currentWorkspace = workspaces.find(v => v.current)
|
||||
const isFreePlan = plan.type === 'sandbox'
|
||||
const handleSwitchWorkspace = async (tenant_id: string) => {
|
||||
try {
|
||||
if (currentWorkspace?.id === tenant_id)
|
||||
|
|
@ -51,8 +36,8 @@ const WorkplaceSelector = () => {
|
|||
<>
|
||||
<Menu.Button className={cn(
|
||||
`
|
||||
${itemClassName} w-full
|
||||
group hover:bg-state-base-hover cursor-pointer ${open && 'bg-state-base-hover'} rounded-lg
|
||||
flex items-center p-0.5 gap-1.5 w-full
|
||||
group hover:bg-state-base-hover cursor-pointer ${open && 'bg-state-base-hover'} rounded-[10px]
|
||||
`,
|
||||
)}>
|
||||
<div className='flex items-center justify-center w-7 h-7 bg-[#EFF4FF] rounded-lg text-xs font-medium text-primary-600'>{currentWorkspace?.name[0].toLocaleUpperCase()}</div>
|
||||
|
|
@ -83,30 +68,18 @@ const WorkplaceSelector = () => {
|
|||
</div>
|
||||
{
|
||||
workspaces.map(workspace => (
|
||||
<div>
|
||||
<div className='flex py-1 pl-3 pr-2 items-center gap-2 self-stretch hover:bg-state-base-hover rounded-lg' key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
|
||||
<div className='flex items-center justify-center w-6 h-6 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600'>{workspace.name[0].toLocaleUpperCase()}</div>
|
||||
<div className='line-clamp-1 grow overflow-hidden text-text-secondary text-ellipsis system-md-regular cursor-pointer'>{workspace.name}</div>
|
||||
{
|
||||
<PremiumBadge size='s' color='gray' allowHover={false}>
|
||||
<div className='system-2xs-medium'>
|
||||
<span className='p-[2px]'>
|
||||
{plan.type === 'professional' ? 'PRO' : plan.type.toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
</PremiumBadge>
|
||||
}
|
||||
</div>
|
||||
<Menu.Item key={workspace.id}>
|
||||
{({ active }) => <div className={classNames(itemClassName,
|
||||
active && 'bg-state-base-hover',
|
||||
)} key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
|
||||
<div className={itemIconClassName}>{workspace.name[0].toLocaleUpperCase()}</div>
|
||||
<div className={itemNameClassName}>{workspace.name}</div>
|
||||
{/* {workspace.current && <Check className={itemCheckClassName} />} */}
|
||||
</div>}
|
||||
|
||||
</Menu.Item>
|
||||
<div className='flex py-1 pl-3 pr-2 items-center gap-2 self-stretch hover:bg-state-base-hover rounded-lg' key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
|
||||
<div className='flex items-center justify-center w-6 h-6 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600'>{workspace.name[0].toLocaleUpperCase()}</div>
|
||||
<div className='line-clamp-1 grow overflow-hidden text-text-secondary text-ellipsis system-md-regular cursor-pointer'>{workspace.name}</div>
|
||||
{
|
||||
<PremiumBadge size='s' color='gray' allowHover={false}>
|
||||
<div className='system-2xs-medium'>
|
||||
<span className='p-[2px]'>
|
||||
{plan.type === 'professional' ? 'PRO' : plan.type.toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
</PremiumBadge>
|
||||
}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@ const ModelIcon: FC<ModelIconProps> = ({
|
|||
}) => {
|
||||
const language = useLanguage()
|
||||
if (provider?.provider.includes('openai') && modelName?.includes('gpt-4o'))
|
||||
return <div className='flex w-6 h-6 items-center justify-center'><OpenaiBlue className={cn('w-5 h-5', className)}/></div>
|
||||
return <div className='flex items-center justify-center'><OpenaiBlue className={cn('w-5 h-5', className)}/></div>
|
||||
if (provider?.provider.includes('openai') && modelName?.startsWith('gpt-4'))
|
||||
return <div className='flex w-6 h-6 items-center justify-center'><OpenaiViolet className={cn('w-5 h-5', className)}/></div>
|
||||
return <div className='flex items-center justify-center'><OpenaiViolet className={cn('w-5 h-5', className)}/></div>
|
||||
|
||||
if (provider?.icon_small) {
|
||||
return (
|
||||
|
||||
<div className={`flex w-6 h-6 items-center justify-center ${isDeprecated ? 'opacity-50' : ''}`}>
|
||||
<div className={`flex items-center justify-center ${isDeprecated ? 'opacity-50' : ''}`}>
|
||||
<img
|
||||
alt='model-icon'
|
||||
src={`${provider.icon_small[language] || provider.icon_small.en_US}`}
|
||||
|
|
@ -41,7 +41,7 @@ const ModelIcon: FC<ModelIconProps> = ({
|
|||
|
||||
return (
|
||||
<div className={cn(
|
||||
'flex items-center justify-center w-6 h-6 rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default-subtle',
|
||||
'flex items-center justify-center rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default-subtle',
|
||||
className,
|
||||
)}>
|
||||
<div className='flex w-5 h5 items-center justify-center opacity-35'>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ const ModelName: FC<ModelNameProps> = ({
|
|||
if (!modelItem)
|
||||
return null
|
||||
return (
|
||||
<div className={cn('flex items-center overflow-hidden text-ellipsis truncate text-components-input-text-filled system-sm-regular', className)}>
|
||||
<div className={cn('flex gap-0.5 items-center overflow-hidden text-ellipsis truncate text-components-input-text-filled system-sm-regular', className)}>
|
||||
<div
|
||||
className='truncate'
|
||||
title={modelItem.label[language] || modelItem.label.en_US}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@ import {
|
|||
ModelFeatureTextEnum,
|
||||
} from '../declarations'
|
||||
import {
|
||||
AudioSupportIcon,
|
||||
DocumentSupportIcon,
|
||||
// MagicBox,
|
||||
MagicEyes,
|
||||
// MagicWand,
|
||||
// Robot,
|
||||
VideoSupportIcon,
|
||||
} from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
|
||||
|
|
@ -65,7 +68,7 @@ const FeatureIcon: FC<FeatureIconProps> = ({
|
|||
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.vision })}
|
||||
>
|
||||
<div className='inline-block cursor-help'>
|
||||
<ModelBadge className={`mr-0.5 !px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<ModelBadge className={`!px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<MagicEyes className='w-3 h-3' />
|
||||
</ModelBadge>
|
||||
</div>
|
||||
|
|
@ -73,6 +76,48 @@ const FeatureIcon: FC<FeatureIconProps> = ({
|
|||
)
|
||||
}
|
||||
|
||||
if (feature === ModelFeatureEnum.document) {
|
||||
return (
|
||||
<Tooltip
|
||||
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.document })}
|
||||
>
|
||||
<div className='inline-block cursor-help'>
|
||||
<ModelBadge className={`!px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<DocumentSupportIcon className='w-3 h-3' />
|
||||
</ModelBadge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
if (feature === ModelFeatureEnum.audio) {
|
||||
return (
|
||||
<Tooltip
|
||||
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.audio })}
|
||||
>
|
||||
<div className='inline-block cursor-help'>
|
||||
<ModelBadge className={`!px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<AudioSupportIcon className='w-3 h-3' />
|
||||
</ModelBadge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
if (feature === ModelFeatureEnum.video) {
|
||||
return (
|
||||
<Tooltip
|
||||
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.video })}
|
||||
>
|
||||
<div className='inline-block cursor-help'>
|
||||
<ModelBadge className={`!px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<VideoSupportIcon className='w-3 h-3' />
|
||||
</ModelBadge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,41 +34,45 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'group flex items-center p-1 gap-0.5 h-8 rounded-lg bg-components-input-bg-normal',
|
||||
'group flex items-center p-1 gap-0.5 rounded-lg bg-components-input-bg-normal',
|
||||
!readonly && 'hover:bg-components-input-bg-hover cursor-pointer',
|
||||
open && 'bg-components-input-bg-hover',
|
||||
model.status !== ModelStatusEnum.active && 'bg-components-input-bg-disabled hover:bg-components-input-bg-disabled',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<ModelIcon
|
||||
className='shrink-0 mr-1.5'
|
||||
provider={provider}
|
||||
modelName={model.model}
|
||||
/>
|
||||
<ModelName
|
||||
className='grow'
|
||||
modelItem={model}
|
||||
showMode
|
||||
showFeatures
|
||||
/>
|
||||
{!readonly && (
|
||||
<div className='shrink-0 flex items-center justify-center w-4 h-4'>
|
||||
{
|
||||
model.status !== ModelStatusEnum.active
|
||||
? (
|
||||
<Tooltip popupContent={MODEL_STATUS_TEXT[model.status][language]}>
|
||||
<AlertTriangle className='w-4 h-4 text-[#F79009]' />
|
||||
</Tooltip>
|
||||
)
|
||||
: (
|
||||
<RiArrowDownSLine
|
||||
className='w-3.5 h-3.5 text-text-tertiary'
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
<div className='flex items-center justify-center w-6 h-6'>
|
||||
<ModelIcon
|
||||
className='w-5 h-5 m-0.5'
|
||||
provider={provider}
|
||||
modelName={model.model}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex px-1 py-[3px] items-center gap-1 grow truncate'>
|
||||
<ModelName
|
||||
className='grow'
|
||||
modelItem={model}
|
||||
showMode
|
||||
showFeatures
|
||||
/>
|
||||
{!readonly && (
|
||||
<div className='shrink-0 flex items-center justify-center w-4 h-4'>
|
||||
{
|
||||
model.status !== ModelStatusEnum.active
|
||||
? (
|
||||
<Tooltip popupContent={MODEL_STATUS_TEXT[model.status][language]}>
|
||||
<AlertTriangle className='w-4 h-4 text-text-warning-secondary' />
|
||||
</Tooltip>
|
||||
)
|
||||
: (
|
||||
<RiArrowDownSLine
|
||||
className='w-3.5 h-3.5 text-text-tertiary'
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ const Card = ({
|
|||
{/* Header */}
|
||||
<div className="flex">
|
||||
<Icon src={icon} installed={installed} installFailed={installFailed} />
|
||||
<div className="ml-3 grow">
|
||||
<div className="ml-3 w-0 grow">
|
||||
<div className="flex items-center h-5">
|
||||
<Title title={getLocalizedText(label)} />
|
||||
{verified && <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" />}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ const ToolSelector: FC<Props> = ({
|
|||
|
||||
const [isShowChooseTool, setIsShowChooseTool] = useState(false)
|
||||
const handleSelectTool = (tool: ToolDefaultValue) => {
|
||||
const paramValues = addDefaultValue(tool.params, toolParametersToFormSchemas(tool.paramSchemas as any))
|
||||
const paramValues = addDefaultValue(tool.params, toolParametersToFormSchemas(tool.paramSchemas.filter(param => param.form !== 'llm') as any))
|
||||
const toolValue = {
|
||||
provider_name: tool.provider_id,
|
||||
tool_name: tool.tool_name,
|
||||
|
|
@ -133,7 +133,7 @@ const ToolSelector: FC<Props> = ({
|
|||
|
||||
const currentToolParams = useMemo(() => {
|
||||
if (!currentProvider) return []
|
||||
return currentProvider.tools.find(tool => tool.name === value?.tool_name)?.parameters || []
|
||||
return currentProvider.tools.find(tool => tool.name === value?.tool_name)?.parameters.filter(param => param.form !== 'llm') || []
|
||||
}, [currentProvider, value])
|
||||
|
||||
const formSchemas = useMemo(() => toolParametersToFormSchemas(currentToolParams), [currentToolParams])
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export type Collection = {
|
|||
allow_delete: boolean
|
||||
labels: string[]
|
||||
plugin_id?: string
|
||||
letter?: string
|
||||
}
|
||||
|
||||
export type ToolParameter = {
|
||||
|
|
|
|||
|
|
@ -6,31 +6,53 @@ import type { BlockEnum } from '../../../types'
|
|||
import type { ToolDefaultValue } from '../../types'
|
||||
import Tool from '../tool'
|
||||
import { ViewType } from '../../view-type-select'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
type Props = {
|
||||
payload: ToolWithProvider[]
|
||||
isShowLetterIndex: boolean
|
||||
hasSearchText: boolean
|
||||
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
|
||||
letters: string[]
|
||||
toolRefs: any
|
||||
}
|
||||
|
||||
const ToolViewFlatView: FC<Props> = ({
|
||||
letters,
|
||||
payload,
|
||||
isShowLetterIndex,
|
||||
hasSearchText,
|
||||
onSelect,
|
||||
toolRefs,
|
||||
}) => {
|
||||
const firstLetterToolIds = useMemo(() => {
|
||||
const res: Record<string, string> = {}
|
||||
letters.forEach((letter) => {
|
||||
const firstToolId = payload.find(tool => tool.letter === letter)?.id
|
||||
if (firstToolId)
|
||||
res[firstToolId] = letter
|
||||
})
|
||||
return res
|
||||
}, [payload, letters])
|
||||
return (
|
||||
<div>
|
||||
{payload.map(tool => (
|
||||
<Tool
|
||||
<div
|
||||
key={tool.id}
|
||||
payload={tool}
|
||||
viewType={ViewType.flat}
|
||||
isShowLetterIndex={isShowLetterIndex}
|
||||
hasSearchText={hasSearchText}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
ref={(el) => {
|
||||
const letter = firstLetterToolIds[tool.id]
|
||||
if (letter)
|
||||
toolRefs.current[letter] = el
|
||||
}}
|
||||
>
|
||||
<Tool
|
||||
payload={tool}
|
||||
viewType={ViewType.flat}
|
||||
isShowLetterIndex={isShowLetterIndex}
|
||||
hasSearchText={hasSearchText}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -69,13 +69,19 @@ const Blocks = ({
|
|||
|
||||
const listViewToolData = useMemo(() => {
|
||||
const result: ToolWithProvider[] = []
|
||||
Object.keys(withLetterAndGroupViewToolsData).forEach((letter) => {
|
||||
letters.forEach((letter) => {
|
||||
Object.keys(withLetterAndGroupViewToolsData[letter]).forEach((groupName) => {
|
||||
result.push(...withLetterAndGroupViewToolsData[letter][groupName])
|
||||
result.push(...withLetterAndGroupViewToolsData[letter][groupName].map((item) => {
|
||||
return {
|
||||
...item,
|
||||
letter,
|
||||
}
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
return result
|
||||
}, [withLetterAndGroupViewToolsData])
|
||||
}, [withLetterAndGroupViewToolsData, letters])
|
||||
|
||||
const toolRefs = useRef({})
|
||||
|
||||
|
|
@ -94,6 +100,8 @@ const Blocks = ({
|
|||
{!!tools.length && (
|
||||
isFlatView ? (
|
||||
<ToolListFlatView
|
||||
toolRefs={toolRefs}
|
||||
letters={letters}
|
||||
payload={listViewToolData}
|
||||
isShowLetterIndex={isShowLetterIndex}
|
||||
hasSearchText={hasSearchText}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ export type ToolDefaultValue = {
|
|||
title: string
|
||||
is_team_authorization: boolean
|
||||
params: Record<string, any>
|
||||
paramSchemas: Record<string, any>
|
||||
paramSchemas: Record<string, any>[]
|
||||
output_schema: Record<string, any>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ export const AgentStrategy = (props: AgentStrategyProps) => {
|
|||
} : undefined
|
||||
}
|
||||
placeholderClassName='px-2 py-1'
|
||||
titleClassName='system-sm-semibold-uppercase text-text-secondary text-[13px]'
|
||||
inputClassName='px-2 py-1 bg-components-input-bg-normal focus:bg-components-input-bg-active focus:border-components-input-border-active focus:border rounded-lg'
|
||||
/>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ type Props = {
|
|||
inputClassName?: string
|
||||
editorContainerClassName?: string
|
||||
placeholderClassName?: string
|
||||
titleClassName?: string
|
||||
}
|
||||
|
||||
const Editor: FC<Props> = ({
|
||||
|
|
@ -107,6 +108,7 @@ const Editor: FC<Props> = ({
|
|||
titleTooltip,
|
||||
inputClassName,
|
||||
placeholderClassName,
|
||||
titleClassName,
|
||||
editorContainerClassName,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
|
@ -145,7 +147,7 @@ const Editor: FC<Props> = ({
|
|||
<div className={cn(isFocus ? 'bg-gray-50' : 'bg-gray-100', isExpand && 'h-full flex flex-col', 'rounded-lg', containerClassName)}>
|
||||
<div className={cn('pt-1 pl-3 pr-2 flex justify-between items-center', headerClassName)}>
|
||||
<div className='flex gap-2'>
|
||||
<div className='leading-4 text-xs font-semibold text-gray-700 uppercase'>{title}</div>
|
||||
<div className={cn('leading-4 text-xs font-semibold text-gray-700 uppercase', titleClassName)}>{title}</div>
|
||||
{titleTooltip && <Tooltip popupContent={titleTooltip} />}
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
|
|
|
|||
|
|
@ -8,11 +8,33 @@ import type { ToolIconProps } from './components/tool-icon'
|
|||
import { ToolIcon } from './components/tool-icon'
|
||||
import useConfig from './use-config'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { FormTypeEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
const useAllModel = () => {
|
||||
const { data: textGeneration } = useModelList(ModelTypeEnum.textGeneration)
|
||||
const { data: moderation } = useModelList(ModelTypeEnum.moderation)
|
||||
const { data: rerank } = useModelList(ModelTypeEnum.rerank)
|
||||
const { data: speech2text } = useModelList(ModelTypeEnum.speech2text)
|
||||
const { data: textEmbedding } = useModelList(ModelTypeEnum.textEmbedding)
|
||||
const { data: tts } = useModelList(ModelTypeEnum.tts)
|
||||
const models = useMemo(() => {
|
||||
return textGeneration
|
||||
.concat(moderation)
|
||||
.concat(rerank)
|
||||
.concat(speech2text)
|
||||
.concat(textEmbedding)
|
||||
.concat(tts)
|
||||
}, [textGeneration, moderation, rerank, speech2text, textEmbedding, tts])
|
||||
if (!textGeneration || !moderation || !rerank || !speech2text || !textEmbedding || !tts)
|
||||
return undefined
|
||||
return models
|
||||
}
|
||||
|
||||
const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
||||
const { inputs, currentStrategy } = useConfig(props.id, props.data)
|
||||
const { t } = useTranslation()
|
||||
const modelList = useAllModel()
|
||||
const models = useMemo(() => {
|
||||
if (!inputs) return []
|
||||
// if selected, show in node
|
||||
|
|
@ -73,7 +95,7 @@ const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
|||
{inputs.agent_strategy_label}
|
||||
</SettingItem>
|
||||
: <SettingItem label={t('workflow.nodes.agent.strategyNotSet')} />}
|
||||
{models.length > 0 && <Group
|
||||
{models.length > 0 && modelList && <Group
|
||||
label={<GroupLabel className='mt-1'>
|
||||
{t('workflow.nodes.agent.model')}
|
||||
</GroupLabel>}
|
||||
|
|
@ -81,7 +103,8 @@ const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
|||
{models.map((model) => {
|
||||
return <ModelSelector
|
||||
key={model.param}
|
||||
modelList={[]}
|
||||
modelList={modelList}
|
||||
triggerClassName='bg-workflow-block-parma-bg'
|
||||
defaultModel={
|
||||
'provider' in model
|
||||
? {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { FC } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import type { NodePanelProps } from '../../types'
|
||||
import type { AgentNodeType } from './types'
|
||||
import Field from '../_base/components/field'
|
||||
|
|
@ -8,6 +9,11 @@ import { useTranslation } from 'react-i18next'
|
|||
import OutputVars, { VarItem } from '../_base/components/output-vars'
|
||||
import type { StrategyParamItem } from '@/app/components/plugins/types'
|
||||
import type { CredentialFormSchema } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/before-run-form'
|
||||
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'
|
||||
|
||||
const i18nPrefix = 'workflow.nodes.agent'
|
||||
|
||||
|
|
@ -20,10 +26,49 @@ export function strategyParamToCredientialForm(param: StrategyParamItem): Creden
|
|||
}
|
||||
|
||||
const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
||||
const { inputs, setInputs, currentStrategy, formData, onFormChange } = useConfig(props.id, props.data)
|
||||
const {
|
||||
inputs,
|
||||
setInputs,
|
||||
currentStrategy,
|
||||
formData,
|
||||
onFormChange,
|
||||
|
||||
isShowSingleRun,
|
||||
hideSingleRun,
|
||||
runningStatus,
|
||||
handleRun,
|
||||
handleStop,
|
||||
runResult,
|
||||
runInputData,
|
||||
setRunInputData,
|
||||
varInputs,
|
||||
} = useConfig(props.id, props.data)
|
||||
const { t } = useTranslation()
|
||||
const nodeInfo = useMemo(() => {
|
||||
if (!runResult)
|
||||
return
|
||||
return formatTracing([runResult], t)[0]
|
||||
}, [runResult, t])
|
||||
const logsParams = useLogs()
|
||||
const singleRunForms = (() => {
|
||||
const forms: FormProps[] = []
|
||||
|
||||
if (varInputs.length > 0) {
|
||||
forms.push(
|
||||
{
|
||||
label: t(`${i18nPrefix}.singleRun.variable`)!,
|
||||
inputs: varInputs,
|
||||
values: runInputData,
|
||||
onChange: setRunInputData,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return forms
|
||||
})()
|
||||
|
||||
return <div className='my-2'>
|
||||
<Field title={t('workflow.nodes.agent.strategy.label')} className='px-4' >
|
||||
<Field title={t('workflow.nodes.agent.strategy.label')} className='px-4 py-2' >
|
||||
<AgentStrategy
|
||||
strategy={inputs.agent_strategy_name ? {
|
||||
agent_strategy_provider_name: inputs.agent_strategy_provider_name!,
|
||||
|
|
@ -72,6 +117,21 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
|||
))}
|
||||
</OutputVars>
|
||||
</div>
|
||||
{
|
||||
isShowSingleRun && (
|
||||
<BeforeRunForm
|
||||
nodeName={inputs.title}
|
||||
nodeType={inputs.type}
|
||||
onHide={hideSingleRun}
|
||||
forms={singleRunForms}
|
||||
runningStatus={runningStatus}
|
||||
onRun={handleRun}
|
||||
onStop={handleStop}
|
||||
{...logsParams}
|
||||
result={<ResultPanel {...runResult} nodeInfo={nodeInfo} showSteps={false} {...logsParams} />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,26 +21,6 @@ const useConfig = (id: string, payload: AgentNodeType) => {
|
|||
inputs.agent_strategy_provider_name || '',
|
||||
)
|
||||
|
||||
// single run
|
||||
const agentInputKey = `${id}.input_selector`
|
||||
const {
|
||||
isShowSingleRun,
|
||||
showSingleRun,
|
||||
hideSingleRun,
|
||||
toVarInputs,
|
||||
runningStatus,
|
||||
handleRun,
|
||||
handleStop,
|
||||
runInputData,
|
||||
setRunInputData,
|
||||
runResult,
|
||||
} = useOneStepRun<AgentNodeType>({
|
||||
id,
|
||||
data: inputs,
|
||||
defaultRunInputData: {
|
||||
[agentInputKey]: [''],
|
||||
},
|
||||
})
|
||||
const currentStrategy = strategyProvider.data?.declaration.strategies.find(
|
||||
str => str.identity.name === inputs.agent_strategy_name,
|
||||
)
|
||||
|
|
@ -70,6 +50,36 @@ const useConfig = (id: string, payload: AgentNodeType) => {
|
|||
agent_parameters: res,
|
||||
})
|
||||
}
|
||||
|
||||
// single run
|
||||
const {
|
||||
isShowSingleRun,
|
||||
showSingleRun,
|
||||
hideSingleRun,
|
||||
toVarInputs,
|
||||
runningStatus,
|
||||
handleRun,
|
||||
handleStop,
|
||||
runInputData,
|
||||
setRunInputData,
|
||||
runResult,
|
||||
getInputVars,
|
||||
} = useOneStepRun<AgentNodeType>({
|
||||
id,
|
||||
data: inputs,
|
||||
defaultRunInputData: {},
|
||||
})
|
||||
const allVarStrArr = (() => {
|
||||
const arr = ['']
|
||||
|
||||
return arr
|
||||
})()
|
||||
const varInputs = (() => {
|
||||
const vars = getInputVars(allVarStrArr)
|
||||
|
||||
return vars
|
||||
})()
|
||||
|
||||
return {
|
||||
readOnly,
|
||||
inputs,
|
||||
|
|
@ -92,7 +102,7 @@ const useConfig = (id: string, payload: AgentNodeType) => {
|
|||
runInputData,
|
||||
setRunInputData,
|
||||
runResult,
|
||||
agentInputKey,
|
||||
varInputs,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,10 +78,10 @@ const NodePanel: FC<Props> = ({
|
|||
setCollapseState(!nodeInfo.expand)
|
||||
}, [nodeInfo.expand, setCollapseState])
|
||||
|
||||
const isIterationNode = nodeInfo.node_type === BlockEnum.Iteration
|
||||
const isRetryNode = hasRetryNode(nodeInfo.node_type) && nodeInfo.retryDetail
|
||||
const isAgentNode = nodeInfo.node_type === BlockEnum.Agent
|
||||
const isToolNode = nodeInfo.node_type === BlockEnum.Tool
|
||||
const isIterationNode = nodeInfo.node_type === BlockEnum.Iteration && nodeInfo.details?.length
|
||||
const isRetryNode = hasRetryNode(nodeInfo.node_type) && nodeInfo.retryDetail?.length
|
||||
const isAgentNode = nodeInfo.node_type === BlockEnum.Agent && nodeInfo.agentLog?.length
|
||||
const isToolNode = nodeInfo.node_type === BlockEnum.Tool && nodeInfo.agentLog?.length
|
||||
|
||||
return (
|
||||
<div className={cn('px-2 py-1', className)}>
|
||||
|
|
|
|||
|
|
@ -57,10 +57,10 @@ const ResultPanel: FC<ResultPanelProps> = ({
|
|||
handleShowAgentOrToolLog,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const isIterationNode = nodeInfo?.node_type === BlockEnum.Iteration
|
||||
const isRetryNode = hasRetryNode(nodeInfo?.node_type) && nodeInfo?.retryDetail
|
||||
const isAgentNode = nodeInfo?.node_type === BlockEnum.Agent
|
||||
const isToolNode = nodeInfo?.node_type === BlockEnum.Tool
|
||||
const isIterationNode = nodeInfo?.node_type === BlockEnum.Iteration && nodeInfo?.details?.length
|
||||
const isRetryNode = hasRetryNode(nodeInfo?.node_type) && nodeInfo?.retryDetail?.length
|
||||
const isAgentNode = nodeInfo?.node_type === BlockEnum.Agent && nodeInfo?.agentLog?.length
|
||||
const isToolNode = nodeInfo?.node_type === BlockEnum.Tool && nodeInfo?.agentLog?.length
|
||||
|
||||
return (
|
||||
<div className='bg-components-panel-bg py-2'>
|
||||
|
|
|
|||
Loading…
Reference in New Issue