'use client' import React, { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' import { AuthHeaderPrefix, AuthType, CollectionType } from '../types' import type { Collection, CustomCollectionBackend, Tool, WorkflowToolProviderRequest, WorkflowToolProviderResponse } from '../types' import ToolItem from './tool-item' import cn from '@/utils/classnames' import I18n from '@/context/i18n' import { getLanguage } from '@/i18n/language' import Confirm from '@/app/components/base/confirm' import AppIcon from '@/app/components/base/app-icon' import Button from '@/app/components/base/button' import Indicator from '@/app/components/header/indicator' import { LinkExternal02, Settings01 } from '@/app/components/base/icons/src/vender/line/general' import ConfigCredential from '@/app/components/tools/setting/build-in/config-credentials' import EditCustomToolModal from '@/app/components/tools/edit-custom-collection-modal' import WorkflowToolModal from '@/app/components/tools/workflow-tool' import Toast from '@/app/components/base/toast' import { deleteWorkflowTool, fetchBuiltInToolList, fetchCustomCollection, fetchCustomToolList, fetchModelToolList, fetchWorkflowToolDetail, removeBuiltInToolCredential, removeCustomCollection, saveWorkflowToolProvider, updateBuiltInToolCredential, updateCustomCollection, } from '@/service/tools' import { useModalContext } from '@/context/modal-context' import { useProviderContext } from '@/context/provider-context' import { ConfigurationMethodEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import Loading from '@/app/components/base/loading' import { useAppContext } from '@/context/app-context' type Props = { collection: Collection onRefreshData: () => void } const ProviderDetail = ({ collection, onRefreshData, }: Props) => { const { t } = useTranslation() const { locale } = useContext(I18n) const language = getLanguage(locale) const needAuth = collection.allow_delete || collection.type === CollectionType.model const isAuthed = collection.is_team_authorization const isBuiltIn = collection.type === CollectionType.builtIn const isModel = collection.type === CollectionType.model const { isCurrentWorkspaceManager } = useAppContext() const [isDetailLoading, setIsDetailLoading] = useState(false) // built in provider const [showSettingAuth, setShowSettingAuth] = useState(false) const { setShowModelModal } = useModalContext() const { modelProviders: providers } = useProviderContext() const showSettingAuthModal = () => { if (isModel) { const provider = providers.find(item => item.provider === collection?.id) if (provider) { setShowModelModal({ payload: { currentProvider: provider, currentConfigurationMethod: ConfigurationMethodEnum.predefinedModel, currentCustomConfigurationModelFixedFields: undefined, }, onSaveCallback: () => { onRefreshData() }, }) } } else { setShowSettingAuth(true) } } // custom provider const [customCollection, setCustomCollection] = useState(null) const [isShowEditCollectionToolModal, setIsShowEditCustomCollectionModal] = useState(false) const [showConfirmDelete, setShowConfirmDelete] = useState(false) const [deleteAction, setDeleteAction] = useState('') const doUpdateCustomToolCollection = async (data: CustomCollectionBackend) => { await updateCustomCollection(data) onRefreshData() Toast.notify({ type: 'success', message: t('common.api.actionSuccess'), }) setIsShowEditCustomCollectionModal(false) } const doRemoveCustomToolCollection = async () => { await removeCustomCollection(collection?.name as string) onRefreshData() Toast.notify({ type: 'success', message: t('common.api.actionSuccess'), }) setIsShowEditCustomCollectionModal(false) } const getCustomProvider = useCallback(async () => { setIsDetailLoading(true) const res = await fetchCustomCollection(collection.name) if (res.credentials.auth_type === AuthType.apiKey && !res.credentials.api_key_header_prefix) { if (res.credentials.api_key_value) res.credentials.api_key_header_prefix = AuthHeaderPrefix.custom } setCustomCollection({ ...res, labels: collection.labels, provider: collection.name, }) setIsDetailLoading(false) }, [collection.labels, collection.name]) // workflow provider const [isShowEditWorkflowToolModal, setIsShowEditWorkflowToolModal] = useState(false) const getWorkflowToolProvider = useCallback(async () => { setIsDetailLoading(true) const res = await fetchWorkflowToolDetail(collection.id) const payload = { ...res, parameters: res.tool?.parameters.map((item) => { return { name: item.name, description: item.llm_description, form: item.form, required: item.required, type: item.type, } }) || [], labels: res.tool?.labels || [], } setCustomCollection(payload) setIsDetailLoading(false) }, [collection.id]) const removeWorkflowToolProvider = async () => { await deleteWorkflowTool(collection.id) onRefreshData() Toast.notify({ type: 'success', message: t('common.api.actionSuccess'), }) setIsShowEditWorkflowToolModal(false) } const updateWorkflowToolProvider = async (data: WorkflowToolProviderRequest & Partial<{ workflow_app_id: string workflow_tool_id: string }>) => { await saveWorkflowToolProvider(data) onRefreshData() getWorkflowToolProvider() Toast.notify({ type: 'success', message: t('common.api.actionSuccess'), }) setIsShowEditWorkflowToolModal(false) } const onClickCustomToolDelete = () => { setDeleteAction('customTool') setShowConfirmDelete(true) } const onClickWorkflowToolDelete = () => { setDeleteAction('workflowTool') setShowConfirmDelete(true) } const handleConfirmDelete = () => { if (deleteAction === 'customTool') doRemoveCustomToolCollection() else if (deleteAction === 'workflowTool') removeWorkflowToolProvider() setShowConfirmDelete(false) } // ToolList const [toolList, setToolList] = useState([]) const getProviderToolList = useCallback(async () => { setIsDetailLoading(true) try { if (collection.type === CollectionType.builtIn) { const list = await fetchBuiltInToolList(collection.name) setToolList(list) } else if (collection.type === CollectionType.model) { const list = await fetchModelToolList(collection.name) setToolList(list) } else if (collection.type === CollectionType.workflow) { setToolList([]) } else { const list = await fetchCustomToolList(collection.name) setToolList(list) } } catch (e) { } setIsDetailLoading(false) }, [collection.name, collection.type]) useEffect(() => { if (collection.type === CollectionType.custom) getCustomProvider() if (collection.type === CollectionType.workflow) getWorkflowToolProvider() getProviderToolList() }, [collection.name, collection.type, getCustomProvider, getProviderToolList, getWorkflowToolProvider]) return (
{typeof collection.icon === 'string' && (
)} {typeof collection.icon !== 'string' && ( )}
{collection.label[language]}
{collection.description[language]}
{(collection.type === CollectionType.builtIn) && needAuth && ( )} {collection.type === CollectionType.custom && !isDetailLoading && ( )} {collection.type === CollectionType.workflow && !isDetailLoading && customCollection && ( <> )}
{/* Tools */}
{isDetailLoading &&
} {!isDetailLoading && (
{collection.type === CollectionType.workflow && {t('tools.createTool.toolInput.title').toLocaleUpperCase()}} {collection.type !== CollectionType.workflow && {t('tools.includeToolNum', { num: toolList.length }).toLocaleUpperCase()}} {needAuth && (isBuiltIn || isModel) && !isAuthed && ( <> ยท {t('tools.auth.setup').toLocaleUpperCase()} )}
)} {!isDetailLoading && (
{collection.type !== CollectionType.workflow && toolList.map(tool => ( ))} {collection.type === CollectionType.workflow && (customCollection as WorkflowToolProviderResponse)?.tool?.parameters.map(item => (
{item.name} {item.type} {item.required ? t('tools.createTool.toolInput.required') : ''}
{item.llm_description}
))}
)}
{showSettingAuth && ( setShowSettingAuth(false)} onSaved={async (value) => { await updateBuiltInToolCredential(collection.name, value) Toast.notify({ type: 'success', message: t('common.api.actionSuccess'), }) await onRefreshData() setShowSettingAuth(false) }} onRemove={async () => { await removeBuiltInToolCredential(collection.name) Toast.notify({ type: 'success', message: t('common.api.actionSuccess'), }) await onRefreshData() setShowSettingAuth(false) }} /> )} {isShowEditCollectionToolModal && ( setIsShowEditCustomCollectionModal(false)} onEdit={doUpdateCustomToolCollection} onRemove={onClickCustomToolDelete} /> )} {isShowEditWorkflowToolModal && ( setIsShowEditWorkflowToolModal(false)} onRemove={onClickWorkflowToolDelete} onSave={updateWorkflowToolProvider} /> )} {showConfirmDelete && ( setShowConfirmDelete(false)} /> )}
) } export default ProviderDetail