feat: added error handling and knowledge base provider support

This commit is contained in:
kangfenmao 2025-01-02 14:16:37 +08:00
parent 3fc7911c97
commit 6384525e20
9 changed files with 75 additions and 12 deletions

View File

@ -573,6 +573,7 @@
"directory_placeholder": "Enter Directory Path",
"model_info": "Model Info",
"not_support": "Knowledge base database engine updated, the knowledge base will no longer be supported, please create a new knowledge base",
"no_provider": "Knowledge base model provider is not set, the knowledge base will no longer be supported, please create a new knowledge base",
"source": "Source"
},
"models": {

View File

@ -556,7 +556,11 @@
"sitemap_placeholder": "サイトマップURLを入力",
"directories": "ディレクトリ",
"add_directory": "ディレクトリを追加",
"directory_placeholder": "ディレクトリパスを入力"
"directory_placeholder": "ディレクトリパスを入力",
"model_info": "モデル情報",
"not_support": "ナレッジベースデータベースエンジンが更新されました。このナレッジベースはもうサポートされていません。新しいナレッジベースを作成してください",
"no_provider": "ナレッジベースモデルプロバイダーが設定されていません。ナレッジベースはもうサポートされていません。新しいナレッジベースを作成してください",
"source": "ソース"
},
"models": {
"pinned": "固定済み",

View File

@ -573,6 +573,7 @@
"directory_placeholder": "Введите путь к директории",
"model_info": "Модель информации",
"not_support": "База знаний базы данных движок обновлен, база знаний больше не поддерживается, пожалуйста, создайте новую базу знаний",
"no_provider": "База знаний модель поставщика не настроена, база знаний больше не поддерживается, пожалуйста, создайте новую базу знаний",
"source": "Источник"
},
"models": {

View File

@ -562,6 +562,7 @@
"directory_placeholder": "请输入目录路径",
"model_info": "模型信息",
"not_support": "知识库数据库引擎已更新,该知识库将不再支持,请重新创建知识库",
"no_provider": "知识库模型服务商丢失,该知识库将不再支持,请重新创建知识库",
"source": "来源"
},
"models": {

View File

@ -561,6 +561,7 @@
"directory_placeholder": "請輸入目錄路徑",
"model_info": "模型信息",
"not_support": "知識庫數據庫引擎已更新,該知識庫將不再支持,請重新創建知識庫",
"no_provider": "知識庫模型提供商遺失,該知識庫將不再支持,請重新創建知識庫",
"source": "來源"
},
"models": {

View File

@ -391,6 +391,7 @@ const Container = styled(Scrollbar)`
padding: 0 10px;
padding-right: 5px;
padding-top: 2px;
padding-bottom: 10px;
`
const Label = styled.p`
@ -410,7 +411,7 @@ const SettingRowTitleSmall = styled(SettingRowTitle)`
`
export const SettingGroup = styled.div<{ theme?: ThemeMode }>`
padding: 10px 5px;
padding: 0 5px;
width: 100%;
margin-top: 0;
border-radius: 8px;

View File

@ -4,7 +4,7 @@ import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup'
import { isLocalAi } from '@renderer/config/env'
import { isVisionModel } from '@renderer/config/models'
import { useAssistant } from '@renderer/hooks/useAssistant'
import { getProviderByModel } from '@renderer/services/AssistantService'
import { getProviderName } from '@renderer/services/ProviderService'
import { Assistant } from '@renderer/types'
import { Button } from 'antd'
import { FC } from 'react'
@ -31,13 +31,14 @@ const SelectModelButton: FC<Props> = ({ assistant }) => {
}
}
const providerName = getProviderName(model?.provider)
return (
<DropdownButton size="small" type="default" onClick={onSelectModel}>
<ButtonContent>
<ModelAvatar model={model} size={20} />
<ModelName>
{model ? model.name : t('button.select_model')} |{' '}
{t(`provider.${model?.provider}`, { defaultValue: getProviderByModel(model)?.name })}
{model ? model.name : t('button.select_model')} {providerName ? '| ' + providerName : ''}
</ModelName>
{isVisionModel(model) && <VisionIcon style={{ marginLeft: 0 }} />}
</ButtonContent>

View File

@ -13,6 +13,7 @@ import TextEditPopup from '@renderer/components/Popups/TextEditPopup'
import Scrollbar from '@renderer/components/Scrollbar'
import { useKnowledge } from '@renderer/hooks/useKnowledge'
import FileManager from '@renderer/services/FileManager'
import { getProviderName } from '@renderer/services/ProviderService'
import { FileType, FileTypes, KnowledgeBase } from '@renderer/types'
import { Alert, Button, Card, Divider, message, Tag, Typography, Upload } from 'antd'
import { FC } from 'react'
@ -74,11 +75,17 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
addDirectory
} = useKnowledge(selectedBase.id || '')
const providerName = getProviderName(base?.model.provider || '')
const disabled = !base?.version || !providerName
if (!base) {
return null
}
const handleAddFile = () => {
if (disabled) {
return
}
const input = document.createElement('input')
input.type = 'file'
input.multiple = true
@ -91,6 +98,10 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
}
const handleDrop = async (files: File[]) => {
if (disabled) {
return
}
if (files) {
const _files: FileType[] = files.map((file) => ({
id: file.name,
@ -110,6 +121,10 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
}
const handleAddUrl = async () => {
if (disabled) {
return
}
const url = await PromptPopup.show({
title: t('knowledge_base.add_url'),
message: '',
@ -135,6 +150,10 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
}
const handleAddSitemap = async () => {
if (disabled) {
return
}
const url = await PromptPopup.show({
title: t('knowledge_base.add_sitemap'),
message: '',
@ -160,16 +179,28 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
}
const handleAddNote = async () => {
if (disabled) {
return
}
const note = await TextEditPopup.show({ text: '', textareaProps: { rows: 20 } })
note && addNote(note)
}
const handleEditNote = async (note: any) => {
if (disabled) {
return
}
const editedText = await TextEditPopup.show({ text: note.content as string, textareaProps: { rows: 20 } })
editedText && updateNoteContent(note.id, editedText)
}
const handleAddDirectory = async () => {
if (disabled) {
return
}
const path = await window.api.file.selectFolder()
console.log('[KnowledgeContent] Selected directory:', path)
path && addDirectory(path)
@ -180,10 +211,13 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
{!base?.version && (
<Alert message={t('knowledge_base.not_support')} type="error" style={{ marginBottom: 20 }} showIcon />
)}
{!providerName && (
<Alert message={t('knowledge_base.no_provider')} type="error" style={{ marginBottom: 20 }} showIcon />
)}
<FileSection>
<TitleWrapper>
<Title level={5}>{t('files.title')}</Title>
<Button icon={<PlusOutlined />} onClick={handleAddFile}>
<Button icon={<PlusOutlined />} onClick={handleAddFile} disabled={disabled}>
{t('knowledge_base.add_file')}
</Button>
</TitleWrapper>
@ -223,7 +257,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
<ContentSection>
<TitleWrapper>
<Title level={5}>{t('knowledge_base.directories')}</Title>
<Button icon={<PlusOutlined />} onClick={handleAddDirectory}>
<Button icon={<PlusOutlined />} onClick={handleAddDirectory} disabled={disabled}>
{t('knowledge_base.add_directory')}
</Button>
</TitleWrapper>
@ -250,7 +284,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
<ContentSection>
<TitleWrapper>
<Title level={5}>{t('knowledge_base.urls')}</Title>
<Button icon={<PlusOutlined />} onClick={handleAddUrl}>
<Button icon={<PlusOutlined />} onClick={handleAddUrl} disabled={disabled}>
{t('knowledge_base.add_url')}
</Button>
</TitleWrapper>
@ -277,7 +311,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
<ContentSection>
<TitleWrapper>
<Title level={5}>{t('knowledge_base.sitemaps')}</Title>
<Button icon={<PlusOutlined />} onClick={handleAddSitemap}>
<Button icon={<PlusOutlined />} onClick={handleAddSitemap} disabled={disabled}>
{t('knowledge_base.add_sitemap')}
</Button>
</TitleWrapper>
@ -304,7 +338,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
<ContentSection>
<TitleWrapper>
<Title level={5}>{t('knowledge_base.notes')}</Title>
<Button icon={<PlusOutlined />} onClick={handleAddNote}>
<Button icon={<PlusOutlined />} onClick={handleAddNote} disabled={disabled}>
{t('knowledge_base.add_note')}
</Button>
</TitleWrapper>
@ -332,11 +366,15 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
<label htmlFor="model-info">{t('knowledge_base.model_info')}</label>
<Tag color="blue">{base.model.name}</Tag>
<Tag color="cyan">{t('models.dimensions', { dimensions: base.dimensions || 0 })}</Tag>
<Tag color="purple">{base.model.provider}</Tag>
{providerName && <Tag color="purple">{providerName}</Tag>}
</ModelInfo>
<IndexSection>
<Button type="primary" onClick={() => KnowledgeSearchPopup.show({ base })} icon={<SearchOutlined />}>
<Button
type="primary"
onClick={() => KnowledgeSearchPopup.show({ base })}
icon={<SearchOutlined />}
disabled={disabled}>
{t('knowledge_base.search')}
</Button>
</IndexSection>

View File

@ -0,0 +1,15 @@
import i18n from '@renderer/i18n'
import store from '@renderer/store'
export function getProviderName(id: string) {
const provider = store.getState().llm.providers.find((p) => p.id === id)
if (!provider) {
return ''
}
if (provider.isSystem) {
return i18n.t(`provider.${provider.id}`, { defaultValue: provider.name })
}
return provider?.name
}