mirror of
https://github.com/langgenius/dify.git
synced 2026-04-26 02:06:35 +08:00
model auth
This commit is contained in:
parent
3f57e4a643
commit
2e28a64d38
@ -186,6 +186,22 @@ export type Credential = {
|
|||||||
credential_name: string
|
credential_name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CustomModel = {
|
||||||
|
model: string
|
||||||
|
model_type: ModelTypeEnum
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CustomModelCredential = CustomModel & {
|
||||||
|
credentials?: Record<string, any>
|
||||||
|
available_model_credentials?: Credential[]
|
||||||
|
current_credential_id?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CredentialWithModel = Credential & {
|
||||||
|
model: string
|
||||||
|
model_type: ModelTypeEnum
|
||||||
|
}
|
||||||
|
|
||||||
export type ModelProvider = {
|
export type ModelProvider = {
|
||||||
provider: string
|
provider: string
|
||||||
label: TypeWithI18N
|
label: TypeWithI18N
|
||||||
@ -215,6 +231,7 @@ export type ModelProvider = {
|
|||||||
current_credential_id?: string
|
current_credential_id?: string
|
||||||
current_credential_name?: string
|
current_credential_name?: string
|
||||||
available_credentials?: Credential[]
|
available_credentials?: Credential[]
|
||||||
|
custom_models?: CustomModelCredential[]
|
||||||
}
|
}
|
||||||
system_configuration: {
|
system_configuration: {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
@ -280,9 +297,22 @@ export type ModelLoadBalancingConfigEntry = {
|
|||||||
in_cooldown?: boolean
|
in_cooldown?: boolean
|
||||||
/** cooldown time (in seconds) */
|
/** cooldown time (in seconds) */
|
||||||
ttl?: number
|
ttl?: number
|
||||||
|
credential_id?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ModelLoadBalancingConfig = {
|
export type ModelLoadBalancingConfig = {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
configs: ModelLoadBalancingConfigEntry[]
|
configs: ModelLoadBalancingConfigEntry[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ProviderCredential = {
|
||||||
|
credentials: Record<string, any>
|
||||||
|
name: string
|
||||||
|
credential_id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ModelCredential = {
|
||||||
|
credentials: Record<string, any>
|
||||||
|
load_balancing: ModelLoadBalancingConfig
|
||||||
|
available_credentials: Credential[]
|
||||||
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { useContext } from 'use-context-selector'
|
|||||||
import type {
|
import type {
|
||||||
Credential,
|
Credential,
|
||||||
CustomConfigurationModelFixedFields,
|
CustomConfigurationModelFixedFields,
|
||||||
|
CustomModel,
|
||||||
DefaultModel,
|
DefaultModel,
|
||||||
DefaultModelResponse,
|
DefaultModelResponse,
|
||||||
Model,
|
Model,
|
||||||
@ -354,6 +355,7 @@ export const useModelModalHandler = () => {
|
|||||||
configurationMethod: ConfigurationMethodEnum,
|
configurationMethod: ConfigurationMethodEnum,
|
||||||
CustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields,
|
CustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields,
|
||||||
credential?: Credential,
|
credential?: Credential,
|
||||||
|
model?: CustomModel,
|
||||||
) => {
|
) => {
|
||||||
setShowModelModal({
|
setShowModelModal({
|
||||||
payload: {
|
payload: {
|
||||||
@ -361,6 +363,7 @@ export const useModelModalHandler = () => {
|
|||||||
currentConfigurationMethod: configurationMethod,
|
currentConfigurationMethod: configurationMethod,
|
||||||
currentCustomConfigurationModelFixedFields: CustomConfigurationModelFixedFields,
|
currentCustomConfigurationModelFixedFields: CustomConfigurationModelFixedFields,
|
||||||
credential,
|
credential,
|
||||||
|
model,
|
||||||
},
|
},
|
||||||
onSaveCallback: () => {
|
onSaveCallback: () => {
|
||||||
handleRefreshModel(provider, configurationMethod, CustomConfigurationModelFixedFields)
|
handleRefreshModel(provider, configurationMethod, CustomConfigurationModelFixedFields)
|
||||||
|
|||||||
@ -3,13 +3,21 @@ import {
|
|||||||
useCallback,
|
useCallback,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { RiAddLine } from '@remixicon/react'
|
import { RiAddLine } from '@remixicon/react'
|
||||||
import {
|
import { Authorized } from '@/app/components/header/account-setting/model-provider-page/model-auth'
|
||||||
AuthCategory,
|
|
||||||
Authorized,
|
|
||||||
} from '@/app/components/plugins/plugin-auth'
|
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
import type {
|
||||||
|
Credential,
|
||||||
|
ModelProvider,
|
||||||
|
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
|
|
||||||
const AddCredentialInLoadBalancing = () => {
|
type AddCredentialInLoadBalancingProps = {
|
||||||
|
provider: ModelProvider
|
||||||
|
onSetup: (credential?: Credential) => void
|
||||||
|
}
|
||||||
|
const AddCredentialInLoadBalancing = ({
|
||||||
|
provider,
|
||||||
|
onSetup,
|
||||||
|
}: AddCredentialInLoadBalancingProps) => {
|
||||||
const renderTrigger = useCallback((open?: boolean) => {
|
const renderTrigger = useCallback((open?: boolean) => {
|
||||||
return (
|
return (
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
@ -25,13 +33,9 @@ const AddCredentialInLoadBalancing = () => {
|
|||||||
return (
|
return (
|
||||||
<Authorized
|
<Authorized
|
||||||
credentials={[]}
|
credentials={[]}
|
||||||
pluginPayload={{
|
provider={provider.provider}
|
||||||
provider: '',
|
|
||||||
category: AuthCategory.model,
|
|
||||||
}}
|
|
||||||
canApiKey
|
|
||||||
offset={4}
|
|
||||||
renderTrigger={renderTrigger}
|
renderTrigger={renderTrigger}
|
||||||
|
onSetup={onSetup}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,78 @@
|
|||||||
|
import {
|
||||||
|
memo,
|
||||||
|
useCallback,
|
||||||
|
useMemo,
|
||||||
|
} from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import {
|
||||||
|
RiAddCircleFill,
|
||||||
|
} from '@remixicon/react'
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
} from '@/app/components/base/button'
|
||||||
|
import type {
|
||||||
|
CustomConfigurationModelFixedFields,
|
||||||
|
CustomModelCredential,
|
||||||
|
ModelProvider,
|
||||||
|
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
|
import { ConfigurationMethodEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
|
import Authorized from './authorized'
|
||||||
|
import { useAuth } from './hooks'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
|
type AddCustomModelProps = {
|
||||||
|
provider: ModelProvider,
|
||||||
|
configurationMethod: ConfigurationMethodEnum,
|
||||||
|
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields,
|
||||||
|
models: CustomModelCredential[]
|
||||||
|
}
|
||||||
|
const AddCustomModel = ({
|
||||||
|
provider,
|
||||||
|
configurationMethod,
|
||||||
|
currentCustomConfigurationModelFixedFields,
|
||||||
|
models,
|
||||||
|
}: AddCustomModelProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const noModels = !models.length
|
||||||
|
const {
|
||||||
|
handleOpenModal,
|
||||||
|
} = useAuth(provider, configurationMethod, currentCustomConfigurationModelFixedFields)
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
if (noModels)
|
||||||
|
handleOpenModal()
|
||||||
|
}, [handleOpenModal, noModels])
|
||||||
|
const ButtonComponent = useMemo(() => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant='ghost-accent'
|
||||||
|
size='small'
|
||||||
|
onClick={handleClick}
|
||||||
|
className={cn(noModels && 'text-text-accent')}
|
||||||
|
>
|
||||||
|
<RiAddCircleFill className='mr-1 h-3.5 w-3.5' />
|
||||||
|
{t('common.modelProvider.addModel')}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}, [handleClick, noModels])
|
||||||
|
|
||||||
|
const renderTrigger = useCallback(() => {
|
||||||
|
return ButtonComponent
|
||||||
|
}, [ButtonComponent])
|
||||||
|
|
||||||
|
if (noModels)
|
||||||
|
return ButtonComponent
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Authorized
|
||||||
|
provider={provider}
|
||||||
|
configurationMethod={ConfigurationMethodEnum.customizableModel}
|
||||||
|
items={models.map(model => ({
|
||||||
|
model,
|
||||||
|
credentials: model.available_model_credentials ?? [],
|
||||||
|
}))}
|
||||||
|
renderTrigger={renderTrigger}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(AddCustomModel)
|
||||||
@ -1,76 +0,0 @@
|
|||||||
import {
|
|
||||||
memo,
|
|
||||||
useState,
|
|
||||||
} from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import {
|
|
||||||
RiAddCircleFill,
|
|
||||||
RiAddLine,
|
|
||||||
} from '@remixicon/react'
|
|
||||||
import {
|
|
||||||
PortalToFollowElem,
|
|
||||||
PortalToFollowElemContent,
|
|
||||||
PortalToFollowElemTrigger,
|
|
||||||
} from '@/app/components/base/portal-to-follow-elem'
|
|
||||||
import Button from '@/app/components/base/button'
|
|
||||||
import Tooltip from '@/app/components/base/tooltip'
|
|
||||||
|
|
||||||
const AddModel = () => {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
const [open, setOpen] = useState(false)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PortalToFollowElem
|
|
||||||
placement='bottom-end'
|
|
||||||
offset={{
|
|
||||||
mainAxis: 4,
|
|
||||||
crossAxis: -4,
|
|
||||||
}}
|
|
||||||
open={open}
|
|
||||||
onOpenChange={setOpen}
|
|
||||||
>
|
|
||||||
<PortalToFollowElemTrigger>
|
|
||||||
<Button
|
|
||||||
variant='ghost-accent'
|
|
||||||
size='small'
|
|
||||||
>
|
|
||||||
<RiAddCircleFill className='mr-1 h-3.5 w-3.5' />
|
|
||||||
{t('common.modelProvider.addModel')}
|
|
||||||
</Button>
|
|
||||||
</PortalToFollowElemTrigger>
|
|
||||||
<PortalToFollowElemContent>
|
|
||||||
<div className='w-[360px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg'>
|
|
||||||
<div className='p-1'>
|
|
||||||
<div className='flex h-9 items-center'>
|
|
||||||
<div className='h-5 w-5 shrink-0'></div>
|
|
||||||
<div
|
|
||||||
className='system-md-medium mx-1 truncate text-text-primary'
|
|
||||||
title='chat-finetune-01'
|
|
||||||
>
|
|
||||||
chat-finetune-01
|
|
||||||
</div>
|
|
||||||
<Tooltip
|
|
||||||
asChild
|
|
||||||
popupContent='Add model credential'
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
className='h-6 w-6 rounded-full p-0'
|
|
||||||
size='small'
|
|
||||||
variant='secondary-accent'
|
|
||||||
>
|
|
||||||
<RiAddLine className='h-4 w-4' />
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='system-xs-medium flex h-10 cursor-pointer items-center border-t border-divider-subtle px-4 text-text-accent-light-mode-only'>
|
|
||||||
<RiAddLine className='mr-1 h-4 w-4' />
|
|
||||||
{t('common.modelProvider.addModel')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</PortalToFollowElemContent>
|
|
||||||
</PortalToFollowElem>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(AddModel)
|
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
import {
|
||||||
|
memo,
|
||||||
|
useCallback,
|
||||||
|
} from 'react'
|
||||||
|
import { RiAddLine } from '@remixicon/react'
|
||||||
|
import CredentialItem from './credential-item'
|
||||||
|
import type {
|
||||||
|
Credential,
|
||||||
|
CustomModel,
|
||||||
|
} from '../../declarations'
|
||||||
|
import Button from '@/app/components/base/button'
|
||||||
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
|
|
||||||
|
type AuthorizedItemProps = {
|
||||||
|
model?: CustomModel
|
||||||
|
disabled?: boolean
|
||||||
|
onDelete?: (id: string) => void
|
||||||
|
onEdit?: (model?: CustomModel, credential?: Credential) => void
|
||||||
|
onSetDefault?: (id: string) => void
|
||||||
|
onItemClick?: (id: string) => void
|
||||||
|
showItemSelectedIcon?: boolean
|
||||||
|
selectedCredentialId?: string
|
||||||
|
disableSetDefault?: boolean
|
||||||
|
credentials: Credential[]
|
||||||
|
}
|
||||||
|
export const AuthorizedItem = ({
|
||||||
|
model,
|
||||||
|
credentials,
|
||||||
|
disabled,
|
||||||
|
onDelete,
|
||||||
|
onEdit,
|
||||||
|
onSetDefault,
|
||||||
|
onItemClick,
|
||||||
|
showItemSelectedIcon,
|
||||||
|
selectedCredentialId,
|
||||||
|
disableSetDefault,
|
||||||
|
}: AuthorizedItemProps) => {
|
||||||
|
const handleEdit = useCallback((credential?: Credential) => {
|
||||||
|
onEdit?.(model, credential)
|
||||||
|
}, [onEdit, model])
|
||||||
|
return (
|
||||||
|
<div className='p-1'>
|
||||||
|
{
|
||||||
|
model && (
|
||||||
|
<div
|
||||||
|
className='flex h-9 items-center'
|
||||||
|
>
|
||||||
|
<div className='h-5 w-5 shrink-0'></div>
|
||||||
|
<div
|
||||||
|
className='system-md-medium mx-1 truncate text-text-primary'
|
||||||
|
title={model.model}
|
||||||
|
>
|
||||||
|
{model.model}
|
||||||
|
</div>
|
||||||
|
<Tooltip
|
||||||
|
asChild
|
||||||
|
popupContent='Add model credential'
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
className='h-6 w-6 rounded-full p-0'
|
||||||
|
size='small'
|
||||||
|
variant='secondary-accent'
|
||||||
|
>
|
||||||
|
<RiAddLine className='h-4 w-4' />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
credentials.map(credential => (
|
||||||
|
<CredentialItem
|
||||||
|
key={credential.credential_id}
|
||||||
|
credential={credential}
|
||||||
|
disabled={disabled}
|
||||||
|
onDelete={onDelete}
|
||||||
|
onEdit={handleEdit}
|
||||||
|
onSetDefault={onSetDefault}
|
||||||
|
onItemClick={onItemClick}
|
||||||
|
showSelectedIcon={showItemSelectedIcon}
|
||||||
|
selectedCredentialId={selectedCredentialId}
|
||||||
|
disableSetDefault={disableSetDefault}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(AuthorizedItem)
|
||||||
@ -15,11 +15,11 @@ import cn from '@/utils/classnames'
|
|||||||
import type { Credential } from '../../declarations'
|
import type { Credential } from '../../declarations'
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
|
|
||||||
type ItemProps = {
|
type CredentialItemProps = {
|
||||||
credential: Credential
|
credential: Credential
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
onDelete?: (id: string) => void
|
onDelete?: (id: string) => void
|
||||||
onEdit?: (credential: Credential) => void
|
onEdit?: (credential?: Credential) => void
|
||||||
onSetDefault?: (id: string) => void
|
onSetDefault?: (id: string) => void
|
||||||
disableRename?: boolean
|
disableRename?: boolean
|
||||||
disableEdit?: boolean
|
disableEdit?: boolean
|
||||||
@ -29,7 +29,7 @@ type ItemProps = {
|
|||||||
showSelectedIcon?: boolean
|
showSelectedIcon?: boolean
|
||||||
selectedCredentialId?: string
|
selectedCredentialId?: string
|
||||||
}
|
}
|
||||||
const Item = ({
|
const CredentialItem = ({
|
||||||
credential,
|
credential,
|
||||||
disabled,
|
disabled,
|
||||||
onDelete,
|
onDelete,
|
||||||
@ -42,7 +42,7 @@ const Item = ({
|
|||||||
onItemClick,
|
onItemClick,
|
||||||
showSelectedIcon,
|
showSelectedIcon,
|
||||||
selectedCredentialId,
|
selectedCredentialId,
|
||||||
}: ItemProps) => {
|
}: CredentialItemProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const showAction = useMemo(() => {
|
const showAction = useMemo(() => {
|
||||||
return !(disableRename && disableEdit && disableDelete && disableSetDefault)
|
return !(disableRename && disableEdit && disableDelete && disableSetDefault)
|
||||||
@ -131,4 +131,4 @@ const Item = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default memo(Item)
|
export default memo(CredentialItem)
|
||||||
@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
useRef,
|
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import {
|
import {
|
||||||
@ -19,17 +18,25 @@ import type {
|
|||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
import Confirm from '@/app/components/base/confirm'
|
import Confirm from '@/app/components/base/confirm'
|
||||||
import Item from './item'
|
import type {
|
||||||
import { useToastContext } from '@/app/components/base/toast'
|
ConfigurationMethodEnum,
|
||||||
import type { Credential } from '../../declarations'
|
Credential,
|
||||||
import {
|
CustomConfigurationModelFixedFields,
|
||||||
useDeleteModelCredential,
|
CustomModel,
|
||||||
useSetModelCredentialDefault,
|
ModelProvider,
|
||||||
} from '@/service/use-models'
|
} from '../../declarations'
|
||||||
|
import { useAuth } from '../hooks'
|
||||||
|
import AuthorizedItem from './authorized-item'
|
||||||
|
|
||||||
type AuthorizedProps = {
|
type AuthorizedProps = {
|
||||||
provider: string
|
provider: ModelProvider,
|
||||||
credentials: Credential[]
|
configurationMethod: ConfigurationMethodEnum,
|
||||||
|
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields,
|
||||||
|
items: {
|
||||||
|
model?: CustomModel
|
||||||
|
credentials: Credential[]
|
||||||
|
}[]
|
||||||
|
selectedCredential?: Credential
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
renderTrigger?: (open?: boolean) => React.ReactNode
|
renderTrigger?: (open?: boolean) => React.ReactNode
|
||||||
isOpen?: boolean
|
isOpen?: boolean
|
||||||
@ -40,13 +47,15 @@ type AuthorizedProps = {
|
|||||||
popupClassName?: string
|
popupClassName?: string
|
||||||
onItemClick?: (id: string) => void
|
onItemClick?: (id: string) => void
|
||||||
showItemSelectedIcon?: boolean
|
showItemSelectedIcon?: boolean
|
||||||
selectedCredentialId?: string
|
|
||||||
onUpdate?: () => void
|
onUpdate?: () => void
|
||||||
onSetup: (credential?: Credential) => void
|
disableSetDefault?: boolean
|
||||||
}
|
}
|
||||||
const Authorized = ({
|
const Authorized = ({
|
||||||
provider,
|
provider,
|
||||||
credentials,
|
configurationMethod,
|
||||||
|
currentCustomConfigurationModelFixedFields,
|
||||||
|
items,
|
||||||
|
selectedCredential,
|
||||||
disabled,
|
disabled,
|
||||||
renderTrigger,
|
renderTrigger,
|
||||||
isOpen,
|
isOpen,
|
||||||
@ -57,12 +66,10 @@ const Authorized = ({
|
|||||||
popupClassName,
|
popupClassName,
|
||||||
onItemClick,
|
onItemClick,
|
||||||
showItemSelectedIcon,
|
showItemSelectedIcon,
|
||||||
selectedCredentialId,
|
|
||||||
onUpdate,
|
onUpdate,
|
||||||
onSetup,
|
disableSetDefault,
|
||||||
}: AuthorizedProps) => {
|
}: AuthorizedProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { notify } = useToastContext()
|
|
||||||
const [isLocalOpen, setIsLocalOpen] = useState(false)
|
const [isLocalOpen, setIsLocalOpen] = useState(false)
|
||||||
const mergedIsOpen = isOpen ?? isLocalOpen
|
const mergedIsOpen = isOpen ?? isLocalOpen
|
||||||
const setMergedIsOpen = useCallback((open: boolean) => {
|
const setMergedIsOpen = useCallback((open: boolean) => {
|
||||||
@ -71,68 +78,20 @@ const Authorized = ({
|
|||||||
|
|
||||||
setIsLocalOpen(open)
|
setIsLocalOpen(open)
|
||||||
}, [onOpenChange])
|
}, [onOpenChange])
|
||||||
const pendingOperationCredentialId = useRef<string | null>(null)
|
const {
|
||||||
const [deleteCredentialId, setDeleteCredentialId] = useState<string | null>(null)
|
openConfirmDelete,
|
||||||
const openConfirm = useCallback((credentialId?: string) => {
|
closeConfirmDelete,
|
||||||
if (credentialId)
|
doingAction,
|
||||||
pendingOperationCredentialId.current = credentialId
|
handleActiveCredential,
|
||||||
|
handleConfirmDelete,
|
||||||
|
deleteCredentialId,
|
||||||
|
handleOpenModal,
|
||||||
|
} = useAuth(provider, configurationMethod, currentCustomConfigurationModelFixedFields, onUpdate)
|
||||||
|
|
||||||
setDeleteCredentialId(pendingOperationCredentialId.current)
|
const handleEdit = useCallback((model?: CustomModel, credential?: Credential) => {
|
||||||
}, [])
|
handleOpenModal(model, credential)
|
||||||
const closeConfirm = useCallback(() => {
|
|
||||||
setDeleteCredentialId(null)
|
|
||||||
pendingOperationCredentialId.current = null
|
|
||||||
}, [])
|
|
||||||
const [doingAction, setDoingAction] = useState(false)
|
|
||||||
const doingActionRef = useRef(doingAction)
|
|
||||||
const handleSetDoingAction = useCallback((doing: boolean) => {
|
|
||||||
doingActionRef.current = doing
|
|
||||||
setDoingAction(doing)
|
|
||||||
}, [])
|
|
||||||
const { mutateAsync: deleteModelCredential } = useDeleteModelCredential(provider)
|
|
||||||
const { mutateAsync: setModelCredentialDefault } = useSetModelCredentialDefault(provider)
|
|
||||||
const handleSetDefault = useCallback(async (id: string) => {
|
|
||||||
if (doingActionRef.current)
|
|
||||||
return
|
|
||||||
try {
|
|
||||||
handleSetDoingAction(true)
|
|
||||||
await setModelCredentialDefault(id)
|
|
||||||
notify({
|
|
||||||
type: 'success',
|
|
||||||
message: t('common.api.actionSuccess'),
|
|
||||||
})
|
|
||||||
onUpdate?.()
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
handleSetDoingAction(false)
|
|
||||||
}
|
|
||||||
}, [setModelCredentialDefault, onUpdate, notify, t, handleSetDoingAction])
|
|
||||||
const handleConfirm = useCallback(async () => {
|
|
||||||
if (doingActionRef.current)
|
|
||||||
return
|
|
||||||
if (!pendingOperationCredentialId.current) {
|
|
||||||
setDeleteCredentialId(null)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
handleSetDoingAction(true)
|
|
||||||
await deleteModelCredential(pendingOperationCredentialId.current)
|
|
||||||
notify({
|
|
||||||
type: 'success',
|
|
||||||
message: t('common.api.actionSuccess'),
|
|
||||||
})
|
|
||||||
onUpdate?.()
|
|
||||||
setDeleteCredentialId(null)
|
|
||||||
pendingOperationCredentialId.current = null
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
handleSetDoingAction(false)
|
|
||||||
}
|
|
||||||
}, [onUpdate, notify, t, handleSetDoingAction])
|
|
||||||
const handleOpenSetup = useCallback((credential?: Credential) => {
|
|
||||||
onSetup(credential)
|
|
||||||
setMergedIsOpen(false)
|
setMergedIsOpen(false)
|
||||||
}, [onSetup, setMergedIsOpen])
|
}, [handleOpenModal, setMergedIsOpen])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -166,39 +125,29 @@ const Authorized = ({
|
|||||||
'w-[360px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg',
|
'w-[360px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg',
|
||||||
popupClassName,
|
popupClassName,
|
||||||
)}>
|
)}>
|
||||||
<div className='max-h-[304px] overflow-y-auto py-1'>
|
<div className='max-h-[304px] overflow-y-auto'>
|
||||||
{
|
{
|
||||||
!!credentials.length && (
|
items.map((item, index) => (
|
||||||
<div className='p-1'>
|
<AuthorizedItem
|
||||||
<div className={cn(
|
key={index}
|
||||||
'system-xs-medium px-3 pb-0.5 pt-1 text-text-tertiary',
|
model={item.model}
|
||||||
showItemSelectedIcon && 'pl-7',
|
credentials={item.credentials}
|
||||||
)}>
|
disabled={disabled}
|
||||||
API Keys
|
onDelete={openConfirmDelete}
|
||||||
</div>
|
onEdit={handleEdit}
|
||||||
{
|
onSetDefault={handleActiveCredential}
|
||||||
credentials.map(credential => (
|
onItemClick={onItemClick}
|
||||||
<Item
|
showItemSelectedIcon={showItemSelectedIcon}
|
||||||
key={credential.credential_id}
|
selectedCredentialId={selectedCredential?.credential_id}
|
||||||
credential={credential}
|
disableSetDefault={disableSetDefault}
|
||||||
disabled={disabled}
|
/>
|
||||||
onDelete={openConfirm}
|
))
|
||||||
onEdit={handleOpenSetup}
|
|
||||||
onSetDefault={handleSetDefault}
|
|
||||||
onItemClick={onItemClick}
|
|
||||||
showSelectedIcon={showItemSelectedIcon}
|
|
||||||
selectedCredentialId={selectedCredentialId}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className='h-[1px] bg-divider-subtle'></div>
|
<div className='h-[1px] bg-divider-subtle'></div>
|
||||||
<div className='p-2'>
|
<div className='p-2'>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => handleOpenSetup()}
|
onClick={() => handleOpenModal()}
|
||||||
className='w-full'
|
className='w-full'
|
||||||
>
|
>
|
||||||
add api key
|
add api key
|
||||||
@ -211,10 +160,10 @@ const Authorized = ({
|
|||||||
deleteCredentialId && (
|
deleteCredentialId && (
|
||||||
<Confirm
|
<Confirm
|
||||||
isShow
|
isShow
|
||||||
title={t('datasetDocuments.list.delete.title')}
|
title={t('common.modelProvider.confirmDelete')}
|
||||||
isDisabled={doingAction}
|
isDisabled={doingAction}
|
||||||
onCancel={closeConfirm}
|
onCancel={closeConfirmDelete}
|
||||||
onConfirm={handleConfirm}
|
onConfirm={handleConfirmDelete}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,82 @@
|
|||||||
|
import {
|
||||||
|
memo,
|
||||||
|
useCallback,
|
||||||
|
useMemo,
|
||||||
|
} from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import {
|
||||||
|
RiEqualizer2Line,
|
||||||
|
} from '@remixicon/react'
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
} from '@/app/components/base/button'
|
||||||
|
import type {
|
||||||
|
CustomConfigurationModelFixedFields,
|
||||||
|
ModelProvider,
|
||||||
|
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
|
import { ConfigurationMethodEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
|
import Authorized from './authorized'
|
||||||
|
import { useAuth, useCredentialStatus } from './hooks'
|
||||||
|
|
||||||
|
type ConfigProviderProps = {
|
||||||
|
provider: ModelProvider,
|
||||||
|
configurationMethod: ConfigurationMethodEnum,
|
||||||
|
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields,
|
||||||
|
}
|
||||||
|
const ConfigProvider = ({
|
||||||
|
provider,
|
||||||
|
configurationMethod,
|
||||||
|
currentCustomConfigurationModelFixedFields,
|
||||||
|
}: ConfigProviderProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const {
|
||||||
|
handleOpenModal,
|
||||||
|
} = useAuth(provider, configurationMethod, currentCustomConfigurationModelFixedFields)
|
||||||
|
const {
|
||||||
|
hasCredential,
|
||||||
|
authorized,
|
||||||
|
current_credential_id,
|
||||||
|
current_credential_name,
|
||||||
|
available_credentials,
|
||||||
|
} = useCredentialStatus(provider)
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
if (!hasCredential)
|
||||||
|
handleOpenModal()
|
||||||
|
}, [handleOpenModal, hasCredential])
|
||||||
|
|
||||||
|
const ButtonComponent = useMemo(() => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className='grow'
|
||||||
|
size='small'
|
||||||
|
onClick={handleClick}
|
||||||
|
variant={!authorized ? 'secondary-accent' : 'secondary'}
|
||||||
|
>
|
||||||
|
<RiEqualizer2Line className='mr-1 h-3.5 w-3.5' />
|
||||||
|
{t('common.operation.setup')}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}, [handleClick, authorized])
|
||||||
|
|
||||||
|
if (!hasCredential)
|
||||||
|
return ButtonComponent
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Authorized
|
||||||
|
provider={provider}
|
||||||
|
configurationMethod={ConfigurationMethodEnum.predefinedModel}
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
credentials: available_credentials ?? [],
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
selectedCredential={{
|
||||||
|
credential_id: current_credential_id ?? '',
|
||||||
|
credential_name: current_credential_name ?? '',
|
||||||
|
}}
|
||||||
|
showItemSelectedIcon
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(ConfigProvider)
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
export * from './use-model-form-schemas'
|
||||||
|
export * from './use-credential-status'
|
||||||
|
export * from './use-custom-models'
|
||||||
|
export * from './use-auth'
|
||||||
|
export * from './use-auth-service'
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
import { useCallback } from 'react'
|
||||||
|
import {
|
||||||
|
useActiveModelCredential,
|
||||||
|
useActiveProviderCredential,
|
||||||
|
useAddModelCredential,
|
||||||
|
useAddProviderCredential,
|
||||||
|
useDeleteModelCredential,
|
||||||
|
useDeleteProviderCredential,
|
||||||
|
useEditModelCredential,
|
||||||
|
useEditProviderCredential,
|
||||||
|
useGetModelCredential,
|
||||||
|
useGetProviderCredential,
|
||||||
|
} from '@/service/use-models'
|
||||||
|
import type {
|
||||||
|
CustomModel,
|
||||||
|
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
|
|
||||||
|
export const useGetCredential = (provider: string, credentialId?: string, model?: CustomModel, configFrom?: string) => {
|
||||||
|
const providerData = useGetProviderCredential(!model && !!credentialId, provider, credentialId)
|
||||||
|
const modelData = useGetModelCredential(!!model && !!credentialId, provider, credentialId, model?.model, model?.model_type, configFrom)
|
||||||
|
return model ? modelData : providerData
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAuthService = (provider: string) => {
|
||||||
|
const { mutateAsync: addProviderCredential } = useAddProviderCredential(provider)
|
||||||
|
const { mutateAsync: editProviderCredential } = useEditProviderCredential(provider)
|
||||||
|
const { mutateAsync: deleteProviderCredential } = useDeleteProviderCredential(provider)
|
||||||
|
const { mutateAsync: activeProviderCredential } = useActiveProviderCredential(provider)
|
||||||
|
|
||||||
|
const { mutateAsync: addModelCredential } = useAddModelCredential(provider)
|
||||||
|
const { mutateAsync: activeModelCredential } = useActiveModelCredential(provider)
|
||||||
|
const { mutateAsync: deleteModelCredential } = useDeleteModelCredential(provider)
|
||||||
|
const { mutateAsync: editModelCredential } = useEditModelCredential(provider)
|
||||||
|
|
||||||
|
const getAddCredentialService = useCallback((isModel: boolean) => {
|
||||||
|
return isModel ? addModelCredential : addProviderCredential
|
||||||
|
}, [addModelCredential, addProviderCredential])
|
||||||
|
|
||||||
|
const getEditCredentialService = useCallback((isModel: boolean) => {
|
||||||
|
return isModel ? editModelCredential : editProviderCredential
|
||||||
|
}, [editModelCredential, editProviderCredential])
|
||||||
|
|
||||||
|
const getDeleteCredentialService = useCallback((isModel: boolean) => {
|
||||||
|
return isModel ? deleteModelCredential : deleteProviderCredential
|
||||||
|
}, [deleteModelCredential, deleteProviderCredential])
|
||||||
|
|
||||||
|
const getActiveCredentialService = useCallback((isModel: boolean) => {
|
||||||
|
return isModel ? activeModelCredential : activeProviderCredential
|
||||||
|
}, [activeModelCredential, activeProviderCredential])
|
||||||
|
|
||||||
|
return {
|
||||||
|
getAddCredentialService,
|
||||||
|
getEditCredentialService,
|
||||||
|
getDeleteCredentialService,
|
||||||
|
getActiveCredentialService,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,153 @@
|
|||||||
|
import {
|
||||||
|
useCallback,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { useToastContext } from '@/app/components/base/toast'
|
||||||
|
import { useAuthService } from './use-auth-service'
|
||||||
|
import type {
|
||||||
|
ConfigurationMethodEnum,
|
||||||
|
Credential,
|
||||||
|
CustomConfigurationModelFixedFields,
|
||||||
|
CustomModel,
|
||||||
|
ModelProvider,
|
||||||
|
} from '../../declarations'
|
||||||
|
import {
|
||||||
|
useModelModalHandler,
|
||||||
|
useRefreshModel,
|
||||||
|
} from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||||
|
|
||||||
|
export const useAuth = (
|
||||||
|
provider: ModelProvider,
|
||||||
|
configurationMethod: ConfigurationMethodEnum,
|
||||||
|
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields,
|
||||||
|
onUpdate?: () => void,
|
||||||
|
) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const { notify } = useToastContext()
|
||||||
|
const {
|
||||||
|
getDeleteCredentialService,
|
||||||
|
getActiveCredentialService,
|
||||||
|
getEditCredentialService,
|
||||||
|
getAddCredentialService,
|
||||||
|
} = useAuthService(provider.provider)
|
||||||
|
const handleOpenModelModal = useModelModalHandler()
|
||||||
|
const { handleRefreshModel } = useRefreshModel()
|
||||||
|
const pendingOperationCredentialId = useRef<string | null>(null)
|
||||||
|
const pendingOperationModel = useRef<CustomModel | null>(null)
|
||||||
|
const [deleteCredentialId, setDeleteCredentialId] = useState<string | null>(null)
|
||||||
|
const openConfirmDelete = useCallback((credentialId?: string, model?: CustomModel) => {
|
||||||
|
if (credentialId)
|
||||||
|
pendingOperationCredentialId.current = credentialId
|
||||||
|
if (model)
|
||||||
|
pendingOperationModel.current = model
|
||||||
|
|
||||||
|
setDeleteCredentialId(pendingOperationCredentialId.current)
|
||||||
|
}, [])
|
||||||
|
const closeConfirmDelete = useCallback(() => {
|
||||||
|
setDeleteCredentialId(null)
|
||||||
|
pendingOperationCredentialId.current = null
|
||||||
|
}, [])
|
||||||
|
const [doingAction, setDoingAction] = useState(false)
|
||||||
|
const doingActionRef = useRef(doingAction)
|
||||||
|
const handleSetDoingAction = useCallback((doing: boolean) => {
|
||||||
|
doingActionRef.current = doing
|
||||||
|
setDoingAction(doing)
|
||||||
|
}, [])
|
||||||
|
const handleActiveCredential = useCallback(async (id: string, model?: CustomModel) => {
|
||||||
|
if (doingActionRef.current)
|
||||||
|
return
|
||||||
|
try {
|
||||||
|
handleSetDoingAction(true)
|
||||||
|
await getActiveCredentialService(!!model)({
|
||||||
|
credential_id: id,
|
||||||
|
model: model?.model,
|
||||||
|
model_type: model?.model_type,
|
||||||
|
})
|
||||||
|
notify({
|
||||||
|
type: 'success',
|
||||||
|
message: t('common.api.actionSuccess'),
|
||||||
|
})
|
||||||
|
onUpdate?.()
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
handleSetDoingAction(false)
|
||||||
|
}
|
||||||
|
}, [getActiveCredentialService, onUpdate, notify, t, handleSetDoingAction])
|
||||||
|
const handleConfirmDelete = useCallback(async () => {
|
||||||
|
if (doingActionRef.current)
|
||||||
|
return
|
||||||
|
if (!pendingOperationCredentialId.current) {
|
||||||
|
setDeleteCredentialId(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
handleSetDoingAction(true)
|
||||||
|
await getDeleteCredentialService(!!pendingOperationModel.current)({
|
||||||
|
credential_id: pendingOperationCredentialId.current,
|
||||||
|
model: pendingOperationModel.current?.model,
|
||||||
|
model_type: pendingOperationModel.current?.model_type,
|
||||||
|
})
|
||||||
|
notify({
|
||||||
|
type: 'success',
|
||||||
|
message: t('common.api.actionSuccess'),
|
||||||
|
})
|
||||||
|
onUpdate?.()
|
||||||
|
handleRefreshModel(provider, configurationMethod, undefined)
|
||||||
|
setDeleteCredentialId(null)
|
||||||
|
pendingOperationCredentialId.current = null
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
handleSetDoingAction(false)
|
||||||
|
}
|
||||||
|
}, [onUpdate, notify, t, handleSetDoingAction, getDeleteCredentialService])
|
||||||
|
const handleAddCredential = useCallback((model?: CustomModel) => {
|
||||||
|
if (model)
|
||||||
|
pendingOperationModel.current = model
|
||||||
|
}, [])
|
||||||
|
const handleSaveCredential = useCallback(async (payload: Record<string, any>) => {
|
||||||
|
if (doingActionRef.current)
|
||||||
|
return
|
||||||
|
try {
|
||||||
|
handleSetDoingAction(true)
|
||||||
|
|
||||||
|
let res: { result?: string } = {}
|
||||||
|
if (payload.credential_id)
|
||||||
|
res = await getEditCredentialService(!!payload.model)(payload as any)
|
||||||
|
else
|
||||||
|
res = await getAddCredentialService(!!payload.model)(payload as any)
|
||||||
|
|
||||||
|
if (res.result === 'success') {
|
||||||
|
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
||||||
|
onUpdate?.()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
handleSetDoingAction(false)
|
||||||
|
}
|
||||||
|
}, [onUpdate, notify, t, handleSetDoingAction, getEditCredentialService, getAddCredentialService])
|
||||||
|
const handleOpenModal = useCallback((model?: CustomModel, credential?: Credential) => {
|
||||||
|
handleOpenModelModal(
|
||||||
|
provider,
|
||||||
|
configurationMethod,
|
||||||
|
currentCustomConfigurationModelFixedFields,
|
||||||
|
credential,
|
||||||
|
model,
|
||||||
|
)
|
||||||
|
}, [handleOpenModelModal, provider, configurationMethod, currentCustomConfigurationModelFixedFields])
|
||||||
|
|
||||||
|
return {
|
||||||
|
pendingOperationCredentialId,
|
||||||
|
pendingOperationModel,
|
||||||
|
openConfirmDelete,
|
||||||
|
closeConfirmDelete,
|
||||||
|
doingAction,
|
||||||
|
handleActiveCredential,
|
||||||
|
handleConfirmDelete,
|
||||||
|
handleAddCredential,
|
||||||
|
deleteCredentialId,
|
||||||
|
handleSaveCredential,
|
||||||
|
handleOpenModal,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
import { useMemo } from 'react'
|
||||||
|
import type {
|
||||||
|
ModelProvider,
|
||||||
|
} from '../../declarations'
|
||||||
|
|
||||||
|
export const useCredentialStatus = (provider: ModelProvider) => {
|
||||||
|
const {
|
||||||
|
current_credential_id,
|
||||||
|
current_credential_name,
|
||||||
|
available_credentials,
|
||||||
|
} = provider.custom_configuration
|
||||||
|
const hasCredential = !!available_credentials?.length
|
||||||
|
const authorized = current_credential_id && current_credential_name
|
||||||
|
const authRemoved = hasCredential && !current_credential_id && !current_credential_name
|
||||||
|
|
||||||
|
return useMemo(() => ({
|
||||||
|
hasCredential,
|
||||||
|
authorized,
|
||||||
|
authRemoved,
|
||||||
|
current_credential_id,
|
||||||
|
current_credential_name,
|
||||||
|
available_credentials,
|
||||||
|
}), [hasCredential, authorized, authRemoved, current_credential_id, current_credential_name, available_credentials])
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import type {
|
||||||
|
ModelProvider,
|
||||||
|
} from '../../declarations'
|
||||||
|
|
||||||
|
export const useCustomModels = (provider: ModelProvider) => {
|
||||||
|
const { custom_models } = provider.custom_configuration
|
||||||
|
|
||||||
|
return custom_models || []
|
||||||
|
}
|
||||||
@ -3,11 +3,11 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import type {
|
import type {
|
||||||
ModelLoadBalancingConfig,
|
ModelLoadBalancingConfig,
|
||||||
ModelProvider,
|
ModelProvider,
|
||||||
} from '../declarations'
|
} from '../../declarations'
|
||||||
import {
|
import {
|
||||||
genModelNameFormSchema,
|
genModelNameFormSchema,
|
||||||
genModelTypeFormSchema,
|
genModelTypeFormSchema,
|
||||||
} from '../utils'
|
} from '../../utils'
|
||||||
import { FormTypeEnum } from '@/app/components/base/form/types'
|
import { FormTypeEnum } from '@/app/components/base/form/types'
|
||||||
|
|
||||||
export const useModelFormSchemas = (
|
export const useModelFormSchemas = (
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
export { default as Authorized } from './authorized'
|
||||||
|
export { default as SwitchCredentialInLoadBalancing } from './switch-credential-in-load-balancing'
|
||||||
|
export { default as AddCredentialInLoadBalancing } from './add-credential-in-load-balancing'
|
||||||
|
export { default as AddCustomModel } from './add-custom-model'
|
||||||
|
export { default as ConfigProvider } from './config-provider'
|
||||||
@ -1,45 +1,107 @@
|
|||||||
|
import type { Dispatch, SetStateAction } from 'react'
|
||||||
import {
|
import {
|
||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
import { RiArrowDownSLine } from '@remixicon/react'
|
import { RiArrowDownSLine } from '@remixicon/react'
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
import {
|
|
||||||
AuthCategory,
|
|
||||||
Authorized,
|
|
||||||
} from '@/app/components/plugins/plugin-auth'
|
|
||||||
import Indicator from '@/app/components/header/indicator'
|
import Indicator from '@/app/components/header/indicator'
|
||||||
import Badge from '@/app/components/base/badge'
|
import Badge from '@/app/components/base/badge'
|
||||||
|
import Authorized from './authorized'
|
||||||
|
import type {
|
||||||
|
Credential,
|
||||||
|
ModelLoadBalancingConfig,
|
||||||
|
ModelProvider,
|
||||||
|
} from '../declarations'
|
||||||
|
import { ConfigurationMethodEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
|
import { useCredentialStatus } from './hooks'
|
||||||
|
import { useModelModalHandler } from '../hooks'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
|
type SwitchCredentialInLoadBalancingProps = {
|
||||||
|
provider: ModelProvider
|
||||||
|
draftConfig?: ModelLoadBalancingConfig
|
||||||
|
setDraftConfig: Dispatch<SetStateAction<ModelLoadBalancingConfig | undefined>>
|
||||||
|
}
|
||||||
|
const SwitchCredentialInLoadBalancing = ({
|
||||||
|
provider,
|
||||||
|
draftConfig,
|
||||||
|
setDraftConfig,
|
||||||
|
}: SwitchCredentialInLoadBalancingProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const {
|
||||||
|
available_credentials,
|
||||||
|
current_credential_name,
|
||||||
|
} = useCredentialStatus(provider)
|
||||||
|
const handleOpenModal = useModelModalHandler()
|
||||||
|
console.log(draftConfig, 'draftConfig')
|
||||||
|
|
||||||
|
const handleSetup = useCallback((credential?: Credential) => {
|
||||||
|
handleOpenModal(provider, ConfigurationMethodEnum.predefinedModel, undefined, credential)
|
||||||
|
}, [handleOpenModal, provider])
|
||||||
|
|
||||||
|
const handleItemClick = useCallback((id: string) => {
|
||||||
|
setDraftConfig((prev) => {
|
||||||
|
if (!prev)
|
||||||
|
return prev
|
||||||
|
const newConfigs = [...prev.configs]
|
||||||
|
const index = newConfigs.findIndex(config => config.name === '__inherit__')
|
||||||
|
const inheritConfig = newConfigs[index]
|
||||||
|
const modifiedConfig = inheritConfig ? {
|
||||||
|
...inheritConfig,
|
||||||
|
credential_id: id,
|
||||||
|
} : {
|
||||||
|
name: '__inherit__',
|
||||||
|
credential_id: id,
|
||||||
|
credentials: {},
|
||||||
|
}
|
||||||
|
newConfigs.splice(index, 1, modifiedConfig)
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
configs: newConfigs,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [setDraftConfig])
|
||||||
|
|
||||||
const SwitchCredentialInLoadBalancing = () => {
|
|
||||||
const renderTrigger = useCallback(() => {
|
const renderTrigger = useCallback(() => {
|
||||||
|
const selectedCredentialId = draftConfig?.configs.find(config => config.name === '__inherit__')?.credential_id
|
||||||
|
const selectedCredential = available_credentials?.find(credential => credential.credential_id === selectedCredentialId)
|
||||||
|
const name = selectedCredential?.credential_name || current_credential_name
|
||||||
|
const authRemoved = !!selectedCredentialId && !selectedCredential
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
variant='secondary'
|
variant='secondary'
|
||||||
className='space-x-1'
|
className={cn(
|
||||||
|
'shrink-0 space-x-1',
|
||||||
|
authRemoved && 'text-components-button-destructive-secondary-text',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<Indicator />
|
<Indicator
|
||||||
chat-enterprise
|
className='mr-2'
|
||||||
<Badge>enterprise</Badge>
|
color={authRemoved ? 'red' : 'green'}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
authRemoved ? t('common.model.authRemoved') : name
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!authRemoved && (
|
||||||
|
<Badge>enterprise</Badge>
|
||||||
|
)
|
||||||
|
}
|
||||||
<RiArrowDownSLine className='h-4 w-4' />
|
<RiArrowDownSLine className='h-4 w-4' />
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}, [])
|
}, [current_credential_name, t, draftConfig, available_credentials])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Authorized
|
<Authorized
|
||||||
credentials={[]}
|
provider={provider.provider}
|
||||||
pluginPayload={{
|
credentials={available_credentials || []}
|
||||||
provider: '',
|
onSetup={handleSetup}
|
||||||
category: AuthCategory.model,
|
|
||||||
}}
|
|
||||||
canApiKey
|
|
||||||
placement='bottom-end'
|
|
||||||
offset={{
|
|
||||||
mainAxis: 4,
|
|
||||||
crossAxis: -8,
|
|
||||||
}}
|
|
||||||
renderTrigger={renderTrigger}
|
renderTrigger={renderTrigger}
|
||||||
|
onItemClick={handleItemClick}
|
||||||
|
disableSetDefault
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,34 +2,20 @@ import type { FC } from 'react'
|
|||||||
import {
|
import {
|
||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import type {
|
import type {
|
||||||
CustomConfigurationModelFixedFields,
|
CustomConfigurationModelFixedFields,
|
||||||
ModelLoadBalancingConfig,
|
|
||||||
ModelLoadBalancingConfigEntry,
|
|
||||||
ModelProvider,
|
ModelProvider,
|
||||||
} from '../declarations'
|
} from '../declarations'
|
||||||
import {
|
import {
|
||||||
ConfigurationMethodEnum,
|
ConfigurationMethodEnum,
|
||||||
CustomConfigurationStatusEnum,
|
|
||||||
FormTypeEnum,
|
FormTypeEnum,
|
||||||
} from '../declarations'
|
} from '../declarations'
|
||||||
import {
|
|
||||||
genModelNameFormSchema,
|
|
||||||
genModelTypeFormSchema,
|
|
||||||
removeCredentials,
|
|
||||||
saveCredentials,
|
|
||||||
} from '../utils'
|
|
||||||
import {
|
import {
|
||||||
useLanguage,
|
useLanguage,
|
||||||
useProviderCredentialsAndLoadBalancing,
|
|
||||||
} from '../hooks'
|
} from '../hooks'
|
||||||
import ModelLoadBalancingConfigs from '../provider-added-card/model-load-balancing-configs'
|
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security'
|
import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security'
|
||||||
import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
|
import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
|
||||||
@ -37,7 +23,6 @@ import {
|
|||||||
PortalToFollowElem,
|
PortalToFollowElem,
|
||||||
PortalToFollowElemContent,
|
PortalToFollowElemContent,
|
||||||
} from '@/app/components/base/portal-to-follow-elem'
|
} from '@/app/components/base/portal-to-follow-elem'
|
||||||
import { useToastContext } from '@/app/components/base/toast'
|
|
||||||
import Confirm from '@/app/components/base/confirm'
|
import Confirm from '@/app/components/base/confirm'
|
||||||
import { useAppContext } from '@/context/app-context'
|
import { useAppContext } from '@/context/app-context'
|
||||||
import AuthForm from '@/app/components/base/form/form-scenarios/auth'
|
import AuthForm from '@/app/components/base/form/form-scenarios/auth'
|
||||||
@ -46,20 +31,29 @@ import type {
|
|||||||
FormSchema,
|
FormSchema,
|
||||||
} from '@/app/components/base/form/types'
|
} from '@/app/components/base/form/types'
|
||||||
import { useModelFormSchemas } from '../model-auth/hooks'
|
import { useModelFormSchemas } from '../model-auth/hooks'
|
||||||
import type { Credential } from '../declarations'
|
import type {
|
||||||
|
Credential,
|
||||||
|
CustomModel,
|
||||||
|
} from '../declarations'
|
||||||
import Loading from '@/app/components/base/loading'
|
import Loading from '@/app/components/base/loading'
|
||||||
|
import {
|
||||||
|
useAuth,
|
||||||
|
useGetCredential,
|
||||||
|
} from '@/app/components/header/account-setting/model-provider-page/model-auth/hooks'
|
||||||
|
|
||||||
type ModelModalProps = {
|
type ModelModalProps = {
|
||||||
provider: ModelProvider
|
provider: ModelProvider
|
||||||
|
model?: CustomModel
|
||||||
|
credential?: Credential
|
||||||
configurateMethod: ConfigurationMethodEnum
|
configurateMethod: ConfigurationMethodEnum
|
||||||
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields
|
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields
|
||||||
credential?: Credential
|
|
||||||
onCancel: () => void
|
onCancel: () => void
|
||||||
onSave: () => void
|
onSave: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModelModal: FC<ModelModalProps> = ({
|
const ModelModal: FC<ModelModalProps> = ({
|
||||||
provider,
|
provider,
|
||||||
|
model,
|
||||||
configurateMethod,
|
configurateMethod,
|
||||||
currentCustomConfigurationModelFixedFields,
|
currentCustomConfigurationModelFixedFields,
|
||||||
credential,
|
credential,
|
||||||
@ -68,134 +62,62 @@ const ModelModal: FC<ModelModalProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const providerFormSchemaPredefined = configurateMethod === ConfigurationMethodEnum.predefinedModel
|
const providerFormSchemaPredefined = configurateMethod === ConfigurationMethodEnum.predefinedModel
|
||||||
const {
|
const {
|
||||||
credentials: formSchemasValue,
|
|
||||||
loadBalancing: originalConfig,
|
|
||||||
mutate,
|
|
||||||
isLoading,
|
isLoading,
|
||||||
} = useProviderCredentialsAndLoadBalancing(
|
data: credentialData = {},
|
||||||
provider.provider,
|
} = useGetCredential(provider.provider, credential?.credential_id, model)
|
||||||
configurateMethod,
|
const {
|
||||||
providerFormSchemaPredefined && provider.custom_configuration.status === CustomConfigurationStatusEnum.active,
|
handleSaveCredential,
|
||||||
currentCustomConfigurationModelFixedFields,
|
handleConfirmDelete,
|
||||||
credential?.credential_id,
|
deleteCredentialId,
|
||||||
)
|
closeConfirmDelete,
|
||||||
|
openConfirmDelete,
|
||||||
|
doingAction,
|
||||||
|
} = useAuth(provider, configurateMethod, currentCustomConfigurationModelFixedFields, onSave)
|
||||||
|
const {
|
||||||
|
credentials: formSchemasValue,
|
||||||
|
} = credentialData as any
|
||||||
|
|
||||||
const { isCurrentWorkspaceManager } = useAppContext()
|
const { isCurrentWorkspaceManager } = useAppContext()
|
||||||
const isEditMode = !!formSchemasValue && isCurrentWorkspaceManager
|
const isEditMode = !!formSchemasValue && isCurrentWorkspaceManager
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { notify } = useToastContext()
|
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
const [loading, setLoading] = useState(false)
|
const { formSchemas } = useModelFormSchemas(provider, providerFormSchemaPredefined)
|
||||||
const [showConfirm, setShowConfirm] = useState(false)
|
|
||||||
|
|
||||||
const [draftConfig, setDraftConfig] = useState<ModelLoadBalancingConfig>()
|
|
||||||
const originalConfigMap = useMemo(() => {
|
|
||||||
if (!originalConfig)
|
|
||||||
return {}
|
|
||||||
return originalConfig?.configs.reduce((prev, config) => {
|
|
||||||
if (config.id)
|
|
||||||
prev[config.id] = config
|
|
||||||
return prev
|
|
||||||
}, {} as Record<string, ModelLoadBalancingConfigEntry>)
|
|
||||||
}, [originalConfig])
|
|
||||||
useEffect(() => {
|
|
||||||
if (originalConfig && !draftConfig)
|
|
||||||
setDraftConfig(originalConfig)
|
|
||||||
}, [draftConfig, originalConfig])
|
|
||||||
|
|
||||||
const { formSchemas } = useModelFormSchemas(provider, providerFormSchemaPredefined, draftConfig)
|
|
||||||
const formRef = useRef<FormRefObject>(null)
|
const formRef = useRef<FormRefObject>(null)
|
||||||
|
|
||||||
const extendedSecretFormSchemas = useMemo(
|
const handleSave = useCallback(async () => {
|
||||||
() =>
|
const {
|
||||||
(providerFormSchemaPredefined
|
isCheckValidated,
|
||||||
? provider.provider_credential_schema.credential_form_schemas
|
values,
|
||||||
: [
|
} = formRef.current?.getFormValues({
|
||||||
genModelTypeFormSchema(provider.supported_model_types),
|
needCheckValidatedValues: true,
|
||||||
genModelNameFormSchema(provider.model_credential_schema?.model),
|
needTransformWhenSecretFieldIsPristine: true,
|
||||||
...provider.model_credential_schema.credential_form_schemas,
|
}) || { isCheckValidated: false, values: {} }
|
||||||
]).filter(({ type }) => type === FormTypeEnum.secretInput),
|
if (!isCheckValidated)
|
||||||
[
|
return
|
||||||
provider.model_credential_schema?.credential_form_schemas,
|
|
||||||
provider.model_credential_schema?.model,
|
|
||||||
provider.provider_credential_schema?.credential_form_schemas,
|
|
||||||
provider.supported_model_types,
|
|
||||||
providerFormSchemaPredefined,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
const encodeConfigEntrySecretValues = useCallback((entry: ModelLoadBalancingConfigEntry) => {
|
const {
|
||||||
const result = { ...entry }
|
__authorization_name__,
|
||||||
extendedSecretFormSchemas.forEach(({ variable }) => {
|
__model_name,
|
||||||
if (entry.id && result.credentials[variable] === originalConfigMap[entry.id]?.credentials?.[variable])
|
__model_type,
|
||||||
result.credentials[variable] = '[__HIDDEN__]'
|
...rest
|
||||||
})
|
} = values
|
||||||
return result
|
if (__model_name && __model_type) {
|
||||||
}, [extendedSecretFormSchemas, originalConfigMap])
|
handleSaveCredential({
|
||||||
|
credential_id: credential?.credential_id,
|
||||||
const handleSave = async () => {
|
credentials: rest,
|
||||||
try {
|
name: __authorization_name__,
|
||||||
setLoading(true)
|
model: __model_name,
|
||||||
const {
|
model_type: __model_type,
|
||||||
isCheckValidated,
|
})
|
||||||
values,
|
|
||||||
} = formRef.current?.getFormValues({
|
|
||||||
needCheckValidatedValues: true,
|
|
||||||
needTransformWhenSecretFieldIsPristine: true,
|
|
||||||
}) || { isCheckValidated: false, values: {} }
|
|
||||||
if (!isCheckValidated)
|
|
||||||
return
|
|
||||||
|
|
||||||
const res = await saveCredentials(
|
|
||||||
providerFormSchemaPredefined,
|
|
||||||
provider.provider,
|
|
||||||
values,
|
|
||||||
{
|
|
||||||
...draftConfig,
|
|
||||||
enabled: Boolean(draftConfig?.enabled),
|
|
||||||
configs: draftConfig?.configs.map(encodeConfigEntrySecretValues) || [],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if (res.result === 'success') {
|
|
||||||
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
|
||||||
mutate()
|
|
||||||
onSave()
|
|
||||||
onCancel()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally {
|
else {
|
||||||
setLoading(false)
|
handleSaveCredential({
|
||||||
|
credential_id: credential?.credential_id,
|
||||||
|
credentials: rest,
|
||||||
|
name: __authorization_name__,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}, [handleSaveCredential, credential?.credential_id, model])
|
||||||
|
|
||||||
const handleRemove = async () => {
|
|
||||||
try {
|
|
||||||
setLoading(true)
|
|
||||||
const {
|
|
||||||
isCheckValidated,
|
|
||||||
values,
|
|
||||||
} = formRef.current?.getFormValues({
|
|
||||||
needCheckValidatedValues: true,
|
|
||||||
needTransformWhenSecretFieldIsPristine: true,
|
|
||||||
}) || { isCheckValidated: false, values: {} }
|
|
||||||
if (!isCheckValidated)
|
|
||||||
return
|
|
||||||
const res = await removeCredentials(
|
|
||||||
providerFormSchemaPredefined,
|
|
||||||
provider.provider,
|
|
||||||
values,
|
|
||||||
credential?.credential_id,
|
|
||||||
)
|
|
||||||
if (res.result === 'success') {
|
|
||||||
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
|
||||||
// mutate()
|
|
||||||
onSave()
|
|
||||||
onCancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const renderTitlePrefix = () => {
|
const renderTitlePrefix = () => {
|
||||||
const prefix = isEditMode ? t('common.operation.setup') : t('common.operation.add')
|
const prefix = isEditMode ? t('common.operation.setup') : t('common.operation.add')
|
||||||
@ -239,20 +161,6 @@ const ModelModal: FC<ModelModalProps> = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
!!draftConfig && (
|
|
||||||
<>
|
|
||||||
<div className='mb-4 mt-1 border-t-[0.5px] border-t-divider-regular' />
|
|
||||||
<ModelLoadBalancingConfigs withSwitch {...{
|
|
||||||
draftConfig,
|
|
||||||
setDraftConfig,
|
|
||||||
provider,
|
|
||||||
currentCustomConfigurationModelFixedFields,
|
|
||||||
configurationMethod: configurateMethod,
|
|
||||||
}} />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='sticky bottom-0 -mx-2 mt-2 flex flex-wrap items-center justify-between gap-y-2 bg-components-panel-bg px-2 pb-6 pt-4'>
|
<div className='sticky bottom-0 -mx-2 mt-2 flex flex-wrap items-center justify-between gap-y-2 bg-components-panel-bg px-2 pb-6 pt-4'>
|
||||||
@ -278,7 +186,7 @@ const ModelModal: FC<ModelModalProps> = ({
|
|||||||
variant='warning'
|
variant='warning'
|
||||||
size='large'
|
size='large'
|
||||||
className='mr-2'
|
className='mr-2'
|
||||||
onClick={() => setShowConfirm(true)}
|
onClick={() => openConfirmDelete(credential?.credential_id, model)}
|
||||||
>
|
>
|
||||||
{t('common.operation.remove')}
|
{t('common.operation.remove')}
|
||||||
</Button>
|
</Button>
|
||||||
@ -295,11 +203,7 @@ const ModelModal: FC<ModelModalProps> = ({
|
|||||||
size='large'
|
size='large'
|
||||||
variant='primary'
|
variant='primary'
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
disabled={
|
disabled={isLoading || doingAction}
|
||||||
loading
|
|
||||||
|| (draftConfig?.enabled && (draftConfig?.configs.filter(config => config.enabled).length ?? 0) < 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
>
|
>
|
||||||
{t('common.operation.save')}
|
{t('common.operation.save')}
|
||||||
</Button>
|
</Button>
|
||||||
@ -322,12 +226,13 @@ const ModelModal: FC<ModelModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
showConfirm && (
|
deleteCredentialId && (
|
||||||
<Confirm
|
<Confirm
|
||||||
|
isShow
|
||||||
title={t('common.modelProvider.confirmDelete')}
|
title={t('common.modelProvider.confirmDelete')}
|
||||||
isShow={showConfirm}
|
isDisabled={doingAction}
|
||||||
onCancel={() => setShowConfirm(false)}
|
onCancel={closeConfirmDelete}
|
||||||
onConfirm={handleRemove}
|
onConfirm={handleConfirmDelete}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { RiEqualizer2Line } from '@remixicon/react'
|
|
||||||
import type {
|
import type {
|
||||||
Credential,
|
|
||||||
ModelProvider,
|
ModelProvider,
|
||||||
} from '../declarations'
|
} from '../declarations'
|
||||||
import {
|
import {
|
||||||
@ -18,22 +16,18 @@ import PrioritySelector from './priority-selector'
|
|||||||
import PriorityUseTip from './priority-use-tip'
|
import PriorityUseTip from './priority-use-tip'
|
||||||
import { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './index'
|
import { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './index'
|
||||||
import Indicator from '@/app/components/header/indicator'
|
import Indicator from '@/app/components/header/indicator'
|
||||||
import Button from '@/app/components/base/button'
|
|
||||||
import { changeModelProviderPriority } from '@/service/common'
|
import { changeModelProviderPriority } from '@/service/common'
|
||||||
import { useToastContext } from '@/app/components/base/toast'
|
import { useToastContext } from '@/app/components/base/toast'
|
||||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||||
import Authorized from '../model-auth/authorized'
|
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
import { useCredentialStatus } from '@/app/components/header/account-setting/model-provider-page/model-auth/hooks'
|
||||||
|
import { ConfigProvider } from '@/app/components/header/account-setting/model-provider-page/model-auth'
|
||||||
|
|
||||||
type CredentialPanelProps = {
|
type CredentialPanelProps = {
|
||||||
provider: ModelProvider
|
provider: ModelProvider
|
||||||
onSetup: (credential?: Credential) => void
|
|
||||||
onUpdate: () => void
|
|
||||||
}
|
}
|
||||||
const CredentialPanel = ({
|
const CredentialPanel = ({
|
||||||
provider,
|
provider,
|
||||||
onSetup,
|
|
||||||
onUpdate,
|
|
||||||
}: CredentialPanelProps) => {
|
}: CredentialPanelProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { notify } = useToastContext()
|
const { notify } = useToastContext()
|
||||||
@ -46,13 +40,11 @@ const CredentialPanel = ({
|
|||||||
const isCustomConfigured = customConfig.status === CustomConfigurationStatusEnum.active
|
const isCustomConfigured = customConfig.status === CustomConfigurationStatusEnum.active
|
||||||
const configurateMethods = provider.configurate_methods
|
const configurateMethods = provider.configurate_methods
|
||||||
const {
|
const {
|
||||||
current_credential_id,
|
hasCredential,
|
||||||
|
authorized,
|
||||||
|
authRemoved,
|
||||||
current_credential_name,
|
current_credential_name,
|
||||||
available_credentials,
|
} = useCredentialStatus(provider)
|
||||||
} = provider.custom_configuration
|
|
||||||
const hasCredential = !!available_credentials?.length
|
|
||||||
const authorized = current_credential_id && current_credential_name
|
|
||||||
const authRemoved = hasCredential && !current_credential_id && !current_credential_name
|
|
||||||
|
|
||||||
const handleChangePriority = async (key: PreferredProviderTypeEnum) => {
|
const handleChangePriority = async (key: PreferredProviderTypeEnum) => {
|
||||||
const res = await changeModelProviderPriority({
|
const res = await changeModelProviderPriority({
|
||||||
@ -108,31 +100,10 @@ const CredentialPanel = ({
|
|||||||
<Indicator className='shrink-0' color={authorized ? 'green' : 'red'} />
|
<Indicator className='shrink-0' color={authorized ? 'green' : 'red'} />
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center gap-0.5'>
|
<div className='flex items-center gap-0.5'>
|
||||||
{
|
<ConfigProvider
|
||||||
!hasCredential && (
|
provider={provider}
|
||||||
<Button
|
configurationMethod={ConfigurationMethodEnum.predefinedModel}
|
||||||
className='grow'
|
/>
|
||||||
size='small'
|
|
||||||
onClick={() => onSetup()}
|
|
||||||
variant={!authorized ? 'secondary-accent' : 'secondary'}
|
|
||||||
>
|
|
||||||
<RiEqualizer2Line className='mr-1 h-3.5 w-3.5' />
|
|
||||||
{t('common.operation.setup')}
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
(hasCredential || authRemoved) && (
|
|
||||||
<Authorized
|
|
||||||
provider={provider.provider}
|
|
||||||
onSetup={onSetup}
|
|
||||||
credentials={available_credentials ?? []}
|
|
||||||
selectedCredentialId={current_credential_id}
|
|
||||||
showItemSelectedIcon
|
|
||||||
onUpdate={onUpdate}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
systemConfig.enabled && isCustomConfigured && (
|
systemConfig.enabled && isCustomConfigured && (
|
||||||
<PrioritySelector
|
<PrioritySelector
|
||||||
|
|||||||
@ -28,7 +28,6 @@ import { useEventEmitterContextContext } from '@/context/event-emitter'
|
|||||||
import { IS_CE_EDITION } from '@/config'
|
import { IS_CE_EDITION } from '@/config'
|
||||||
import { useAppContext } from '@/context/app-context'
|
import { useAppContext } from '@/context/app-context'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
import { useRefreshModel } from '../hooks'
|
|
||||||
|
|
||||||
export const UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST = 'UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST'
|
export const UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST = 'UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST'
|
||||||
type ProviderAddedCardProps = {
|
type ProviderAddedCardProps = {
|
||||||
@ -82,8 +81,6 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({
|
|||||||
getModelList(v.payload)
|
getModelList(v.payload)
|
||||||
})
|
})
|
||||||
|
|
||||||
const { handleRefreshModel } = useRefreshModel()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
@ -118,8 +115,6 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({
|
|||||||
{
|
{
|
||||||
showCredential && (
|
showCredential && (
|
||||||
<CredentialPanel
|
<CredentialPanel
|
||||||
onSetup={(credential?: Credential) => onOpenModal(ConfigurationMethodEnum.predefinedModel, undefined, credential)}
|
|
||||||
onUpdate={() => handleRefreshModel(provider, ConfigurationMethodEnum.predefinedModel, undefined)}
|
|
||||||
provider={provider}
|
provider={provider}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import {
|
|||||||
RiArrowRightSLine,
|
RiArrowRightSLine,
|
||||||
} from '@remixicon/react'
|
} from '@remixicon/react'
|
||||||
import type {
|
import type {
|
||||||
|
Credential,
|
||||||
CustomConfigurationModelFixedFields,
|
CustomConfigurationModelFixedFields,
|
||||||
ModelItem,
|
ModelItem,
|
||||||
ModelProvider,
|
ModelProvider,
|
||||||
@ -13,10 +14,11 @@ import {
|
|||||||
ConfigurationMethodEnum,
|
ConfigurationMethodEnum,
|
||||||
} from '../declarations'
|
} from '../declarations'
|
||||||
// import Tab from './tab'
|
// import Tab from './tab'
|
||||||
import AddModelButton from './add-model-button'
|
|
||||||
import ModelListItem from './model-list-item'
|
import ModelListItem from './model-list-item'
|
||||||
import { useModalContextSelector } from '@/context/modal-context'
|
import { useModalContextSelector } from '@/context/modal-context'
|
||||||
import { useAppContext } from '@/context/app-context'
|
import { useAppContext } from '@/context/app-context'
|
||||||
|
import { useCustomModels } from '@/app/components/header/account-setting/model-provider-page/model-auth/hooks'
|
||||||
|
import { AddCustomModel } from '@/app/components/header/account-setting/model-provider-page/model-auth'
|
||||||
|
|
||||||
type ModelListProps = {
|
type ModelListProps = {
|
||||||
provider: ModelProvider
|
provider: ModelProvider
|
||||||
@ -36,11 +38,12 @@ const ModelList: FC<ModelListProps> = ({
|
|||||||
const configurativeMethods = provider.configurate_methods.filter(method => method !== ConfigurationMethodEnum.fetchFromRemote)
|
const configurativeMethods = provider.configurate_methods.filter(method => method !== ConfigurationMethodEnum.fetchFromRemote)
|
||||||
const { isCurrentWorkspaceManager } = useAppContext()
|
const { isCurrentWorkspaceManager } = useAppContext()
|
||||||
const isConfigurable = configurativeMethods.includes(ConfigurationMethodEnum.customizableModel)
|
const isConfigurable = configurativeMethods.includes(ConfigurationMethodEnum.customizableModel)
|
||||||
|
const customModels = useCustomModels(provider)
|
||||||
const setShowModelLoadBalancingModal = useModalContextSelector(state => state.setShowModelLoadBalancingModal)
|
const setShowModelLoadBalancingModal = useModalContextSelector(state => state.setShowModelLoadBalancingModal)
|
||||||
const onModifyLoadBalancing = useCallback((model: ModelItem) => {
|
const onModifyLoadBalancing = useCallback((model: ModelItem, credential?: Credential) => {
|
||||||
setShowModelLoadBalancingModal({
|
setShowModelLoadBalancingModal({
|
||||||
provider,
|
provider,
|
||||||
|
credential,
|
||||||
model: model!,
|
model: model!,
|
||||||
open: !!model,
|
open: !!model,
|
||||||
onClose: () => setShowModelLoadBalancingModal(null),
|
onClose: () => setShowModelLoadBalancingModal(null),
|
||||||
@ -65,17 +68,15 @@ const ModelList: FC<ModelListProps> = ({
|
|||||||
<RiArrowRightSLine className='mr-0.5 h-4 w-4 rotate-90' />
|
<RiArrowRightSLine className='mr-0.5 h-4 w-4 rotate-90' />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
{/* {
|
|
||||||
isConfigurable && canSystemConfig && (
|
|
||||||
<span className='flex items-center'>
|
|
||||||
<Tab active='all' onSelect={() => {}} />
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
} */}
|
|
||||||
{
|
{
|
||||||
isConfigurable && isCurrentWorkspaceManager && (
|
isConfigurable && isCurrentWorkspaceManager && (
|
||||||
<div className='flex grow justify-end'>
|
<div className='flex grow justify-end'>
|
||||||
<AddModelButton onClick={() => onConfig()} />
|
<AddCustomModel
|
||||||
|
provider={provider}
|
||||||
|
configurationMethod={ConfigurationMethodEnum.customizableModel}
|
||||||
|
currentCustomConfigurationModelFixedFields={undefined}
|
||||||
|
models={customModels}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import classNames from '@/utils/classnames'
|
|||||||
import Tooltip from '@/app/components/base/tooltip'
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
import Switch from '@/app/components/base/switch'
|
import Switch from '@/app/components/base/switch'
|
||||||
import { Balance } from '@/app/components/base/icons/src/vender/line/financeAndECommerce'
|
import { Balance } from '@/app/components/base/icons/src/vender/line/financeAndECommerce'
|
||||||
import { Edit02, Plus02 } from '@/app/components/base/icons/src/vender/line/general'
|
import { Edit02 } from '@/app/components/base/icons/src/vender/line/general'
|
||||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
|
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
|
||||||
import { useModalContextSelector } from '@/context/modal-context'
|
import { useModalContextSelector } from '@/context/modal-context'
|
||||||
import UpgradeBtn from '@/app/components/billing/upgrade-btn'
|
import UpgradeBtn from '@/app/components/billing/upgrade-btn'
|
||||||
@ -19,6 +19,7 @@ import s from '@/app/components/custom/style.module.css'
|
|||||||
import GridMask from '@/app/components/base/grid-mask'
|
import GridMask from '@/app/components/base/grid-mask'
|
||||||
import { useProviderContextSelector } from '@/context/provider-context'
|
import { useProviderContextSelector } from '@/context/provider-context'
|
||||||
import { IS_CE_EDITION } from '@/config'
|
import { IS_CE_EDITION } from '@/config'
|
||||||
|
import { AddCredentialInLoadBalancing } from '@/app/components/header/account-setting/model-provider-page/model-auth'
|
||||||
|
|
||||||
export type ModelLoadBalancingConfigsProps = {
|
export type ModelLoadBalancingConfigsProps = {
|
||||||
draftConfig?: ModelLoadBalancingConfig
|
draftConfig?: ModelLoadBalancingConfig
|
||||||
@ -234,15 +235,10 @@ const ModelLoadBalancingConfigs = ({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
<AddCredentialInLoadBalancing
|
||||||
<div
|
provider={provider}
|
||||||
className='mt-1 flex h-8 items-center px-3 text-[13px] font-medium text-primary-600'
|
onSetup={() => toggleEntryModal()}
|
||||||
onClick={() => toggleEntryModal()}
|
/>
|
||||||
>
|
|
||||||
<div className='flex cursor-pointer items-center'>
|
|
||||||
<Plus02 className='mr-2 h-3 w-3' />{t('common.modelProvider.addConfig')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
import type { ModelItem, ModelLoadBalancingConfig, ModelLoadBalancingConfigEntry, ModelProvider } from '../declarations'
|
import type {
|
||||||
|
Credential,
|
||||||
|
ModelItem,
|
||||||
|
ModelLoadBalancingConfig,
|
||||||
|
ModelLoadBalancingConfigEntry,
|
||||||
|
ModelProvider,
|
||||||
|
} from '../declarations'
|
||||||
import { FormTypeEnum } from '../declarations'
|
import { FormTypeEnum } from '../declarations'
|
||||||
import ModelIcon from '../model-icon'
|
import ModelIcon from '../model-icon'
|
||||||
import ModelName from '../model-name'
|
import ModelName from '../model-name'
|
||||||
@ -13,17 +19,26 @@ import Button from '@/app/components/base/button'
|
|||||||
import { fetchModelLoadBalancingConfig } from '@/service/common'
|
import { fetchModelLoadBalancingConfig } from '@/service/common'
|
||||||
import Loading from '@/app/components/base/loading'
|
import Loading from '@/app/components/base/loading'
|
||||||
import { useToastContext } from '@/app/components/base/toast'
|
import { useToastContext } from '@/app/components/base/toast'
|
||||||
|
import { SwitchCredentialInLoadBalancing } from '@/app/components/header/account-setting/model-provider-page/model-auth'
|
||||||
|
|
||||||
export type ModelLoadBalancingModalProps = {
|
export type ModelLoadBalancingModalProps = {
|
||||||
provider: ModelProvider
|
provider: ModelProvider
|
||||||
model: ModelItem
|
model: ModelItem
|
||||||
|
credential?: Credential
|
||||||
open?: boolean
|
open?: boolean
|
||||||
onClose?: () => void
|
onClose?: () => void
|
||||||
onSave?: (provider: string) => void
|
onSave?: (provider: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
// model balancing config modal
|
// model balancing config modal
|
||||||
const ModelLoadBalancingModal = ({ provider, model, open = false, onClose, onSave }: ModelLoadBalancingModalProps) => {
|
const ModelLoadBalancingModal = ({
|
||||||
|
provider,
|
||||||
|
model,
|
||||||
|
credential,
|
||||||
|
open = false,
|
||||||
|
onClose,
|
||||||
|
onSave,
|
||||||
|
}: ModelLoadBalancingModalProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { notify } = useToastContext()
|
const { notify } = useToastContext()
|
||||||
|
|
||||||
@ -152,6 +167,11 @@ const ModelLoadBalancingModal = ({ provider, model, open = false, onClose, onSav
|
|||||||
<div className='text-sm text-text-secondary'>{t('common.modelProvider.providerManaged')}</div>
|
<div className='text-sm text-text-secondary'>{t('common.modelProvider.providerManaged')}</div>
|
||||||
<div className='text-xs text-text-tertiary'>{t('common.modelProvider.providerManagedDescription')}</div>
|
<div className='text-xs text-text-tertiary'>{t('common.modelProvider.providerManagedDescription')}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<SwitchCredentialInLoadBalancing
|
||||||
|
draftConfig={draftConfig}
|
||||||
|
setDraftConfig={setDraftConfig}
|
||||||
|
provider={provider}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { ValidatedStatus } from '../key-validator/declarations'
|
import { ValidatedStatus } from '../key-validator/declarations'
|
||||||
import type {
|
import type {
|
||||||
CredentialFormSchemaRadio,
|
|
||||||
CredentialFormSchemaTextInput,
|
CredentialFormSchemaTextInput,
|
||||||
FormValue,
|
FormValue,
|
||||||
ModelLoadBalancingConfig,
|
ModelLoadBalancingConfig,
|
||||||
@ -181,7 +180,7 @@ export const genModelTypeFormSchema = (modelTypes: ModelTypeEnum[]) => {
|
|||||||
show_on: [],
|
show_on: [],
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
} as CredentialFormSchemaRadio
|
} as any
|
||||||
}
|
}
|
||||||
|
|
||||||
export const genModelNameFormSchema = (model?: Pick<CredentialFormSchemaTextInput, 'label' | 'placeholder'>) => {
|
export const genModelNameFormSchema = (model?: Pick<CredentialFormSchemaTextInput, 'label' | 'placeholder'>) => {
|
||||||
@ -198,5 +197,5 @@ export const genModelNameFormSchema = (model?: Pick<CredentialFormSchemaTextInpu
|
|||||||
zh_Hans: '请输入模型名称',
|
zh_Hans: '请输入模型名称',
|
||||||
en_US: 'Please enter model name',
|
en_US: 'Please enter model name',
|
||||||
},
|
},
|
||||||
} as CredentialFormSchemaTextInput
|
} as any
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import type {
|
|||||||
ConfigurationMethodEnum,
|
ConfigurationMethodEnum,
|
||||||
Credential,
|
Credential,
|
||||||
CustomConfigurationModelFixedFields,
|
CustomConfigurationModelFixedFields,
|
||||||
|
CustomModel,
|
||||||
ModelLoadBalancingConfigEntry,
|
ModelLoadBalancingConfigEntry,
|
||||||
ModelProvider,
|
ModelProvider,
|
||||||
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
@ -81,6 +82,7 @@ export type ModelModalType = {
|
|||||||
currentConfigurationMethod: ConfigurationMethodEnum
|
currentConfigurationMethod: ConfigurationMethodEnum
|
||||||
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields
|
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields
|
||||||
credential?: Credential
|
credential?: Credential
|
||||||
|
model?: CustomModel
|
||||||
}
|
}
|
||||||
export type LoadBalancingEntryModalType = ModelModalType & {
|
export type LoadBalancingEntryModalType = ModelModalType & {
|
||||||
entry?: ModelLoadBalancingConfigEntry
|
entry?: ModelLoadBalancingConfigEntry
|
||||||
@ -338,6 +340,7 @@ export const ModalContextProvider = ({
|
|||||||
<ModelModal
|
<ModelModal
|
||||||
provider={showModelModal.payload.currentProvider}
|
provider={showModelModal.payload.currentProvider}
|
||||||
configurateMethod={showModelModal.payload.currentConfigurationMethod}
|
configurateMethod={showModelModal.payload.currentConfigurationMethod}
|
||||||
|
model={showModelModal.payload.model}
|
||||||
currentCustomConfigurationModelFixedFields={showModelModal.payload.currentCustomConfigurationModelFixedFields}
|
currentCustomConfigurationModelFixedFields={showModelModal.payload.currentCustomConfigurationModelFixedFields}
|
||||||
credential={showModelModal.payload.credential}
|
credential={showModelModal.payload.credential}
|
||||||
onCancel={handleCancelModelModal}
|
onCancel={handleCancelModelModal}
|
||||||
|
|||||||
@ -2,9 +2,13 @@ import {
|
|||||||
del,
|
del,
|
||||||
get,
|
get,
|
||||||
post,
|
post,
|
||||||
|
put,
|
||||||
} from './base'
|
} from './base'
|
||||||
import type {
|
import type {
|
||||||
|
ModelCredential,
|
||||||
ModelItem,
|
ModelItem,
|
||||||
|
ModelTypeEnum,
|
||||||
|
ProviderCredential,
|
||||||
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||||
import {
|
import {
|
||||||
useMutation,
|
useMutation,
|
||||||
@ -21,35 +25,114 @@ export const useModelProviderModelList = (provider: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAddModelCredential = (providerName: string) => {
|
export const useGetProviderCredential = (enabled: boolean, provider: string, credentialId?: string) => {
|
||||||
return useMutation({
|
|
||||||
mutationFn: (data: any) => post<{ result: string }>(`/workspaces/current/model-providers/${providerName}/credentials`, data),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useGetModelCredential = (providerName: string, credentialId: string) => {
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: [NAME_SPACE, 'model-credential', providerName, credentialId],
|
enabled,
|
||||||
queryFn: () => get<{ data: Credential[] }>(`/workspaces/current/model-providers/${providerName}/credentials?credential_id=${credentialId}`),
|
queryKey: [NAME_SPACE, 'model-list', provider, credentialId],
|
||||||
|
queryFn: () => get<{ data: ProviderCredential }>(`/workspaces/current/model-providers/${provider}/credentials${credentialId ? `?credential_id=${credentialId}` : ''}`),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDeleteModelCredential = (providerName: string) => {
|
export const useAddProviderCredential = (provider: string) => {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: (credentialId: string) => del<{ result: string }>(`/workspaces/current/model-providers/${providerName}/credentials`, {
|
mutationFn: (data: ProviderCredential) => post<{ result: string }>(`/workspaces/current/model-providers/${provider}/credentials`, {
|
||||||
body: {
|
body: data,
|
||||||
credential_id: credentialId,
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSetModelCredentialDefault = (providerName: string) => {
|
export const useEditProviderCredential = (provider: string) => {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: (credentialId: string) => post<{ result: string }>(`/workspaces/current/model-providers/${providerName}/credentials/switch`, {
|
mutationFn: (data: ProviderCredential) => put<{ result: string }>(`/workspaces/current/model-providers/${provider}/credentials`, {
|
||||||
body: {
|
body: data,
|
||||||
credential_id: credentialId,
|
}),
|
||||||
},
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDeleteProviderCredential = (provider: string) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (data: {
|
||||||
|
credential_id: string
|
||||||
|
}) => del<{ result: string }>(`/workspaces/current/model-providers/${provider}/credentials`, {
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useActiveProviderCredential = (provider: string) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (data: {
|
||||||
|
credential_id: string
|
||||||
|
model?: string
|
||||||
|
model_type?: ModelTypeEnum
|
||||||
|
}) => post<{ result: string }>(`/workspaces/current/model-providers/${provider}/credentials/switch`, {
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useGetModelCredential = (
|
||||||
|
enabled: boolean,
|
||||||
|
provider: string,
|
||||||
|
credentialId?: string,
|
||||||
|
model?: string,
|
||||||
|
modelType?: string,
|
||||||
|
configFrom?: string,
|
||||||
|
) => {
|
||||||
|
return useQuery({
|
||||||
|
enabled,
|
||||||
|
queryKey: [NAME_SPACE, 'model-list', provider, model, modelType, credentialId],
|
||||||
|
queryFn: () => get<{ data: ModelCredential }>(`/workspaces/current/model-providers/${provider}/models/credentials?model=${model}&model_type=${modelType}$credential_id=${credentialId}$config_from=${configFrom}`),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAddModelCredential = (provider: string) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (data: ModelCredential) => post<{ result: string }>(`/workspaces/current/model-providers/${provider}/models/credentials`, {
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useEditModelCredential = (provider: string) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (data: ModelCredential) => put<{ result: string }>(`/workspaces/current/model-providers/${provider}/models/credentials`, {
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDeleteModelCredential = (provider: string) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (data: {
|
||||||
|
credential_id: string
|
||||||
|
model?: string
|
||||||
|
model_type?: ModelTypeEnum
|
||||||
|
}) => del<{ result: string }>(`/workspaces/current/model-providers/${provider}/models/credentials`, {
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDeleteModel = (provider: string) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (data: {
|
||||||
|
model: string
|
||||||
|
model_type: ModelTypeEnum
|
||||||
|
}) => del<{ result: string }>(`/workspaces/current/model-providers/${provider}/models/credentials`, {
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useActiveModelCredential = (provider: string) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (data: {
|
||||||
|
credential_id: string
|
||||||
|
model?: string
|
||||||
|
model_type?: ModelTypeEnum
|
||||||
|
}) => post<{ result: string }>(`/workspaces/current/model-providers/${provider}/models/credentials/switch`, {
|
||||||
|
body: data,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user